commit 1dbe3feb4079342040749d3d5b16f4fda9f2b85d Author: root Date: Thu Apr 4 01:51:47 2024 +0000 first commit diff --git a/AMBETools-20140519.zip b/AMBETools-20140519.zip new file mode 100755 index 0000000..6b36267 Binary files /dev/null and b/AMBETools-20140519.zip differ diff --git a/AMBETools/AMBETools.sln b/AMBETools/AMBETools.sln new file mode 100755 index 0000000..1163f1c --- /dev/null +++ b/AMBETools/AMBETools.sln @@ -0,0 +1,74 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DVToolReader", "DVToolReader\DVToolReader.vcproj", "{415003E0-04C2-4757-B47B-D1465C3FE461}" + ProjectSection(ProjectDependencies) = postProject + {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} = {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "Common\Common.vcproj", "{EF9E87F7-40A0-4916-AB29-00F9A4526A7B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DVToolWriter", "DVToolWriter\DVToolWriter.vcproj", "{034377C2-0DA9-4D11-B882-D8B8F120B663}" + ProjectSection(ProjectDependencies) = postProject + {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} = {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wav2ambe", "wav2ambe\wav2ambe.vcproj", "{18684994-D6B0-40EF-A9BE-C148EF2BD5EC}" + ProjectSection(ProjectDependencies) = postProject + {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} = {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wav2dvtool", "wav2dvtool\wav2dvtool.vcproj", "{34B0F1FA-82D0-4A8A-BCE3-8EE54A5C44A1}" + ProjectSection(ProjectDependencies) = postProject + {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} = {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ambe2wav", "ambe2wav\ambe2wav.vcproj", "{8C55A75D-7BE1-4DCE-82D9-DEB44D8A369B}" + ProjectSection(ProjectDependencies) = postProject + {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} = {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dvtool2wav", "dvtool2wav\dvtool2wav.vcproj", "{1633EFC4-CEB7-455A-8587-10FE7ABB33AB}" + ProjectSection(ProjectDependencies) = postProject + {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} = {EF9E87F7-40A0-4916-AB29-00F9A4526A7B} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {415003E0-04C2-4757-B47B-D1465C3FE461}.Debug|Win32.ActiveCfg = Debug|Win32 + {415003E0-04C2-4757-B47B-D1465C3FE461}.Debug|Win32.Build.0 = Debug|Win32 + {415003E0-04C2-4757-B47B-D1465C3FE461}.Release|Win32.ActiveCfg = Release|Win32 + {415003E0-04C2-4757-B47B-D1465C3FE461}.Release|Win32.Build.0 = Release|Win32 + {EF9E87F7-40A0-4916-AB29-00F9A4526A7B}.Debug|Win32.ActiveCfg = Debug|Win32 + {EF9E87F7-40A0-4916-AB29-00F9A4526A7B}.Debug|Win32.Build.0 = Debug|Win32 + {EF9E87F7-40A0-4916-AB29-00F9A4526A7B}.Release|Win32.ActiveCfg = Release|Win32 + {EF9E87F7-40A0-4916-AB29-00F9A4526A7B}.Release|Win32.Build.0 = Release|Win32 + {034377C2-0DA9-4D11-B882-D8B8F120B663}.Debug|Win32.ActiveCfg = Debug|Win32 + {034377C2-0DA9-4D11-B882-D8B8F120B663}.Debug|Win32.Build.0 = Debug|Win32 + {034377C2-0DA9-4D11-B882-D8B8F120B663}.Release|Win32.ActiveCfg = Release|Win32 + {034377C2-0DA9-4D11-B882-D8B8F120B663}.Release|Win32.Build.0 = Release|Win32 + {18684994-D6B0-40EF-A9BE-C148EF2BD5EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {18684994-D6B0-40EF-A9BE-C148EF2BD5EC}.Debug|Win32.Build.0 = Debug|Win32 + {18684994-D6B0-40EF-A9BE-C148EF2BD5EC}.Release|Win32.ActiveCfg = Release|Win32 + {18684994-D6B0-40EF-A9BE-C148EF2BD5EC}.Release|Win32.Build.0 = Release|Win32 + {34B0F1FA-82D0-4A8A-BCE3-8EE54A5C44A1}.Debug|Win32.ActiveCfg = Debug|Win32 + {34B0F1FA-82D0-4A8A-BCE3-8EE54A5C44A1}.Debug|Win32.Build.0 = Debug|Win32 + {34B0F1FA-82D0-4A8A-BCE3-8EE54A5C44A1}.Release|Win32.ActiveCfg = Release|Win32 + {34B0F1FA-82D0-4A8A-BCE3-8EE54A5C44A1}.Release|Win32.Build.0 = Release|Win32 + {8C55A75D-7BE1-4DCE-82D9-DEB44D8A369B}.Debug|Win32.ActiveCfg = Debug|Win32 + {8C55A75D-7BE1-4DCE-82D9-DEB44D8A369B}.Debug|Win32.Build.0 = Debug|Win32 + {8C55A75D-7BE1-4DCE-82D9-DEB44D8A369B}.Release|Win32.ActiveCfg = Release|Win32 + {8C55A75D-7BE1-4DCE-82D9-DEB44D8A369B}.Release|Win32.Build.0 = Release|Win32 + {1633EFC4-CEB7-455A-8587-10FE7ABB33AB}.Debug|Win32.ActiveCfg = Debug|Win32 + {1633EFC4-CEB7-455A-8587-10FE7ABB33AB}.Debug|Win32.Build.0 = Debug|Win32 + {1633EFC4-CEB7-455A-8587-10FE7ABB33AB}.Release|Win32.ActiveCfg = Release|Win32 + {1633EFC4-CEB7-455A-8587-10FE7ABB33AB}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/AMBETools/BUILD.txt b/AMBETools/BUILD.txt new file mode 100755 index 0000000..c8b2f89 --- /dev/null +++ b/AMBETools/BUILD.txt @@ -0,0 +1,62 @@ +AMBE Tools - 20140519 +===================== + +Windows +------- + +To use the AMBE Tools software (D-Star only at present) you will first need to +build the latest version of wxWidgets (http://www.wxwidgets.org), the version I +used was 2.8.12, I also installed it in the default location which is +C:\wxWidgets-2.8.12. + +You will also need a copy of PortAudio (http://www.portaudio.com), I used the +latest stable version which is currently 20071207 and it appears to be fine. I +put that into the "Visual Studio 2008\Projects" folder alongside the source code +for Digital Voice itself. + +For compiling I use Visual C++ 2008 Express Edition downloaded from Microsoft +for free. I recommend that you use the same. + +To build wxWidgets, you simply need to open Visual Studio 2008 using the File -> +Open -> Projects/Solutions and load the wx_dll.dsw file to be found in +wxWidgets-2.8.12\build\msw directory and then go into Batch Build and select the +DLL Unicode Debug and DLL Uncode Release entries for every one, this take a +little time! Then build them. + +The path names for things like wxWidgets and PortAudio are embedded within the +Solution and Project preferences, and will need changing if anything other than +these default locations are used. The first pass through the compiler will no +doubt tell you all that you need to know if there are problems. + +Once you have built the executables, you will need to copy the +portaudio_x86.dll, wxbase28u_vc_custom.dll, wxmsw28u_adv_vc_custom.dll, and +wxmsw28u_core_vc_custom.dll files to the same directory as your newly built +executables in order for it to run. If you are running in debug mode then the +required wxWidgets files have the names xxx28ud_xxxx instead. These can be found +in the wxWidgets-2.8.12\lib\vc_dll directory. + +It is also probable that you'll need to install a copy of the latest Visual C++ +run-time libraries from Microsoft, if you are not running the Digital Voice +software on the same machine as the development/compilation was done on. To do +this you need to copy and run the Vcredist_x86.exe file which is found at + + +Linux +----- + +You need to ensure that wxGTK and PortAudio are already installed on your +machine, under Ubuntu these are available from the standard repositories, the +versions provided are adequate. Alternatively install them from scratch, wxGTK +can be found at http://www.wxwidgets.org and PortAudio can be found at +http://www.portaudio.com. If you do a "make install" on both then they'll be +installed in the right places and nothing more needs to be done. + +To actually build the software, type "make" in the same directory as this file +and all should build without errors, there may be a warning or two though. Once +compiled, do "make install". + +Depending on your Linux distribution, you mat find that both PortAudio and +wxWidgets are available in a suitable repository, however the names probably +are different in each one. wxGTK is probably named something like +wxGTK-devel-xxxx for example, and make sure that you get a version in the 2.8 +series. diff --git a/AMBETools/CHANGES.txt b/AMBETools/CHANGES.txt new file mode 100755 index 0000000..5d9398b --- /dev/null +++ b/AMBETools/CHANGES.txt @@ -0,0 +1,10 @@ +AMBE Tools - 20140519 +===================== + +20140519 +-------- + +Split from the Digital Voice package. +Add support for the DV3000 on the Raspberry Pi. +Added the DV Tool Writer program. +Added the ambe2wav, dvtool2wav, wav2ambe and wav2dvtool command-line programs. diff --git a/AMBETools/COPYING.txt b/AMBETools/COPYING.txt new file mode 100755 index 0000000..b860267 --- /dev/null +++ b/AMBETools/COPYING.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The 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., 51 Franklin St, 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 Library General +Public License instead of this License. diff --git a/AMBETools/Common/AMBE3000Thread.cpp b/AMBETools/Common/AMBE3000Thread.cpp new file mode 100755 index 0000000..0e41216 --- /dev/null +++ b/AMBETools/Common/AMBE3000Thread.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "AMBE3000Thread.h" +#include "DStarDefines.h" + +const unsigned int MAX_PACKETS = 10U; + +CAMBE3000Thread::CAMBE3000Thread(CDV3000Controller* dongle) : +CDongleThread(), +m_dongle(dongle), +m_wantMode(A3_IDLE), +m_mode(A3_IDLE), +m_packets(0U) +{ + wxASSERT(dongle != NULL); +} + +CAMBE3000Thread::~CAMBE3000Thread() +{ +} + +bool CAMBE3000Thread::open() +{ + m_mode = m_wantMode = A3_IDLE; + + m_packets = 0U; + + return m_dongle->open(); +} + +void* CAMBE3000Thread::Entry() +{ + while (!m_killed) { + if (m_mode != m_wantMode) { + if (m_mode == A3_DECODE && m_packets == 0U && m_decodeData.isEmpty()) { + if (m_bleep) + sendBleep(); + + reset(); + m_mode = m_wantMode; + } else if (m_mode == A3_ENCODE && m_packets == 0U && m_encodeAudio.isEmpty()) { + reset(); + m_mode = m_wantMode; + } else if (m_mode == A3_IDLE) { + m_mode = m_wantMode; + } + } + + switch (m_mode) { + case A3_DECODE: + processDecodeIn(); + processDecodeOut(); + break; + + case A3_ENCODE: + processEncodeIn(); + processEncodeOut(); + break; + + default: + break; + } + + Sleep(5UL); + } + + m_dongle->close(); + delete m_dongle; + + return NULL; +} + +void CAMBE3000Thread::setDecode() +{ + if (m_mode != A3_DECODE && m_decodeCallback == NULL) + return; + + m_wantMode = A3_DECODE; +} + +void CAMBE3000Thread::setEncode() +{ + if (m_mode != A3_ENCODE && m_encodeCallback == NULL) + return; + + m_wantMode = A3_ENCODE; +} + +void CAMBE3000Thread::setIdle() +{ + m_wantMode = A3_IDLE; +} + +void CAMBE3000Thread::processDecodeIn() +{ + if (m_packets >= MAX_PACKETS) + return; + + unsigned char ambe[VOICE_FRAME_LENGTH_BYTES]; + + unsigned int len = m_decodeData.getData(ambe, VOICE_FRAME_LENGTH_BYTES); + if (len == 0U) + return; + + // Convert the AMBE data to real audio, even if it's nonsense + m_dongle->decodeIn(ambe, VOICE_FRAME_LENGTH_BYTES); + + m_packets++; +} + +void CAMBE3000Thread::processDecodeOut() +{ + wxFloat32 audioIn[DSTAR_AUDIO_BLOCK_SIZE]; + bool res = m_dongle->decodeOut(audioIn, DSTAR_AUDIO_BLOCK_SIZE); + if (res) { + wxFloat32 audioOut[DSTAR_RADIO_BLOCK_SIZE]; + upSample(audioIn, audioOut); + + m_decodeCallback->decodeCallback(audioOut, DSTAR_RADIO_BLOCK_SIZE); + + if (m_packets > 0U) + m_packets--; + } +} + +void CAMBE3000Thread::processEncodeIn() +{ + if (m_packets >= MAX_PACKETS) + return; + + wxFloat32 audioIn[DSTAR_RADIO_BLOCK_SIZE]; + ::memset(audioIn, 0x00, DSTAR_RADIO_BLOCK_SIZE * sizeof(wxFloat32)); + + unsigned int len = m_encodeAudio.getData(audioIn, DSTAR_RADIO_BLOCK_SIZE); + if (len == 0U) + return; + + wxFloat32 audioOut[DSTAR_AUDIO_BLOCK_SIZE]; + downSample(audioIn, audioOut); + + // Convert the audio into AMBE data + m_dongle->encodeIn(audioOut, DSTAR_AUDIO_BLOCK_SIZE); + + m_packets++; +} + +void CAMBE3000Thread::processEncodeOut() +{ + unsigned char ambe[VOICE_FRAME_LENGTH_BYTES]; + bool res = m_dongle->encodeOut(ambe, VOICE_FRAME_LENGTH_BYTES); + if (res) { + m_encodeCallback->encodeCallback(ambe, VOICE_FRAME_LENGTH_BYTES); + + if (m_packets > 0U) + m_packets--; + } +} diff --git a/AMBETools/Common/AMBE3000Thread.h b/AMBETools/Common/AMBE3000Thread.h new file mode 100755 index 0000000..46dc277 --- /dev/null +++ b/AMBETools/Common/AMBE3000Thread.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef AMBE3000Thread_H +#define AMBE3000Thread_H + +#include "DV3000Controller.h" +#include "DongleThread.h" + +#include + +class CAMBE3000Thread : public CDongleThread { +public: + CAMBE3000Thread(CDV3000Controller* dongle); + virtual ~CAMBE3000Thread(); + + virtual bool open(); + + virtual void setEncode(); + virtual void setDecode(); + virtual void setIdle(); + + virtual void* Entry(); + +private: + enum AMBE3000MODE { + A3_DECODE, + A3_ENCODE, + A3_IDLE + }; + + CDV3000Controller* m_dongle; + AMBE3000MODE m_wantMode; + AMBE3000MODE m_mode; + unsigned int m_packets; + + void processDecodeOut(); + void processDecodeIn(); + void processEncodeOut(); + void processEncodeIn(); +}; + +#endif diff --git a/AMBETools/Common/AMBE3000Thread.o b/AMBETools/Common/AMBE3000Thread.o new file mode 100644 index 0000000..8a1575f Binary files /dev/null and b/AMBETools/Common/AMBE3000Thread.o differ diff --git a/AMBETools/Common/AMBEFileReader.cpp b/AMBETools/Common/AMBEFileReader.cpp new file mode 100755 index 0000000..9ae8506 --- /dev/null +++ b/AMBETools/Common/AMBEFileReader.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "AMBEFileReader.h" +#include "DStarDefines.h" + +#include + +static const char AMBE_SIGNATURE[] = "AMBE"; +static const unsigned int AMBE_SIGNATURE_LENGTH = 4U; + +CAMBEFileReader::CAMBEFileReader() : +m_fileName(), +m_file() +{ +} + +CAMBEFileReader::~CAMBEFileReader() +{ +} + +wxString CAMBEFileReader::getFileName() +{ + return m_fileName; +} + +bool CAMBEFileReader::open(const wxString& fileName) +{ + m_fileName = fileName; + + bool res = m_file.Open(fileName, wxT("rb")); + if (!res) + return false; + + unsigned char buffer[AMBE_SIGNATURE_LENGTH]; + size_t n = m_file.Read(buffer, AMBE_SIGNATURE_LENGTH); + if (n != AMBE_SIGNATURE_LENGTH) { + m_file.Close(); + return false; + } + + if (::memcmp(buffer, AMBE_SIGNATURE, AMBE_SIGNATURE_LENGTH) != 0) { + m_file.Close(); + return false; + } + + return true; +} + +unsigned int CAMBEFileReader::read(unsigned char* buffer, unsigned int length, DVTFR_TYPE& type) +{ + wxASSERT(buffer != 0); + wxASSERT(length > 0U); + + if (length > VOICE_FRAME_LENGTH_BYTES) + length = VOICE_FRAME_LENGTH_BYTES; + + size_t n = m_file.Read(buffer, length); + if (n != length) + return 0U; + + type = DVTFR_DETAIL; + + return length; +} + +void CAMBEFileReader::close() +{ + m_file.Close(); +} diff --git a/AMBETools/Common/AMBEFileReader.h b/AMBETools/Common/AMBEFileReader.h new file mode 100755 index 0000000..a4791b9 --- /dev/null +++ b/AMBETools/Common/AMBEFileReader.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef AMBEFileReader_H +#define AMBEFileReader_H + +#include "FileReader.h" + +#include +#include + +class CAMBEFileReader : public IFileReader { +public: + CAMBEFileReader(); + virtual ~CAMBEFileReader(); + + virtual wxString getFileName(); + + virtual bool open(const wxString& fileName); + virtual unsigned int read(unsigned char* buffer, unsigned int length, DVTFR_TYPE& type); + virtual void close(); + +private: + wxString m_fileName; + wxFFile m_file; +}; + +#endif diff --git a/AMBETools/Common/AMBEFileReader.o b/AMBETools/Common/AMBEFileReader.o new file mode 100644 index 0000000..9880a48 Binary files /dev/null and b/AMBETools/Common/AMBEFileReader.o differ diff --git a/AMBETools/Common/AMBEFileWriter.cpp b/AMBETools/Common/AMBEFileWriter.cpp new file mode 100755 index 0000000..4c9595c --- /dev/null +++ b/AMBETools/Common/AMBEFileWriter.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "AMBEFileWriter.h" +#include "DStarDefines.h" + +#include + +static const char AMBE_SIGNATURE[] = "AMBE"; +static unsigned int AMBE_SIGNATURE_LENGTH = 4U; + +CAMBEFileWriter::CAMBEFileWriter(const wxString& filename) : +m_filename(filename), +m_file() +{ +} + +CAMBEFileWriter::~CAMBEFileWriter() +{ +} + +wxString CAMBEFileWriter::getFilename() +{ + return m_filename; +} + +bool CAMBEFileWriter::open() +{ + if (m_file.IsOpened()) + close(); + + bool res = m_file.Open(m_filename, wxT("wb")); + if (!res) + return false; + + size_t n = m_file.Write(AMBE_SIGNATURE, AMBE_SIGNATURE_LENGTH); + if (n != AMBE_SIGNATURE_LENGTH) { + m_file.Close(); + return false; + } + + return true; +} + +bool CAMBEFileWriter::writeHeader(const CHeaderData& header) +{ + return true; +} + +bool CAMBEFileWriter::writeHeader(const unsigned char* buffer, unsigned int length) +{ + wxASSERT(buffer != 0); + wxASSERT(length > 0U); + + return true; +} + +bool CAMBEFileWriter::writeFrame(const unsigned char* buffer, unsigned int length) +{ + wxASSERT(buffer != 0); + wxASSERT(length > 0U); + + if (length > VOICE_FRAME_LENGTH_BYTES) + length = VOICE_FRAME_LENGTH_BYTES; + + size_t n = m_file.Write(buffer, length); + if (n != length) { + m_file.Close(); + return false; + } + + return true; +} + +void CAMBEFileWriter::close() +{ + m_file.Close(); +} diff --git a/AMBETools/Common/AMBEFileWriter.h b/AMBETools/Common/AMBEFileWriter.h new file mode 100755 index 0000000..acbf75d --- /dev/null +++ b/AMBETools/Common/AMBEFileWriter.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef AMBEFileWriter_H +#define AMBEFileWriter_H + +#include "FileWriter.h" + +#include +#include + +class CAMBEFileWriter : public IFileWriter { +public: + CAMBEFileWriter(const wxString& filename); + virtual ~CAMBEFileWriter(); + + virtual wxString getFilename(); + + virtual bool open(); + virtual bool writeHeader(const CHeaderData& header); + virtual bool writeHeader(const unsigned char* buffer, unsigned int length); + virtual bool writeFrame(const unsigned char* buffer, unsigned int length); + virtual void close(); + +private: + wxString m_filename; + wxFFile m_file; +}; + +#endif diff --git a/AMBETools/Common/AMBEFileWriter.o b/AMBETools/Common/AMBEFileWriter.o new file mode 100644 index 0000000..0e9d9bb Binary files /dev/null and b/AMBETools/Common/AMBEFileWriter.o differ diff --git a/AMBETools/Common/AddressTextCtrl.cpp b/AMBETools/Common/AddressTextCtrl.cpp new file mode 100755 index 0000000..bf859bb --- /dev/null +++ b/AMBETools/Common/AddressTextCtrl.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2002,2003,2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "AddressTextCtrl.h" + +CAddressTextCtrl::CAddressTextCtrl(wxWindow* parent, int id, const wxString& value, const wxPoint& pos, const wxSize& size, long style) : +CRestrictedTextCtrl(parent, id, value, pos, size, style, ADDRESS_CHARS) +{ +} + +CAddressTextCtrl::~CAddressTextCtrl() +{ +} + diff --git a/AMBETools/Common/AddressTextCtrl.h b/AMBETools/Common/AddressTextCtrl.h new file mode 100755 index 0000000..44e12e3 --- /dev/null +++ b/AMBETools/Common/AddressTextCtrl.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2002,2003,2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef AddressTextCtrl_H +#define AddressTextCtrl_H + +#include + +#include "RestrictedTextCtrl.h" + +const wxString ADDRESS_CHARS = wxT("0123456789."); + +class CAddressTextCtrl : public CRestrictedTextCtrl { + +public: + CAddressTextCtrl(wxWindow* parent, int id, const wxString& value, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0L); + virtual ~CAddressTextCtrl(); + + private: +}; + +#endif diff --git a/AMBETools/Common/AddressTextCtrl.o b/AMBETools/Common/AddressTextCtrl.o new file mode 100644 index 0000000..b864059 Binary files /dev/null and b/AMBETools/Common/AddressTextCtrl.o differ diff --git a/AMBETools/Common/AudioCallback.h b/AMBETools/Common/AudioCallback.h new file mode 100755 index 0000000..14e2329 --- /dev/null +++ b/AMBETools/Common/AudioCallback.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef AudioCallback_H +#define AudioCallback_H + +#include + +class IAudioCallback { +public: + virtual void callback(const wxFloat32* input, wxFloat32* output, unsigned int nSamples, int id) = 0; + +private: +}; + +#endif diff --git a/AMBETools/Common/BleepSet.cpp b/AMBETools/Common/BleepSet.cpp new file mode 100755 index 0000000..d104fc8 --- /dev/null +++ b/AMBETools/Common/BleepSet.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "BleepSet.h" + +const unsigned int BORDER_SIZE = 5U; +const unsigned int CONTROL_WIDTH = 200U; + +CBleepSet::CBleepSet(wxWindow* parent, int id, const wxString& title, bool bleep) : +wxPanel(parent, id), +m_title(title), +m_bleep(NULL) +{ + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + + m_bleep = new wxCheckBox(this, -1, _("End Bleep")); + m_bleep->SetValue(bleep); + sizer->Add(m_bleep, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE); + + SetAutoLayout(true); + + sizer->Fit(this); + sizer->SetSizeHints(this); + + SetSizer(sizer); +} + + +CBleepSet::~CBleepSet() +{ +} + +bool CBleepSet::getBleep() const +{ + return m_bleep->GetValue(); +} diff --git a/AMBETools/Common/BleepSet.h b/AMBETools/Common/BleepSet.h new file mode 100755 index 0000000..9d8157e --- /dev/null +++ b/AMBETools/Common/BleepSet.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef BleepSet_H +#define BleepSet_H + +#include + +class CBleepSet : public wxPanel { +public: + CBleepSet(wxWindow* parent, int id, const wxString& title, bool bleep); + virtual ~CBleepSet(); + + virtual bool getBleep() const; + +private: + wxString m_title; + wxCheckBox* m_bleep; +}; + +#endif diff --git a/AMBETools/Common/BleepSet.o b/AMBETools/Common/BleepSet.o new file mode 100644 index 0000000..b92d037 Binary files /dev/null and b/AMBETools/Common/BleepSet.o differ diff --git a/AMBETools/Common/Bleeper.cpp b/AMBETools/Common/Bleeper.cpp new file mode 100755 index 0000000..7367699 --- /dev/null +++ b/AMBETools/Common/Bleeper.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2009,2010 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "Bleeper.h" + +#include + +CBleeper::CBleeper(unsigned int sampleRate, unsigned int hz, unsigned int ms, float amplitude) : +m_audio(NULL), +m_length(0U), +m_total(0U), +m_position(0U) +{ + wxASSERT(sampleRate > 0U); + wxASSERT(hz > 0U); + wxASSERT(ms > 0U); + wxASSERT(amplitude > 0.0F); + + m_length = sampleRate / hz; + m_total = (sampleRate * ms) / 1000U; + + m_audio = new wxFloat32[m_length]; + + for (unsigned int i = 0U; i < m_length; i++) { + if (i < m_length / 2U) + m_audio[i] = amplitude; + else + m_audio[i] = -amplitude; + } +} + +CBleeper::~CBleeper() +{ + delete[] m_audio; +} + +unsigned int CBleeper::getAudio(wxFloat32* audio, unsigned int length) +{ + wxASSERT(audio != NULL); + wxASSERT(length > 0U); + + unsigned int n = 0U; + while (n < length && m_position < m_total) { + unsigned int pos = m_position % m_length; + + audio[n] = m_audio[pos]; + + m_position++; + n++; + } + + return n; +} + +void CBleeper::reset() +{ + m_position = 0U; +} diff --git a/AMBETools/Common/Bleeper.h b/AMBETools/Common/Bleeper.h new file mode 100755 index 0000000..175883c --- /dev/null +++ b/AMBETools/Common/Bleeper.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef Bleeper_H +#define Bleeper_H + +#include + +class CBleeper { +public: + CBleeper(unsigned int sampleRate, unsigned int hz, unsigned int ms, float amplitude); + ~CBleeper(); + + unsigned int getAudio(wxFloat32* audio, unsigned int length); + + void reset(); + +private: + wxFloat32* m_audio; + unsigned int m_length; + unsigned int m_total; + unsigned int m_position; +}; + +#endif diff --git a/AMBETools/Common/Bleeper.o b/AMBETools/Common/Bleeper.o new file mode 100644 index 0000000..5f32c71 Binary files /dev/null and b/AMBETools/Common/Bleeper.o differ diff --git a/AMBETools/Common/CCITTChecksumReverse.cpp b/AMBETools/Common/CCITTChecksumReverse.cpp new file mode 100755 index 0000000..77e16ca --- /dev/null +++ b/AMBETools/Common/CCITTChecksumReverse.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2009,2011,2014 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#include "CCITTChecksumReverse.h" + +#include "Utils.h" + +static const unsigned short ccittTab[] = { + 0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf, + 0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7, + 0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e, + 0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876, + 0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd, + 0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5, + 0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c, + 0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974, + 0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb, + 0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3, + 0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a, + 0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72, + 0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9, + 0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1, + 0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738, + 0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70, + 0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7, + 0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff, + 0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036, + 0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e, + 0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5, + 0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd, + 0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134, + 0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c, + 0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3, + 0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb, + 0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232, + 0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a, + 0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1, + 0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9, + 0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330, + 0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78}; + +CCCITTChecksumReverse::CCCITTChecksumReverse() : +m_crc16(0xFFFFU) +{ +} + +CCCITTChecksumReverse::~CCCITTChecksumReverse() +{ +} + +void CCCITTChecksumReverse::update(const unsigned char* data, unsigned int length) +{ + wxASSERT(data != NULL); + + for (unsigned int i = 0U; i < length; i++) + m_crc16 = wxUint16(m_crc8[1U]) ^ ccittTab[m_crc8[0U] ^ data[i]]; +} + +void CCCITTChecksumReverse::result(unsigned char* data) +{ + wxASSERT(data != NULL); + + m_crc16 = ~m_crc16; + + data[0U] = m_crc8[0U]; + data[1U] = m_crc8[1U]; +} + +bool CCCITTChecksumReverse::check(const unsigned char* data) +{ + wxASSERT(data != NULL); + + unsigned char sum[2U]; + result(sum); + + return sum[0U] == data[0U] && sum[1U] == data[1U]; +} + +void CCCITTChecksumReverse::reset() +{ + m_crc16 = 0xFFFFU; +} diff --git a/AMBETools/Common/CCITTChecksumReverse.h b/AMBETools/Common/CCITTChecksumReverse.h new file mode 100755 index 0000000..6898035 --- /dev/null +++ b/AMBETools/Common/CCITTChecksumReverse.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009,2011,2014 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef CCITTChecksumReverse_H +#define CCITTChecksumReverse_H + +#include + +class CCCITTChecksumReverse { +public: + CCCITTChecksumReverse(); + ~CCCITTChecksumReverse(); + + void update(const unsigned char* data, unsigned int length); + + void result(unsigned char* data); + + bool check(const unsigned char* data); + + void reset(); + +private: + union { + wxUint16 m_crc16; + wxUint8 m_crc8[2U]; + }; +}; + +#endif diff --git a/AMBETools/Common/CCITTChecksumReverse.o b/AMBETools/Common/CCITTChecksumReverse.o new file mode 100644 index 0000000..6814232 Binary files /dev/null and b/AMBETools/Common/CCITTChecksumReverse.o differ diff --git a/AMBETools/Common/CallsignSet.cpp b/AMBETools/Common/CallsignSet.cpp new file mode 100755 index 0000000..2c31599 --- /dev/null +++ b/AMBETools/Common/CallsignSet.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DStarDefines.h" +#include "CallsignSet.h" + +#if defined(__WINDOWS__) +const unsigned int LONG_CALLSIGN_WIDTH = 80U; +const unsigned int SHORT_CALLSIGN_WIDTH = 50U; +#else +const unsigned int LONG_CALLSIGN_WIDTH = 100U; +const unsigned int SHORT_CALLSIGN_WIDTH = 60U; +#endif + +const unsigned int BORDER_SIZE = 5U; + +CCallsignSet::CCallsignSet(wxWindow* parent, int id, const wxString& title, const wxString& callsign1, const wxString& callsign2) : +wxPanel(parent, id), +m_title(title), +m_callsign1(NULL), +m_callsign2(NULL) +{ + wxFlexGridSizer* sizer = new wxFlexGridSizer(4); + + wxStaticText* callsignLabel = new wxStaticText(this, -1, _("Callsign")); + sizer->Add(callsignLabel, 0, wxALL | wxALIGN_RIGHT, BORDER_SIZE); + + m_callsign1 = new CCallsignTextCtrl(this, -1, callsign1, wxDefaultPosition, wxSize(LONG_CALLSIGN_WIDTH, -1)); + m_callsign1->SetMaxLength(LONG_CALLSIGN_LENGTH); + sizer->Add(m_callsign1, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE); + + wxStaticText* slashLabel = new wxStaticText(this, -1, wxT("/")); + sizer->Add(slashLabel, 0, wxALL | wxALIGN_RIGHT, BORDER_SIZE); + + m_callsign2 = new CCallsignTextCtrl(this, -1, callsign2, wxDefaultPosition, wxSize(SHORT_CALLSIGN_WIDTH, -1)); + m_callsign2->SetMaxLength(SHORT_CALLSIGN_LENGTH); + sizer->Add(m_callsign2, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE); + + SetAutoLayout(true); + + sizer->Fit(this); + sizer->SetSizeHints(this); + + SetSizer(sizer); +} + + +CCallsignSet::~CCallsignSet() +{ +} + +bool CCallsignSet::Validate() +{ + bool res = !getCallsign1().IsEmpty(); + if (!res) { + wxMessageDialog dialog(this, _("The Callsign may not be empty"), m_title + _(" Error"), wxICON_ERROR); + dialog.ShowModal(); + } + + return res; +} + +wxString CCallsignSet::getCallsign1() const +{ + return m_callsign1->GetValue().MakeUpper(); +} + +wxString CCallsignSet::getCallsign2() const +{ + return m_callsign2->GetValue().MakeUpper(); +} diff --git a/AMBETools/Common/CallsignSet.h b/AMBETools/Common/CallsignSet.h new file mode 100755 index 0000000..2f8835b --- /dev/null +++ b/AMBETools/Common/CallsignSet.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010,2011,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef CallsignSet_H +#define CallsignSet_H + +#include "CallsignTextCtrl.h" + +#include + +class CCallsignSet : public wxPanel { +public: + CCallsignSet(wxWindow* parent, int id, const wxString& title, const wxString& callsign1, const wxString& callsign2); + virtual ~CCallsignSet(); + + virtual bool Validate(); + + virtual wxString getCallsign1() const; + virtual wxString getCallsign2() const; + +private: + wxString m_title; + CCallsignTextCtrl* m_callsign1; + CCallsignTextCtrl* m_callsign2; +}; + +#endif diff --git a/AMBETools/Common/CallsignSet.o b/AMBETools/Common/CallsignSet.o new file mode 100644 index 0000000..1df7eac Binary files /dev/null and b/AMBETools/Common/CallsignSet.o differ diff --git a/AMBETools/Common/CallsignTextCtrl.cpp b/AMBETools/Common/CallsignTextCtrl.cpp new file mode 100755 index 0000000..44bce03 --- /dev/null +++ b/AMBETools/Common/CallsignTextCtrl.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2002,2003 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "CallsignTextCtrl.h" + +CCallsignTextCtrl::CCallsignTextCtrl(wxWindow* parent, int id, const wxString& value, const wxPoint& pos, const wxSize& size, long style) : +CRestrictedTextCtrl(parent, id, value, pos, size, style, CALLSIGN_CHARS) +{ +} + +CCallsignTextCtrl::~CCallsignTextCtrl() +{ +} + diff --git a/AMBETools/Common/CallsignTextCtrl.h b/AMBETools/Common/CallsignTextCtrl.h new file mode 100755 index 0000000..795f4a2 --- /dev/null +++ b/AMBETools/Common/CallsignTextCtrl.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2002,2003 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef CallsignTextCtrl_H +#define CallsignTextCtrl_H + +#include + +#include "RestrictedTextCtrl.h" + +const wxString CALLSIGN_CHARS = wxT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/ "); + +class CCallsignTextCtrl : public CRestrictedTextCtrl { + +public: + CCallsignTextCtrl(wxWindow* parent, int id, const wxString& value, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0L); + virtual ~CCallsignTextCtrl(); + + private: +}; + +#endif diff --git a/AMBETools/Common/CallsignTextCtrl.o b/AMBETools/Common/CallsignTextCtrl.o new file mode 100644 index 0000000..d8ef1ab Binary files /dev/null and b/AMBETools/Common/CallsignTextCtrl.o differ diff --git a/AMBETools/Common/Common.a b/AMBETools/Common/Common.a new file mode 100644 index 0000000..bd1272d Binary files /dev/null and b/AMBETools/Common/Common.a differ diff --git a/AMBETools/Common/Common.vcproj b/AMBETools/Common/Common.vcproj new file mode 100755 index 0000000..ea40e26 --- /dev/null +++ b/AMBETools/Common/Common.vcproj @@ -0,0 +1,491 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AMBETools/Common/DStarDefines.h b/AMBETools/Common/DStarDefines.h new file mode 100755 index 0000000..3c3c9e1 --- /dev/null +++ b/AMBETools/Common/DStarDefines.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2009,2012 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef DStarDefines_H +#define DStarDefines_H + +const unsigned int DSTAR_GMSK_SYMBOL_RATE = 4800U; +const float DSTAR_GMSK_BT = 0.5F; + +const bool BIT_SYNC_BITS[] = {true, false, true, false}; +const unsigned int BIT_SYNC_LENGTH_BITS = 4U; + +const bool FRAME_SYNC_BITS[] = {true, true, true, false, true, true, false, false, + true, false, true, false, false, false, false}; +const unsigned int FRAME_SYNC_LENGTH_BITS = 15U; + +const unsigned char DATA_SYNC_BYTES[] = {0x55, 0x2D, 0x16}; +const bool DATA_SYNC_BITS[] = {true, false, true, false, true, false, true, false, + true, false, true, true, false, true, false, false, + false, true, true, false, true, false, false, false}; + +const unsigned char END_PATTERN_BYTES[] = {0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A}; +const bool END_PATTERN_BITS[] = {true, false, true, false, true, false, true, false, + true, false, true, false, true, false, true, false, + true, false, true, false, true, false, true, false, + true, false, true, false, true, false, true, false, + false, false, false, true, false, false, true, true, + false, true, false, true, true, true, true, false}; +const unsigned int END_PATTERN_LENGTH_BITS = 48U; +const unsigned int END_PATTERN_LENGTH_BYTES = END_PATTERN_LENGTH_BITS / 8U; + +const unsigned char NULL_AMBE_DATA_BYTES[] = {0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8}; +const bool NULL_AMBE_DATA_BITS[] = {false, true, true, true, true, false, false, true, + true, false, true, true, false, false, false, true, + false, true, false, false, true, true, false, false, + false, false, false, true, false, false, false, true, + false, true, true, false, false, true, false, false, + false, true, false, true, true, false, false, false, + true, true, true, true, true, true, false, false, + true, false, false, false, false, true, true, false, + false, false, false, true, false, true, true, true}; + +// Note that these are already scrambled, 0x66 0x66 0x66 otherwise +const bool NULL_SLOW_DATA_BITS[] = {false, false, false, true, false, true, true, false, + false, false, true, false, true, false, false, true, + true, true, true, true, false, true, false, true}; + +const unsigned int VOICE_FRAME_LENGTH_BITS = 72U; +const unsigned int VOICE_FRAME_LENGTH_BYTES = VOICE_FRAME_LENGTH_BITS / 8U; + +const unsigned int DATA_FRAME_LENGTH_BITS = 24U; +const unsigned int DATA_FRAME_LENGTH_BYTES = DATA_FRAME_LENGTH_BITS / 8U; + +const unsigned int DV_FRAME_LENGTH_BITS = VOICE_FRAME_LENGTH_BITS + DATA_FRAME_LENGTH_BITS; +const unsigned int DV_FRAME_LENGTH_BYTES = VOICE_FRAME_LENGTH_BYTES + DATA_FRAME_LENGTH_BYTES; + +const unsigned int FEC_SECTION_LENGTH_BITS = 660U; + +const unsigned int RADIO_HEADER_LENGTH_BITS = 330U; +const unsigned int RADIO_HEADER_LENGTH_BYTES = 41U; + +const unsigned int DATA_BLOCK_SIZE_BITS = 21U * DV_FRAME_LENGTH_BITS; +const unsigned int DATA_BLOCK_SIZE_BYTES = 21U * DV_FRAME_LENGTH_BYTES; + +const unsigned char SLOW_DATA_TYPE_MASK = 0xF0; +const unsigned char SLOW_DATA_TYPE_GPSDATA = 0x30; +const unsigned char SLOW_DATA_TYPE_MESSAGE = 0x40; +const unsigned char SLOW_DATA_TYPE_HEADER = 0x50; +const unsigned char SLOW_DATA_TYPE_SQUELCH = 0xC0; +const unsigned char SLOW_DATA_LENGTH_MASK = 0x0F; + +const unsigned int DSTAR_AUDIO_BLOCK_SIZE = 160U; +const unsigned int DSTAR_AUDIO_BLOCK_BYTES = DSTAR_AUDIO_BLOCK_SIZE * 2U; + +const unsigned int DSTAR_RADIO_SAMPLE_RATE = 48000U; +const unsigned int DSTAR_RADIO_BLOCK_SIZE = 960U; + +const unsigned int LONG_CALLSIGN_LENGTH = 8U; +const unsigned int SHORT_CALLSIGN_LENGTH = 4U; + +const unsigned int MESSAGE_LENGTH = 20U; + +const unsigned char DATA_MASK = 0x80U; +const unsigned char REPEATER_MASK = 0x40U; +const unsigned char INTERRUPTED_MASK = 0x20U; +const unsigned char CONTROL_SIGNAL_MASK = 0x10U; +const unsigned char URGENT_MASK = 0x08U; + +const unsigned char REPEATER_CONTROL_MASK = 0x07U; +const unsigned char REPEATER_CONTROL = 0x07U; +const unsigned char AUTO_REPLY = 0x06U; +const unsigned char RESEND_REQUESTED = 0x04U; +const unsigned char ACK_FLAG = 0x03U; +const unsigned char NO_RESPONSE = 0x02U; +const unsigned char RELAY_UNAVAILABLE = 0x01U; + +const unsigned int DSTAR_BLEEP_FREQ = 2000U; +const unsigned int DSTAR_BLEEP_LENGTH = 100U; +const float DSTAR_BLEEP_AMPL = 0.5F; + +const unsigned int DSTAR_RADIO_BIT_LENGTH = DSTAR_RADIO_SAMPLE_RATE / DSTAR_GMSK_SYMBOL_RATE; + +const unsigned int FRAME_TIME_MS = 20U; + +const unsigned int FRAMES_BETWEEN_SYNC = 20U; + +const unsigned int TICKS_PER_SEC = 50U; + +enum DONGLE_TYPE { + DT_DVDONGLE, + DT_DV3000 +}; + +#endif diff --git a/AMBETools/Common/DV3000Controller.cpp b/AMBETools/Common/DV3000Controller.cpp new file mode 100755 index 0000000..8bfa8df --- /dev/null +++ b/AMBETools/Common/DV3000Controller.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DV3000Controller.h" +#include "DStarDefines.h" +#include "Utils.h" + +const unsigned char DV3000_START_BYTE = 0x61U; + +const unsigned char DV3000_TYPE_CONTROL = 0x00U; +const unsigned char DV3000_TYPE_AMBE = 0x01U; +const unsigned char DV3000_TYPE_AUDIO = 0x02U; + +const unsigned char DV3000_CONTROL_RATEP = 0x0AU; +const unsigned char DV3000_CONTROL_PRODID = 0x30U; +const unsigned char DV3000_CONTROL_READY = 0x39U; + +const unsigned char DV3000_REQ_PRODID[] = {DV3000_START_BYTE, 0x00U, 0x01U, DV3000_TYPE_CONTROL, DV3000_CONTROL_PRODID}; +const unsigned int DV3000_REQ_PRODID_LEN = 5U; + +const unsigned char DV3000_REQ_RATEP[] = {DV3000_START_BYTE, 0x00U, 0x0DU, DV3000_TYPE_CONTROL, DV3000_CONTROL_RATEP, 0x01U, 0x30U, 0x07U, 0x63U, 0x40U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x48U}; +const unsigned int DV3000_REQ_RATEP_LEN = 17U; + +const unsigned char DV3000_AUDIO_HEADER[] = {DV3000_START_BYTE, 0x01U, 0x42U, DV3000_TYPE_AUDIO, 0x00U, 0xA0U}; +const unsigned char DV3000_AUDIO_HEADER_LEN = 6U; + +const unsigned char DV3000_AMBE_HEADER[] = {DV3000_START_BYTE, 0x00U, 0x0BU, DV3000_TYPE_AMBE, 0x01U, 0x48U}; +const unsigned char DV3000_AMBE_HEADER_LEN = 6U; + +const unsigned int DV3000_HEADER_LEN = 4U; + +const unsigned int BUFFER_LENGTH = 400U; + +CDV3000Controller::CDV3000Controller(const wxString& address, unsigned int port) : +m_socket(address, port) +{ +} + +CDV3000Controller::~CDV3000Controller() +{ +} + +bool CDV3000Controller::open() +{ + bool res = m_socket.open(); + if (!res) + return false; + + m_socket.write(DV3000_REQ_PRODID, DV3000_REQ_PRODID_LEN); + + bool found = false; + for (unsigned int i = 0U; i < 10U; i++) { + unsigned char buffer[BUFFER_LENGTH]; + RESP_TYPE type = getResponse(buffer, BUFFER_LENGTH); + + if (type == RESP_ERROR) { + m_socket.close(); + return false; + } + + if (type == RESP_NAME) { + found = true; + break; + } + + ::wxMilliSleep(10UL); + } + + if (!found) { + m_socket.close(); + return false; + } + + m_socket.write(DV3000_REQ_RATEP, DV3000_REQ_RATEP_LEN); + + for (;;) { + unsigned char buffer[BUFFER_LENGTH]; + RESP_TYPE type = getResponse(buffer, BUFFER_LENGTH); + + if (type == RESP_ERROR) { + m_socket.close(); + return false; + } + + if (type == RESP_RATEP) + return true; + + ::wxMilliSleep(10UL); + } +} + +void CDV3000Controller::encodeIn(const wxFloat32* audio, unsigned int length) +{ + wxASSERT(audio != NULL); + wxASSERT(length == DSTAR_AUDIO_BLOCK_SIZE); + + unsigned char buffer[DV3000_AUDIO_HEADER_LEN + DSTAR_AUDIO_BLOCK_BYTES]; + ::memcpy(buffer, DV3000_AUDIO_HEADER, DV3000_AUDIO_HEADER_LEN); + + wxInt8* q = (wxInt8*)(buffer + DV3000_AUDIO_HEADER_LEN); + for (unsigned int i = 0; i < DSTAR_AUDIO_BLOCK_SIZE; i++, q += 2U) { + wxInt16 word = wxInt16(audio[i] * 32767.0F); + + q[0U] = (word & 0xFF00) >> 8; + q[1U] = (word & 0x00FF) >> 0; + } + + m_socket.write(buffer, DV3000_AUDIO_HEADER_LEN + DSTAR_AUDIO_BLOCK_BYTES); +} + +bool CDV3000Controller::encodeOut(unsigned char* ambe, unsigned int length) +{ + wxASSERT(ambe != NULL); + wxASSERT(length == VOICE_FRAME_LENGTH_BYTES); + + unsigned char buffer[BUFFER_LENGTH]; + RESP_TYPE type = getResponse(buffer, BUFFER_LENGTH); + if (type != RESP_AMBE) + return false; + + ::memcpy(ambe, buffer + DV3000_AMBE_HEADER_LEN, VOICE_FRAME_LENGTH_BYTES); + + return true; +} + +void CDV3000Controller::decodeIn(const unsigned char* ambe, unsigned int length) +{ + wxASSERT(ambe != NULL); + wxASSERT(length == VOICE_FRAME_LENGTH_BYTES); + + unsigned char buffer[DV3000_AMBE_HEADER_LEN + VOICE_FRAME_LENGTH_BYTES]; + ::memcpy(buffer, DV3000_AMBE_HEADER, DV3000_AMBE_HEADER_LEN); + + ::memcpy(buffer + DV3000_AMBE_HEADER_LEN, ambe, VOICE_FRAME_LENGTH_BYTES); + + m_socket.write(buffer, DV3000_AMBE_HEADER_LEN + VOICE_FRAME_LENGTH_BYTES); +} + +bool CDV3000Controller::decodeOut(wxFloat32* audio, unsigned int length) +{ + wxASSERT(audio != NULL); + wxASSERT(length == DSTAR_AUDIO_BLOCK_SIZE); + + unsigned char buffer[BUFFER_LENGTH]; + RESP_TYPE type = getResponse(buffer, BUFFER_LENGTH); + if (type != RESP_AUDIO) + return false; + + wxUint8* q = (wxUint8*)(buffer + DV3000_AUDIO_HEADER_LEN); + for (unsigned int i = 0U; i < DSTAR_AUDIO_BLOCK_SIZE; i++, q += 2U) { + wxInt16 word = (q[0] << 8) | (q[1U] << 0); + + audio[i] = wxFloat32(word) / 32768.0F; + } + + return true; +} + +void CDV3000Controller::close() +{ + m_socket.close(); +} + +CDV3000Controller::RESP_TYPE CDV3000Controller::getResponse(unsigned char* buffer, unsigned int length) +{ + wxASSERT(buffer != NULL); + wxASSERT(length >= BUFFER_LENGTH); + + int len = m_socket.read(buffer, length); + if (len == 0) + return RESP_NONE; + if (len < 0) + return RESP_ERROR; + + if (buffer[0U] != DV3000_START_BYTE) { + wxLogError(wxT("Unknown byte from the DV3000, %02X"), buffer[0U]); + CUtils::dump(wxT("Bad data"), buffer, len); + return RESP_UNKNOWN; + } + + unsigned int respLen = buffer[1U] * 256U + buffer[2U] + DV3000_HEADER_LEN; + + if (len != int(respLen)) { + wxLogError(wxT("Invalid DV3000 data, %d != %u"), len, respLen); + CUtils::dump(wxT("Bad data"), buffer, len); + return RESP_ERROR; + } + + if (buffer[3U] == DV3000_TYPE_AUDIO) { + return RESP_AUDIO; + } else if (buffer[3U] == DV3000_TYPE_AMBE) { + return RESP_AMBE; + } else if (buffer[3U] == DV3000_TYPE_CONTROL) { + if (buffer[4U] == DV3000_CONTROL_PRODID) { + return RESP_NAME; + } else if (buffer[4U] == DV3000_CONTROL_RATEP) { + return RESP_RATEP; + } else if (buffer[4U] == DV3000_CONTROL_READY) { + return RESP_UNKNOWN; + } else { + CUtils::dump(wxT("Unknown control data"), buffer, respLen); + return RESP_UNKNOWN; + } + } else { + CUtils::dump(wxT("Unknown data"), buffer, respLen); + return RESP_UNKNOWN; + } +} diff --git a/AMBETools/Common/DV3000Controller.h b/AMBETools/Common/DV3000Controller.h new file mode 100755 index 0000000..b2d6e18 --- /dev/null +++ b/AMBETools/Common/DV3000Controller.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DV3000Controller_H +#define DV3000Controller_H + +#include "UDPReaderWriter.h" + +#include + +class CDV3000Controller { +public: + CDV3000Controller(const wxString& address, unsigned int port); + ~CDV3000Controller(); + + bool open(); + + void encodeIn(const wxFloat32* audio, unsigned int length); + bool encodeOut(unsigned char* ambe, unsigned int length); + + void decodeIn(const unsigned char* ambe, unsigned int length); + bool decodeOut(wxFloat32* audio, unsigned int length); + + void close(); + +private: + CUDPReaderWriter m_socket; + + enum RESP_TYPE { + RESP_NONE, + RESP_ERROR, + RESP_RATEP, + RESP_NAME, + RESP_AMBE, + RESP_AUDIO, + RESP_UNKNOWN + }; + + RESP_TYPE getResponse(unsigned char* buffer, unsigned int length); +}; + +#endif diff --git a/AMBETools/Common/DV3000Controller.o b/AMBETools/Common/DV3000Controller.o new file mode 100644 index 0000000..b9ca7ad Binary files /dev/null and b/AMBETools/Common/DV3000Controller.o differ diff --git a/AMBETools/Common/DVDongleController.cpp b/AMBETools/Common/DVDongleController.cpp new file mode 100755 index 0000000..cead6fe --- /dev/null +++ b/AMBETools/Common/DVDongleController.cpp @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2010,2011,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DVDongleController.h" + +#include "DStarDefines.h" + +const unsigned char DVD_RESP_NOP[] = {0x02, 0x00}; +const unsigned int DVD_RESP_NOP_LEN = 2U; + +const unsigned char DVD_REQ_START[] = {0x05, 0x00, 0x18, 0x00, 0x01}; +const unsigned int DVD_REQ_START_LEN = 5U; + +const unsigned char DVD_RESP_START[] = {0x05, 0x00, 0x18, 0x00, 0x01}; +const unsigned int DVD_RESP_START_LEN = 5U; + +const unsigned char DVD_REQ_STOP[] = {0x05, 0x00, 0x18, 0x00, 0x00}; +const unsigned int DVD_REQ_STOP_LEN = 5U; + +const unsigned char DVD_RESP_STOP[] = {0x05, 0x00, 0x18, 0x00, 0x00}; +const unsigned int DVD_RESP_STOP_LEN = 5U; + +const unsigned char DVD_REQ_NAME[] = {0x04, 0x20, 0x01, 0x00}; +const unsigned int DVD_REQ_NAME_LEN = 4U; + +const unsigned char DVD_RESP_NAME[] = {0x0E, 0x00, 0x01, 0x00, 'D', 'V', ' ', 'D', 'o', 'n', 'g', 'l', 'e', 0x00}; +const unsigned int DVD_RESP_NAME_LEN = 14U; + +const unsigned char DVD_AMBE_HEADER[] = {0x32, 0xA0}; +const unsigned char DVD_AUDIO_HEADER[] = {0x42, 0x81}; +const unsigned int DVD_HEADER_LEN = 2U; + +const unsigned char DVD_AMBE_DEC_DATA[] = {0xEC, 0x13, 0x00, 0x00, 0x30, 0x10, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x20, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +const unsigned char DVD_AMBE_ENC_DATA[] = {0xEC, 0x13, 0x00, 0x00, 0x30, 0x10, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x04, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +const unsigned int DVD_AMBE_HEADER_LEN = 24U; +const unsigned int DVD_AMBE_LENGTH_BYTES = 48U; +const unsigned int DVD_AUDIO_LENGTH_BYTES = 320U; + +const unsigned int DVD_DATA_LEN = DVD_AMBE_LENGTH_BYTES + DVD_HEADER_LEN + DVD_AUDIO_LENGTH_BYTES + DVD_HEADER_LEN; + +CDVDongleController::CDVDongleController(const wxString& device) : +m_serial(device, SERIAL_230400) +{ +} + +CDVDongleController::~CDVDongleController() +{ +} + +bool CDVDongleController::open() +{ + bool res = m_serial.open(); + if (!res) + return false; + + m_serial.write(DVD_REQ_NAME, DVD_REQ_NAME_LEN); + + for (;;) { + unsigned char buffer[DVD_AUDIO_LENGTH_BYTES]; + RESP_TYPE type = getResponse(buffer, DVD_AUDIO_LENGTH_BYTES); + if (type == RESP_ERROR) + return false; + + if (type == RESP_NAME) + return true; + + ::wxMilliSleep(5UL); + } +} + +bool CDVDongleController::start() +{ + m_serial.write(DVD_REQ_START, DVD_REQ_START_LEN); + + for (;;) { + unsigned char buffer[DVD_AUDIO_LENGTH_BYTES]; + RESP_TYPE type = getResponse(buffer, DVD_AUDIO_LENGTH_BYTES); + if (type == RESP_ERROR) + return false; + + if (type == RESP_START) + return true; + + ::wxMilliSleep(5UL); + } +} + +bool CDVDongleController::stop() +{ + m_serial.write(DVD_REQ_STOP, DVD_REQ_STOP_LEN); + + for (;;) { + unsigned char buffer[DVD_AUDIO_LENGTH_BYTES]; + RESP_TYPE type = getResponse(buffer, DVD_AUDIO_LENGTH_BYTES); + if (type == RESP_ERROR) + return false; + + if (type == RESP_STOP) + return true; + + ::wxMilliSleep(5UL); + } +} + +void CDVDongleController::encodeIn(const wxFloat32* audio, unsigned int length) +{ + wxASSERT(audio != NULL); + wxASSERT(length == DSTAR_AUDIO_BLOCK_SIZE); + + unsigned char buffer[DVD_HEADER_LEN + DVD_AUDIO_LENGTH_BYTES]; + unsigned char* p = buffer; + + // First a dummy AMBE packet with parameter information in + ::memcpy(p, DVD_AMBE_HEADER, DVD_HEADER_LEN); + p += DVD_HEADER_LEN; + + ::memcpy(p, DVD_AMBE_ENC_DATA, DVD_AMBE_LENGTH_BYTES); + + m_serial.write(buffer, DVD_HEADER_LEN + DVD_AMBE_LENGTH_BYTES); + + // Then the Audio data to be encoded + p = buffer; + ::memcpy(p, DVD_AUDIO_HEADER, DVD_HEADER_LEN); + p += DVD_HEADER_LEN; + + wxInt16* q = (wxInt16*)p; + + for (unsigned int i = 0; i < DSTAR_AUDIO_BLOCK_SIZE; i++) { + wxInt16 word = wxInt16(audio[i] * 32767.0F); + *q++ = wxINT16_SWAP_ON_BE(word); + } + + m_serial.write(buffer, DVD_HEADER_LEN + DVD_AUDIO_LENGTH_BYTES); +} + +bool CDVDongleController::encodeOut(unsigned char* ambe, unsigned int length) +{ + wxASSERT(ambe != NULL); + wxASSERT(length == VOICE_FRAME_LENGTH_BYTES); + + bool ambeFound = false; + bool audioFound = false; + + for (;;) { + unsigned char buffer[DVD_AUDIO_LENGTH_BYTES]; + RESP_TYPE type = getResponse(buffer, DVD_AUDIO_LENGTH_BYTES); + if (type == RESP_ERROR) + return false; + + if (type == RESP_AMBE) { + ::memcpy(ambe, buffer + DVD_AMBE_HEADER_LEN, VOICE_FRAME_LENGTH_BYTES); + ambeFound = true; + } else if (type == RESP_AUDIO) { + audioFound = true; + } + + if (ambeFound && audioFound) + return true; + + ::wxMilliSleep(5UL); + } +} + +void CDVDongleController::decodeIn(const unsigned char* ambe, unsigned int length) +{ + wxASSERT(ambe != NULL); + wxASSERT(length == VOICE_FRAME_LENGTH_BYTES); + + unsigned char buffer[DVD_HEADER_LEN + DVD_AUDIO_LENGTH_BYTES]; + unsigned char* p = buffer; + + // First the received AMBE data for decoding + ::memcpy(p, DVD_AMBE_HEADER, DVD_HEADER_LEN); + p += DVD_HEADER_LEN; + + ::memcpy(p, DVD_AMBE_DEC_DATA, DVD_AMBE_LENGTH_BYTES); + + ::memcpy(p + DVD_AMBE_HEADER_LEN, ambe, VOICE_FRAME_LENGTH_BYTES); + + m_serial.write(buffer, DVD_HEADER_LEN + DVD_AMBE_LENGTH_BYTES); + + // Then a dummy Audio packet + p = buffer; + ::memcpy(p, DVD_AUDIO_HEADER, DVD_HEADER_LEN); + p += DVD_HEADER_LEN; + + ::memset(p, 0x00, DVD_AUDIO_LENGTH_BYTES); + + m_serial.write(buffer, DVD_HEADER_LEN + DVD_AUDIO_LENGTH_BYTES); +} + +bool CDVDongleController::decodeOut(wxFloat32* audio, unsigned int length) +{ + wxASSERT(audio != NULL); + wxASSERT(length == DSTAR_AUDIO_BLOCK_SIZE); + + bool ambeFound = false; + bool audioFound = false; + + for (;;) { + unsigned char buffer[DVD_AUDIO_LENGTH_BYTES]; + RESP_TYPE type = getResponse(buffer, DVD_AUDIO_LENGTH_BYTES); + if (type == RESP_ERROR) + return false; + + if (type == RESP_AMBE) { + ambeFound = true; + } else if (type == RESP_AUDIO) { + wxInt16* q = (wxInt16*)buffer; + for (unsigned int i = 0U; i < DSTAR_AUDIO_BLOCK_SIZE; i++) { + wxInt16 word = wxINT16_SWAP_ON_BE(*q++); + audio[i] = wxFloat32(word) / 32768.0F; + } + audioFound = true; + } + + if (ambeFound && audioFound) + return true; + + ::wxMilliSleep(5UL); + } +} + +void CDVDongleController::close() +{ + m_serial.close(); +} + +CDVDongleController::RESP_TYPE CDVDongleController::getResponse(unsigned char* buffer, unsigned int length) +{ + wxASSERT(buffer != NULL); + wxASSERT(length >= DVD_AUDIO_LENGTH_BYTES); + + unsigned char c1, c2; + int len = m_serial.read(&c1, 1U); + if (len == 0) + return RESP_NONE; + + if (len < 0) { + wxLogError(wxT("Unable to receive the DVD header: len=%d"), len); + return RESP_ERROR; + } + + switch (c1) { + case 0xA0U: // DVD_AMBE_HEADER + wxLogMessage(wxT("Re-synchronising with the DV-Dongle")); + buffer[0U] = 0x32U; + buffer[1U] = c1; + return processResponse(buffer, length); + + case 0x81U: // DVD_AUDIO_HEADER + wxLogMessage(wxT("Re-synchronising with the DV-Dongle")); + buffer[0U] = 0x42U; + buffer[1U] = c1; + return processResponse(buffer, length); + + default: + m_serial.read(&c2, 1U); + buffer[0U] = c1; + buffer[1U] = c2; + return processResponse(buffer, length); + } +} + +CDVDongleController::RESP_TYPE CDVDongleController::processResponse(unsigned char* buffer, unsigned int length) +{ + wxASSERT(buffer != NULL); + wxASSERT(length >= DVD_AUDIO_LENGTH_BYTES); + + int len; + + if (::memcmp(buffer, DVD_AUDIO_HEADER, DVD_HEADER_LEN) == 0) { // Audio data + do { + len = m_serial.read(buffer, DVD_AUDIO_LENGTH_BYTES); + if (len == 0) + ::wxMilliSleep(5UL); + } while (len == 0); + + if (len != int(DVD_AUDIO_LENGTH_BYTES)) { + wxLogError(wxT("Unable to receive the DVD audio data, len=%d"), len); + return RESP_ERROR; + } + + return RESP_AUDIO; + } else if (::memcmp(buffer, DVD_AMBE_HEADER, DVD_HEADER_LEN) == 0) { // AMBE data + do { + len = m_serial.read(buffer, DVD_AMBE_LENGTH_BYTES); + if (len == 0) + ::wxMilliSleep(5UL); + } while (len == 0); + + if (len != int(DVD_AMBE_LENGTH_BYTES)) { + wxLogError(wxT("Unable to receive the DVD AMBE data, len=%d"), len); + return RESP_ERROR; + } + + return RESP_AMBE; + } else if (::memcmp(buffer, DVD_RESP_STOP, DVD_HEADER_LEN) == 0) { // Start or Stop response + do { + len = m_serial.read(buffer + DVD_HEADER_LEN, DVD_RESP_STOP_LEN - DVD_HEADER_LEN); + if (len == 0) + ::wxMilliSleep(5UL); + } while (len == 0); + + if (len != int(DVD_RESP_STOP_LEN - DVD_HEADER_LEN)) { + wxLogError(wxT("Unable to receive the DVD start/stop response, len=%d"), len); + return RESP_ERROR; + } + + bool res = ::memcmp(buffer, DVD_RESP_START, DVD_RESP_START_LEN) == 0; + if (res) + return RESP_START; + + res = ::memcmp(buffer, DVD_RESP_STOP, DVD_RESP_STOP_LEN) == 0; + if (res) + return RESP_STOP; + + wxLogError(wxT("Incorrect response to start/stop request: %02X %02X %02X %02X %02X"), buffer[0U], buffer[1U], buffer[2U], buffer[3U], buffer[4U]); + return RESP_ERROR; + } else if (::memcmp(buffer, DVD_RESP_NAME, DVD_HEADER_LEN) == 0) { // Dongle name + do { + len = m_serial.read(buffer + DVD_HEADER_LEN, DVD_RESP_NAME_LEN - DVD_HEADER_LEN); + if (len == 0) + ::wxMilliSleep(5UL); + } while (len == 0); + + if (len != int(DVD_RESP_NAME_LEN - DVD_HEADER_LEN)) { + wxLogError(wxT("Unable to receive the DVD name data, len=%d"), len); + return RESP_ERROR; + } + + bool res = ::memcmp(buffer, DVD_RESP_NAME, DVD_RESP_NAME_LEN) == 0; + if (res) + return RESP_NAME; + + wxLogError(wxT("Incorrect response to name request: %02X %02X %02X %02X %02X..."), buffer[0U], buffer[1U], buffer[2U], buffer[3U], buffer[4U]); + return RESP_ERROR; + } else if (::memcmp(buffer, DVD_RESP_NOP, DVD_HEADER_LEN) == 0) { // No op + return RESP_NOP; + } else { // Unknown data + wxLogError(wxT("Unknown DV Dongle header: %02X %02X"), buffer[0U], buffer[1U]); + return RESP_UNKNOWN; + } +} diff --git a/AMBETools/Common/DVDongleController.h b/AMBETools/Common/DVDongleController.h new file mode 100755 index 0000000..33cd7cf --- /dev/null +++ b/AMBETools/Common/DVDongleController.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2010,2011,2012,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVDongleController_H +#define DVDongleController_H + +#include "SerialDataController.h" + +#include + +class CDVDongleController { +public: + CDVDongleController(const wxString& device); + ~CDVDongleController(); + + bool open(); + bool start(); + + void encodeIn(const wxFloat32* audio, unsigned int length); + bool encodeOut(unsigned char* ambe, unsigned int length); + + void decodeIn(const unsigned char* ambe, unsigned int length); + bool decodeOut(wxFloat32* audio, unsigned int length); + + bool stop(); + void close(); + +private: + CSerialDataController m_serial; + + enum RESP_TYPE { + RESP_NONE, + RESP_ERROR, + RESP_START, + RESP_NAME, + RESP_STOP, + RESP_AMBE, + RESP_AUDIO, + RESP_NOP, + RESP_UNKNOWN + }; + + RESP_TYPE getResponse(unsigned char* buffer, unsigned int length); + RESP_TYPE processResponse(unsigned char* buffer, unsigned int length); +}; + +#endif diff --git a/AMBETools/Common/DVDongleController.o b/AMBETools/Common/DVDongleController.o new file mode 100644 index 0000000..fad5ff0 Binary files /dev/null and b/AMBETools/Common/DVDongleController.o differ diff --git a/AMBETools/Common/DVDongleThread.cpp b/AMBETools/Common/DVDongleThread.cpp new file mode 100755 index 0000000..0a9860d --- /dev/null +++ b/AMBETools/Common/DVDongleThread.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2010,2011,2012,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DVDongleThread.h" +#include "DStarDefines.h" + +CDVDongleThread::CDVDongleThread(CDVDongleController* dongle) : +CDongleThread(), +m_dongle(dongle), +m_wantMode(DM_IDLE), +m_mode(DM_IDLE) +{ + wxASSERT(dongle != NULL); +} + +CDVDongleThread::~CDVDongleThread() +{ +} + +bool CDVDongleThread::open() +{ + return m_dongle->open(); +} + +void* CDVDongleThread::Entry() +{ + m_dongle->start(); + + while (!m_killed) { + if (m_mode != m_wantMode) { + if (m_mode == DM_DECODE && m_bleep) + sendBleep(); + + // Reset the FIR filter shift register + reset(); + + m_mode = m_wantMode; + } + + switch (m_mode) { + case DM_IDLE: + processIdle(); + break; + + case DM_DECODE: + processDecode(); + break; + + case DM_ENCODE: + processEncode(); + break; + } + } + + m_dongle->stop(); + m_dongle->close(); + delete m_dongle; + + return NULL; +} + +void CDVDongleThread::setDecode() +{ + if (m_mode == DM_ENCODE && m_decodeCallback == NULL) + return; + + m_wantMode = DM_DECODE; +} + +void CDVDongleThread::setEncode() +{ + if (m_mode == DM_DECODE && m_encodeCallback == NULL) + return; + + m_wantMode = DM_ENCODE; +} + +void CDVDongleThread::setIdle() +{ + m_wantMode = DM_IDLE; +} + +void CDVDongleThread::processDecode() +{ + unsigned char ambe[VOICE_FRAME_LENGTH_BYTES]; + ::memset(ambe, 0x00, VOICE_FRAME_LENGTH_BYTES); + + m_decodeData.getData(ambe, VOICE_FRAME_LENGTH_BYTES); + + // Convert the AMBE data to real audio, even if it's nonsense + m_dongle->decodeIn(ambe, VOICE_FRAME_LENGTH_BYTES); + + wxFloat32 audioIn[DSTAR_AUDIO_BLOCK_SIZE]; + bool res = m_dongle->decodeOut(audioIn, DSTAR_AUDIO_BLOCK_SIZE); + if (!res) + wxLogError(wxT("An error occurred in decodeOut")); + + wxFloat32 audioOut[DSTAR_RADIO_BLOCK_SIZE]; + upSample(audioIn, audioOut); + + m_decodeCallback->decodeCallback(audioOut, DSTAR_RADIO_BLOCK_SIZE); +} + +void CDVDongleThread::processEncode() +{ + wxFloat32 audioIn[DSTAR_RADIO_BLOCK_SIZE]; + ::memset(audioIn, 0x00, DSTAR_RADIO_BLOCK_SIZE * sizeof(wxFloat32)); + + m_encodeAudio.getData(audioIn, DSTAR_RADIO_BLOCK_SIZE); + + wxFloat32 audioOut[DSTAR_AUDIO_BLOCK_SIZE]; + downSample(audioIn, audioOut); + + // Convert the audio into AMBE data + m_dongle->encodeIn(audioOut, DSTAR_AUDIO_BLOCK_SIZE); + + unsigned char ambe[VOICE_FRAME_LENGTH_BYTES]; + bool res = m_dongle->encodeOut(ambe, VOICE_FRAME_LENGTH_BYTES); + if (!res) + wxLogError(wxT("An error occurred in encodeOut")); + + m_encodeCallback->encodeCallback(ambe, VOICE_FRAME_LENGTH_BYTES); +} + +void CDVDongleThread::processIdle() +{ + unsigned char ambe[VOICE_FRAME_LENGTH_BYTES]; + ::memset(ambe, 0x00, VOICE_FRAME_LENGTH_BYTES); + + // Convert the AMBE data to real audio, even if it's nonsense + m_dongle->decodeIn(ambe, VOICE_FRAME_LENGTH_BYTES); + + wxFloat32 audio[DSTAR_RADIO_BLOCK_SIZE]; + bool res = m_dongle->decodeOut(audio, DSTAR_AUDIO_BLOCK_SIZE); + if (!res) + wxLogError(wxT("An error occurred in decodeOut")); +} diff --git a/AMBETools/Common/DVDongleThread.h b/AMBETools/Common/DVDongleThread.h new file mode 100755 index 0000000..c5462e1 --- /dev/null +++ b/AMBETools/Common/DVDongleThread.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010,2011,2012,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVDongleThread_H +#define DVDongleThread_H + +#include "DVDongleController.h" +#include "DongleThread.h" + +#include + +class CDVDongleThread : public CDongleThread { +public: + CDVDongleThread(CDVDongleController* dongle); + virtual ~CDVDongleThread(); + + virtual bool open(); + + virtual void setEncode(); + virtual void setDecode(); + virtual void setIdle(); + + virtual void* Entry(); + +private: + enum DVDMODE { + DM_IDLE, + DM_DECODE, + DM_ENCODE + }; + + CDVDongleController* m_dongle; + DVDMODE m_wantMode; + DVDMODE m_mode; + + void processDecode(); + void processEncode(); + void processIdle(); +}; + +#endif diff --git a/AMBETools/Common/DVDongleThread.o b/AMBETools/Common/DVDongleThread.o new file mode 100644 index 0000000..1eea0ea Binary files /dev/null and b/AMBETools/Common/DVDongleThread.o differ diff --git a/AMBETools/Common/DVTOOLFileReader.cpp b/AMBETools/Common/DVTOOLFileReader.cpp new file mode 100755 index 0000000..8849327 --- /dev/null +++ b/AMBETools/Common/DVTOOLFileReader.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2009,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DVTOOLFileReader.h" + +#include + +static const char DVTOOL_SIGNATURE[] = "DVTOOL"; +static const unsigned int DVTOOL_SIGNATURE_LENGTH = 6U; + +static const char DSVT_SIGNATURE[] = "DSVT"; +static const unsigned int DSVT_SIGNATURE_LENGTH = 4U; + +static const unsigned int FIXED_DATA_LENGTH = 9U; + +static const unsigned char HEADER_FLAG = 0x10; +static const unsigned char DATA_FLAG = 0x20; + +static const unsigned char HEADER_MASK = 0x80; +static const unsigned char TRAILER_MASK = 0x40; + +CDVTOOLFileReader::CDVTOOLFileReader() : +m_fileName(), +m_file(), +m_records(0U) +{ +} + +CDVTOOLFileReader::~CDVTOOLFileReader() +{ +} + +wxString CDVTOOLFileReader::getFileName() +{ + return m_fileName; +} + +bool CDVTOOLFileReader::open(const wxString& fileName) +{ + m_fileName = fileName; + + bool res = m_file.Open(fileName, wxT("rb")); + if (!res) + return false; + + unsigned char buffer[DVTOOL_SIGNATURE_LENGTH]; + size_t n = m_file.Read(buffer, DVTOOL_SIGNATURE_LENGTH); + if (n != DVTOOL_SIGNATURE_LENGTH) { + m_file.Close(); + return false; + } + + if (::memcmp(buffer, DVTOOL_SIGNATURE, DVTOOL_SIGNATURE_LENGTH) != 0) { + m_file.Close(); + return false; + } + + wxUint32 uint32; + n = m_file.Read(&uint32, sizeof(wxUint32)); + if (n != sizeof(wxUint32)) { + m_file.Close(); + return false; + } + + m_records = wxUINT32_SWAP_ON_LE(uint32); + + return true; +} + +unsigned int CDVTOOLFileReader::read(unsigned char* buffer, unsigned int length, DVTFR_TYPE& type) +{ + wxASSERT(buffer != 0); + wxASSERT(length > 0U); + + wxUint16 uint16; + size_t n = m_file.Read(&uint16, sizeof(wxUint16)); + if (n != sizeof(wxUint16)) + return 0U; + + wxUint16 len = wxUINT16_SWAP_ON_BE(uint16) - 15U; + if (len > length) + return 0U; + + unsigned char bytes[FIXED_DATA_LENGTH]; + n = m_file.Read(bytes, DSVT_SIGNATURE_LENGTH); + if (n != DSVT_SIGNATURE_LENGTH) + return 0U; + + if (::memcmp(bytes, DSVT_SIGNATURE, DSVT_SIGNATURE_LENGTH) != 0) + return 0U; + + char flag; + n = m_file.Read(&flag, 1U); + if (n != 1U) + return 0U; + + type = (flag == HEADER_FLAG) ? DVTFR_HEADER : DVTFR_DETAIL; + + n = m_file.Read(bytes, FIXED_DATA_LENGTH); + if (n != FIXED_DATA_LENGTH) + return 0U; + + n = m_file.Read(&flag, 1U); + if (n != 1U) + return 0U; + + if (type == DVTFR_DETAIL) { + if ((flag & TRAILER_MASK) == TRAILER_MASK) + type = DVTFR_TRAILER; + } + + n = m_file.Read(buffer, len); + if (n != len) + return 0U; + + return len; +} + +void CDVTOOLFileReader::close() +{ + m_file.Close(); +} diff --git a/AMBETools/Common/DVTOOLFileReader.h b/AMBETools/Common/DVTOOLFileReader.h new file mode 100755 index 0000000..70c4630 --- /dev/null +++ b/AMBETools/Common/DVTOOLFileReader.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVTOOLFileReader_H +#define DVTOOLFileReader_H + +#include "FileReader.h" + +#include +#include + +class CDVTOOLFileReader : public IFileReader { +public: + CDVTOOLFileReader(); + virtual ~CDVTOOLFileReader(); + + virtual wxString getFileName(); + + virtual bool open(const wxString& fileName); + virtual unsigned int read(unsigned char* buffer, unsigned int length, DVTFR_TYPE& type); + virtual void close(); + +private: + wxString m_fileName; + wxFFile m_file; + wxUint32 m_records; +}; + +#endif diff --git a/AMBETools/Common/DVTOOLFileReader.o b/AMBETools/Common/DVTOOLFileReader.o new file mode 100644 index 0000000..a230128 Binary files /dev/null and b/AMBETools/Common/DVTOOLFileReader.o differ diff --git a/AMBETools/Common/DVTOOLFileWriter.cpp b/AMBETools/Common/DVTOOLFileWriter.cpp new file mode 100755 index 0000000..9218214 --- /dev/null +++ b/AMBETools/Common/DVTOOLFileWriter.cpp @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2009,2010,2012,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "CCITTChecksumReverse.h" +#include "DVTOOLFileWriter.h" +#include "DStarDefines.h" + +#include + +static const char DVTOOL_SIGNATURE[] = "DVTOOL"; +static unsigned int DVTOOL_SIGNATURE_LENGTH = 6U; + +static const char DSVT_SIGNATURE[] = "DSVT"; +static unsigned int DSVT_SIGNATURE_LENGTH = 4U; + +static const unsigned char HEADER_FLAG = 0x10; +static const unsigned char DATA_FLAG = 0x20; + +static const unsigned char FIXED_DATA[] = {0x00, 0x81, 0x00, 0x20, 0x00, 0x01, 0x02, 0xC0, 0xDE}; +static unsigned int FIXED_DATA_LENGTH = 9U; + +static const unsigned char TRAILER_DATA[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static unsigned int TRAILER_DATA_LENGTH = 12U; + +static const unsigned char HEADER_MASK = 0x80; +static const unsigned char TRAILER_MASK = 0x40; + +CDVTOOLFileWriter::CDVTOOLFileWriter(const wxString& filename) : +m_filename(filename), +m_file(), +m_count(0U), +m_sequence(0U), +m_offset(0) +{ +} + +CDVTOOLFileWriter::~CDVTOOLFileWriter() +{ +} + +wxString CDVTOOLFileWriter::getFilename() +{ + return m_filename; +} + +bool CDVTOOLFileWriter::open() +{ + if (m_file.IsOpened()) + close(); + + bool res = m_file.Open(m_filename, wxT("wb")); + if (!res) + return false; + + size_t n = m_file.Write(DVTOOL_SIGNATURE, DVTOOL_SIGNATURE_LENGTH); + if (n != DVTOOL_SIGNATURE_LENGTH) { + m_file.Close(); + return false; + } + + m_offset = m_file.Tell(); + + wxUint32 dummy = 0U; + n = m_file.Write(&dummy, sizeof(wxUint32)); + if (n != sizeof(wxUint32)) { + m_file.Close(); + return false; + } + + m_sequence = 0U; + m_count = 0U; + + return true; +} + +bool CDVTOOLFileWriter::writeHeader(const CHeaderData& header) +{ + unsigned char buffer[RADIO_HEADER_LENGTH_BYTES]; + + buffer[0] = header.getFlag1(); + buffer[1] = header.getFlag2(); + buffer[2] = header.getFlag3(); + + for (unsigned int i = 0U; i < LONG_CALLSIGN_LENGTH; i++) + buffer[3 + i] = header.getRptCall1().GetChar(i); + + for (unsigned int i = 0U; i < LONG_CALLSIGN_LENGTH; i++) + buffer[11 + i] = header.getRptCall2().GetChar(i); + + for (unsigned int i = 0U; i < LONG_CALLSIGN_LENGTH; i++) + buffer[19 + i] = header.getYourCall().GetChar(i); + + for (unsigned int i = 0U; i < LONG_CALLSIGN_LENGTH; i++) + buffer[27 + i] = header.getMyCall1().GetChar(i); + + for (unsigned int i = 0U; i < SHORT_CALLSIGN_LENGTH; i++) + buffer[35 + i] = header.getMyCall2().GetChar(i); + + // Get the checksum for the header + CCCITTChecksumReverse csum; + csum.update(buffer + 0, 4U * LONG_CALLSIGN_LENGTH + SHORT_CALLSIGN_LENGTH + 3U); + csum.result(buffer + 39); + + return writeHeader(buffer, RADIO_HEADER_LENGTH_BYTES); +} + +bool CDVTOOLFileWriter::writeHeader(const unsigned char* buffer, unsigned int length) +{ + wxASSERT(buffer != 0); + wxASSERT(length > 0U); + + wxUint16 len = wxUINT16_SWAP_ON_BE(length + 15U); + size_t n = m_file.Write(&len, sizeof(wxUint16)); + if (n != sizeof(wxUint16)) { + m_file.Close(); + return false; + } + + n = m_file.Write(DSVT_SIGNATURE, DSVT_SIGNATURE_LENGTH); + if (n != DSVT_SIGNATURE_LENGTH) { + m_file.Close(); + return false; + } + + char byte = HEADER_FLAG; + n = m_file.Write(&byte, 1U); + if (n != 1U) { + m_file.Close(); + return false; + } + + n = m_file.Write(FIXED_DATA, FIXED_DATA_LENGTH); + if (n != FIXED_DATA_LENGTH) { + m_file.Close(); + return false; + } + + byte = HEADER_MASK; + n = m_file.Write(&byte, 1U); + if (n != 1U) { + m_file.Close(); + return false; + } + + n = m_file.Write(buffer, length); + if (n != length) { + m_file.Close(); + return false; + } + + m_count++; + + return true; +} + +bool CDVTOOLFileWriter::writeFrame(const unsigned char* buffer, unsigned int length) +{ + wxASSERT(buffer != 0); + wxASSERT(length > 0U); + + wxUint16 len = wxUINT16_SWAP_ON_BE(length + 15U); + size_t n = m_file.Write(&len, sizeof(wxUint16)); + if (n != sizeof(wxUint16)) { + m_file.Close(); + return false; + } + + n = m_file.Write(DSVT_SIGNATURE, DSVT_SIGNATURE_LENGTH); + if (n != DSVT_SIGNATURE_LENGTH) { + m_file.Close(); + return false; + } + + char byte = DATA_FLAG; + n = m_file.Write(&byte, 1U); + if (n != 1U) { + m_file.Close(); + return false; + } + + n = m_file.Write(FIXED_DATA, FIXED_DATA_LENGTH); + if (n != FIXED_DATA_LENGTH) { + m_file.Close(); + return false; + } + + byte = m_sequence; + n = m_file.Write(&byte, 1U); + if (n != 1U) { + m_file.Close(); + return false; + } + + n = m_file.Write(buffer, length); + if (n != length) { + m_file.Close(); + return false; + } + + m_count++; + m_sequence++; + if (m_sequence >= 0x15U) + m_sequence = 0U; + + return true; +} + +void CDVTOOLFileWriter::close() +{ + writeTrailer(); + + m_file.Seek(m_offset); + + wxUint32 count = wxUINT32_SWAP_ON_LE(m_count); + m_file.Write(&count, sizeof(wxUint32)); + + m_file.Close(); +} + +bool CDVTOOLFileWriter::writeTrailer() +{ + wxUint16 len = wxUINT16_SWAP_ON_BE(27U); + size_t n = m_file.Write(&len, sizeof(wxUint16)); + if (n != sizeof(wxUint16)) { + m_file.Close(); + return false; + } + + n = m_file.Write(DSVT_SIGNATURE, DSVT_SIGNATURE_LENGTH); + if (n != DSVT_SIGNATURE_LENGTH) { + m_file.Close(); + return false; + } + + char byte = DATA_FLAG; + n = m_file.Write(&byte, 1U); + if (n != 1U) { + m_file.Close(); + return false; + } + + n = m_file.Write(FIXED_DATA, FIXED_DATA_LENGTH); + if (n != FIXED_DATA_LENGTH) { + m_file.Close(); + return false; + } + + byte = TRAILER_MASK | m_sequence; + n = m_file.Write(&byte, 1U); + if (n != 1U) { + m_file.Close(); + return false; + } + + n = m_file.Write(TRAILER_DATA, TRAILER_DATA_LENGTH); + if (n != TRAILER_DATA_LENGTH) { + m_file.Close(); + return false; + } + + return true; +} diff --git a/AMBETools/Common/DVTOOLFileWriter.h b/AMBETools/Common/DVTOOLFileWriter.h new file mode 100755 index 0000000..445f09e --- /dev/null +++ b/AMBETools/Common/DVTOOLFileWriter.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVTOOLFileWriter_H +#define DVTOOLFileWriter_H + +#include "FileWriter.h" + +#include +#include + +class CDVTOOLFileWriter : public IFileWriter { +public: + CDVTOOLFileWriter(const wxString& filename); + virtual ~CDVTOOLFileWriter(); + + virtual wxString getFilename(); + + virtual bool open(); + virtual bool writeHeader(const CHeaderData& header); + virtual bool writeHeader(const unsigned char* buffer, unsigned int length); + virtual bool writeFrame(const unsigned char* buffer, unsigned int length); + virtual void close(); + +private: + wxString m_filename; + wxFFile m_file; + wxUint32 m_count; + unsigned int m_sequence; + wxFileOffset m_offset; + + bool writeTrailer(); +}; + +#endif diff --git a/AMBETools/Common/DVTOOLFileWriter.o b/AMBETools/Common/DVTOOLFileWriter.o new file mode 100644 index 0000000..da29a7d Binary files /dev/null and b/AMBETools/Common/DVTOOLFileWriter.o differ diff --git a/AMBETools/Common/DecodeCallback.h b/AMBETools/Common/DecodeCallback.h new file mode 100755 index 0000000..1abcf1e --- /dev/null +++ b/AMBETools/Common/DecodeCallback.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef DecodeCallback_H +#define DecodeCallback_H + +#include + +class IDecodeCallback { +public: + virtual void decodeCallback(const wxFloat32* audio, unsigned int length) = 0; + +private: +}; + +#endif diff --git a/AMBETools/Common/DongleSet.cpp b/AMBETools/Common/DongleSet.cpp new file mode 100755 index 0000000..3947639 --- /dev/null +++ b/AMBETools/Common/DongleSet.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "SerialDataController.h" +#include "DongleSet.h" + +const unsigned int BORDER_SIZE = 5U; +const unsigned int CONTROL_WIDTH = 150U; + +const unsigned int ADDRESS_LENGTH = 15U; +const unsigned int PORT_LENGTH = 5U; + +const int CHOICE_TYPE = 8750; + +BEGIN_EVENT_TABLE(CDongleSet, wxPanel) + EVT_CHOICE(CHOICE_TYPE, CDongleSet::onType) +END_EVENT_TABLE() + +CDongleSet::CDongleSet(wxWindow* parent, int id, const wxString& title, DONGLE_TYPE type, const wxString& device, const wxString& address, unsigned int port) : +wxPanel(parent, id), +m_title(title), +m_type(NULL), +m_device(NULL), +m_address(NULL), +m_port(NULL) +{ + wxFlexGridSizer* sizer = new wxFlexGridSizer(2); + + wxStaticText* typeLabel = new wxStaticText(this, -1, _("Type")); + sizer->Add(typeLabel, 0, wxALL, BORDER_SIZE); + + m_type = new wxChoice(this, CHOICE_TYPE, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1)); + m_type->Append(wxT("DV-Dongle")); + m_type->Append(wxT("DV3000")); + sizer->Add(m_type, 0, wxALL, BORDER_SIZE); + m_type->SetSelection(int(type)); + + wxArrayString devices = CSerialDataController::getDevices(); + + wxStaticText* deviceLabel = new wxStaticText(this, -1, _("Device")); + sizer->Add(deviceLabel, 0, wxALL, BORDER_SIZE); + + m_device = new wxChoice(this, -1, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1), devices); + m_device->Insert(_(""), 0U); + sizer->Add(m_device, 0, wxALL, BORDER_SIZE); + + if (devices.GetCount() == 0U) { + m_device->SetSelection(0); + } else { + bool res = m_device->SetStringSelection(device); + if (!res) + m_device->SetSelection(0); + } + + wxStaticText* addressLabel = new wxStaticText(this, -1, _("Address")); + sizer->Add(addressLabel, 0, wxALL, BORDER_SIZE); + + m_address = new CAddressTextCtrl(this, -1, address, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1)); + m_address->SetMaxLength(ADDRESS_LENGTH); + sizer->Add(m_address, 0, wxALL, BORDER_SIZE); + + wxStaticText* portLabel = new wxStaticText(this, -1, _("Port")); + sizer->Add(portLabel, 0, wxALL, BORDER_SIZE); + + wxString text; + text.Printf(wxT("%u"), port); + + m_port = new CPortTextCtrl(this, -1, text, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1)); + m_port->SetMaxLength(PORT_LENGTH); + sizer->Add(m_port, 0, wxALL, BORDER_SIZE); + + if (type == DT_DV3000) { + m_device->Disable(); + } else { + m_address->Disable(); + m_port->Disable(); + } + + SetAutoLayout(true); + + //sizer->Fit(this); + //sizer->SetSizeHints(this); + + SetSizer(sizer); +} + + +CDongleSet::~CDongleSet() +{ +} + +bool CDongleSet::Validate() +{ + int n = m_type->GetSelection(); + + if (n == wxNOT_FOUND) { + wxMessageDialog dialog(this, _("The AMBE Dongle type is not set"), m_title + _(" Error"), wxICON_ERROR); + dialog.ShowModal(); + return false; + } + + if (n == 0) { + n = m_device->GetSelection(); + + if (n == wxNOT_FOUND) { + wxMessageDialog dialog(this, _("The AMBE Dongle device is not set"), m_title + _(" Error"), wxICON_ERROR); + dialog.ShowModal(); + return false; + } + } else { + unsigned int port = getPort(); + + if (port == 0U || port > 65535U) { + wxMessageDialog dialog(this, _("The Dongle Port is not valid"), m_title + _(" Error"), wxICON_ERROR); + dialog.ShowModal(); + return false; + } + } + + return true; +} + +DONGLE_TYPE CDongleSet::getType() const +{ + int n = m_type->GetSelection(); + + if (n == wxNOT_FOUND) + return DT_DVDONGLE; + + return DONGLE_TYPE(n); +} + +wxString CDongleSet::getDevice() const +{ + wxString device = m_device->GetStringSelection(); + + if (device.IsSameAs(_(""))) + return wxEmptyString; + else + return device; +} + +wxString CDongleSet::getAddress() const +{ + return m_address->GetValue(); +} + +unsigned int CDongleSet::getPort() const +{ + unsigned long n; + + m_port->GetValue().ToULong(&n); + + return n; +} + +void CDongleSet::onType(wxCommandEvent& event) +{ + int n = event.GetSelection(); + + switch (n) { + default: // DV-Dongle + m_device->Enable(); + m_address->Disable(); + m_port->Disable(); + break; + + case 1: // DV3000 + m_device->Disable(); + m_address->Enable(); + m_port->Enable(); + break; + } +} diff --git a/AMBETools/Common/DongleSet.h b/AMBETools/Common/DongleSet.h new file mode 100755 index 0000000..0840ce4 --- /dev/null +++ b/AMBETools/Common/DongleSet.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DongleSet_H +#define DongleSet_H + +#include "AddressTextCtrl.h" +#include "PortTextCtrl.h" +#include "DStarDefines.h" + +#include + +class CDongleSet : public wxPanel { +public: + CDongleSet(wxWindow* parent, int id, const wxString& title, DONGLE_TYPE type, const wxString& device, const wxString& address, unsigned int port); + virtual ~CDongleSet(); + + virtual bool Validate(); + + virtual DONGLE_TYPE getType() const; + virtual wxString getDevice() const; + virtual wxString getAddress() const; + virtual unsigned int getPort() const; + + virtual void onType(wxCommandEvent& event); + +private: + wxString m_title; + wxChoice* m_type; + wxChoice* m_device; + CAddressTextCtrl* m_address; + CPortTextCtrl* m_port; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/AMBETools/Common/DongleSet.o b/AMBETools/Common/DongleSet.o new file mode 100644 index 0000000..a90e43a Binary files /dev/null and b/AMBETools/Common/DongleSet.o differ diff --git a/AMBETools/Common/DongleThread.cpp b/AMBETools/Common/DongleThread.cpp new file mode 100755 index 0000000..a058a06 --- /dev/null +++ b/AMBETools/Common/DongleThread.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#include "DongleThread.h" +#include "DStarDefines.h" +#include "Bleeper.h" + +// A 3 kHz low pass filter at a sample rate of 48000 samples/sec. Calculated by the fir1 command in +// MATLAB. +const wxFloat32 FIR_TAPS[] = { + 0.001215122399171F, 0.001363519692447F, 0.001447384226195F, 0.001287712318712F, 0.000614680825630F, + -0.000833383976996F, -0.003176495118124F, -0.006261958697776F, -0.009578203328048F, -0.012249770207721F, + -0.013132705407240F, -0.011005254575316F, -0.004822958879920F, 0.006013373011413F, 0.021438048217733F, + 0.040605942188804F, 0.061921094815680F, 0.083217403172960F, 0.102067175368858F, 0.116163746412471F, + 0.123705527541065F, 0.123705527541065F, 0.116163746412471F, 0.102067175368858F, 0.083217403172960F, + 0.061921094815680F, 0.040605942188804F, 0.021438048217733F, 0.006013373011413F, -0.004822958879920F, + -0.011005254575316F, -0.013132705407240F, -0.012249770207721F, -0.009578203328048F, -0.006261958697776F, + -0.003176495118124F, -0.000833383976996F, 0.000614680825630F, 0.001287712318712F, 0.001447384226195F, + 0.001363519692447F, 0.001215122399171F}; + +const unsigned int FIR_LEN = 42U; + +const wxFloat32 UPSAMPLE_AMP = 6.0F; +const wxFloat32 DOWNSAMPLE_AMP = 0.9F; + +CDongleThread::CDongleThread() : +wxThread(wxTHREAD_JOINABLE), +m_encodeCallback(NULL), +m_decodeCallback(NULL), +m_encodeAudio(DSTAR_RADIO_BLOCK_SIZE * 30U), +m_decodeData(VOICE_FRAME_LENGTH_BYTES * 30U), +m_bleep(true), +m_killed(false), +m_filter(FIR_TAPS, FIR_LEN) +{ +} + +CDongleThread::~CDongleThread() +{ +} + +void CDongleThread::setEncodeCallback(IEncodeCallback* callback) +{ + wxASSERT(callback != NULL); + + m_encodeCallback = callback; +} + +void CDongleThread::setDecodeCallback(IDecodeCallback* callback) +{ + wxASSERT(callback != NULL); + + m_decodeCallback = callback; +} + +unsigned int CDongleThread::getEncodeSpace() const +{ + return m_encodeAudio.freeSpace(); +} + +unsigned int CDongleThread::getDecodeSpace() const +{ + return m_decodeData.freeSpace(); +} + +unsigned int CDongleThread::writeEncode(const wxFloat32* audio, unsigned int length) +{ + wxASSERT(audio != NULL); + + return m_encodeAudio.addData(audio, length); +} + +unsigned int CDongleThread::writeDecode(const unsigned char* ambe, unsigned int length) +{ + wxASSERT(ambe != NULL); + + return m_decodeData.addData(ambe, length); +} + +void CDongleThread::setBleep(bool on) +{ + m_bleep = on; +} + +void CDongleThread::kill() +{ + m_killed = true; + + Wait(); +} + +void CDongleThread::reset() +{ + m_filter.reset(); +} + +void CDongleThread::sendBleep() +{ + wxFloat32 audio[DSTAR_RADIO_BLOCK_SIZE]; + unsigned int n; + + CBleeper bleep(DSTAR_RADIO_SAMPLE_RATE, DSTAR_BLEEP_FREQ, DSTAR_BLEEP_LENGTH, DSTAR_BLEEP_AMPL); + + while ((n = bleep.getAudio(audio, DSTAR_RADIO_BLOCK_SIZE)) > 0U) + m_decodeCallback->decodeCallback(audio, n); +} + +// Convert from 8000 samples/sec to 48000 samples/sec +void CDongleThread::upSample(const wxFloat32* audioIn, wxFloat32* audioOut) +{ + unsigned int out = 0U; + for (unsigned int in = 0U; in < DSTAR_AUDIO_BLOCK_SIZE; in++) { + audioOut[out++] = m_filter.process(audioIn[in]) * UPSAMPLE_AMP; + + audioOut[out++] = m_filter.process(0.0F) * UPSAMPLE_AMP; + audioOut[out++] = m_filter.process(0.0F) * UPSAMPLE_AMP; + audioOut[out++] = m_filter.process(0.0F) * UPSAMPLE_AMP; + audioOut[out++] = m_filter.process(0.0F) * UPSAMPLE_AMP; + audioOut[out++] = m_filter.process(0.0F) * UPSAMPLE_AMP; + } +} + +// Convert from 48000 samples/sec to 8000 samples/sec +void CDongleThread::downSample(const wxFloat32* audioIn, wxFloat32* audioOut) +{ + unsigned int in = 0U; + for (unsigned int out = 0U; out < DSTAR_AUDIO_BLOCK_SIZE; out++) { + audioOut[out] = m_filter.process(audioIn[in++]) * DOWNSAMPLE_AMP; + + m_filter.process(audioIn[in++]); + m_filter.process(audioIn[in++]); + m_filter.process(audioIn[in++]); + m_filter.process(audioIn[in++]); + m_filter.process(audioIn[in++]); + } +} diff --git a/AMBETools/Common/DongleThread.h b/AMBETools/Common/DongleThread.h new file mode 100755 index 0000000..0777be0 --- /dev/null +++ b/AMBETools/Common/DongleThread.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DongleThread_H +#define DongleThread_H + +#include "EncodeCallback.h" +#include "DecodeCallback.h" +#include "RingBuffer.h" +#include "FIRFilter.h" + +#include + +class CDongleThread : public wxThread { +public: + CDongleThread(); + virtual ~CDongleThread(); + + virtual void setEncodeCallback(IEncodeCallback* callback); + virtual void setDecodeCallback(IDecodeCallback* callback); + + virtual bool open() = 0; + + virtual void setEncode() = 0; + virtual void setDecode() = 0; + virtual void setIdle() = 0; + + virtual unsigned int getEncodeSpace() const; + virtual unsigned int getDecodeSpace() const; + + virtual unsigned int writeEncode(const wxFloat32* audio, unsigned int length); + virtual unsigned int writeDecode(const unsigned char* ambe, unsigned int length); + + virtual void setBleep(bool on); + + virtual void kill(); + +protected: + IEncodeCallback* m_encodeCallback; + IDecodeCallback* m_decodeCallback; + CRingBuffer m_encodeAudio; + CRingBuffer m_decodeData; + bool m_bleep; + bool m_killed; + + void reset(); + + void upSample(const wxFloat32* audioIn, wxFloat32* audioOut); + void downSample(const wxFloat32* audioIn, wxFloat32* audioOut); + + void sendBleep(); + +private: + CFIRFilter m_filter; +}; + +#endif diff --git a/AMBETools/Common/DongleThread.o b/AMBETools/Common/DongleThread.o new file mode 100644 index 0000000..0ee703e Binary files /dev/null and b/AMBETools/Common/DongleThread.o differ diff --git a/AMBETools/Common/EncodeCallback.h b/AMBETools/Common/EncodeCallback.h new file mode 100755 index 0000000..8b3a432 --- /dev/null +++ b/AMBETools/Common/EncodeCallback.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef EncodeCallback_H +#define EncodeCallback_H + +#include + +class IEncodeCallback { +public: + virtual void encodeCallback(const unsigned char* ambe, unsigned int length) = 0; + +private: +}; + +#endif diff --git a/AMBETools/Common/ErrorEvent.cpp b/AMBETools/Common/ErrorEvent.cpp new file mode 100755 index 0000000..2380c69 --- /dev/null +++ b/AMBETools/Common/ErrorEvent.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "ErrorEvent.h" + +CErrorEvent::CErrorEvent(const wxString& text, wxEventType type, int id) : +wxEvent(id, type), +m_text(text) +{ +} + +CErrorEvent::CErrorEvent(const CErrorEvent& event) : +wxEvent(event), +m_text(event.m_text) +{ +} + +CErrorEvent::~CErrorEvent() +{ +} + +wxString CErrorEvent::getText() const +{ + return m_text; +} + +wxEvent* CErrorEvent::Clone() const +{ + return new CErrorEvent(*this); +} diff --git a/AMBETools/Common/ErrorEvent.h b/AMBETools/Common/ErrorEvent.h new file mode 100755 index 0000000..4ee0bdb --- /dev/null +++ b/AMBETools/Common/ErrorEvent.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef ErrorEvent_H +#define ErrorEvent_H + +#include + +class CErrorEvent : public wxEvent { +public: + CErrorEvent(const wxString& text, wxEventType type, int id = 0); + virtual ~CErrorEvent(); + + virtual wxString getText() const; + + virtual wxEvent* Clone() const; + +protected: + CErrorEvent(const CErrorEvent& event); + +private: + wxString m_text; +}; + +#endif diff --git a/AMBETools/Common/ErrorEvent.o b/AMBETools/Common/ErrorEvent.o new file mode 100644 index 0000000..11af190 Binary files /dev/null and b/AMBETools/Common/ErrorEvent.o differ diff --git a/AMBETools/Common/FIRFilter.cpp b/AMBETools/Common/FIRFilter.cpp new file mode 100755 index 0000000..63727fc --- /dev/null +++ b/AMBETools/Common/FIRFilter.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2001, 2002, 2003 by Tomi Manninen, OH2BNS + * Copyright (C) 2009 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#include "FIRFilter.h" + +CFIRFilter::CFIRFilter(const wxFloat32* taps, unsigned int length) : +m_taps(NULL), +m_length(length), +m_buffer(NULL), +m_bufLen(20U * m_length), +m_pointer(length) +{ + wxASSERT(taps != NULL); + wxASSERT(length > 0U); + + m_taps = new wxFloat32[m_length]; + m_buffer = new wxFloat32[m_bufLen]; + + ::memcpy(m_taps, taps, m_length * sizeof(wxFloat32)); + ::memset(m_buffer, 0x00, m_bufLen * sizeof(wxFloat32)); +} + +CFIRFilter::CFIRFilter() : +m_taps(NULL), +m_length(0U), +m_buffer(NULL), +m_bufLen(0U), +m_pointer(0U) +{ +} + +CFIRFilter::~CFIRFilter() +{ + delete[] m_taps; + delete[] m_buffer; +} + +void CFIRFilter::setTaps(const wxFloat32* taps, unsigned int length) +{ + wxASSERT(taps != NULL); + wxASSERT(length > 0U); + + delete[] m_taps; + delete[] m_buffer; + + m_length = length; + m_pointer = length; + m_bufLen = 20U * m_length; + + m_taps = new wxFloat32[m_length]; + m_buffer = new wxFloat32[m_bufLen]; + + ::memcpy(m_taps, taps, m_length * sizeof(wxFloat32)); + ::memset(m_buffer, 0x00, m_bufLen * sizeof(wxFloat32)); +} + +wxFloat32 CFIRFilter::process(wxFloat32 val) +{ + wxFloat32* ptr = m_buffer + m_pointer++; + + *ptr = val; + + wxFloat32* a = ptr - m_length; + wxFloat32* b = m_taps; + + wxFloat32 out = 0.0F; + for (unsigned int i = 0U; i < m_length; i++) + out += (*a++) * (*b++); + + if (m_pointer == m_bufLen) { + ::memcpy(m_buffer, m_buffer + m_bufLen - m_length, m_length * sizeof(wxFloat32)); + m_pointer = m_length; + } + + return out; +} + +void CFIRFilter::process(wxFloat32* inOut, unsigned int length) +{ + wxASSERT(inOut != NULL); + + for (unsigned int i = 0U; i < length; i++) + inOut[i] = process(inOut[i]); +} + +void CFIRFilter::process(const wxFloat32* in, wxFloat32* out, unsigned int length) +{ + wxASSERT(in != NULL); + wxASSERT(out != NULL); + + for (unsigned int i = 0U; i < length; i++) + out[i] = process(in[i]); +} + +void CFIRFilter::reset() +{ + ::memset(m_buffer, 0x00, m_bufLen * sizeof(wxFloat32));; +} diff --git a/AMBETools/Common/FIRFilter.h b/AMBETools/Common/FIRFilter.h new file mode 100755 index 0000000..7cce478 --- /dev/null +++ b/AMBETools/Common/FIRFilter.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2009,2014 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef FIRFilter_H +#define FIRFilter_H + +#include + +class CFIRFilter { +public: + CFIRFilter(const wxFloat32* taps, unsigned int length); + CFIRFilter(); + ~CFIRFilter(); + + void setTaps(const wxFloat32* taps, unsigned int length); + + wxFloat32 process(wxFloat32 val); + void process(wxFloat32* inOut, unsigned int length); + void process(const wxFloat32* in, wxFloat32* out, unsigned int length); + + void reset(); + +private: + wxFloat32* m_taps; + unsigned int m_length; + wxFloat32* m_buffer; + unsigned int m_bufLen; + unsigned int m_pointer; +}; + +#endif diff --git a/AMBETools/Common/FIRFilter.o b/AMBETools/Common/FIRFilter.o new file mode 100644 index 0000000..bb7efcf Binary files /dev/null and b/AMBETools/Common/FIRFilter.o differ diff --git a/AMBETools/Common/FileReader.cpp b/AMBETools/Common/FileReader.cpp new file mode 100755 index 0000000..b943b1a --- /dev/null +++ b/AMBETools/Common/FileReader.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#include "FileReader.h" + +IFileReader::~IFileReader() +{ +} diff --git a/AMBETools/Common/FileReader.h b/AMBETools/Common/FileReader.h new file mode 100755 index 0000000..752af97 --- /dev/null +++ b/AMBETools/Common/FileReader.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef FileReader_H +#define FileReader_H + +enum DVTFR_TYPE { + DVTFR_HEADER, + DVTFR_DETAIL, + DVTFR_TRAILER +}; + +#include + +class IFileReader { +public: + virtual ~IFileReader() = 0; + + virtual wxString getFileName() = 0; + + virtual bool open(const wxString& fileName) = 0; + virtual unsigned int read(unsigned char* buffer, unsigned int length, DVTFR_TYPE& type) = 0; + virtual void close() = 0; +}; + +#endif diff --git a/AMBETools/Common/FileReader.o b/AMBETools/Common/FileReader.o new file mode 100644 index 0000000..9523136 Binary files /dev/null and b/AMBETools/Common/FileReader.o differ diff --git a/AMBETools/Common/FileWriter.cpp b/AMBETools/Common/FileWriter.cpp new file mode 100755 index 0000000..f80f02e --- /dev/null +++ b/AMBETools/Common/FileWriter.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#include "FileWriter.h" + +IFileWriter::~IFileWriter() +{ +} diff --git a/AMBETools/Common/FileWriter.h b/AMBETools/Common/FileWriter.h new file mode 100755 index 0000000..5f8375f --- /dev/null +++ b/AMBETools/Common/FileWriter.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef FileWriter_H +#define FileWriter_H + +#include "HeaderData.h" + +#include + +class IFileWriter { +public: + virtual ~IFileWriter() = 0; + + virtual wxString getFilename() = 0; + + virtual bool open() = 0; + virtual bool writeHeader(const CHeaderData& header) = 0; + virtual bool writeHeader(const unsigned char* buffer, unsigned int length) = 0; + virtual bool writeFrame(const unsigned char* buffer, unsigned int length) = 0; + virtual void close() = 0; +}; + +#endif diff --git a/AMBETools/Common/FileWriter.o b/AMBETools/Common/FileWriter.o new file mode 100644 index 0000000..a3f0e0a Binary files /dev/null and b/AMBETools/Common/FileWriter.o differ diff --git a/AMBETools/Common/HeaderData.cpp b/AMBETools/Common/HeaderData.cpp new file mode 100755 index 0000000..7331bc7 --- /dev/null +++ b/AMBETools/Common/HeaderData.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2009,2012 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "CCITTChecksumReverse.h" +#include "HeaderData.h" +#include "DStarDefines.h" + +CHeaderData::CHeaderData() : +m_time(), +m_myCall1(), +m_myCall2(), +m_yourCall(), +m_rptCall1(), +m_rptCall2(), +m_flag1(0x00), +m_flag2(0x00), +m_flag3(0x00), +m_valid(false) +{ +} + +CHeaderData::CHeaderData(const CHeaderData& header) : +m_time(header.m_time), +m_myCall1(header.m_myCall1), +m_myCall2(header.m_myCall2), +m_yourCall(header.m_yourCall), +m_rptCall1(header.m_rptCall1), +m_rptCall2(header.m_rptCall2), +m_flag1(header.m_flag1), +m_flag2(header.m_flag2), +m_flag3(header.m_flag3), +m_valid(header.m_valid) +{ +} + +CHeaderData::CHeaderData(const unsigned char* data, unsigned int length, bool check) : +m_time(), +m_myCall1(), +m_myCall2(), +m_yourCall(), +m_rptCall1(), +m_rptCall2(), +m_flag1(0x00), +m_flag2(0x00), +m_flag3(0x00), +m_valid(true) +{ + wxASSERT(data != NULL); + wxASSERT(length >= (RADIO_HEADER_LENGTH_BYTES - 2U)); + + const unsigned char* p = data; + m_flag1 = *p++; + m_flag2 = *p++; + m_flag3 = *p++; + + m_rptCall2 = wxString((const char*)p, wxConvLocal, LONG_CALLSIGN_LENGTH); + p += LONG_CALLSIGN_LENGTH; + + m_rptCall1 = wxString((const char*)p, wxConvLocal, LONG_CALLSIGN_LENGTH); + p += LONG_CALLSIGN_LENGTH; + + m_yourCall = wxString((const char*)p, wxConvLocal, LONG_CALLSIGN_LENGTH); + p += LONG_CALLSIGN_LENGTH; + + m_myCall1 = wxString((const char*)p, wxConvLocal, LONG_CALLSIGN_LENGTH); + p += LONG_CALLSIGN_LENGTH; + + m_myCall2 = wxString((const char*)p, wxConvLocal, SHORT_CALLSIGN_LENGTH); + + m_time.SetToCurrent(); + + // We have a checksum, check it if asked + if (length >= RADIO_HEADER_LENGTH_BYTES && check) { + CCCITTChecksumReverse cksum; + + cksum.update(data, RADIO_HEADER_LENGTH_BYTES - 2U); + + m_valid = cksum.check(data + RADIO_HEADER_LENGTH_BYTES - 2U); + } +} + +CHeaderData::CHeaderData(const wxString& myCall1, const wxString& myCall2, const wxString& yourCall, + const wxString& rptCall1, const wxString& rptCall2, unsigned char flag1, + unsigned char flag2, unsigned char flag3) : +m_time(), +m_myCall1(myCall1), +m_myCall2(myCall2), +m_yourCall(yourCall), +m_rptCall1(rptCall1), +m_rptCall2(rptCall2), +m_flag1(flag1), +m_flag2(flag2), +m_flag3(flag3), +m_valid(true) +{ + m_time.SetToCurrent(); + + m_myCall1.Append(wxT(' '), LONG_CALLSIGN_LENGTH); + m_myCall2.Append(wxT(' '), SHORT_CALLSIGN_LENGTH); + m_yourCall.Append(wxT(' '), LONG_CALLSIGN_LENGTH); + m_rptCall1.Append(wxT(' '), LONG_CALLSIGN_LENGTH); + m_rptCall2.Append(wxT(' '), LONG_CALLSIGN_LENGTH); + + m_myCall1.Truncate(LONG_CALLSIGN_LENGTH); + m_myCall2.Truncate(SHORT_CALLSIGN_LENGTH); + m_yourCall.Truncate(LONG_CALLSIGN_LENGTH); + m_rptCall1.Truncate(LONG_CALLSIGN_LENGTH); + m_rptCall2.Truncate(LONG_CALLSIGN_LENGTH); +} + +CHeaderData::~CHeaderData() +{ +} + +wxDateTime CHeaderData::getTime() const +{ + return m_time; +} + +wxString CHeaderData::getMyCall1() const +{ + return m_myCall1; +} + +wxString CHeaderData::getMyCall2() const +{ + return m_myCall2; +} + +wxString CHeaderData::getYourCall() const +{ + return m_yourCall; +} + +wxString CHeaderData::getRptCall1() const +{ + return m_rptCall1; +} + +wxString CHeaderData::getRptCall2() const +{ + return m_rptCall2; +} + +unsigned char CHeaderData::getFlag1() const +{ + return m_flag1; +} + +unsigned char CHeaderData::getFlag2() const +{ + return m_flag2; +} + +unsigned char CHeaderData::getFlag3() const +{ + return m_flag3; +} + +void CHeaderData::setRepeaterMode(bool set) +{ + if (set) { + m_flag1 |= REPEATER_MASK; + } else { + m_flag1 &= ~REPEATER_MASK; + m_rptCall1 = wxT("DIRECT "); + m_rptCall2 = wxT("DIRECT "); + } +} + +bool CHeaderData::isRepeaterMode() const +{ + return (m_flag1 & REPEATER_MASK) == REPEATER_MASK; +} + +void CHeaderData::setDataPacket(bool set) +{ + if (set) + m_flag1 |= DATA_MASK; + else + m_flag1 &= ~DATA_MASK; +} + +bool CHeaderData::isDataPacket() const +{ + return (m_flag1 & DATA_MASK) == DATA_MASK; +} + +void CHeaderData::setInterrupted(bool set) +{ + if (set) + m_flag1 |= INTERRUPTED_MASK; + else + m_flag1 &= ~INTERRUPTED_MASK; +} + +bool CHeaderData::isInterrupted() const +{ + return (m_flag1 & INTERRUPTED_MASK) == INTERRUPTED_MASK; +} + +void CHeaderData::setControlSignal(bool set) +{ + if (set) + m_flag1 |= CONTROL_SIGNAL_MASK; + else + m_flag1 &= ~CONTROL_SIGNAL_MASK; +} + +bool CHeaderData::isControlSignal() const +{ + return (m_flag1 & CONTROL_SIGNAL_MASK) == CONTROL_SIGNAL_MASK; +} + +void CHeaderData::setUrgent(bool set) +{ + if (set) + m_flag1 |= URGENT_MASK; + else + m_flag1 &= ~URGENT_MASK; +} + +bool CHeaderData::isUrgent() const +{ + return (m_flag1 & URGENT_MASK) == URGENT_MASK; +} + +void CHeaderData::setRepeaterFlags(unsigned char set) +{ + m_flag1 &= ~REPEATER_CONTROL_MASK; + m_flag1 |= set & REPEATER_CONTROL_MASK; +} + +unsigned char CHeaderData::getRepeaterFlags() const +{ + return m_flag1 & REPEATER_CONTROL_MASK; +} + +bool CHeaderData::isValid() const +{ + return m_valid; +} + +void CHeaderData::reset() +{ + m_myCall1 = wxT(" "); + m_myCall2 = wxT(" "); + m_yourCall = wxT("CQCQCQ "); + m_rptCall1 = wxT("DIRECT "); + m_rptCall2 = wxT("DIRECT "); + + m_flag1 = 0x00; + m_flag2 = 0x00; + m_flag3 = 0x00; +} diff --git a/AMBETools/Common/HeaderData.h b/AMBETools/Common/HeaderData.h new file mode 100755 index 0000000..c1a5aac --- /dev/null +++ b/AMBETools/Common/HeaderData.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2009,2010 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef HeaderData_H +#define HeaderData_H + +#include + +class CHeaderData { +public: + CHeaderData(); + CHeaderData(const CHeaderData& header); + CHeaderData(const unsigned char* data, unsigned int length, bool check); + CHeaderData(const wxString& myCall1, const wxString& myCall2, const wxString& yourCall, + const wxString& rptCall1, const wxString& rptCall2, unsigned char flag1 = 0x00, + unsigned char flag2 = 0x00, unsigned char flag3 = 0x00); + ~CHeaderData(); + + wxDateTime getTime() const; + wxString getMyCall1() const; + wxString getMyCall2() const; + wxString getYourCall() const; + wxString getRptCall1() const; + wxString getRptCall2() const; + + unsigned char getFlag1() const; + unsigned char getFlag2() const; + unsigned char getFlag3() const; + + bool isRepeaterMode() const; + bool isDataPacket() const; + bool isInterrupted() const; + bool isControlSignal() const; + bool isUrgent() const; + unsigned char getRepeaterFlags() const; + + void setRepeaterMode(bool set); + void setDataPacket(bool set); + void setInterrupted(bool set); + void setControlSignal(bool set); + void setUrgent(bool set); + void setRepeaterFlags(unsigned char set); + + bool isValid() const; + + void reset(); + +private: + wxDateTime m_time; + wxString m_myCall1; + wxString m_myCall2; + wxString m_yourCall; + wxString m_rptCall1; + wxString m_rptCall2; + unsigned char m_flag1; + unsigned char m_flag2; + unsigned char m_flag3; + bool m_valid; +}; + +#endif diff --git a/AMBETools/Common/HeaderData.o b/AMBETools/Common/HeaderData.o new file mode 100644 index 0000000..56d3067 Binary files /dev/null and b/AMBETools/Common/HeaderData.o differ diff --git a/AMBETools/Common/HeaderEvent.cpp b/AMBETools/Common/HeaderEvent.cpp new file mode 100755 index 0000000..452e129 --- /dev/null +++ b/AMBETools/Common/HeaderEvent.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "HeaderEvent.h" + +CHeaderEvent::CHeaderEvent(CHeaderData* header, wxEventType type, int id) : +wxEvent(id, type), +m_header(header) +{ +} + +CHeaderEvent::CHeaderEvent(const CHeaderEvent& event) : +wxEvent(event), +m_header(event.m_header) +{ +} + +CHeaderEvent::~CHeaderEvent() +{ +} + +CHeaderData* CHeaderEvent::getHeaderData() const +{ + return m_header; +} + +wxEvent* CHeaderEvent::Clone() const +{ + return new CHeaderEvent(*this); +} diff --git a/AMBETools/Common/HeaderEvent.h b/AMBETools/Common/HeaderEvent.h new file mode 100755 index 0000000..db3df11 --- /dev/null +++ b/AMBETools/Common/HeaderEvent.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef HeaderEvent_H +#define HeaderEvent_H + +#include + +#include "HeaderData.h" + +class CHeaderEvent : public wxEvent { +public: + CHeaderEvent(CHeaderData* header, wxEventType type, int id = 0); + virtual ~CHeaderEvent(); + + virtual CHeaderData* getHeaderData() const; + + virtual wxEvent* Clone() const; + +protected: + CHeaderEvent(const CHeaderEvent& event); + +private: + CHeaderData* m_header; +}; + +#endif diff --git a/AMBETools/Common/HeaderEvent.o b/AMBETools/Common/HeaderEvent.o new file mode 100644 index 0000000..83e8b51 Binary files /dev/null and b/AMBETools/Common/HeaderEvent.o differ diff --git a/AMBETools/Common/Logger.cpp b/AMBETools/Common/Logger.cpp new file mode 100755 index 0000000..ae64276 --- /dev/null +++ b/AMBETools/Common/Logger.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2002,2003,2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "Logger.h" + +CLogger::CLogger(const wxString& fileName) : +wxLog(), +m_file(NULL) +{ + m_file = new wxFFile; + m_file->Open(fileName, wxT("a+t")); +} + +CLogger::~CLogger() +{ + wxASSERT(m_file != NULL); + + m_file->Close(); + delete m_file; +} + +void CLogger::DoLog(wxLogLevel level, const wxChar* msg, time_t timestamp) +{ + wxASSERT(m_file != NULL); + wxASSERT(m_file->IsOpened()); + wxASSERT(msg != NULL); + + wxString letter; + + switch (level) { + case wxLOG_FatalError: letter = wxT("F"); break; + case wxLOG_Error: letter = wxT("E"); break; + case wxLOG_Warning: letter = wxT("W"); break; + case wxLOG_Info: letter = wxT("I"); break; + case wxLOG_Message: letter = wxT("M"); break; + case wxLOG_Status: letter = wxT("M"); break; + case wxLOG_Trace: letter = wxT("T"); break; + case wxLOG_Debug: letter = wxT("D"); break; + default: letter = wxT("U"); break; + } + + wxDateTime dateTime(timestamp); + wxString timeText = dateTime.Format(wxT(": %Y-%m-%d %H:%M:%S: ")); + wxString message = letter + timeText + msg + wxT("\n"); + + DoLogString(message.c_str(), timestamp); + + if (level == wxLOG_FatalError) + ::abort(); +} + +void CLogger::DoLogString(const wxChar* msg, time_t timestamp) +{ + wxASSERT(m_file != NULL); + wxASSERT(m_file->IsOpened()); + wxASSERT(msg != NULL); + + m_file->Write(wxString(msg)); + m_file->Flush(); +} diff --git a/AMBETools/Common/Logger.h b/AMBETools/Common/Logger.h new file mode 100755 index 0000000..0f617a5 --- /dev/null +++ b/AMBETools/Common/Logger.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2002,2003,2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef Logger_H +#define Logger_H + +#include +#include + +class CLogger : public wxLog { +public: + CLogger(const wxString& fileName); + virtual ~CLogger(); + + virtual void DoLog(wxLogLevel level, const wxChar* msg, time_t timestamp); + virtual void DoLogString(const wxChar* msg, time_t timestamp); + +private: + wxFFile* m_file; +}; + +#endif diff --git a/AMBETools/Common/Logger.o b/AMBETools/Common/Logger.o new file mode 100644 index 0000000..c3b6df6 Binary files /dev/null and b/AMBETools/Common/Logger.o differ diff --git a/AMBETools/Common/Makefile b/AMBETools/Common/Makefile new file mode 100755 index 0000000..8c7da17 --- /dev/null +++ b/AMBETools/Common/Makefile @@ -0,0 +1,126 @@ +all: Common.a + +OBJS := AddressTextCtrl.o AMBE3000Thread.o AMBEFileReader.o AMBEFileWriter.o Bleeper.o BleepSet.o CallsignSet.o CallsignTextCtrl.o CCITTChecksumReverse.o \ + DongleThread.o DV3000Controller.o DVDongleController.o DongleSet.o DVDongleThread.o DVTOOLFileReader.o DVTOOLFileWriter.o ErrorEvent.o FileReader.o \ + FileWriter.o FIRFilter.o HeaderData.o HeaderEvent.o Logger.o MessageData.o MessageEvent.o MessageSet.o MessageTextCtrl.o PortTextCtrl.o RestrictedTextCtrl.o \ + SerialDataController.o SlowDataDecoder.o SlowDataEncoder.o SoundCardReaderWriter.o SoundcardSet.o UDPReaderWriter.o Utils.o WAVFileReader.o WAVFileWriter.o + +Common.a: $(OBJS) + ar rcs Common.a $(OBJS) + +AddressTextCtrl.o: AddressTextCtrl.cpp AddressTextCtrl.h RestrictedTextCtrl.h + $(CC) $(CFLAGS) -c AddressTextCtrl.cpp + +AMBE3000Thread.o: AMBE3000Thread.cpp AMBE3000Thread.h DongleThread.h DV3000Controller.h DStarDefines.h + $(CC) $(CFLAGS) -c AMBE3000Thread.cpp + +AMBEFileReader.o: AMBEFileReader.cpp AMBEFileReader.h FileReader.h DStarDefines.h + $(CC) $(CFLAGS) -c AMBEFileReader.cpp + +AMBEFileWriter.o: AMBEFileWriter.cpp AMBEFileWriter.h FileWriter.h DStarDefines.h + $(CC) $(CFLAGS) -c AMBEFileWriter.cpp + +Bleeper.o: Bleeper.cpp Bleeper.h + $(CC) $(CFLAGS) -c Bleeper.cpp + +BleepSet.o: BleepSet.cpp BleepSet.h + $(CC) $(CFLAGS) -c BleepSet.cpp + +CallsignSet.o: CallsignSet.cpp CallsignSet.h CallsignTextCtrl.h DStarDefines.h + $(CC) $(CFLAGS) -c CallsignSet.cpp + +CallsignTextCtrl.o: CallsignTextCtrl.cpp CallsignTextCtrl.h RestrictedTextCtrl.h + $(CC) $(CFLAGS) -c CallsignTextCtrl.cpp + +CCITTChecksumReverse.o: CCITTChecksumReverse.cpp CCITTChecksumReverse.h Utils.h + $(CC) $(CFLAGS) -c CCITTChecksumReverse.cpp + +DongleThread.o: DongleThread.cpp DongleThread.h EncodeCallback.h DecodeCallback.h FIRFilter.h Bleeper.h RingBuffer.h + $(CC) $(CFLAGS) -c DongleThread.cpp + +DV3000Controller.o: DV3000Controller.cpp DV3000Controller.h DStarDefines.h UDPReaderWriter.h Utils.h + $(CC) $(CFLAGS) -c DV3000Controller.cpp + +DongleSet.o: DongleSet.cpp DongleSet.h SerialDataController.h AddressTextCtrl.h PortTextCtrl.h + $(CC) $(CFLAGS) -c DongleSet.cpp + +DVDongleController.o: DVDongleController.cpp DVDongleController.h DStarDefines.h SerialDataController.h + $(CC) $(CFLAGS) -c DVDongleController.cpp + +DVDongleThread.o: DVDongleThread.cpp DVDongleThread.h DongleThread.h DVDongleController.h DStarDefines.h + $(CC) $(CFLAGS) -c DVDongleThread.cpp + +DVTOOLFileReader.o: DVTOOLFileReader.cpp DVTOOLFileReader.h FileReader.h + $(CC) $(CFLAGS) -c DVTOOLFileReader.cpp + +DVTOOLFileWriter.o: DVTOOLFileWriter.cpp DVTOOLFileWriter.h FileWriter.h CCITTChecksumReverse.h DStarDefines.h + $(CC) $(CFLAGS) -c DVTOOLFileWriter.cpp + +ErrorEvent.o: ErrorEvent.cpp ErrorEvent.h + $(CC) $(CFLAGS) -c ErrorEvent.cpp + +FileReader.o: FileReader.cpp FileReader.h + $(CC) $(CFLAGS) -c FileReader.cpp + +FileWriter.o: FileWriter.cpp FileWriter.h HeaderData.h + $(CC) $(CFLAGS) -c FileWriter.cpp + +FIRFilter.o: FIRFilter.cpp FIRFilter.h + $(CC) $(CFLAGS) -c FIRFilter.cpp + +HeaderData.o: HeaderData.cpp HeaderData.h DStarDefines.h CCITTChecksumReverse.h + $(CC) $(CFLAGS) -c HeaderData.cpp + +HeaderEvent.o: HeaderEvent.cpp HeaderEvent.h HeaderData.h + $(CC) $(CFLAGS) -c HeaderEvent.cpp + +Logger.o: Logger.cpp Logger.h + $(CC) $(CFLAGS) -c Logger.cpp + +MessageData.o: MessageData.cpp MessageData.h + $(CC) $(CFLAGS) -c MessageData.cpp + +MessageEvent.o: MessageEvent.cpp MessageEvent.h MessageData.h + $(CC) $(CFLAGS) -c MessageEvent.cpp + +MessageSet.o: MessageSet.cpp MessageSet.h MessageTextCtrl.h + $(CC) $(CFLAGS) -c MessageSet.cpp + +MessageTextCtrl.o: MessageTextCtrl.cpp MessageTextCtrl.h RestrictedTextCtrl.h + $(CC) $(CFLAGS) -c MessageTextCtrl.cpp + +PortTextCtrl.o: PortTextCtrl.cpp PortTextCtrl.h RestrictedTextCtrl.h + $(CC) $(CFLAGS) -c PortTextCtrl.cpp + +RestrictedTextCtrl.o: RestrictedTextCtrl.cpp RestrictedTextCtrl.h + $(CC) $(CFLAGS) -c RestrictedTextCtrl.cpp + +SerialDataController.o: SerialDataController.cpp SerialDataController.h + $(CC) $(CFLAGS) -c SerialDataController.cpp + +SlowDataDecoder.o: SlowDataDecoder.cpp SlowDataDecoder.h DStarDefines.h MessageData.h HeaderData.h + $(CC) $(CFLAGS) -c SlowDataDecoder.cpp + +SlowDataEncoder.o: SlowDataEncoder.cpp SlowDataEncoder.h DStarDefines.h CCITTChecksumReverse.h MessageData.h HeaderData.h + $(CC) $(CFLAGS) -c SlowDataEncoder.cpp + +SoundCardReaderWriter.o: SoundCardReaderWriter.cpp SoundCardReaderWriter.h AudioCallback.h + $(CC) $(CFLAGS) -c SoundCardReaderWriter.cpp + +SoundcardSet.o: SoundcardSet.cpp SoundcardSet.h SoundCardReaderWriter.h + $(CC) $(CFLAGS) -c SoundcardSet.cpp + +UDPReaderWriter.o: UDPReaderWriter.cpp UDPReaderWriter.h Utils.h + $(CC) $(CFLAGS) -c UDPReaderWriter.cpp + +Utils.o: Utils.cpp Utils.h + $(CC) $(CFLAGS) -c Utils.cpp + +WAVFileReader.o: WAVFileReader.cpp WAVFileReader.h + $(CC) $(CFLAGS) -c WAVFileReader.cpp + +WAVFileWriter.o: WAVFileWriter.cpp WAVFileWriter.h + $(CC) $(CFLAGS) -c WAVFileWriter.cpp + +clean: + rm -f core Common.a *.o *~ *.bak diff --git a/AMBETools/Common/MessageData.cpp b/AMBETools/Common/MessageData.cpp new file mode 100755 index 0000000..baa649c --- /dev/null +++ b/AMBETools/Common/MessageData.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "MessageData.h" + +CMessageData::CMessageData(const CMessageData& message) : +m_msgText(message.m_msgText) +{ +} + +CMessageData::CMessageData(const unsigned char* msgText, unsigned int length) : +m_msgText() +{ + wxASSERT(msgText != NULL); + wxASSERT(length > 0U); + + m_msgText = wxString((const char*)msgText, wxConvLocal, length); +} + +CMessageData::CMessageData(const wxString& msgText) : +m_msgText(msgText) +{ +} + +CMessageData::~CMessageData() +{ +} + +wxString CMessageData::getMsgText() const +{ + return m_msgText; +} diff --git a/AMBETools/Common/MessageData.h b/AMBETools/Common/MessageData.h new file mode 100755 index 0000000..23f2f94 --- /dev/null +++ b/AMBETools/Common/MessageData.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009,2010 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef MessageData_H +#define MessageData_H + +#include + +class CMessageData { +public: + CMessageData(const CMessageData& message); + CMessageData(const unsigned char* msgText, unsigned int length); + CMessageData(const wxString& msgText); + ~CMessageData(); + + wxString getMsgText() const; + +private: + wxString m_msgText; +}; + +#endif diff --git a/AMBETools/Common/MessageData.o b/AMBETools/Common/MessageData.o new file mode 100644 index 0000000..d6c03b6 Binary files /dev/null and b/AMBETools/Common/MessageData.o differ diff --git a/AMBETools/Common/MessageEvent.cpp b/AMBETools/Common/MessageEvent.cpp new file mode 100755 index 0000000..4bf3098 --- /dev/null +++ b/AMBETools/Common/MessageEvent.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "MessageEvent.h" + +CMessageEvent::CMessageEvent(CMessageData* message, wxEventType type, int id) : +wxEvent(id, type), +m_message(message) +{ +} + +CMessageEvent::CMessageEvent(const CMessageEvent& event) : +wxEvent(event), +m_message(event.m_message) +{ +} + +CMessageEvent::~CMessageEvent() +{ +} + +CMessageData* CMessageEvent::getMessageData() const +{ + return m_message; +} + +wxEvent* CMessageEvent::Clone() const +{ + return new CMessageEvent(*this); +} diff --git a/AMBETools/Common/MessageEvent.h b/AMBETools/Common/MessageEvent.h new file mode 100755 index 0000000..f14fa3f --- /dev/null +++ b/AMBETools/Common/MessageEvent.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef MessageEvent_H +#define MessageEvent_H + +#include + +#include "MessageData.h" + +class CMessageEvent : public wxEvent { +public: + CMessageEvent(CMessageData* message, wxEventType type, int id = 0); + virtual ~CMessageEvent(); + + virtual CMessageData* getMessageData() const; + + virtual wxEvent* Clone() const; + +protected: + CMessageEvent(const CMessageEvent& event); + +private: + CMessageData* m_message; +}; + +#endif diff --git a/AMBETools/Common/MessageEvent.o b/AMBETools/Common/MessageEvent.o new file mode 100644 index 0000000..dbcafc9 Binary files /dev/null and b/AMBETools/Common/MessageEvent.o differ diff --git a/AMBETools/Common/MessageSet.cpp b/AMBETools/Common/MessageSet.cpp new file mode 100755 index 0000000..4e16586 --- /dev/null +++ b/AMBETools/Common/MessageSet.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009,2010 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "MessageSet.h" + +const unsigned int MAX_MESSAGE_LENGTH = 20U; + +const unsigned int CONTROL_SIZE = 200U; +const unsigned int BORDER_SIZE = 5U; + +CMessageSet::CMessageSet(wxWindow* parent, int id, const wxString& title, const wxString& message) : +wxPanel(parent, id), +m_title(title), +m_message(NULL) +{ + wxFlexGridSizer* sizer = new wxFlexGridSizer(2); + + wxStaticText* messageText = new wxStaticText(this, -1, _("Message")); + sizer->Add(messageText, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE); + + m_message = new CMessageTextCtrl(this, -1, message, wxDefaultPosition, wxSize(CONTROL_SIZE, -1)); + m_message->SetMaxLength(MAX_MESSAGE_LENGTH); + sizer->Add(m_message, 0, wxALL, BORDER_SIZE); + + SetAutoLayout(true); + + sizer->Fit(this); + sizer->SetSizeHints(this); + + SetSizer(sizer); +} + + +CMessageSet::~CMessageSet() +{ +} + +wxString CMessageSet::getMessage() const +{ + return m_message->GetValue(); +} diff --git a/AMBETools/Common/MessageSet.h b/AMBETools/Common/MessageSet.h new file mode 100755 index 0000000..6fa21fa --- /dev/null +++ b/AMBETools/Common/MessageSet.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2009,2010 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef MessageSet_H +#define MessageSet_H + +#include "MessageTextCtrl.h" + +#include + +class CMessageSet : public wxPanel { +public: + CMessageSet(wxWindow* parent, int id, const wxString& title, const wxString& message); + virtual ~CMessageSet(); + + virtual wxString getMessage() const; + +private: + wxString m_title; + CMessageTextCtrl* m_message; +}; + +#endif diff --git a/AMBETools/Common/MessageSet.o b/AMBETools/Common/MessageSet.o new file mode 100644 index 0000000..97cde86 Binary files /dev/null and b/AMBETools/Common/MessageSet.o differ diff --git a/AMBETools/Common/MessageTextCtrl.cpp b/AMBETools/Common/MessageTextCtrl.cpp new file mode 100755 index 0000000..0aa50ca --- /dev/null +++ b/AMBETools/Common/MessageTextCtrl.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "MessageTextCtrl.h" + +CMessageTextCtrl::CMessageTextCtrl(wxWindow* parent, int id, const wxString& value, const wxPoint& pos, const wxSize& size, long style) : +CRestrictedTextCtrl(parent, id, value, pos, size, style, MSG_CHARS) +{ +} + +CMessageTextCtrl::~CMessageTextCtrl() +{ +} + diff --git a/AMBETools/Common/MessageTextCtrl.h b/AMBETools/Common/MessageTextCtrl.h new file mode 100755 index 0000000..a493d72 --- /dev/null +++ b/AMBETools/Common/MessageTextCtrl.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef MessageTextCtrl_H +#define MessageTextCtrl_H + +#include + +#include "RestrictedTextCtrl.h" + +const wxString MSG_CHARS = wxT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ "); + +class CMessageTextCtrl : public CRestrictedTextCtrl { + +public: + CMessageTextCtrl(wxWindow* parent, int id, const wxString& value, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0L); + virtual ~CMessageTextCtrl(); + + private: +}; + +#endif diff --git a/AMBETools/Common/MessageTextCtrl.o b/AMBETools/Common/MessageTextCtrl.o new file mode 100644 index 0000000..734d5d4 Binary files /dev/null and b/AMBETools/Common/MessageTextCtrl.o differ diff --git a/AMBETools/Common/PortTextCtrl.cpp b/AMBETools/Common/PortTextCtrl.cpp new file mode 100755 index 0000000..4aa2c03 --- /dev/null +++ b/AMBETools/Common/PortTextCtrl.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2002,2003,2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "PortTextCtrl.h" + +CPortTextCtrl::CPortTextCtrl(wxWindow* parent, int id, const wxString& value, const wxPoint& pos, const wxSize& size, long style) : +CRestrictedTextCtrl(parent, id, value, pos, size, style, PORT_CHARS) +{ +} + +CPortTextCtrl::~CPortTextCtrl() +{ +} + diff --git a/AMBETools/Common/PortTextCtrl.h b/AMBETools/Common/PortTextCtrl.h new file mode 100755 index 0000000..c227118 --- /dev/null +++ b/AMBETools/Common/PortTextCtrl.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2002,2003,2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef PortTextCtrl_H +#define PortTextCtrl_H + +#include + +#include "RestrictedTextCtrl.h" + +const wxString PORT_CHARS = wxT("0123456789"); + +class CPortTextCtrl : public CRestrictedTextCtrl { + +public: + CPortTextCtrl(wxWindow* parent, int id, const wxString& value, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0L); + virtual ~CPortTextCtrl(); + + private: +}; + +#endif diff --git a/AMBETools/Common/PortTextCtrl.o b/AMBETools/Common/PortTextCtrl.o new file mode 100644 index 0000000..09714da Binary files /dev/null and b/AMBETools/Common/PortTextCtrl.o differ diff --git a/AMBETools/Common/RestrictedTextCtrl.cpp b/AMBETools/Common/RestrictedTextCtrl.cpp new file mode 100755 index 0000000..33b3f57 --- /dev/null +++ b/AMBETools/Common/RestrictedTextCtrl.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2002,2003,2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "RestrictedTextCtrl.h" + +CRestrictedTextCtrl::CRestrictedTextCtrl(wxWindow* parent, int id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxString& wantedChars) : +wxTextCtrl() +{ + wxASSERT(parent != NULL); + + wxArrayString charList; + + for (unsigned int i = 0; i < wantedChars.Length(); i++) + charList.Add(wantedChars.Mid(i, 1)); + + wxTextValidator validator(wxFILTER_INCLUDE_CHAR_LIST); + validator.SetIncludes(charList); + + Create(parent, id, value, pos, size, style, validator); +} + +CRestrictedTextCtrl::~CRestrictedTextCtrl() +{ +} + diff --git a/AMBETools/Common/RestrictedTextCtrl.h b/AMBETools/Common/RestrictedTextCtrl.h new file mode 100755 index 0000000..023e47a --- /dev/null +++ b/AMBETools/Common/RestrictedTextCtrl.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2002,2003 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef RestrictedTextCtrl_H +#define RestrictedTextCtrl_H + +#include + +class CRestrictedTextCtrl : public wxTextCtrl { +public: + CRestrictedTextCtrl(wxWindow* parent, int id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxString& wantedChars); + virtual ~CRestrictedTextCtrl(); + +private: +}; + +#endif diff --git a/AMBETools/Common/RestrictedTextCtrl.o b/AMBETools/Common/RestrictedTextCtrl.o new file mode 100644 index 0000000..cb6ce75 Binary files /dev/null and b/AMBETools/Common/RestrictedTextCtrl.o differ diff --git a/AMBETools/Common/RingBuffer.h b/AMBETools/Common/RingBuffer.h new file mode 100755 index 0000000..62ecc9a --- /dev/null +++ b/AMBETools/Common/RingBuffer.h @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2006-2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef RingBuffer_H +#define RingBuffer_H + +#include + +enum RBSTATE { + RBSTATE_EMPTY, + RBSTATE_FULL, + RBSTATE_DATA +}; + +template class CRingBuffer { +public: + CRingBuffer(unsigned int length) : + m_length(length), + m_buffer(NULL), + m_iPtr(0U), + m_oPtr(0U), + m_state(RBSTATE_EMPTY) + { + wxASSERT(length > 0U); + + m_buffer = new T[length]; + + ::memset(m_buffer, 0x00, length * sizeof(T)); + } + + ~CRingBuffer() + { + delete[] m_buffer; + } + + unsigned int addData(const T* buffer, unsigned int nSamples) + { + unsigned int space = freeSpace(); + + if (nSamples >= space) { + nSamples = space; + m_state = RBSTATE_FULL; + } else { + m_state = RBSTATE_DATA; + } + + for (unsigned int i = 0U; i < nSamples; i++) { + m_buffer[m_iPtr++] = buffer[i]; + + if (m_iPtr == m_length) + m_iPtr = 0U; + } + + return nSamples; + } + + unsigned int getData(T* buffer, unsigned int nSamples) + { + unsigned int space = dataSpace(); + + if (nSamples >= space) { + nSamples = space; + m_state = RBSTATE_EMPTY; + } else { + m_state = RBSTATE_DATA; + } + + for (unsigned int i = 0U; i < nSamples; i++) { + buffer[i] = m_buffer[m_oPtr++]; + + if (m_oPtr == m_length) + m_oPtr = 0U; + } + + return nSamples; + } + + void clear() + { + m_iPtr = 0U; + m_oPtr = 0U; + m_state = RBSTATE_EMPTY; + + ::memset(m_buffer, 0x00, m_length * sizeof(T)); + } + + unsigned int freeSpace() const + { + if (isEmpty()) + return m_length; + + if (isFull()) + return 0U; + + if (m_oPtr > m_iPtr) + return m_oPtr - m_iPtr; + + return m_length - (m_iPtr - m_oPtr); + } + + unsigned int dataSpace() const + { + if (isEmpty()) + return 0U; + + if (isFull()) + return m_length; + + if (m_iPtr >= m_oPtr) + return m_iPtr - m_oPtr; + + return m_length - (m_oPtr - m_iPtr); + } + + bool isEmpty() const + { + return m_state == RBSTATE_EMPTY; + } + + bool isFull() const + { + return m_state == RBSTATE_FULL; + } + +private: + unsigned int m_length; + T* m_buffer; + unsigned int m_iPtr; + unsigned int m_oPtr; + RBSTATE m_state; +}; + +#endif diff --git a/AMBETools/Common/SerialDataController.cpp b/AMBETools/Common/SerialDataController.cpp new file mode 100755 index 0000000..5d7933c --- /dev/null +++ b/AMBETools/Common/SerialDataController.cpp @@ -0,0 +1,511 @@ +/* + * Copyright (C) 2002-2004,2007-2011,2013,2014 by Jonathan Naylor G4KLX + * Copyright (C) 1999-2001 by Thomas Sailor HB9JNX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "SerialDataController.h" + +#include + +#if defined(__WINDOWS__) +#include +#include +#else +#include +#include +#include +#include +#include +#include +#endif + +wxArrayString CSerialDataController::getDevices() +{ + wxArrayString devices; + + devices.Alloc(10); + +#if defined(__WINDOWS__) + devices.Add(wxT("\\\\.\\COM1")); + devices.Add(wxT("\\\\.\\COM2")); + devices.Add(wxT("\\\\.\\COM3")); + devices.Add(wxT("\\\\.\\COM4")); + devices.Add(wxT("\\\\.\\COM5")); + devices.Add(wxT("\\\\.\\COM6")); + devices.Add(wxT("\\\\.\\COM7")); + devices.Add(wxT("\\\\.\\COM8")); + devices.Add(wxT("\\\\.\\COM9")); + devices.Add(wxT("\\\\.\\COM10")); + devices.Add(wxT("\\\\.\\COM11")); + devices.Add(wxT("\\\\.\\COM12")); + devices.Add(wxT("\\\\.\\COM13")); + devices.Add(wxT("\\\\.\\COM14")); + devices.Add(wxT("\\\\.\\COM15")); + devices.Add(wxT("\\\\.\\COM16")); + devices.Add(wxT("\\\\.\\COM17")); + devices.Add(wxT("\\\\.\\COM18")); + devices.Add(wxT("\\\\.\\COM19")); +#else +#if defined(RASPBERRY_PI) + devices.Add(wxT("/dev/ttyAMA0")); +#endif + devices.Add(wxT("/dev/ttyUSB0")); + devices.Add(wxT("/dev/ttyUSB1")); + devices.Add(wxT("/dev/ttyUSB2")); + devices.Add(wxT("/dev/ttyUSB3")); + devices.Add(wxT("/dev/ttyUSB4")); +#endif + + return devices; +} + +#if defined(__WINDOWS__) + +const unsigned int BUFFER_LENGTH = 1000U; + +CSerialDataController::CSerialDataController(const wxString& device, SERIAL_SPEED speed) : +m_device(device), +m_speed(speed), +m_handle(INVALID_HANDLE_VALUE), +m_readOverlapped(), +m_writeOverlapped(), +m_readBuffer(NULL), +m_readLength(0U), +m_readPending(false) +{ + wxASSERT(!device.IsEmpty()); + + m_readBuffer = new unsigned char[BUFFER_LENGTH]; +} + +CSerialDataController::~CSerialDataController() +{ + delete[] m_readBuffer; +} + +bool CSerialDataController::open() +{ + wxASSERT(m_handle == INVALID_HANDLE_VALUE); + + DWORD errCode; + + wxString baseName = m_device.Mid(4U); // Convert "\\.\COM10" to "COM10" + + m_handle = ::CreateFile(m_device.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + if (m_handle == INVALID_HANDLE_VALUE) { + wxLogError(wxT("Cannot open device - %s, err=%04lx"), m_device.c_str(), ::GetLastError()); + return false; + } + + if (!::SetupComm(m_handle, 32768UL, 32768UL)) { + wxLogError(wxT("Cannot set the communications parameters for %s, err=%04lx"), m_device.c_str(), ::GetLastError()); + ::ClearCommError(m_handle, &errCode, NULL); + ::CloseHandle(m_handle); + return false; + } + + DWORD size = sizeof(COMMCONFIG); + + COMMCONFIG config; + ::memset(&config, 0x00U, sizeof(COMMCONFIG)); + config.dwSize = size; + + if (!::GetDefaultCommConfig(baseName.c_str(), &config, &size)) { + wxLogError(wxT("Cannot get the default comm config for %s, err=%04lx"), m_device.c_str(), ::GetLastError()); + ::ClearCommError(m_handle, &errCode, NULL); + ::CloseHandle(m_handle); + return false; + } + + if (!::SetCommConfig(m_handle, &config, size)) { + wxLogError(wxT("Cannot set the comm config for %s, err=%04lx"), m_device.c_str(), ::GetLastError()); + ::ClearCommError(m_handle, &errCode, NULL); + ::CloseHandle(m_handle); + return false; + } + + DCB dcb; + if (::GetCommState(m_handle, &dcb) == 0) { + wxLogError(wxT("Cannot get the attributes for %s, err=%04lx"), m_device.c_str(), ::GetLastError()); + ::ClearCommError(m_handle, &errCode, NULL); + ::CloseHandle(m_handle); + return false; + } + + dcb.BaudRate = DWORD(m_speed); + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; + dcb.fParity = FALSE; + dcb.StopBits = ONESTOPBIT; + dcb.fInX = FALSE; + dcb.fOutX = FALSE; + dcb.fOutxCtsFlow = FALSE; + dcb.fOutxDsrFlow = FALSE; + dcb.fDtrControl = DTR_CONTROL_DISABLE; + dcb.fRtsControl = RTS_CONTROL_DISABLE; + + if (::SetCommState(m_handle, &dcb) == 0) { + wxLogError(wxT("Cannot set the attributes for %s, err=%04lx"), m_device.c_str(), ::GetLastError()); + ::ClearCommError(m_handle, &errCode, NULL); + ::CloseHandle(m_handle); + return false; + } + + COMMTIMEOUTS timeouts; + if (!::GetCommTimeouts(m_handle, &timeouts)) { + wxLogError(wxT("Cannot get the timeouts for %s, err=%04lx"), m_device.c_str(), ::GetLastError()); + ::ClearCommError(m_handle, &errCode, NULL); + ::CloseHandle(m_handle); + return false; + } + + timeouts.ReadIntervalTimeout = MAXDWORD; + timeouts.ReadTotalTimeoutMultiplier = 0UL; + timeouts.ReadTotalTimeoutConstant = 0UL; + + if (!::SetCommTimeouts(m_handle, &timeouts)) { + wxLogError(wxT("Cannot set the timeouts for %s, err=%04lx"), m_device.c_str(), ::GetLastError()); + ::ClearCommError(m_handle, &errCode, NULL); + ::CloseHandle(m_handle); + return false; + } + + if (::EscapeCommFunction(m_handle, CLRDTR) == 0) { + wxLogError(wxT("Cannot clear DTR for %s, err=%04lx"), m_device.c_str(), ::GetLastError()); + ::ClearCommError(m_handle, &errCode, NULL); + ::CloseHandle(m_handle); + return false; + } + + if (::EscapeCommFunction(m_handle, CLRRTS) == 0) { + wxLogError(wxT("Cannot clear RTS for %s, err=%04lx"), m_device.c_str(), ::GetLastError()); + ::ClearCommError(m_handle, &errCode, NULL); + ::CloseHandle(m_handle); + return false; + } + + ::ClearCommError(m_handle, &errCode, NULL); + + ::memset(&m_readOverlapped, 0x00U, sizeof(OVERLAPPED)); + ::memset(&m_writeOverlapped, 0x00U, sizeof(OVERLAPPED)); + + m_readOverlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); + m_writeOverlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); + + m_readLength = 0U; + m_readPending = false; + ::memset(m_readBuffer, 0x00U, BUFFER_LENGTH); + + return true; +} + +int CSerialDataController::read(unsigned char* buffer, unsigned int length) +{ + wxASSERT(m_handle != INVALID_HANDLE_VALUE); + wxASSERT(buffer != NULL); + + unsigned int ptr = 0U; + + while (ptr < length) { + int ret = readNonblock(buffer + ptr, length - ptr); + if (ret < 0) { + return ret; + } else if (ret == 0) { + if (ptr == 0U) + return 0; + } else { + ptr += ret; + } + } + + return int(length); +} + +int CSerialDataController::readNonblock(unsigned char* buffer, unsigned int length) +{ + wxASSERT(m_handle != INVALID_HANDLE_VALUE); + wxASSERT(buffer != NULL); + + if (length > BUFFER_LENGTH) + length = BUFFER_LENGTH; + + if (m_readPending && length != m_readLength) { + ::CancelIo(m_handle); + m_readPending = false; + } + + m_readLength = length; + + if (length == 0U) + return 0; + + if (!m_readPending) { + DWORD bytes = 0UL; + BOOL res = ::ReadFile(m_handle, m_readBuffer, m_readLength, &bytes, &m_readOverlapped); + if (res) { + ::memcpy(buffer, m_readBuffer, bytes); + return int(bytes); + } + + DWORD error = ::GetLastError(); + if (error != ERROR_IO_PENDING) { + wxLogError(wxT("Error from ReadFile: %04lx"), error); + return -1; + } + + m_readPending = true; + } + + BOOL res = HasOverlappedIoCompleted(&m_readOverlapped); + if (!res) + return 0; + + DWORD bytes = 0UL; + res = ::GetOverlappedResult(m_handle, &m_readOverlapped, &bytes, TRUE); + if (!res) { + wxLogError(wxT("Error from GetOverlappedResult (ReadFile): %04lx"), ::GetLastError()); + return -1; + } + + ::memcpy(buffer, m_readBuffer, bytes); + m_readPending = false; + + return int(bytes); +} + +int CSerialDataController::write(const unsigned char* buffer, unsigned int length) +{ + wxASSERT(m_handle != INVALID_HANDLE_VALUE); + wxASSERT(buffer != NULL); + + if (length == 0U) + return 0; + + unsigned int ptr = 0U; + + while (ptr < length) { + DWORD bytes = 0UL; + BOOL res = ::WriteFile(m_handle, buffer + ptr, length - ptr, &bytes, &m_writeOverlapped); + if (!res) { + DWORD error = ::GetLastError(); + if (error != ERROR_IO_PENDING) { + wxLogError(wxT("Error from WriteFile: %04lx"), error); + return -1; + } + + res = ::GetOverlappedResult(m_handle, &m_writeOverlapped, &bytes, TRUE); + if (!res) { + wxLogError(wxT("Error from GetOverlappedResult (WriteFile): %04lx"), ::GetLastError()); + return -1; + } + } + + ptr += bytes; + } + + return int(length); +} + +void CSerialDataController::close() +{ + wxASSERT(m_handle != INVALID_HANDLE_VALUE); + + ::CloseHandle(m_handle); + m_handle = INVALID_HANDLE_VALUE; + + ::CloseHandle(m_readOverlapped.hEvent); + ::CloseHandle(m_writeOverlapped.hEvent); +} + +#else + +CSerialDataController::CSerialDataController(const wxString& device, SERIAL_SPEED speed) : +m_device(device), +m_speed(speed), +m_fd(-1) +{ + wxASSERT(!device.IsEmpty()); +} + +CSerialDataController::~CSerialDataController() +{ +} + +bool CSerialDataController::open() +{ + wxASSERT(m_fd == -1); + + m_fd = ::open(m_device.mb_str(), O_RDWR | O_NOCTTY | O_NDELAY, 0); + if (m_fd < 0) { + wxLogError(wxT("Cannot open device - %s"), m_device.c_str()); + return false; + } + + if (::isatty(m_fd) == 0) { + wxLogError(wxT("%s is not a TTY device"), m_device.c_str()); + ::close(m_fd); + return false; + } + + termios termios; + if (::tcgetattr(m_fd, &termios) < 0) { + wxLogError(wxT("Cannot get the attributes for %s"), m_device.c_str()); + ::close(m_fd); + return false; + } + + termios.c_lflag &= ~(ECHO | ECHOE | ICANON | IEXTEN | ISIG); + termios.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IXOFF | IXANY); + termios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CRTSCTS); + termios.c_cflag |= CS8; + termios.c_oflag &= ~(OPOST); + termios.c_cc[VMIN] = 0; + termios.c_cc[VTIME] = 10; + + switch (m_speed) { + case SERIAL_1200: + ::cfsetospeed(&termios, B1200); + ::cfsetispeed(&termios, B1200); + break; + case SERIAL_2400: + ::cfsetospeed(&termios, B2400); + ::cfsetispeed(&termios, B2400); + break; + case SERIAL_4800: + ::cfsetospeed(&termios, B4800); + ::cfsetispeed(&termios, B4800); + break; + case SERIAL_9600: + ::cfsetospeed(&termios, B9600); + ::cfsetispeed(&termios, B9600); + break; + case SERIAL_19200: + ::cfsetospeed(&termios, B19200); + ::cfsetispeed(&termios, B19200); + break; + case SERIAL_38400: + ::cfsetospeed(&termios, B38400); + ::cfsetispeed(&termios, B38400); + break; + case SERIAL_115200: + ::cfsetospeed(&termios, B115200); + ::cfsetispeed(&termios, B115200); + break; + case SERIAL_230400: + ::cfsetospeed(&termios, B230400); + ::cfsetispeed(&termios, B230400); + break; + default: + wxLogError(wxT("Unsupported serial port speed - %d"), int(m_speed)); + ::close(m_fd); + return false; + } + + if (::tcsetattr(m_fd, TCSANOW, &termios) < 0) { + wxLogError(wxT("Cannot set the attributes for %s"), m_device.c_str()); + ::close(m_fd); + return false; + } + + return true; +} + +int CSerialDataController::read(unsigned char* buffer, unsigned int length) +{ + wxASSERT(buffer != NULL); + wxASSERT(m_fd != -1); + + if (length == 0U) + return 0; + + unsigned int offset = 0U; + + while (offset < length) { + fd_set fds; + FD_ZERO(&fds); + FD_SET(m_fd, &fds); + + int n; + if (offset == 0U) { + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 0; + + n = ::select(m_fd + 1, &fds, NULL, NULL, &tv); + if (n == 0) + return 0; + } else { + n = ::select(m_fd + 1, &fds, NULL, NULL, NULL); + } + + if (n < 0) { + wxLogError(wxT("Error from select(), errno=%d"), errno); + return -1; + } + + if (n > 0) { + ssize_t len = ::read(m_fd, buffer + offset, length - offset); + if (len < 0) { + if (errno != EAGAIN) { + wxLogError(wxT("Error from read(), errno=%d"), errno); + return -1; + } + } + + if (len > 0) + offset += len; + } + } + + return length; +} + +int CSerialDataController::write(const unsigned char* buffer, unsigned int length) +{ + wxASSERT(buffer != NULL); + wxASSERT(m_fd != -1); + + if (length == 0U) + return 0; + + unsigned int ptr = 0U; + + while (ptr < length) { + ssize_t n = ::write(m_fd, buffer + ptr, length - ptr); + if (n < 0) { + if (errno != EAGAIN) { + wxLogError(wxT("Error returned from write(), errno=%d"), errno); + return -1; + } + } + + if (n > 0) + ptr += n; + } + + return length; +} + +void CSerialDataController::close() +{ + wxASSERT(m_fd != -1); + + ::close(m_fd); + m_fd = -1; +} + +#endif diff --git a/AMBETools/Common/SerialDataController.h b/AMBETools/Common/SerialDataController.h new file mode 100755 index 0000000..e78a44a --- /dev/null +++ b/AMBETools/Common/SerialDataController.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2002-2004,2007-2009,2011-2013 by Jonathan Naylor G4KLX + * Copyright (C) 1999-2001 by Thomas Sailor HB9JNX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SerialDataController_H +#define SerialDataController_H + +#include + +#if defined(__WINDOWS__) +#include +#endif + +enum SERIAL_SPEED { + SERIAL_1200 = 1200, + SERIAL_2400 = 2400, + SERIAL_4800 = 4800, + SERIAL_9600 = 9600, + SERIAL_19200 = 19200, + SERIAL_38400 = 38400, + SERIAL_76800 = 76800, + SERIAL_115200 = 115200, + SERIAL_230400 = 230400 +}; + +class CSerialDataController { +public: + CSerialDataController(const wxString& device, SERIAL_SPEED speed); + ~CSerialDataController(); + + bool open(); + + int read(unsigned char* buffer, unsigned int length); + int write(const unsigned char* buffer, unsigned int length); + + void close(); + + static wxArrayString getDevices(); + +private: + wxString m_device; + SERIAL_SPEED m_speed; +#if defined(__WINDOWS__) + HANDLE m_handle; + OVERLAPPED m_readOverlapped; + OVERLAPPED m_writeOverlapped; + unsigned char* m_readBuffer; + unsigned int m_readLength; + bool m_readPending; +#else + int m_fd; +#endif + +#if defined(__WINDOWS__) + int readNonblock(unsigned char* buffer, unsigned int length); +#endif +}; + +#endif diff --git a/AMBETools/Common/SerialDataController.o b/AMBETools/Common/SerialDataController.o new file mode 100644 index 0000000..baac27f Binary files /dev/null and b/AMBETools/Common/SerialDataController.o differ diff --git a/AMBETools/Common/SlowDataDecoder.cpp b/AMBETools/Common/SlowDataDecoder.cpp new file mode 100755 index 0000000..427f77d --- /dev/null +++ b/AMBETools/Common/SlowDataDecoder.cpp @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2009 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#include "SlowDataDecoder.h" +#include "DStarDefines.h" + +const unsigned char SCRAMBLER_BYTE1 = 0x70; +const unsigned char SCRAMBLER_BYTE2 = 0x4F; +const unsigned char SCRAMBLER_BYTE3 = 0x93; + +CSlowDataDecoder::CSlowDataDecoder() : +m_buffer(NULL), +m_state(SDD_FIRST), +m_header(), +m_message(), +m_messageExp(0U), +// m_gpsMessage(), +m_headerData(NULL), +m_messageData(NULL), +// m_gpsMessageData(NULL), +m_codeSquelchData(0U), +m_hasCodeSquelch(false) +{ + m_buffer = new unsigned char[6U]; +} + +CSlowDataDecoder::~CSlowDataDecoder() +{ + delete[] m_buffer; + + delete m_headerData; + delete m_messageData; +// delete m_gpsMessageData; +} + +void CSlowDataDecoder::addData(const unsigned char* data) +{ + wxASSERT(data != NULL); + + switch (m_state) { + case SDD_FIRST: + m_buffer[0] = data[0] ^ SCRAMBLER_BYTE1; + m_buffer[1] = data[1] ^ SCRAMBLER_BYTE2; + m_buffer[2] = data[2] ^ SCRAMBLER_BYTE3; + m_state = SDD_SECOND; + return; + + case SDD_SECOND: + m_buffer[3] = data[0] ^ SCRAMBLER_BYTE1; + m_buffer[4] = data[1] ^ SCRAMBLER_BYTE2; + m_buffer[5] = data[2] ^ SCRAMBLER_BYTE3; + m_state = SDD_FIRST; + break; + } + + switch (m_buffer[0] & SLOW_DATA_TYPE_MASK) { +// case SLOW_DATA_TYPE_GPSDATA: +// processGPSMessage(); +// break; + case SLOW_DATA_TYPE_MESSAGE: + processMessage(); + break; + case SLOW_DATA_TYPE_HEADER: + processHeader(); + break; + case SLOW_DATA_TYPE_SQUELCH: + processCodeSquelch(); + break; + default: + break; + } +} + +/* +CGPSMessageData* CSlowDataDecoder::getGPSMessageData() +{ + if (m_gpsMessageData == NULL) + return NULL; + + CGPSMessageData* temp = new CGPSMessageData(*m_gpsMessageData); + + delete m_gpsMessageData; + m_gpsMessageData = NULL; + + m_gpsMessage.clear(); + + return temp; +} +*/ +CMessageData* CSlowDataDecoder::getMessageData() +{ + if (m_messageData == NULL) + return NULL; + + CMessageData* temp = new CMessageData(*m_messageData); + + delete m_messageData; + m_messageData = NULL; + + m_message.clear(); + + return temp; +} + +unsigned int CSlowDataDecoder::getHeader(unsigned char* data, unsigned int length) +{ + wxASSERT(data != NULL); + wxASSERT(length == RADIO_HEADER_LENGTH_BYTES); + + if (m_headerData == NULL) + return 0U; + + unsigned int n = 0U; + for (vector::const_iterator it = m_header.begin(); it != m_header.end(); ++it, n++) + data[n] = *it; + + delete m_headerData; + m_headerData = NULL; + + m_header.clear(); + + return RADIO_HEADER_LENGTH_BYTES; +} + +CHeaderData* CSlowDataDecoder::getHeaderData() +{ + if (m_headerData == NULL) + return NULL; + + CHeaderData* temp = new CHeaderData(*m_headerData); + + delete m_headerData; + m_headerData = NULL; + + m_header.clear(); + + return temp; +} + +bool CSlowDataDecoder::getCodeSquelchData(unsigned int& value) +{ + value = m_codeSquelchData; + + return m_hasCodeSquelch; +} + +void CSlowDataDecoder::sync() +{ + m_state = SDD_FIRST; +} + +void CSlowDataDecoder::reset() +{ + m_header.clear(); + m_message.clear(); +// m_gpsMessage.clear(); + + m_hasCodeSquelch = false; + + m_state = SDD_FIRST; + + delete m_headerData; + delete m_messageData; +// delete m_gpsMessageData; + + m_headerData = NULL; + m_messageData = NULL; +// m_gpsMessageData = NULL; + + m_messageExp = 0U; + m_codeSquelchData = 0U; +} + +void CSlowDataDecoder::processHeader() +{ + // Do we have a complete and valid header? + if (m_headerData != NULL) + return; + + unsigned int length = m_buffer[0] & SLOW_DATA_LENGTH_MASK; + if (length > 5U) + return; + + for (unsigned int i = 1U; i <= length; i++) + m_header.push_back(m_buffer[i]); + + // Do we have a complete header? + if (m_header.size() < RADIO_HEADER_LENGTH_BYTES) + return; + + // Something has been corrupted, discard + if (m_header.size() != RADIO_HEADER_LENGTH_BYTES) { + m_header.clear(); + return; + } + + // Convert the vector to an array + unsigned char buffer[RADIO_HEADER_LENGTH_BYTES]; + unsigned int n = 0U; + for (vector::iterator it = m_header.begin(); it != m_header.end(); ++it, n++) + buffer[n] = *it; + + m_headerData = new CHeaderData(buffer, RADIO_HEADER_LENGTH_BYTES, true); + + if (!m_headerData->isValid()) { + m_header.clear(); + delete m_headerData; + m_headerData = NULL; + } +} + +void CSlowDataDecoder::processMessage() +{ + // Do we have a complete message? + if (m_messageData != NULL) + return; + + unsigned int num = m_buffer[0] & SLOW_DATA_LENGTH_MASK; + if (num > 3U) // Sanity check + return; + + // Handle any gaps in the received message + if (num > m_messageExp) { + for (; m_messageExp < num; m_messageExp++) { + m_message.push_back(' '); + m_message.push_back(' '); + m_message.push_back(' '); + m_message.push_back(' '); + m_message.push_back(' '); + } + + m_messageExp = num; + } else { + m_messageExp++; + } + + m_message.push_back(m_buffer[1U]); + m_message.push_back(m_buffer[2U]); + m_message.push_back(m_buffer[3U]); + m_message.push_back(m_buffer[4U]); + m_message.push_back(m_buffer[5U]); + + // Do we have a complete message? + if (m_message.size() < MESSAGE_LENGTH) + return; + + // Something has become corrupted + if (m_message.size() != MESSAGE_LENGTH) { + m_message.clear(); + return; + } + + // Convert the vector to an array + unsigned char buffer[MESSAGE_LENGTH]; + unsigned int n = 0U; + for (vector::iterator it = m_message.begin(); it != m_message.end(); ++it, n++) + buffer[n] = *it; + + m_messageData = new CMessageData(buffer, MESSAGE_LENGTH); +} +/* +void CSlowDataDecoder::processGPSMessage() +{ + if (m_gpsMessageData != NULL) + return; + + unsigned int length = m_buffer[0] & SLOW_DATA_LENGTH_MASK; + if (length > 5U) + length = 5U; + + for (unsigned int i = 0U; i < length; i++) + m_gpsMessage.push_back(m_buffer[i + 1U]); + + // Do we have a complete message? + if (length == 5U) + return; + + // Convert the vector to an array + length = m_gpsMessage.size(); + unsigned char* buffer = new unsigned char[length]; + unsigned int n = 0U; + for (vector::iterator it = m_gpsMessage.begin(); it != m_gpsMessage.end(); ++it, n++) + buffer[n] = *it; + + m_gpsMessageData = new CGPSMessageData(buffer, length); + + delete[] buffer; +} +*/ +void CSlowDataDecoder::processCodeSquelch() +{ + bool ret = m_buffer[1] == m_buffer[2]; + if (ret) { + // Convert the hex to decimal, i.e. 0x99 = 99 + m_codeSquelchData = (m_buffer[1] / 16U) * 10U + (m_buffer[1] % 16U); + m_hasCodeSquelch = true; + } +} diff --git a/AMBETools/Common/SlowDataDecoder.h b/AMBETools/Common/SlowDataDecoder.h new file mode 100755 index 0000000..c294464 --- /dev/null +++ b/AMBETools/Common/SlowDataDecoder.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009,2010 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef SlowDataDecoder_H +#define SlowDataDecoder_H + +#include "MessageData.h" +#include "HeaderData.h" + +#include +using namespace std; + +#include + +enum SDD_STATE { + SDD_FIRST, + SDD_SECOND +}; + +class CSlowDataDecoder { +public: + CSlowDataDecoder(); + ~CSlowDataDecoder(); + + void addData(const unsigned char* data); + +// CGPSMessageData* getGPSMessageData(); + + CMessageData* getMessageData(); + + unsigned int getHeader(unsigned char* data, unsigned int length); + CHeaderData* getHeaderData(); + + bool getCodeSquelchData(unsigned int& value); + + void sync(); + void reset(); + +private: + unsigned char* m_buffer; + SDD_STATE m_state; + vector m_header; + vector m_message; + unsigned int m_messageExp; +// vector m_gpsMessage; + CHeaderData* m_headerData; + CMessageData* m_messageData; +// CGPSMessageData* m_gpsMessageData; + unsigned char m_codeSquelchData; + bool m_hasCodeSquelch; + + void processHeader(); + void processMessage(); +// void processGPSMessage(); + void processCodeSquelch(); +}; + +#endif diff --git a/AMBETools/Common/SlowDataDecoder.o b/AMBETools/Common/SlowDataDecoder.o new file mode 100644 index 0000000..394676d Binary files /dev/null and b/AMBETools/Common/SlowDataDecoder.o differ diff --git a/AMBETools/Common/SlowDataEncoder.cpp b/AMBETools/Common/SlowDataEncoder.cpp new file mode 100755 index 0000000..3a2c201 --- /dev/null +++ b/AMBETools/Common/SlowDataEncoder.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2009,2010,2012 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#include "CCITTChecksumReverse.h" +#include "SlowDataEncoder.h" +#include "DStarDefines.h" + +const unsigned char SCRAMBLER_BYTE1 = 0x70; +const unsigned char SCRAMBLER_BYTE2 = 0x4F; +const unsigned char SCRAMBLER_BYTE3 = 0x93; + +CSlowDataEncoder::CSlowDataEncoder() : +m_initial(), +m_body(), +m_it(), +m_end(), +m_header(), +m_message(), +// m_gpsMessage(), +m_codeSquelch() +{ +} + +CSlowDataEncoder::~CSlowDataEncoder() +{ +} + +void CSlowDataEncoder::getData(unsigned char* data) +{ + wxASSERT(data != NULL); + + // First time, we need to build the output data + if (m_body.empty()) { + buildData(); + + // Do we have any initial data to send? + if (m_initial.empty()) { + m_it = m_body.begin(); + m_end = m_body.end(); + } else { + m_it = m_initial.begin(); + m_end = m_initial.end(); + } + } + + // Create the sequence: initial, body, body, body, ... + if (m_it == m_end) { + m_it = m_body.begin(); + m_end = m_body.end(); + } + + // This assumes that the data is in three byte blocks and won't end half-way through + // the loop. + unsigned char buffer[DATA_FRAME_LENGTH_BYTES]; + for (unsigned int n = 0U; m_it != m_end && n < DATA_FRAME_LENGTH_BYTES; ++m_it, n++) + buffer[n] = *m_it; + + data[0U] = buffer[0U] ^ SCRAMBLER_BYTE1; + data[1U] = buffer[1U] ^ SCRAMBLER_BYTE2; + data[2U] = buffer[2U] ^ SCRAMBLER_BYTE3; +} + +void CSlowDataEncoder::reset() +{ + m_initial.clear(); + m_body.clear(); + + m_header.clear(); + m_message.clear(); +// m_gpsMessage.clear(); + m_codeSquelch.clear(); +} + +void CSlowDataEncoder::setHeaderData(const CHeaderData& header) +{ + CCCITTChecksumReverse cksum; + + unsigned char buffer[5U]; + + m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U); + m_header.push_back(buffer[0] = header.getFlag1()); + m_header.push_back(buffer[1] = header.getFlag2()); + m_header.push_back(buffer[2] = header.getFlag3()); + m_header.push_back(buffer[3] = header.getRptCall1().GetChar(0)); + m_header.push_back(buffer[4] = header.getRptCall1().GetChar(1)); + cksum.update(buffer, 5U); + + m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U); + m_header.push_back(buffer[0] = header.getRptCall1().GetChar(2)); + m_header.push_back(buffer[1] = header.getRptCall1().GetChar(3)); + m_header.push_back(buffer[2] = header.getRptCall1().GetChar(4)); + m_header.push_back(buffer[3] = header.getRptCall1().GetChar(5)); + m_header.push_back(buffer[4] = header.getRptCall1().GetChar(6)); + cksum.update(buffer, 5U); + + m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U); + m_header.push_back(buffer[0] = header.getRptCall1().GetChar(7)); + m_header.push_back(buffer[1] = header.getRptCall2().GetChar(0)); + m_header.push_back(buffer[2] = header.getRptCall2().GetChar(1)); + m_header.push_back(buffer[3] = header.getRptCall2().GetChar(2)); + m_header.push_back(buffer[4] = header.getRptCall2().GetChar(3)); + cksum.update(buffer, 5U); + + m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U); + m_header.push_back(buffer[0] = header.getRptCall2().GetChar(4)); + m_header.push_back(buffer[1] = header.getRptCall2().GetChar(5)); + m_header.push_back(buffer[2] = header.getRptCall2().GetChar(6)); + m_header.push_back(buffer[3] = header.getRptCall2().GetChar(7)); + m_header.push_back(buffer[4] = header.getYourCall().GetChar(0)); + cksum.update(buffer, 5U); + + m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U); + m_header.push_back(buffer[0] = header.getYourCall().GetChar(1)); + m_header.push_back(buffer[1] = header.getYourCall().GetChar(2)); + m_header.push_back(buffer[2] = header.getYourCall().GetChar(3)); + m_header.push_back(buffer[3] = header.getYourCall().GetChar(4)); + m_header.push_back(buffer[4] = header.getYourCall().GetChar(5)); + cksum.update(buffer, 5U); + + m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U); + m_header.push_back(buffer[0] = header.getYourCall().GetChar(6)); + m_header.push_back(buffer[1] = header.getYourCall().GetChar(7)); + m_header.push_back(buffer[2] = header.getMyCall1().GetChar(0)); + m_header.push_back(buffer[3] = header.getMyCall1().GetChar(1)); + m_header.push_back(buffer[4] = header.getMyCall1().GetChar(2)); + cksum.update(buffer, 5U); + + m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U); + m_header.push_back(buffer[0] = header.getMyCall1().GetChar(3)); + m_header.push_back(buffer[1] = header.getMyCall1().GetChar(4)); + m_header.push_back(buffer[2] = header.getMyCall1().GetChar(5)); + m_header.push_back(buffer[3] = header.getMyCall1().GetChar(6)); + m_header.push_back(buffer[4] = header.getMyCall1().GetChar(7)); + cksum.update(buffer, 5U); + + m_header.push_back(SLOW_DATA_TYPE_HEADER | 5U); + m_header.push_back(buffer[0] = header.getMyCall2().GetChar(0)); + m_header.push_back(buffer[1] = header.getMyCall2().GetChar(1)); + m_header.push_back(buffer[2] = header.getMyCall2().GetChar(2)); + m_header.push_back(buffer[3] = header.getMyCall2().GetChar(3)); + cksum.update(buffer, 4U); + + cksum.result(buffer); + m_header.push_back(buffer[0]); + + m_header.push_back(SLOW_DATA_TYPE_HEADER | 1U); + m_header.push_back(buffer[1]); + m_header.push_back('f'); + m_header.push_back('f'); + m_header.push_back('f'); + m_header.push_back('f'); +} + +void CSlowDataEncoder::setMessageData(const wxString& message) +{ + if (message.IsEmpty()) + return; + + wxString text = message; + text.Append(wxT(" ")); + text.Truncate(MESSAGE_LENGTH); + + unsigned int n = 0U; + for (unsigned int i = 0U; i < MESSAGE_LENGTH; i++) { + if ((i % 5U) == 0U) { + m_message.push_back(SLOW_DATA_TYPE_MESSAGE | n); + n++; + } + + m_message.push_back(text.GetChar(i)); + } +} +/* +void CSlowDataEncoder::setGPSMessageData(const CGPSMessageData& message) +{ + if (message.getGPSMsgText().IsEmpty()) + return; + + unsigned int n = 0U; + unsigned int length = message.getGPSMsgText().Len(); + + for (unsigned int i = 0U; i < length; i++) { + if ((i % 5U) == 0U) { + m_gpsMessage.push_back(SLOW_DATA_TYPE_GPSDATA | n); + n++; + } + + m_gpsMessage.push_back(message.getGPSMsgText().GetChar(i)); + } + + length %= 5U; + + for (unsigned int i = 0U; i < length; i++) + m_gpsMessage.push_back('f'); +} +*/ +void CSlowDataEncoder::setCodeSquelch(unsigned char value) +{ + // Convert decimal to hex, i.e. 99 = 0x99 + unsigned char hexValue = (value / 10U) * 16U + (value % 10U); + + m_codeSquelch.push_back(SLOW_DATA_TYPE_SQUELCH | 2U); + m_codeSquelch.push_back(hexValue); + m_codeSquelch.push_back(hexValue); + m_codeSquelch.push_back('f'); + m_codeSquelch.push_back('f'); + m_codeSquelch.push_back('f'); +} + +void CSlowDataEncoder::buildData() +{ + // Create the initial section, if needed + if (!m_message.empty()) { + if (m_codeSquelch.empty()) { + // T T T T F F F F F F + m_initial.insert(m_initial.begin(), m_message.begin(), m_message.end()); + m_initial.insert(m_initial.end(), 12U * DATA_FRAME_LENGTH_BYTES, 'f'); + } else { + // C T T T T F F F F F + m_initial.insert(m_initial.begin(), m_codeSquelch.begin(), m_codeSquelch.end()); + m_initial.insert(m_initial.end(), m_message.begin(), m_message.end()); + m_initial.insert(m_initial.end(), 10U * DATA_FRAME_LENGTH_BYTES, 'f'); + } + } + + // Create the body section + if (!m_codeSquelch.empty()) { + // C H H H H H H H H H + m_body.insert(m_body.begin(), m_codeSquelch.begin(), m_codeSquelch.end()); + m_body.insert(m_body.end(), m_header.begin(), m_header.end()); + } else { + // H H H H H H H H H F + m_body.insert(m_body.begin(), m_header.begin(), m_header.end()); + m_body.insert(m_body.end(), 2U * DATA_FRAME_LENGTH_BYTES, 'f'); + } +} diff --git a/AMBETools/Common/SlowDataEncoder.h b/AMBETools/Common/SlowDataEncoder.h new file mode 100755 index 0000000..676bc79 --- /dev/null +++ b/AMBETools/Common/SlowDataEncoder.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009,2010 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef SlowDataEncoder_H +#define SlowDataEncoder_H + +#include "MessageData.h" +#include "HeaderData.h" + +#include +using namespace std; + +#include + +class CSlowDataEncoder { +public: + CSlowDataEncoder(); + ~CSlowDataEncoder(); + +// void setGPSMessageData(const CGPSMessageData& gpsMessage); + void setMessageData(const wxString& message); + void setHeaderData(const CHeaderData& header); + void setCodeSquelch(unsigned char value); + + void getData(unsigned char* data); + + void reset(); + +private: + vector m_initial; + vector m_body; + vector::const_iterator m_it; + vector::const_iterator m_end; + vector m_header; + vector m_message; +// vector m_gpsMessage; + vector m_codeSquelch; + + void buildData(); +}; + +#endif diff --git a/AMBETools/Common/SlowDataEncoder.o b/AMBETools/Common/SlowDataEncoder.o new file mode 100644 index 0000000..71dfad5 Binary files /dev/null and b/AMBETools/Common/SlowDataEncoder.o differ diff --git a/AMBETools/Common/SoundCardReaderWriter.cpp b/AMBETools/Common/SoundCardReaderWriter.cpp new file mode 100755 index 0000000..e69cf8c --- /dev/null +++ b/AMBETools/Common/SoundCardReaderWriter.cpp @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2006-2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "SoundCardReaderWriter.h" + +int scrwCallback(const void* input, void* output, unsigned long nSamples, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData) +{ + wxASSERT(userData != NULL); + + CSoundCardReaderWriter* object = reinterpret_cast(userData); + + object->callback(static_cast(input), static_cast(output), nSamples); + + return paContinue; +} + +CSoundCardReaderWriter::CSoundCardReaderWriter(const wxString& readDevice, const wxString& writeDevice, unsigned int sampleRate, unsigned int blockSize) : +m_readDevice(readDevice), +m_writeDevice(writeDevice), +m_sampleRate(sampleRate), +m_blockSize(blockSize), +m_buffer(NULL), +m_stream(NULL), +m_callback(NULL), +m_id(-1) +{ + m_buffer = new wxFloat32[blockSize]; +} + +CSoundCardReaderWriter::~CSoundCardReaderWriter() +{ + delete[] m_buffer; +} + +wxArrayString CSoundCardReaderWriter::getReadDevices() +{ + wxArrayString devices; + + devices.Alloc(10); + + PaError error = ::Pa_Initialize(); + if (error != paNoError) + return devices; + +#if defined(__WINDOWS__) + PaHostApiIndex apiIndex = ::Pa_HostApiTypeIdToHostApiIndex(paDirectSound); +#elif defined(__APPLE__) && defined(__MACH__) + PaHostApiIndex apiIndex = ::Pa_HostApiTypeIdToHostApiIndex(paCoreAudio); +#else + PaHostApiIndex apiIndex = ::Pa_HostApiTypeIdToHostApiIndex(paALSA); +#endif + if (apiIndex == paHostApiNotFound) { + ::Pa_Terminate(); + return devices; + } + + PaDeviceIndex n = ::Pa_GetDeviceCount(); + if (n <= 0) { + ::Pa_Terminate(); + return devices; + } + + for (PaDeviceIndex i = 0; i < n; i++) { + const PaDeviceInfo* device = ::Pa_GetDeviceInfo(i); + + if (device->hostApi != apiIndex) + continue; + + if (device->maxInputChannels > 0) { + wxString name(device->name, wxConvLocal); + devices.Add(name); + } + } + + ::Pa_Terminate(); + + return devices; +} + +wxArrayString CSoundCardReaderWriter::getWriteDevices() +{ + wxArrayString devices; + + devices.Alloc(10); + + PaError error = ::Pa_Initialize(); + if (error != paNoError) + return devices; + +#if defined(__WINDOWS__) + PaHostApiIndex apiIndex = ::Pa_HostApiTypeIdToHostApiIndex(paDirectSound); +#elif defined(__APPLE__) && defined(__MACH__) + PaHostApiIndex apiIndex = ::Pa_HostApiTypeIdToHostApiIndex(paCoreAudio); +#else + PaHostApiIndex apiIndex = ::Pa_HostApiTypeIdToHostApiIndex(paALSA); +#endif + if (apiIndex == paHostApiNotFound) { + ::Pa_Terminate(); + return devices; + } + + PaDeviceIndex n = ::Pa_GetDeviceCount(); + if (n <= 0) { + ::Pa_Terminate(); + return devices; + } + + for (PaDeviceIndex i = 0; i < n; i++) { + const PaDeviceInfo* device = ::Pa_GetDeviceInfo(i); + + if (device->hostApi != apiIndex) + continue; + + if (device->maxOutputChannels > 0) { + wxString name(device->name, wxConvLocal); + devices.Add(name); + } + } + + ::Pa_Terminate(); + + return devices; +} + +void CSoundCardReaderWriter::setCallback(IAudioCallback* callback, int id) +{ + wxASSERT(callback != NULL); + + m_callback = callback; + m_id = id; +} + +bool CSoundCardReaderWriter::open() +{ + PaError error = ::Pa_Initialize(); + if (error != paNoError) { + wxLogError(wxT("Cannot initialise PortAudio")); + return false; + } + + PaStreamParameters* pParamsIn = NULL; + PaStreamParameters* pParamsOut = NULL; + + PaStreamParameters paramsIn; + PaStreamParameters paramsOut; + + PaDeviceIndex inDev, outDev; + bool res = convertNameToDevices(inDev, outDev); + if (!res) { + wxLogError(wxT("Cannot convert name to device")); + return false; + } + + if (inDev != -1) { + const PaDeviceInfo* inInfo = ::Pa_GetDeviceInfo(inDev); + if (inInfo == NULL) { + wxLogError(wxT("Cannot get device information for the input device")); + return false; + } + + paramsIn.device = inDev; + paramsIn.channelCount = 1; + paramsIn.sampleFormat = paFloat32; + paramsIn.hostApiSpecificStreamInfo = NULL; + paramsIn.suggestedLatency = inInfo->defaultLowInputLatency; + + pParamsIn = ¶msIn; + } + + if (outDev != -1) { + const PaDeviceInfo* outInfo = ::Pa_GetDeviceInfo(outDev); + if (outInfo == NULL) { + wxLogError(wxT("Cannot get device information for the output device")); + return false; + } + + paramsOut.device = outDev; + paramsOut.channelCount = 1; + paramsOut.sampleFormat = paFloat32; + paramsOut.hostApiSpecificStreamInfo = NULL; + paramsOut.suggestedLatency = outInfo->defaultLowOutputLatency; + + pParamsOut = ¶msOut; + } + + error = ::Pa_OpenStream(&m_stream, pParamsIn, pParamsOut, double(m_sampleRate), m_blockSize, paNoFlag, &scrwCallback, this); + if (error != paNoError) { + wxLogError(wxT("Cannot open the audios stream(s)")); + ::Pa_Terminate(); + return false; + } + + error = ::Pa_StartStream(m_stream); + if (error != paNoError) { + wxLogError(wxT("Cannot start the audio stream(s)")); + ::Pa_CloseStream(m_stream); + m_stream = NULL; + + ::Pa_Terminate(); + return false; + } + + return true; +} + +void CSoundCardReaderWriter::close() +{ + wxASSERT(m_stream != NULL); + + ::Pa_AbortStream(m_stream); + + ::Pa_CloseStream(m_stream); + + ::Pa_Terminate(); +} + +void CSoundCardReaderWriter::callback(const wxFloat32* input, wxFloat32* output, unsigned int nSamples) +{ + if (m_callback != NULL) + m_callback->callback(input, output, nSamples, m_id); +} + +bool CSoundCardReaderWriter::convertNameToDevices(PaDeviceIndex& inDev, PaDeviceIndex& outDev) +{ + inDev = outDev = -1; + +#if defined(__WINDOWS__) + PaHostApiIndex apiIndex = ::Pa_HostApiTypeIdToHostApiIndex(paDirectSound); +#elif defined(__APPLE__) && defined(__MACH__) + PaHostApiIndex apiIndex = ::Pa_HostApiTypeIdToHostApiIndex(paCoreAudio); +#else + PaHostApiIndex apiIndex = ::Pa_HostApiTypeIdToHostApiIndex(paALSA); +#endif + if (apiIndex == paHostApiNotFound) + return false; + + PaDeviceIndex n = ::Pa_GetDeviceCount(); + if (n <= 0) + return false; + + for (PaDeviceIndex i = 0; i < n; i++) { + const PaDeviceInfo* device = ::Pa_GetDeviceInfo(i); + + if (device->hostApi != apiIndex) + continue; + + wxString name(device->name, wxConvLocal); + + if (!m_readDevice.IsEmpty() && m_readDevice.IsSameAs(name) && device->maxInputChannels > 0) + inDev = i; + + if (!m_writeDevice.IsEmpty() && m_writeDevice.IsSameAs(name) && device->maxOutputChannels > 0) + outDev = i; + } + + if (inDev == -1 && outDev == -1) + return false; + + return true; +} diff --git a/AMBETools/Common/SoundCardReaderWriter.h b/AMBETools/Common/SoundCardReaderWriter.h new file mode 100755 index 0000000..615d25f --- /dev/null +++ b/AMBETools/Common/SoundCardReaderWriter.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009,2010 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef SoundCardReaderWriter_H +#define SoundCardReaderWriter_H + +#include "AudioCallback.h" + +#include + +#include "portaudio.h" + +extern "C" { + int scwCallback(const void* input, void* output, unsigned long nSamples, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData); +} + +class CSoundCardReaderWriter { +public: + CSoundCardReaderWriter(const wxString& readDevice, const wxString& writeDevice, unsigned int sampleRate, unsigned int blockSize); + ~CSoundCardReaderWriter(); + + void setCallback(IAudioCallback* callback, int id); + bool open(); + void close(); + + void callback(const wxFloat32* input, wxFloat32* output, unsigned int nSamples); + + static wxArrayString getReadDevices(); + static wxArrayString getWriteDevices(); + +private: + wxString m_readDevice; + wxString m_writeDevice; + unsigned int m_sampleRate; + unsigned int m_blockSize; + wxFloat32* m_buffer; + PaStream* m_stream; + IAudioCallback* m_callback; + int m_id; + + bool convertNameToDevices(PaDeviceIndex& inDev, PaDeviceIndex& outDev); +}; + +#endif diff --git a/AMBETools/Common/SoundCardReaderWriter.o b/AMBETools/Common/SoundCardReaderWriter.o new file mode 100644 index 0000000..3ae2d30 Binary files /dev/null and b/AMBETools/Common/SoundCardReaderWriter.o differ diff --git a/AMBETools/Common/SoundcardSet.cpp b/AMBETools/Common/SoundcardSet.cpp new file mode 100755 index 0000000..1d15aa8 --- /dev/null +++ b/AMBETools/Common/SoundcardSet.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2009,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "SoundcardSet.h" + +#include "SoundCardReaderWriter.h" + +const unsigned int BORDER_SIZE = 5U; +const unsigned int CONTROL_WIDTH = 200U; + +CSoundcardSet::CSoundcardSet(wxWindow* parent, int id, const wxString& title, const wxString& device, bool read, bool write) : +wxPanel(parent, id), +m_title(title), +m_readDevice(NULL), +m_writeDevice(NULL) +{ + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + + if (write) { + wxArrayString devices = CSoundCardReaderWriter::getWriteDevices(); + + m_writeDevice = new wxChoice(this, -1, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1), devices); + sizer->Add(m_writeDevice, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE); + + if (devices.GetCount() == 0U) { + m_writeDevice->Append(_("")); + m_writeDevice->SetSelection(0); + } else { + bool res = m_writeDevice->SetStringSelection(device); + if (!res) + m_writeDevice->SetSelection(0); + } + } + + if (read) { + wxArrayString devices = CSoundCardReaderWriter::getReadDevices(); + + m_readDevice = new wxChoice(this, -1, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1), devices); + sizer->Add(m_readDevice, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE); + + if (devices.GetCount() == 0U) { + m_readDevice->Append(_("")); + m_readDevice->SetSelection(0); + } else { + bool res = m_readDevice->SetStringSelection(device); + if (!res) + m_readDevice->SetSelection(0); + } + } + + SetAutoLayout(true); + + sizer->Fit(this); + sizer->SetSizeHints(this); + + SetSizer(sizer); +} + + +CSoundcardSet::~CSoundcardSet() +{ +} + +bool CSoundcardSet::Validate() +{ + if (m_readDevice != NULL) { + int n = m_readDevice->GetSelection(); + if (n == wxNOT_FOUND) { + wxMessageDialog dialog(this, _("No sound card selected"), m_title + _(" Error"), wxICON_ERROR); + dialog.ShowModal(); + return false; + } + } + + if (m_writeDevice != NULL) { + int n = m_writeDevice->GetSelection(); + if (n == wxNOT_FOUND) { + wxMessageDialog dialog(this, _("No sound card selected"), m_title + _(" Error"), wxICON_ERROR); + dialog.ShowModal(); + return false; + } + } + + return true; +} + +wxString CSoundcardSet::getReadDevice() const +{ + wxASSERT(m_readDevice != NULL); + + wxString device = m_readDevice->GetStringSelection(); + + if (device.IsSameAs(_(""))) + return wxEmptyString; + else + return device; +} + +wxString CSoundcardSet::getWriteDevice() const +{ + wxASSERT(m_writeDevice != NULL); + + wxString device = m_writeDevice->GetStringSelection(); + + if (device.IsSameAs(_(""))) + return wxEmptyString; + else + return device; +} diff --git a/AMBETools/Common/SoundcardSet.h b/AMBETools/Common/SoundcardSet.h new file mode 100755 index 0000000..b31be46 --- /dev/null +++ b/AMBETools/Common/SoundcardSet.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SoundcardSet_H +#define SoundcardSet_H + +#include + +class CSoundcardSet : public wxPanel { +public: + CSoundcardSet(wxWindow* parent, int id, const wxString& title, const wxString& device, bool read, bool write); + virtual ~CSoundcardSet(); + + virtual wxString getReadDevice() const; + virtual wxString getWriteDevice() const; + + virtual bool Validate(); + +private: + wxString m_title; + wxChoice* m_readDevice; + wxChoice* m_writeDevice; +}; + +#endif diff --git a/AMBETools/Common/SoundcardSet.o b/AMBETools/Common/SoundcardSet.o new file mode 100644 index 0000000..ace6a60 Binary files /dev/null and b/AMBETools/Common/SoundcardSet.o differ diff --git a/AMBETools/Common/UDPReaderWriter.cpp b/AMBETools/Common/UDPReaderWriter.cpp new file mode 100755 index 0000000..c0387ee --- /dev/null +++ b/AMBETools/Common/UDPReaderWriter.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2006-2012 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "UDPReaderWriter.h" +#include "Utils.h" + +#if !defined(__WINDOWS__) +#include +#endif + + +CUDPReaderWriter::CUDPReaderWriter(const wxString& remoteAddress, unsigned int remotePort, const wxString& localAddress, unsigned int localPort) : +m_remoteAddress(remoteAddress), +m_remotePort(remotePort), +m_localAddress(localAddress), +m_localPort(localPort), +m_remAddr(), +m_fd(-1) +{ + wxASSERT(!remoteAddress.IsEmpty()); + wxASSERT(remotePort > 0U); +} + +CUDPReaderWriter::~CUDPReaderWriter() +{ +} + +in_addr CUDPReaderWriter::lookup(const wxString& hostname) +{ + in_addr addr; +#if defined(WIN32) + unsigned long address = ::inet_addr(hostname.mb_str()); + if (address != INADDR_NONE && address != INADDR_ANY) { + addr.s_addr = address; + return addr; + } + + struct hostent* hp = ::gethostbyname(hostname.mb_str()); + if (hp != NULL) { + ::memcpy(&addr, hp->h_addr_list[0], sizeof(struct in_addr)); + return addr; + } + + wxLogError(wxT("Cannot find address for host %s"), hostname.c_str()); + + addr.s_addr = INADDR_NONE; + return addr; +#else + in_addr_t address = ::inet_addr(hostname.mb_str()); + if (address != in_addr_t(-1)) { + addr.s_addr = address; + return addr; + } + + struct hostent* hp = ::gethostbyname(hostname.mb_str()); + if (hp != NULL) { + ::memcpy(&addr, hp->h_addr_list[0], sizeof(struct in_addr)); + return addr; + } + + wxLogError(wxT("Cannot find address for host %s"), hostname.c_str()); + + addr.s_addr = INADDR_NONE; + return addr; +#endif +} + +bool CUDPReaderWriter::open() +{ +#if defined(__WINDOWS__) + WSAData data; + + int wsaRet = ::WSAStartup(0x101, &data); + if (wsaRet != 0) + return false; +#endif + + ::memset(&m_remAddr, 0x00, sizeof(sockaddr_in)); + m_remAddr.sin_family = AF_INET; + m_remAddr.sin_port = htons(m_remotePort); + m_remAddr.sin_addr = CUDPReaderWriter::lookup(m_remoteAddress); + + m_fd = ::socket(PF_INET, SOCK_DGRAM, 0); + if (m_fd < 0) { +#if defined(__WINDOWS__) + wxLogError(wxT("Cannot create the socket, err=%d"), ::GetLastError()); +#else + wxLogError(wxT("Cannot create the socket, err=%d"), errno); +#endif + return false; + } + + sockaddr_in addr; + ::memset(&addr, 0x00, sizeof(sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(m_localPort); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if (!m_localAddress.IsEmpty()) { +#if defined(__WINDOWS__) + addr.sin_addr.s_addr = ::inet_addr(m_localAddress.mb_str()); +#else + addr.sin_addr.s_addr = ::inet_addr(m_localAddress.mb_str()); +#endif + if (addr.sin_addr.s_addr == INADDR_NONE) { + wxLogError(wxT("The local address is invalid - %s"), m_localAddress.c_str()); + return false; + } + } + + int reuse = 1; + if (::setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) { +#if defined(__WINDOWS__) + wxLogError(wxT("Cannot set the socket option, err=%d"), ::GetLastError()); +#else + wxLogError(wxT("Cannot set the socket option, err=%d"), errno); +#endif + return false; + } + + if (::bind(m_fd, (sockaddr*)&addr, sizeof(sockaddr_in)) == -1) { +#if defined(__WINDOWS__) + wxLogError(wxT("Cannot bind the local address, err=%d"), ::GetLastError()); +#else + wxLogError(wxT("Cannot bind the local address, err=%d"), errno); +#endif + return false; + } + + return true; +} + +int CUDPReaderWriter::read(unsigned char* buffer, unsigned int length) +{ + // Check that the readfrom() won't block + fd_set readFds; + FD_ZERO(&readFds); +#if defined(__WINDOWS__) + FD_SET((unsigned int)m_fd, &readFds); +#else + FD_SET(m_fd, &readFds); +#endif + + // Return immediately + timeval tv; + tv.tv_sec = 0L; + tv.tv_usec = 0L; + + int ret = ::select(m_fd + 1, &readFds, NULL, NULL, &tv); + if (ret < 0) { +#if defined(__WINDOWS__) + wxLogError(wxT("Error returned from select, err=%d"), ::GetLastError()); +#else + wxLogError(wxT("Error returned from select, err=%d"), errno); +#endif + return -1; + } + + if (ret == 0) + return 0; + + sockaddr_in addr; +#if defined(__WINDOWS__) + int size = sizeof(sockaddr_in); +#else + socklen_t size = sizeof(sockaddr_in); +#endif + + ssize_t len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&addr, &size); + if (len < 0) { +#if defined(__WINDOWS__) + wxLogError(wxT("Error returned from recvfrom, err=%d"), ::GetLastError()); +#else + wxLogError(wxT("Error returned from recvfrom, err=%d"), errno); +#endif + return -1; + } + + // Check if the data is for us + if (m_remAddr.sin_addr.s_addr != addr.sin_addr.s_addr || m_remAddr.sin_port != addr.sin_port) { + wxLogMessage(wxT("Packet received from an invalid source, %08X != %08X and/or %u != %u"), m_remAddr.sin_addr.s_addr, addr.sin_addr.s_addr, m_remAddr.sin_port, addr.sin_port); + CUtils::dump(wxT("Data"), buffer, len); + return 0; + } + + return len; +} + +bool CUDPReaderWriter::write(const unsigned char* buffer, unsigned int length) +{ + ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&m_remAddr, sizeof(sockaddr_in)); + if (ret < 0) { +#if defined(__WINDOWS__) + wxLogError(wxT("Error returned from sendto, err=%d"), ::GetLastError()); +#else + wxLogError(wxT("Error returned from sendto, err=%d"), errno); +#endif + return false; + } + + if (ret != ssize_t(length)) + return false; + + return true; +} + +void CUDPReaderWriter::close() +{ +#if defined(__WINDOWS__) + ::closesocket(m_fd); + ::WSACleanup(); +#else + ::close(m_fd); +#endif +} + diff --git a/AMBETools/Common/UDPReaderWriter.h b/AMBETools/Common/UDPReaderWriter.h new file mode 100755 index 0000000..f2fdc95 --- /dev/null +++ b/AMBETools/Common/UDPReaderWriter.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009,2011,2012 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef UDPReaderWriter_H +#define UDPReaderWriter_H + +#include + +#if !defined(__WINDOWS__) +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +class CUDPReaderWriter { +public: + CUDPReaderWriter(const wxString& remoteAddress, unsigned int remotePort, const wxString& localAddress = wxEmptyString, unsigned int localPort = 0U); + ~CUDPReaderWriter(); + + static in_addr lookup(const wxString& hostName); + + bool open(); + + int read(unsigned char* buffer, unsigned int length); + bool write(const unsigned char* buffer, unsigned int length); + + void close(); + +private: + wxString m_remoteAddress; + unsigned short m_remotePort; + wxString m_localAddress; + unsigned short m_localPort; + sockaddr_in m_remAddr; + int m_fd; +}; + +#endif diff --git a/AMBETools/Common/UDPReaderWriter.o b/AMBETools/Common/UDPReaderWriter.o new file mode 100644 index 0000000..9aea883 Binary files /dev/null and b/AMBETools/Common/UDPReaderWriter.o differ diff --git a/AMBETools/Common/Utils.cpp b/AMBETools/Common/Utils.cpp new file mode 100755 index 0000000..cce2b36 --- /dev/null +++ b/AMBETools/Common/Utils.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009,2014 Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#include "Utils.h" + +void CUtils::dump(const wxChar* title, const unsigned char* data, unsigned int length) +{ + wxASSERT(title != NULL); + wxASSERT(data != NULL); + + wxLogMessage(wxT("%s"), title); + + unsigned int offset = 0U; + + while (length > 0U) { + wxString output; + + unsigned int bytes = (length > 16U) ? 16U : length; + + for (unsigned i = 0U; i < bytes; i++) { + wxString temp; + temp.Printf(wxT("%02X "), data[offset + i]); + output += temp; + } + + for (unsigned int i = bytes; i < 16U; i++) + output += wxT(" "); + + output += wxT(" *"); + + for (unsigned i = 0U; i < bytes; i++) { + unsigned char c = data[offset + i]; + + if (::isprint(c)) + output += wxChar(c); + else + output += wxT('.'); + } + + output += wxT('*'); + + wxLogMessage(wxT("%04X: %s"), offset, output.c_str()); + + offset += 16U; + + if (length >= 16U) + length -= 16U; + else + length = 0U; + } +} diff --git a/AMBETools/Common/Utils.h b/AMBETools/Common/Utils.h new file mode 100755 index 0000000..fa72296 --- /dev/null +++ b/AMBETools/Common/Utils.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009,2014 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef Utils_H +#define Utils_H + +#include + +enum TRISTATE { + STATE_FALSE, + STATE_TRUE, + STATE_UNKNOWN +}; + +class CUtils { +public: + static void dump(const wxChar* title, const unsigned char* data, unsigned int length); + +private: +}; + +#endif diff --git a/AMBETools/Common/Utils.o b/AMBETools/Common/Utils.o new file mode 100644 index 0000000..a147988 Binary files /dev/null and b/AMBETools/Common/Utils.o differ diff --git a/AMBETools/Common/Version.h b/AMBETools/Common/Version.h new file mode 100755 index 0000000..2a4a456 --- /dev/null +++ b/AMBETools/Common/Version.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2010-2014 by Jonathan Naylor, G4KLX + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef Version_H +#define Version_H + +#include + +const wxString VENDOR_NAME = wxT("G4KLX"); + +const wxString SVNREV = wxT("$Revision: 718 $ on $Date: 2014-05-08 19:47:35 +0100 (Thu, 08 May 2014) $"); + +#if defined(__WXDEBUG__) +const wxString VERSION = wxT("20140519 - DEBUG"); +#else +const wxString VERSION = wxT("20140519"); +#endif + +#endif diff --git a/AMBETools/Common/WAVFileReader.cpp b/AMBETools/Common/WAVFileReader.cpp new file mode 100755 index 0000000..f3dd136 --- /dev/null +++ b/AMBETools/Common/WAVFileReader.cpp @@ -0,0 +1,550 @@ +/* + * Copyright (C) 2002-2004,2006-2009,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "WAVFileReader.h" + +#if defined(__WINDOWS__) + +const int WAVE_FORMAT_IEEE_FLOAT = 3; + +CWAVFileReader::CWAVFileReader(const wxString& fileName, unsigned int blockSize) : +m_fileName(fileName), +m_blockSize(blockSize), +m_format(FORMAT_16BIT), +m_channels(0U), +m_sampleRate(0U), +m_buffer8(NULL), +m_buffer16(NULL), +m_buffer32(NULL), +m_handle(NULL), +m_parent(), +m_child(), +m_offset(0L) +{ + wxASSERT(blockSize > 0U); + + m_buffer8 = new wxUint8[blockSize * 4U]; + m_buffer16 = new wxInt16[blockSize * 4U]; + m_buffer32 = new wxFloat32[blockSize * 4U]; +} + +CWAVFileReader::~CWAVFileReader() +{ + delete[] m_buffer8; + delete[] m_buffer16; + delete[] m_buffer32; +} + +wxString CWAVFileReader::getFilename() const +{ + return m_fileName; +} + +bool CWAVFileReader::open() +{ + m_handle = ::mmioOpen(LPWSTR(m_fileName.c_str()), 0, MMIO_READ | MMIO_ALLOCBUF); + if (m_handle == NULL) { + wxLogError(wxT("WAVFileReader: could not open the WAV file %s\n"), m_fileName.c_str()); + return false; + } + + MMCKINFO parent; + parent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); + + MMRESULT res = ::mmioDescend(m_handle, &parent, 0, MMIO_FINDRIFF); + if (res != MMSYSERR_NOERROR) { + wxLogError(wxT("WAVFileReader: %s has no \"WAVE\" header\n"), m_fileName.c_str()); + ::mmioClose(m_handle, 0U); + m_handle = NULL; + return false; + } + + MMCKINFO child; + child.ckid = mmioFOURCC('f', 'm', 't', ' '); + + res = ::mmioDescend(m_handle, &child, &parent, MMIO_FINDCHUNK); + if (res != MMSYSERR_NOERROR) { + wxLogError(wxT("WAVFileReader: %s has no \"fmt \" chunk\n"), m_fileName.c_str()); + ::mmioClose(m_handle, 0U); + m_handle = NULL; + return false; + } + + WAVEFORMATEX format; + + LONG len = ::mmioRead(m_handle, (char *)&format, child.cksize); + if (len != LONG(child.cksize)) { + wxLogError(wxT("WAVFileReader: %s is corrupt, cannot read the WAVEFORMATEX structure\n"), m_fileName.c_str()); + ::mmioClose(m_handle, 0U); + m_handle = NULL; + return false; + } + + if (format.wFormatTag != WAVE_FORMAT_PCM && format.wFormatTag != WAVE_FORMAT_IEEE_FLOAT) { + wxLogError(wxT("WAVFileReader: %s is not PCM or IEEE Float format, is %u\n"), m_fileName.c_str(), format.wFormatTag); + ::mmioClose(m_handle, 0U); + m_handle = NULL; + return false; + } + + m_sampleRate = format.nSamplesPerSec; + + m_channels = format.nChannels; + if (m_channels > 2U) { + wxLogError(wxT("WAVFileReader: %s has %u channels, more than 2\n"), m_fileName.c_str(), m_channels); + ::mmioClose(m_handle, 0U); + m_handle = NULL; + return false; + } + + if (format.wBitsPerSample == 8U && format.wFormatTag == WAVE_FORMAT_PCM) { + m_format = FORMAT_8BIT; + } else if (format.wBitsPerSample == 16U && format.wFormatTag == WAVE_FORMAT_PCM) { + m_format = FORMAT_16BIT; + } else if (format.wBitsPerSample == 32U && format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { + m_format = FORMAT_32BIT; + } else { + wxLogError(wxT("WAVFileReader: %s has sample width %u and format %u\n"), m_fileName.c_str(), format.wBitsPerSample, format.wFormatTag); + ::mmioClose(m_handle, 0U); + m_handle = NULL; + return false; + } + + res = ::mmioAscend(m_handle, &child, 0); + if (res != MMSYSERR_NOERROR) { + wxLogError(wxT("WAVFileReader: %s is corrupt, cannot ascend\n"), m_fileName.c_str()); + ::mmioClose(m_handle, 0U); + m_handle = NULL; + return false; + } + + child.ckid = mmioFOURCC('d', 'a', 't', 'a'); + + res = ::mmioDescend(m_handle, &child, &parent, MMIO_FINDCHUNK); + if (res != MMSYSERR_NOERROR) { + wxLogError(wxT("WAVFileReader: %s has no \"data\" chunk\n"), m_fileName.c_str()); + ::mmioClose(m_handle, 0U); + m_handle = NULL; + return false; + } + + // Get the current location so we can rewind if needed + m_offset = ::mmioSeek(m_handle, 0L, SEEK_CUR); + + return true; +} + +unsigned int CWAVFileReader::read(wxFloat32* data, unsigned int length) +{ + wxASSERT(m_handle != NULL); + wxASSERT(data != NULL); + + if (length == 0U) + return 0U; + + LONG n = 0L; + LONG i; + + switch (m_format) { + case FORMAT_8BIT: + n = ::mmioRead(m_handle, (char *)m_buffer8, length * m_channels * sizeof(wxUint8)); + + if (n <= 0L) + return 0U; + + n /= sizeof(wxUint8); + + for (i = 0L; i < n; i++) + data[i] = (float(m_buffer8[i]) - 127.0F) / 128.0F; + + n /= m_channels; + break; + + case FORMAT_16BIT: + n = ::mmioRead(m_handle, (char *)m_buffer16, length * m_channels * sizeof(wxInt16)); + + if (n <= 0L) + return 0U; + + n /= sizeof(wxInt16); + + for (i = 0L; i < n; i++) + data[i] = float(m_buffer16[i]) / 32768.0F; + + n /= m_channels; + break; + + case FORMAT_32BIT: + n = ::mmioRead(m_handle, (char *)m_buffer32, length * m_channels * sizeof(float)); + + if (n <= 0L) + return 0U; + + n /= (sizeof(float) * m_channels); + + switch (m_channels) { + case 1U: + for (i = 0L; i < n; i++) + data[i] = m_buffer32[i]; + break; + case 2U: + // Swap I and Q for SDR-1000 data + for (i = 0L; i < n; i++) { + data[i * 2U + 0U] = m_buffer32[i * 2U + 1U]; + data[i * 2U + 1U] = m_buffer32[i * 2U + 0U]; + } + break; + } + break; + } + + return n; +} + +void CWAVFileReader::rewind() +{ + wxASSERT(m_handle != NULL); + + ::mmioSeek(m_handle, m_offset, SEEK_SET); +} + +void CWAVFileReader::close() +{ + wxASSERT(m_handle != NULL); + + ::mmioClose(m_handle, 0U); + + m_handle = NULL; +} + +unsigned int CWAVFileReader::getSampleRate() const +{ + return m_sampleRate; +} + +unsigned int CWAVFileReader::getChannels() const +{ + return m_channels; +} + +#else + +const int FORMAT_PCM = 1; +const int FORMAT_IEEE_FLOAT = 3; + +CWAVFileReader::CWAVFileReader(const wxString& fileName, unsigned int blockSize) : +m_fileName(fileName), +m_blockSize(blockSize), +m_format(FORMAT_16BIT), +m_channels(0U), +m_sampleRate(0U), +m_buffer8(NULL), +m_buffer16(NULL), +m_buffer32(NULL), +m_file(NULL), +m_offset(0), +m_length(0U) +{ + wxASSERT(blockSize > 0U); + + m_buffer8 = new wxUint8[blockSize * 4U]; + m_buffer16 = new wxInt16[blockSize * 4U]; + m_buffer32 = new wxFloat32[blockSize * 4U]; +} + +CWAVFileReader::~CWAVFileReader() +{ + delete[] m_buffer8; + delete[] m_buffer16; + delete[] m_buffer32; +} + +wxString CWAVFileReader::getFilename() const +{ + return m_fileName; +} + +bool CWAVFileReader::open() +{ + m_file = new wxFFile(m_fileName.c_str(), wxT("rb")); + + bool ret = m_file->IsOpened(); + if (!ret) { + wxLogError(wxT("WAVFileReader: could not open the WAV file %s."), m_fileName.c_str()); + delete m_file; + m_file = NULL; + return false; + } + + unsigned char buffer[4]; + unsigned int n = m_file->Read(buffer, 4); + if (n != 4U || ::memcmp(buffer, "RIFF", 4) != 0) { + wxLogError(wxT("WAVFileReader: %s has no \"RIFF\" signature."), m_fileName.c_str()); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + n = m_file->Read(buffer, 4); + if (n != 4U) { + wxLogError(wxT("WAVFileReader: %s is corrupt, cannot read the file length."), m_fileName.c_str()); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + n = m_file->Read(buffer, 4); + if (n != 4U || ::memcmp(buffer, "WAVE", 4) != 0) { + wxLogError(wxT("WAVFileReader: %s has no \"WAVE\" header."), m_fileName.c_str()); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + n = m_file->Read(buffer, 4); + if (n != 4U || ::memcmp(buffer, "fmt ", 4) != 0) { + wxLogError(wxT("WAVFileReader: %s has no \"fmt \" chunk."), m_fileName.c_str()); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + wxUint32 uint32; + n = m_file->Read(&uint32, sizeof(wxUint32)); + + wxUint32 length = wxUINT32_SWAP_ON_BE(uint32); + if (n != sizeof(wxUint32) || length < 16U) { + wxLogError(wxT("WAVFileReader: %s is corrupt, cannot read the WAVEFORMATEX structure length."), m_fileName.c_str()); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + wxUint16 uint16; + n = m_file->Read(&uint16, sizeof(wxUint16)); + + wxUint16 compCode = wxUINT16_SWAP_ON_BE(uint16); + if (n != sizeof(wxUint16) || (compCode != FORMAT_PCM && compCode != FORMAT_IEEE_FLOAT)) { + wxLogError(wxT("WAVFileReader: %s is not PCM or IEEE Float format, is %u."), m_fileName.c_str(), compCode); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + n = m_file->Read(&uint16, sizeof(wxUint16)); + + m_channels = wxUINT16_SWAP_ON_BE(uint16); + if (n != sizeof(wxUint16) || m_channels > 2U) { + wxLogError(wxT("WAVFileReader: %s has %u channels, more than 2."), m_fileName.c_str(), m_channels); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + n = m_file->Read(&uint32, sizeof(wxUint32)); + + m_sampleRate = wxUINT32_SWAP_ON_BE(uint32); + if (n != sizeof(wxUint32)) { + wxLogError(wxT("WAVFileReader: %s is corrupt, cannot read the sample rate."), m_fileName.c_str()); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + n = m_file->Read(&uint32, sizeof(wxUint32)); + + if (n != sizeof(wxUint32)) { + wxLogError(wxT("WAVFileReader: %s is corrupt, cannot read the average bytes per second"), m_fileName.c_str()); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + n = m_file->Read(&uint16, sizeof(wxUint16)); + + if (n != sizeof(wxUint16)) { + wxLogError(wxT("WAVFileReader: %s is corrupt, cannot read the block align."), m_fileName.c_str()); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + n = m_file->Read(&uint16, sizeof(wxUint16)); + + if (n != sizeof(wxUint16)) { + wxLogError(wxT("WAVFileReader: %s is corrupt, cannot read the bitsPerSample."), m_fileName.c_str()); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + wxUint16 bitsPerSample = wxUINT16_SWAP_ON_BE(uint16); + + if (bitsPerSample == 8U && compCode == FORMAT_PCM) { + m_format = FORMAT_8BIT; + } else if (bitsPerSample == 16U && compCode == FORMAT_PCM) { + m_format = FORMAT_16BIT; + } else if (bitsPerSample == 32U && compCode == FORMAT_IEEE_FLOAT) { + m_format = FORMAT_32BIT; + } else { + wxLogError(wxT("WAVFileReader: %s has sample width %u and format %u."), m_fileName.c_str(), bitsPerSample, compCode); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + // Now drain any extra bytes of data + if (length > 16U) + m_file->Seek(length - 16U, wxFromCurrent); + + n = m_file->Read(buffer, 4); + + if (n != 4U || ::memcmp(buffer, "data", 4) != 0) { + wxLogError(wxT("WAVFileReader: %s has no \"data\" chunk."), m_fileName.c_str()); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + n = m_file->Read(&uint32, sizeof(wxUint32)); + + if (n != sizeof(wxUint32)) { + wxLogError(wxT("WAVFileReader: %s is corrupt, cannot read the \"data\" chunk size"), m_fileName.c_str()); + m_file->Close(); + delete m_file; + m_file = NULL; + return false; + } + + m_length = wxUINT32_SWAP_ON_BE(uint32); + + // Get the current location so we can rewind if needed + m_offset = m_file->Tell(); + + return true; +} + +unsigned int CWAVFileReader::read(wxFloat32* data, unsigned int length) +{ + wxASSERT(m_file != NULL); + wxASSERT(data != NULL); + + if (length == 0U) + return 0U; + + unsigned int i; + size_t n = 0U; + + switch (m_format) { + case FORMAT_8BIT: + n = m_file->Read(m_buffer8, length * m_channels * sizeof(wxUint8)); + + if (n == 0U) + return 0U; + + n /= sizeof(wxUint8); + + for (i = 0U; i < n; i++) + data[i] = (wxFloat32(m_buffer8[i]) - 127.0F) / 128.0F; + + n /= m_channels; + break; + + case FORMAT_16BIT: + n = m_file->Read(m_buffer16, length * m_channels * sizeof(wxInt16)); + + if (n == 0U) + return 0U; + + n /= sizeof(wxInt16); + + for (i = 0U; i < n; i++) + data[i] = wxFloat32(m_buffer16[i]) / 32768.0F; + + n /= m_channels; + break; + + case FORMAT_32BIT: + n = m_file->Read(m_buffer32, length * m_channels * sizeof(wxFloat32)); + + if (n == 0U) + return 0U; + + n /= (sizeof(wxFloat32) * m_channels); + + switch (m_channels) { + case 1U: + for (i = 0U; i < n; i++) + data[i] = m_buffer32[i]; + break; + case 2U: + // Swap I and Q for SDR-1000 data + for (i = 0U; i < n; i++) { + data[i * 2U + 0U] = m_buffer32[i * 2U + 1U]; + data[i * 2U + 1U] = m_buffer32[i * 2U + 0U]; + } + break; + } + break; + } + + return n; +} + +void CWAVFileReader::rewind() +{ + wxASSERT(m_file != NULL); + + m_file->Seek(m_offset); +} + +void CWAVFileReader::close() +{ + wxASSERT(m_file != NULL); + + m_file->Close(); + + delete m_file; + + m_file = NULL; +} + +unsigned int CWAVFileReader::getSampleRate() const +{ + return m_sampleRate; +} + +unsigned int CWAVFileReader::getChannels() const +{ + return m_channels; +} + +#endif diff --git a/AMBETools/Common/WAVFileReader.h b/AMBETools/Common/WAVFileReader.h new file mode 100755 index 0000000..d51915d --- /dev/null +++ b/AMBETools/Common/WAVFileReader.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2002-2004,2006-2009,2013 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef WAVFileReader_H +#define WAVFileReader_H + +#include + +#if defined(__WINDOWS__) +#include +#include +#else +#include +#endif + +enum WAVFORMAT { + FORMAT_8BIT, + FORMAT_16BIT, + FORMAT_32BIT +}; + +class CWAVFileReader { +public: + CWAVFileReader(const wxString& fileName, unsigned int blockSize); + ~CWAVFileReader(); + + wxString getFilename() const; + + bool open(); + unsigned int read(wxFloat32* data, unsigned int length); + void rewind(); + void close(); + + unsigned int getSampleRate() const; + unsigned int getChannels() const; + +private: + wxString m_fileName; + unsigned int m_blockSize; + WAVFORMAT m_format; + unsigned int m_channels; + unsigned int m_sampleRate; + wxUint8* m_buffer8; + wxInt16* m_buffer16; + wxFloat32* m_buffer32; +#if defined(__WINDOWS__) + HMMIO m_handle; + MMCKINFO m_parent; + MMCKINFO m_child; + LONG m_offset; +#else + wxFFile* m_file; + wxFileOffset m_offset; + unsigned int m_length; +#endif +}; + +#endif diff --git a/AMBETools/Common/WAVFileReader.o b/AMBETools/Common/WAVFileReader.o new file mode 100644 index 0000000..3289d5f Binary files /dev/null and b/AMBETools/Common/WAVFileReader.o differ diff --git a/AMBETools/Common/WAVFileWriter.cpp b/AMBETools/Common/WAVFileWriter.cpp new file mode 100755 index 0000000..047c221 --- /dev/null +++ b/AMBETools/Common/WAVFileWriter.cpp @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2002-2004,2006-2009 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "WAVFileWriter.h" + +#if defined(__WINDOWS__) + +const int WAVE_FORMAT_IEEE_FLOAT = 3; + +CWAVFileWriter::CWAVFileWriter(const wxString& fileName, unsigned int sampleRate, unsigned int channels, unsigned int sampleWidth, unsigned int blockSize) : +m_fileName(fileName), +m_sampleRate(sampleRate), +m_channels(channels), +m_sampleWidth(sampleWidth), +m_blockSize(blockSize), +m_buffer8(NULL), +m_buffer16(NULL), +m_buffer32(NULL), +m_handle(NULL), +m_parent(), +m_child() +{ + wxASSERT(sampleRate > 0U); + wxASSERT(channels == 1U || channels == 2U); + wxASSERT(sampleWidth == 8U || sampleWidth == 16U || sampleWidth == 32U); + wxASSERT(blockSize > 0U); + + m_buffer8 = new wxUint8[blockSize * channels]; + m_buffer16 = new wxInt16[blockSize * channels]; + m_buffer32 = new wxFloat32[blockSize * channels]; +} + +CWAVFileWriter::~CWAVFileWriter() +{ + delete[] m_buffer8; + delete[] m_buffer16; + delete[] m_buffer32; +} + +bool CWAVFileWriter::open() +{ + m_handle = ::mmioOpen(LPWSTR(m_fileName.c_str()), 0, MMIO_WRITE | MMIO_CREATE | MMIO_ALLOCBUF); + if (m_handle == NULL) { + wxLogError(wxT("WAVFileWriter: could not open the file %s\n"), m_fileName.c_str()); + return false; + } + + m_parent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); + m_parent.cksize = 0; + + MMRESULT res = ::mmioCreateChunk(m_handle, &m_parent, MMIO_CREATERIFF); + if (res != MMSYSERR_NOERROR) { + wxLogError(wxT("WAVFileWriter: could not write to file %s\n"), m_fileName.c_str()); + return false; + } + + m_child.ckid = mmioFOURCC('f', 'm', 't', ' '); + m_child.cksize = sizeof(WAVEFORMATEX); + + res = ::mmioCreateChunk(m_handle, &m_child, 0); + if (res != MMSYSERR_NOERROR) { + wxLogError(wxT("WAVFileWriter: could not write to the file %s\n"), m_fileName.c_str()); + return false; + } + + WAVEFORMATEX format; + format.wBitsPerSample = m_sampleWidth; + if (m_sampleWidth == 8U || m_sampleWidth == 16U) + format.wFormatTag = WAVE_FORMAT_PCM; + else + format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + format.nChannels = m_channels; + format.nSamplesPerSec = m_sampleRate; + format.nAvgBytesPerSec = m_sampleRate * m_channels * m_sampleWidth / 8; + format.nBlockAlign = m_channels * m_sampleWidth / 8; + format.cbSize = 0; + + LONG n = ::mmioWrite(m_handle, (CHAR *)&format, sizeof(WAVEFORMATEX)); + if (n != sizeof(WAVEFORMATEX)) { + wxLogError(wxT("WAVFileWriter: could not write to the file %s\n"), m_fileName.c_str()); + return false; + } + + ::mmioAscend(m_handle, &m_child, 0); + + m_child.ckid = mmioFOURCC('d', 'a', 't', 'a'); + m_child.cksize = 0; + + res = ::mmioCreateChunk(m_handle, &m_child, 0); + if (res != MMSYSERR_NOERROR) { + wxLogError(wxT("WAVFileWriter: could not write to the file %s\n"), m_fileName.c_str()); + return false; + } + + return true; +} + +bool CWAVFileWriter::write(const float* buffer, unsigned int length) +{ + wxASSERT(m_handle != NULL); + wxASSERT(buffer != NULL); + wxASSERT(length > 0U); + + unsigned int i; + LONG bytes = 0L; + LONG n = 0L; + + switch (m_sampleWidth) { + case 8U: + switch (m_channels) { + case 1U: + for (i = 0U; i < length; i++) + m_buffer8[i] = wxUint8(buffer[i] * 128.0F + 127.0F); + break; + case 2U: + for (i = 0U; i < (length * 2U); i++) + m_buffer8[i] = wxUint8(buffer[i] * 128.0F + 127.0F); + break; + } + + bytes = length * m_channels * sizeof(wxUint8); + + n = ::mmioWrite(m_handle, (char *)m_buffer8, bytes); + + break; + + case 16U: + switch (m_channels) { + case 1U: + for (i = 0U; i < length; i++) + m_buffer16[i] = wxInt16(buffer[i] * 32768.0F); + break; + case 2U: + for (i = 0U; i < (length * 2U); i++) + m_buffer16[i] = wxInt16(buffer[i] * 32768.0F); + break; + } + + bytes = length * m_channels * sizeof(wxInt16); + + n = ::mmioWrite(m_handle, (char *)m_buffer16, bytes); + + break; + + case 32U: + switch (m_channels) { + case 1U: + for (i = 0U; i < length; i++) + m_buffer32[i] = wxFloat32(buffer[i]); + break; + case 2U: + // Swap I and Q + for (i = 0U; i < length; i++) { + m_buffer32[i * 2U + 0U] = wxFloat32(buffer[i * 2U + 1U]); + m_buffer32[i * 2U + 1U] = wxFloat32(buffer[i * 2U + 0U]); + } + break; + } + + bytes = length * m_channels * sizeof(wxFloat32); + + n = ::mmioWrite(m_handle, (char *)m_buffer32, bytes); + + break; + } + + return n == bytes; +} + +void CWAVFileWriter::close() +{ + wxASSERT(m_handle != NULL); + + ::mmioAscend(m_handle, &m_child, 0); + ::mmioAscend(m_handle, &m_parent, 0); + + ::mmioClose(m_handle, 0); + m_handle = NULL; +} + +unsigned int CWAVFileWriter::getSampleRate() const +{ + return m_sampleRate; +} + +unsigned int CWAVFileWriter::getChannels() const +{ + return m_channels; +} + +#else + +CWAVFileWriter::CWAVFileWriter(const wxString& fileName, unsigned int sampleRate, unsigned int channels, unsigned int sampleWidth, unsigned int blockSize) : +m_fileName(fileName), +m_sampleRate(sampleRate), +m_channels(channels), +m_sampleWidth(sampleWidth), +m_blockSize(blockSize), +m_buffer8(NULL), +m_buffer16(NULL), +m_buffer32(NULL), +m_file(NULL), +m_offset1(0), +m_offset2(0), +m_length(0U) +{ + wxASSERT(sampleRate > 0U); + wxASSERT(channels == 1U || channels == 2U); + wxASSERT(sampleWidth == 8U || sampleWidth == 16U || sampleWidth == 32U); + wxASSERT(blockSize > 0U); + + m_buffer8 = new wxUint8[channels * blockSize]; + m_buffer16 = new wxInt16[channels * blockSize]; + m_buffer32 = new wxFloat32[channels * blockSize]; +} + +CWAVFileWriter::~CWAVFileWriter() +{ + delete[] m_buffer8; + delete[] m_buffer16; + delete[] m_buffer32; +} + +bool CWAVFileWriter::open() +{ + m_length = 0U ; + + m_file = new wxFFile(m_fileName.c_str(), wxT("wb")); + + bool ret = m_file->IsOpened(); + if (!ret) { + wxLogError(wxT("WAVFileWriter: could not open the file %s in WAVFileWriter"), m_fileName.c_str()); + delete m_file; + m_file = NULL; + return false; + } + + m_file->Write("RIFF", 4); // 4 bytes, file signature + + m_offset1 = m_file->Tell(); + + wxUint32 uint32 = 0; + m_file->Write(&uint32, sizeof(wxUint32)); // 4 bytes, length of file, filled in later + + m_file->Write("WAVE", 4); // 4 bytes, RIFF file type + + m_file->Write("fmt ", 4); // 4 bytes, chunk signature + + uint32 = wxUINT32_SWAP_ON_BE(wxUint32(16)); + m_file->Write(&uint32, sizeof(wxUint32)); // 4 bytes, length of "fmt " chunk + + wxUint16 uint16; + if (m_sampleWidth == 8U || m_sampleWidth == 16U) + uint16 = wxUINT16_SWAP_ON_BE(wxUint16(1)); // 2 bytes, integer PCM/uncompressed + else + uint16 = wxUINT16_SWAP_ON_BE(wxUint16(3)); // 2 bytes, float PCM/uncompressed + m_file->Write(&uint16, sizeof(uint16)); + + uint16 = wxUINT16_SWAP_ON_BE(wxUint16(m_channels)); + m_file->Write(&uint16, sizeof(uint16)); // 2 bytes, no of channels + + uint32 = wxUINT32_SWAP_ON_BE(wxUint32(m_sampleRate)); + m_file->Write(&uint32, sizeof(wxUint32)); // 4 bytes, sample rate + + uint32 = wxUINT32_SWAP_ON_BE(wxUint32(m_sampleRate * m_channels * m_sampleWidth / 8U)); + m_file->Write(&uint32, sizeof(wxUint32)); // 4 bytes, average bytes per second + + uint16 = wxUINT16_SWAP_ON_BE(wxUint16(m_channels * m_sampleWidth / 8U)); + m_file->Write(&uint16, sizeof(uint16)); // 2 bytes, block alignment + + uint16 = wxUINT16_SWAP_ON_BE(wxUint16(m_sampleWidth)); + m_file->Write(&uint16, sizeof(uint16)); // 2 bytes, significant bits per sample + + m_file->Write("data", 4); // 4 bytes, chunk signature + + m_offset2 = m_file->Tell(); + + uint32 = 0U; + m_file->Write(&uint32, sizeof(wxUint32)); // 4 bytes, length of "data" chunk, filled in later + + return true; +} + +bool CWAVFileWriter::write(const wxFloat32* buffer, unsigned int length) +{ + wxASSERT(m_file != NULL); + wxASSERT(buffer != NULL); + wxASSERT(length > 0U && length <= m_blockSize); + + unsigned int bytes = 0U; + unsigned int i; + size_t n = 0UL; + + switch (m_sampleWidth) { + case 8U: + switch (m_channels) { + case 1U: + for (i = 0U; i < length; i++) + m_buffer8[i] = wxUint8(buffer[i] * 128.0F + 127.0F); + break; + case 2U: + for (i = 0U; i < (length * 2U); i++) + m_buffer8[i] = wxUint8(buffer[i] * 128.0F + 127.0F); + break; + } + + bytes = length * m_channels * sizeof(wxUint8); + + n = m_file->Write(m_buffer8, bytes); + + break; + + case 16U: + switch (m_channels) { + case 1U: + for (i = 0U; i < length; i++) + m_buffer16[i] = wxInt16(buffer[i] * 32768.0F); + break; + case 2U: + for (i = 0U; i < (length * 2U); i++) + m_buffer16[i] = wxInt16(buffer[i] * 32768.0F); + break; + } + + bytes = length * m_channels * sizeof(wxInt16); + + n = m_file->Write(m_buffer16, bytes); + + break; + + case 32U: + switch (m_channels) { + case 1U: + for (i = 0U; i < length; i++) + m_buffer32[i] = wxFloat32(buffer[i]); + break; + case 2U: + // Swap I and Q + for (i = 0U; i < length; i++) { + m_buffer32[i * 2U + 0U] = wxFloat32(buffer[i * 2U + 1U]); + m_buffer32[i * 2U + 1U] = wxFloat32(buffer[i * 2U + 0U]); + } + break; + } + + bytes = length * m_channels * sizeof(wxFloat32); + + n = m_file->Write(m_buffer32, bytes); + + break; + } + + m_length += n; + + return n == bytes; +} + +void CWAVFileWriter::close() +{ + wxASSERT(m_file != NULL); + + if ((m_length % 2U) != 0U) { + unsigned char c = 0U; + m_file->Write(&c, 1); + } + + wxUint32 length = wxUINT32_SWAP_ON_BE(m_length); + + m_file->Seek(m_offset2); + m_file->Write(&length, sizeof(wxUint32)); + + length = wxUINT32_SWAP_ON_BE(m_length + 36U); + + m_file->Seek(m_offset1); + m_file->Write(&length, sizeof(wxUint32)); + + m_file->Close(); + delete m_file; + m_file = NULL; +} + +#endif diff --git a/AMBETools/Common/WAVFileWriter.h b/AMBETools/Common/WAVFileWriter.h new file mode 100755 index 0000000..98af57e --- /dev/null +++ b/AMBETools/Common/WAVFileWriter.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2002-2004,2006-2010 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef WAVFileWriter_H +#define WAVFileWriter_H + +#include + +#if defined(__WINDOWS__) +#include +#include +#else +#include +#endif + +class CWAVFileWriter { +public: + CWAVFileWriter(const wxString& fileName, unsigned int sampleRate, unsigned int channels, unsigned int sampleWidth, unsigned int blockSize); + ~CWAVFileWriter(); + + bool open(); + bool write(const wxFloat32* buffer, unsigned int length); + void close(); + + unsigned int getSampleRate() const; + unsigned int getChannels() const; + +private: + wxString m_fileName; + unsigned int m_sampleRate; + unsigned int m_channels; + unsigned int m_sampleWidth; + unsigned int m_blockSize; + wxUint8* m_buffer8; + wxInt16* m_buffer16; + wxFloat32* m_buffer32; +#if defined(__WINDOWS__) + HMMIO m_handle; + MMCKINFO m_parent; + MMCKINFO m_child; +#else + wxFFile* m_file; + wxFileOffset m_offset1; + wxFileOffset m_offset2; + wxUint32 m_length; +#endif +}; + +#endif diff --git a/AMBETools/Common/WAVFileWriter.o b/AMBETools/Common/WAVFileWriter.o new file mode 100644 index 0000000..e29957c Binary files /dev/null and b/AMBETools/Common/WAVFileWriter.o differ diff --git a/AMBETools/DV3000/Makefile b/AMBETools/DV3000/Makefile new file mode 100755 index 0000000..c152323 --- /dev/null +++ b/AMBETools/DV3000/Makefile @@ -0,0 +1,15 @@ +all: dv3000d + +GCC := gcc + +CFLAGS := -O2 -DRASPBERRY_PI -Wall +LIBS := -lwiringPi + +dv3000d: dv3000d.o + $(GCC) $(LDFLAGS) -o dv3000d dv3000d.o $(LIBS) + +dv3000d.o: dv3000d.c + $(GCC) $(CFLAGS) -c dv3000d.c + +clean: + $(RM) -f dv3000d *~ *.bak *.o diff --git a/AMBETools/DV3000/README.txt b/AMBETools/DV3000/README.txt new file mode 100755 index 0000000..bc3dc49 --- /dev/null +++ b/AMBETools/DV3000/README.txt @@ -0,0 +1,70 @@ +dv3000d is a small program which runs on a Raspberry Pi and provides access to +the NWDR DV3000 AMBE board. It makes the AMBE3000R chip on it available via the +network using UDP frames. Details of the chip are beyond the scope of this +document, but sufficient to say that it is capable of vocoding audio for D-Star, +DMR, and P.25 and maybe more. + +In order to use it a few preliminaries need to be done. + +1. Prepare the DV3000 board. You need to ensure that the board is running at + 230400 baud and to do this, ensure that only one jumper is fitted on the + board, BR2, and it is the one between pins 1 and 2. This is the one at the + end nearest to the connector to the Pi. + +2. Prepare the Raspberry Pi. This consists of (a) increasing the clock to the + RPi UART, (b) disabling the getty (to allow terminal login) running on + the RPi serial port, and (c) disable the console on the serial port. + + a. Edit the file /boot/config.txt and add the line: + + init_uart_clock=3686400 + + b. Edit the file /etc/inittab and replace the line: + + T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100 + + with: + + #T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100 + + or delete the line entirely. + + c. Edit the file /boot/cmdline.txt and replace the line: + + dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait + + with: + + dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait + +3. Fit the DV3000 board and reboot your Raspberry Pi. + +The dv3000d program then needs to be built and run on the Pi. Take the files +from this directory and copy them to somewhere suitable on the Pi, once there, +and assuming that you have a set of compilers on your Pi, type in the following +command: + +make + +This should build a new file named dv3000d. This can be copied somewhere more +convenient. + +To run the program you need to use the command: + +sudo dv3000d + +which will run the program in the current window or terminal. However if you +want it to run in the background use the command: + +sudo dv3000d -d + +By default dv3000d uses UDP port 2460 for communicating with programs that need +its services, if this isn't convenient then it can be changed with the -p option. +This can be seen in copies of the above commands, using port 24600 now, below: + +sudo dv3000d -p 24600 +sudo dv3000d -p 24600 -d + +That is all there is to running the dv3000d program. By itself it does very +little but allows other programs to access the DV3000 on your Pi from anywhere +on your network, or even the Internet. diff --git a/AMBETools/DV3000/dv3000d.c b/AMBETools/DV3000/dv3000d.c new file mode 100755 index 0000000..91538a6 --- /dev/null +++ b/AMBETools/DV3000/dv3000d.c @@ -0,0 +1,386 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#if defined(RASPBERRY_PI) +#include +#else +int wiringPiSetup(); +void pinMode(int pin, int mode); +void digitalWrite(int pin, int value); +void delay(unsigned int delay); +#define OUTPUT 1 +#define HIGH 1 +#define LOW 0 +#endif + +#define DV3000_TTY "/dev/ttyAMA0" +#define DV3000_VERSION "2014-05-19" + +#define AMBE3000_HEADER_LEN 4U +#define AMBE3000_START_BYTE 0x61U + +#define DEFAULT_PORT 2460U +#define BUFFER_LENGTH 400U + +struct sockaddr_in sa; +int serialFd; +int sockFd; +int debug = 0; + +void dump(char *text, unsigned char *data, unsigned int length) +{ + unsigned int offset = 0U; + unsigned int i; + + fputs(text, stdout); + fputc('\n', stdout); + + while (length > 0U) { + unsigned int bytes = (length > 16U) ? 16U : length; + + fprintf(stdout, "%04X: ", offset); + + for (i = 0U; i < bytes; i++) + fprintf(stdout, "%02X ", data[offset + i]); + + for (i = bytes; i < 16U; i++) + fputs(" ", stdout); + + fputs(" *", stdout); + + for (i = 0U; i < bytes; i++) { + unsigned char c = data[offset + i]; + + if (isprint(c)) + fputc(c, stdout); + else + fputc('.', stdout); + } + + fputs("*\n", stdout); + + offset += 16U; + + if (length >= 16U) + length -= 16U; + else + length = 0U; + } +} + +int openWiringPi(void) +{ + int ret = wiringPiSetup(); + if (ret == -1) { + fprintf(stderr, "dv3000d: error when initialising wiringPi\n"); + return 0; + } + + pinMode(7, OUTPUT); // Power + + // Reset the hardware + digitalWrite(7, LOW); + + delay(20UL); + + digitalWrite(7, HIGH); + + delay(750UL); + + if (debug) + fprintf(stdout, "opened the Wiring Pi library\n"); + + return 1; +} + +int openSerial() +{ + struct termios tty; + int fd; + + fd = open(DV3000_TTY, O_RDWR | O_NOCTTY | O_SYNC); + if (fd < 0) { + fprintf(stderr, "dv3000d: error when opening " DV3000_TTY ", errno=%d", errno); + return fd; + } + + if (tcgetattr(fd, &tty) != 0) { + fprintf(stderr, "dv3000d: error %d from tcgetattr\n", errno); + return -1; + } + + cfsetospeed(&tty, B230400); + cfsetispeed(&tty, B230400); + + tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; + tty.c_iflag &= ~IGNBRK; + tty.c_lflag = 0; + + tty.c_oflag = 0; + tty.c_cc[VMIN] = 0; + tty.c_cc[VTIME] = 5; + + tty.c_iflag &= ~(IXON | IXOFF | IXANY); + + tty.c_cflag |= (CLOCAL | CREAD); + + tty.c_cflag &= ~(PARENB | PARODD); + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CRTSCTS; + + if (tcsetattr(fd, TCSANOW, &tty) != 0) { + fprintf(stderr, "dv3000d: error %d from tcsetattr\n", errno); + return -1; + } + + if (debug) + fprintf(stdout, "opened " DV3000_TTY "\n"); + + return fd; +} + +int openSocket(uint16_t port) +{ + struct sockaddr_in sa; + int ret; + int fd; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + fprintf(stderr, "dv3000d: error when creating the socket, errno=%d", errno); + return fd; + } + + memset(&sa, 0x00, sizeof(struct sockaddr_in)); + sa.sin_family = AF_INET; + sa.sin_port = htons(port); + sa.sin_addr.s_addr = htonl(INADDR_ANY); + + ret = bind(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)); + if (ret < 0) { + fprintf(stderr, "dv3000d: error when binding the socket to port %u, errno=%d", port, errno); + return fd; + } + + if (debug) + fprintf(stdout, "opened the UDP socket on port %u\n", port); + + return fd; +} + +int processSerial(void) +{ + unsigned char buffer[BUFFER_LENGTH]; + unsigned int respLen; + unsigned int offset; + ssize_t len; + + len = read(serialFd, buffer, 1); + if (len != 1) { + fprintf(stderr, "dv3000d: error when reading from the serial port, errno=%d", errno); + return 0; + } + + if (buffer[0U] != AMBE3000_START_BYTE) { + fprintf(stderr, "dv3000d: unknown byte from the DV3000, 0x%02X", buffer[0U]); + return 1; + } + + offset = 0U; + while (offset < (AMBE3000_HEADER_LEN - 1U)) { + len = read(serialFd, buffer + 1U + offset, AMBE3000_HEADER_LEN - 1 - offset); + + if (len == 0) + delay(5UL); + + offset += len; + } + + respLen = buffer[1U] * 256U + buffer[2U]; + + offset = 0U; + while (offset < respLen) { + len = read(serialFd, buffer + AMBE3000_HEADER_LEN + offset, respLen - offset); + + if (len == 0) + delay(5UL); + + offset += len; + } + + respLen += AMBE3000_HEADER_LEN; + + if (debug) + dump("Serial data", buffer, respLen); + + if (sa.sin_port != 0U) { + len = sendto(sockFd, buffer, respLen, 0, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)); + if (respLen != len) { + fprintf(stderr, "dv3000d: error when writing to the socket, len=%d, errno=%d", len, errno); + return 0; + } + } + + return 1; +} + +int processSocket(void) +{ + unsigned char buffer[BUFFER_LENGTH]; + socklen_t sl = sizeof(struct sockaddr_in); + unsigned int len; + ssize_t n; + + n = recvfrom(sockFd, buffer, BUFFER_LENGTH, 0, (struct sockaddr *)&sa, &sl); + if (n < 0) { + fprintf(stderr, "dv3000d: error when reading from the socket, errno=%d", errno); + return 0; + } + + if (debug) + dump("Socket data", buffer, n); + + if (buffer[0U] != AMBE3000_START_BYTE) { + fprintf(stderr, "dv3000d: invalid start byte when reading from the socket, 0x%02X", buffer[0U]); + return 1; + } + + len = buffer[1U] * 256U + buffer[2U] + AMBE3000_HEADER_LEN; + if (n != len) { + fprintf(stderr, "dv3000d: invalid length when reading from the socket, %u=%d", len, n); + return 1; + } + + n = write(serialFd, buffer, len); + if (n != len) { + fprintf(stderr, "dv3000d: error when writing to the serial port, errno=%d", errno); + return 0; + } + + return 1; +} + +int main(int argc, char **argv) +{ + uint16_t port = DEFAULT_PORT; + int daemon = 0; + int topFd; + fd_set fds; + int ret; + int c; + + while ((c = getopt(argc, argv, "dp:vx")) != -1) { + switch (c) { + case 'd': + daemon = 1; + break; + case 'p': + port = (uint16_t)atoi(optarg); + break; + case 'v': + fprintf(stdout, "dv3000d: version " DV3000_VERSION "\n"); + return 0; + case 'x': + debug = 1; + break; + default: + fprintf(stderr, "Usage: dv3000d [-d] [-p port] [-v] [-x]\n"); + return 1; + } + } + + if (daemon) { + pid_t pid = fork(); + + if (pid < 0) { + fprintf(stderr, "dv3000d: error in fork(), exiting\n"); + return 1; + } + + // If this is the parent, exit + if (pid > 0) + return 0; + + // We are the child from here onwards + setsid(); + + chdir("/"); + + umask(0); + } + + ret = openWiringPi(); + if (!ret) + return 1; + + sockFd = openSocket(port); + if (sockFd < 0) + return 1; + + serialFd = openSerial(); + if (serialFd < 0) + return 1; + + memset(&sa, 0x00, sizeof(struct sockaddr_in)); + + topFd = sockFd; + if (serialFd > topFd) + topFd = serialFd; + topFd++; + + for (;;) { + FD_ZERO(&fds); + FD_SET(sockFd, &fds); + FD_SET(serialFd, &fds); + ret = select(topFd, &fds, NULL, NULL, NULL); + if (ret < 0) { + fprintf(stderr, "dv3000d: error from select, errno=%d\n", errno); + return 1; + } + + if (FD_ISSET(sockFd, &fds)) { + ret = processSocket(); + if (!ret) + return 1; + } + + if (FD_ISSET(serialFd, &fds)) { + ret = processSerial(); + if (!ret) + return 1; + } + } + + return 0; +} diff --git a/AMBETools/DVToolReader/DVToolReader.vcproj b/AMBETools/DVToolReader/DVToolReader.vcproj new file mode 100755 index 0000000..38e09c9 --- /dev/null +++ b/AMBETools/DVToolReader/DVToolReader.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AMBETools/DVToolReader/DVToolReaderApp.cpp b/AMBETools/DVToolReader/DVToolReaderApp.cpp new file mode 100755 index 0000000..49a9ccc --- /dev/null +++ b/AMBETools/DVToolReader/DVToolReaderApp.cpp @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2009,2010,2012,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DVToolReaderApp.h" + +#include "DVDongleController.h" +#include "DV3000Controller.h" +#include "AMBE3000Thread.h" +#include "DVDongleThread.h" +#include "DStarDefines.h" +#include "Version.h" +#include "Logger.h" + +#include +#include + +IMPLEMENT_APP(CDVToolReaderApp) + +const wxString KEY_SOUND_DEVICE = wxT("/soundDevice"); +const wxString KEY_DONGLE_TYPE = wxT("/dongleType"); +const wxString KEY_DONGLE_DEVICE = wxT("/dongleDevice"); +const wxString KEY_DONGLE_ADDRESS = wxT("/dongleAddress"); +const wxString KEY_DONGLE_PORT = wxT("/donglePort"); +const wxString KEY_BLEEP = wxT("/bleep"); + +const wxString DEFAULT_SOUND_DEVICE = wxEmptyString; +const DONGLE_TYPE DEFAULT_DONGLE_TYPE = DT_DVDONGLE; +const wxString DEFAULT_DONGLE_DEVICE = wxEmptyString; +const wxString DEFAULT_DONGLE_ADDRESS = wxEmptyString; +const unsigned int DEFAULT_DONGLE_PORT = 2460L; +const bool DEFAULT_BLEEP = true; + + +CDVToolReaderApp::CDVToolReaderApp() : +wxApp(), +m_frame(NULL), +m_thread(NULL) +{ +} + +CDVToolReaderApp::~CDVToolReaderApp() +{ +} + +bool CDVToolReaderApp::OnInit() +{ + SetVendorName(VENDOR_NAME); + + wxFileName loggerName(wxFileName::GetHomeDir(), LOG_FILE_NAME, wxT("log")); + wxLog* log = new CLogger(loggerName.GetFullPath()); + wxLog::SetActiveTarget(log); + + m_frame = new CDVToolReaderFrame(APPLICATION_NAME + wxT(" - ") + VERSION); + m_frame->Show(); + + SetTopWindow(m_frame); + + wxLogInfo(wxT("Starting ") + APPLICATION_NAME + wxT(" - ") + VERSION); + + // Log the SVN revsion and the version of wxWidgets and the Operating System + wxLogInfo(SVNREV); + wxLogInfo(wxT("Using wxWidgets %d.%d.%d on %s"), wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER, ::wxGetOsDescription().c_str()); + + createThread(); + + return wxApp::OnInit(); +} + +int CDVToolReaderApp::OnExit() +{ + wxLogInfo(APPLICATION_NAME + wxT(" is exiting")); + + m_thread->kill(); + m_thread->Wait(); + delete m_thread; + + return 0; +} + +#if defined(__WXDEBUG__) +void CDVToolReaderApp::OnAssertFailure(const wxChar* file, int line, const wxChar* func, const wxChar* cond, const wxChar* msg) +{ + wxLogFatalError(wxT("Assertion failed on line %d in file %s and function %s: %s %s"), line, file, func, cond, msg); +} +#endif + +void CDVToolReaderApp::showMessage(CMessageData* message) const +{ + wxASSERT(message != NULL); + + m_frame->showMessage(message); +} + +void CDVToolReaderApp::showHeader(CHeaderData* header) const +{ + m_frame->showHeader(header); +} + +void CDVToolReaderApp::error(const wxString& text) const +{ + m_frame->error(text); +} + +void CDVToolReaderApp::getSoundcard(wxString& device) const +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + profile->Read(KEY_SOUND_DEVICE, &device, DEFAULT_SOUND_DEVICE); + + wxLogInfo(wxT("Soundcard set to %s"), device.c_str()); + + delete profile; +} + +void CDVToolReaderApp::setSoundcard(const wxString& device) +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + profile->Write(KEY_SOUND_DEVICE, device); + profile->Flush(); + + wxLogInfo(wxT("Soundcard set to %s"), device.c_str()); + + delete profile; +} + +void CDVToolReaderApp::getDongle(DONGLE_TYPE& type, wxString& device, wxString& address, unsigned int& port) const +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + long temp; + profile->Read(KEY_DONGLE_TYPE, &temp, long(DEFAULT_DONGLE_TYPE)); + type = DONGLE_TYPE(temp); + + profile->Read(KEY_DONGLE_DEVICE, &device, DEFAULT_DONGLE_DEVICE); + + profile->Read(KEY_DONGLE_ADDRESS, &address, DEFAULT_DONGLE_ADDRESS); + + profile->Read(KEY_DONGLE_PORT, &temp, long(DEFAULT_DONGLE_PORT)); + port = (unsigned int)temp; + + wxLogInfo(wxT("Dongle type: %d, device: %s, address: %s:%u"), int(type), device.c_str(), address.c_str(), port); + + delete profile; +} + +void CDVToolReaderApp::setDongle(DONGLE_TYPE type, const wxString& device, const wxString& address, unsigned int port) +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + profile->Write(KEY_DONGLE_TYPE, long(type)); + profile->Write(KEY_DONGLE_DEVICE, device); + profile->Write(KEY_DONGLE_ADDRESS, address); + profile->Write(KEY_DONGLE_PORT, long(port)); + profile->Flush(); + + wxLogInfo(wxT("Dongle type: %d, device: %s, address: %s:%u"), int(type), device.c_str(), address.c_str(), port); + + delete profile; +} + +void CDVToolReaderApp::getBleep(bool& on) const +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + profile->Read(KEY_BLEEP, &on, DEFAULT_BLEEP); + + wxLogInfo(wxT("End bleep set to %d"), int(on)); + + delete profile; +} + +void CDVToolReaderApp::setBleep(bool on) const +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + profile->Write(KEY_BLEEP, on); + profile->Flush(); + + wxLogInfo(wxT("End bleep set to %d"), int(on)); + + m_thread->setBleep(on); + + delete profile; +} + +bool CDVToolReaderApp::setReader(IFileReader* reader) +{ + wxASSERT(reader != NULL); + + return m_thread->setReader(reader); +} + +void CDVToolReaderApp::createThread() +{ + m_thread = new CDVToolReaderThread; + m_thread->Create(); + m_thread->Run(); + + DONGLE_TYPE type; + wxString device, address; + unsigned int port; + getDongle(type, device, address, port); + + CDongleThread* dongle = NULL; + + switch (type) { + case DT_DVDONGLE: + if (!device.IsEmpty()) + dongle = new CDVDongleThread(new CDVDongleController(device)); + break; + case DT_DV3000: + if (!address.IsEmpty() && port > 0U) + dongle = new CAMBE3000Thread(new CDV3000Controller(address, port)); + break; + default: + error(_("Invalid Dongle type specified")); + break; + } + + if (dongle != NULL) { + dongle->setDecodeCallback(m_thread); + + bool res = dongle->open(); + if (!res) + error(_("Can't find the AMBE Dongle on the port specified")); + else + m_thread->setDongle(dongle); + } + + getSoundcard(device); + + if (!device.IsEmpty()) { +#if defined(__WINDOWS__) + CSoundCardReaderWriter* soundcard = new CSoundCardReaderWriter(wxEmptyString, device, DSTAR_RADIO_SAMPLE_RATE, DSTAR_RADIO_BLOCK_SIZE); +#else + CSoundCardReaderWriter* soundcard = new CSoundCardReaderWriter(wxEmptyString, device, DSTAR_RADIO_SAMPLE_RATE, 64U); +#endif + soundcard->setCallback(m_thread, 0); + + bool res = soundcard->open(); + if (!res) + error(_("Cannot open the sound card")); + else + m_thread->setSoundCard(soundcard); + } + + bool bleep; + getBleep(bleep); + m_thread->setBleep(bleep); +} diff --git a/AMBETools/DVToolReader/DVToolReaderApp.h b/AMBETools/DVToolReader/DVToolReaderApp.h new file mode 100755 index 0000000..6acdb7c --- /dev/null +++ b/AMBETools/DVToolReader/DVToolReaderApp.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVToolReaderApp_H +#define DVToolReaderApp_H + +#include "DVToolReaderFrame.h" +#include "DVToolReaderThread.h" +#include "MessageData.h" +#include "HeaderData.h" +#include "FileReader.h" +#include "DongleSet.h" + +#include + +class CDVToolReaderApp : public wxApp { + +public: + CDVToolReaderApp(); + virtual ~CDVToolReaderApp(); + + virtual bool OnInit(); + virtual int OnExit(); + + // This is overridden because dialog boxes from threads are bad news +#if defined(__WXDEBUG__) + virtual void OnAssertFailure(const wxChar* file, int line, const wxChar* func, const wxChar* cond, const wxChar* msg); +#endif + virtual void showMessage(CMessageData* message) const; + virtual void showHeader(CHeaderData* header) const; + virtual void error(const wxString& text) const; + + virtual void setSoundcard(const wxString& device); + virtual void getSoundcard(wxString& device) const; + + virtual void setDongle(DONGLE_TYPE type, const wxString& device, const wxString& address, unsigned int port); + virtual void getDongle(DONGLE_TYPE& type, wxString& device, wxString& address, unsigned int& port) const; + + virtual bool setReader(IFileReader* reader); + + virtual void getBleep(bool& on) const; + virtual void setBleep(bool on) const; + +private: + CDVToolReaderFrame* m_frame; + CDVToolReaderThread* m_thread; + + void createThread(); +}; + +DECLARE_APP(CDVToolReaderApp) + +#endif diff --git a/AMBETools/DVToolReader/DVToolReaderApp.o b/AMBETools/DVToolReader/DVToolReaderApp.o new file mode 100644 index 0000000..d875470 Binary files /dev/null and b/AMBETools/DVToolReader/DVToolReaderApp.o differ diff --git a/AMBETools/DVToolReader/DVToolReaderDefs.h b/AMBETools/DVToolReader/DVToolReaderDefs.h new file mode 100755 index 0000000..959663d --- /dev/null +++ b/AMBETools/DVToolReader/DVToolReaderDefs.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009,2010 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVToolReaderDefs_H +#define DVToolReaderDefs_H + +#include + +const unsigned int LONG_CALLSIGN_WIDTH = 80U; +const unsigned int SHORT_CALLSIGN_WIDTH = 50U; + +const unsigned int BORDER_SIZE = 5U; +const unsigned int LABEL_WIDTH = 80U; +const unsigned int CONTROL_WIDTH = 100U; + +const unsigned int INFO_WIDTH = 690U; +const unsigned int INFO_HEIGHT = 160U; + +const unsigned int HEARD_WIDTH = 690U; +const unsigned int HEARD_HEIGHT = 300U; + +const unsigned int DATETIME_WIDTH = 125U; +const unsigned int CALLSIGN_WIDTH = 90U; +const unsigned int MESSAGE_WIDTH = 200U; + +const wxString LOG_FILE_NAME = wxT("DVToolReader"); + +const wxString APPLICATION_NAME = wxT("DVTool Reader"); + +#endif diff --git a/AMBETools/DVToolReader/DVToolReaderFrame.cpp b/AMBETools/DVToolReader/DVToolReaderFrame.cpp new file mode 100755 index 0000000..9a2c1d2 --- /dev/null +++ b/AMBETools/DVToolReader/DVToolReaderFrame.cpp @@ -0,0 +1,358 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DVToolReaderPreferences.h" +#include "DVToolReaderFrame.h" +#include "DVTOOLFileReader.h" +#include "DVToolReaderApp.h" +#include "AMBEFileReader.h" +#include "DStarDefines.h" +#include "MessageEvent.h" +#include "HeaderEvent.h" +#include "ErrorEvent.h" +#include "Version.h" + +#include +#include + +enum { + Menu_File_OpenDVTOOL = 6000, + Menu_File_OpenAMBE, + Menu_Edit_Preferences +}; + +DEFINE_EVENT_TYPE(MESSAGE_EVENT) +DEFINE_EVENT_TYPE(HEADER_EVENT) +DEFINE_EVENT_TYPE(ERROR_EVENT) + +BEGIN_EVENT_TABLE(CDVToolReaderFrame, wxFrame) + EVT_MENU(Menu_File_OpenDVTOOL, CDVToolReaderFrame::onDVTOOLOpen) + EVT_MENU(Menu_File_OpenAMBE, CDVToolReaderFrame::onAMBEOpen) + + EVT_MENU(wxID_EXIT, CDVToolReaderFrame::onQuit) + EVT_MENU(Menu_Edit_Preferences, CDVToolReaderFrame::onPreferences) + EVT_MENU(wxID_ABOUT, CDVToolReaderFrame::onAbout) + + EVT_CLOSE(CDVToolReaderFrame::onClose) + + EVT_CUSTOM(MESSAGE_EVENT, wxID_ANY, CDVToolReaderFrame::onMessage) + EVT_CUSTOM(HEADER_EVENT, wxID_ANY, CDVToolReaderFrame::onHeader) + EVT_CUSTOM(ERROR_EVENT, wxID_ANY, CDVToolReaderFrame::onError) +END_EVENT_TABLE() + +CDVToolReaderFrame::CDVToolReaderFrame(const wxString& title) : +wxFrame(NULL, -1, title), +m_fileName(NULL), +m_your(NULL), +m_my(NULL), +m_rpt1(NULL), +m_rpt2(NULL), +m_flags(NULL), +m_message(NULL) +{ + SetMenuBar(createMenuBar()); + + wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL); + + wxPanel* panel = new wxPanel(this); + + wxGridBagSizer* panelSizer = new wxGridBagSizer(BORDER_SIZE, BORDER_SIZE); + + wxStaticText* fileNameLabel = new wxStaticText(panel, -1, _("File Name:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(fileNameLabel, wxGBPosition(0, 0), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_fileName = new wxStaticText(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(m_fileName, wxGBPosition(0, 1), wxGBSpan(1, 5), wxALL, BORDER_SIZE); + + wxStaticText* yourLabel = new wxStaticText(panel, -1, _("Your:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(yourLabel, wxGBPosition(1, 0), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_your = new wxStaticText(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1)); + panelSizer->Add(m_your, wxGBPosition(1, 1), wxDefaultSpan, wxALL, BORDER_SIZE); + + wxStaticText* rpt1Label = new wxStaticText(panel, -1, _("RPT1:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(rpt1Label, wxGBPosition(1, 2), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_rpt1 = new wxStaticText(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1)); + panelSizer->Add(m_rpt1, wxGBPosition(1, 3), wxDefaultSpan, wxALL, BORDER_SIZE); + + wxStaticText* rpt2Label = new wxStaticText(panel, -1, _("RPT2:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(rpt2Label, wxGBPosition(1, 4), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_rpt2 = new wxStaticText(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1)); + panelSizer->Add(m_rpt2, wxGBPosition(1, 5), wxDefaultSpan, wxALL, BORDER_SIZE); + + wxStaticText* myLabel = new wxStaticText(panel, -1, _("My:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(myLabel, wxGBPosition(2, 0), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_my = new wxStaticText(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1)); + panelSizer->Add(m_my, wxGBPosition(2, 1), wxDefaultSpan, wxALL, BORDER_SIZE); + + wxStaticText* flagsLabel = new wxStaticText(panel, -1, _("Flags:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(flagsLabel, wxGBPosition(2, 2), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_flags = new wxStaticText(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(LABEL_WIDTH * 3U, -1), wxALIGN_RIGHT); + panelSizer->Add(m_flags, wxGBPosition(2, 3), wxGBSpan(1, 3), wxALL, BORDER_SIZE); + + wxStaticText* messageLabel = new wxStaticText(panel, -1, _("Message:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(messageLabel, wxGBPosition(3, 0), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_message = new wxStaticText(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(LABEL_WIDTH * 3U, -1), wxALIGN_RIGHT); + panelSizer->Add(m_message, wxGBPosition(3, 1), wxGBSpan(1, 3), wxALL, BORDER_SIZE); + + panel->SetSizer(panelSizer); + panelSizer->SetSizeHints(panel); + + mainSizer->Add(panel); + + SetSizer(mainSizer); + mainSizer->SetSizeHints(this); +} + +CDVToolReaderFrame::~CDVToolReaderFrame() +{ +} + +wxMenuBar* CDVToolReaderFrame::createMenuBar() +{ + wxMenu* fileMenu = new wxMenu(); + fileMenu->Append(Menu_File_OpenDVTOOL, _("Open DVTOOL File...")); + fileMenu->Append(Menu_File_OpenAMBE, _("Open AMBE File...")); + fileMenu->AppendSeparator(); + fileMenu->Append(wxID_EXIT, _("Exit")); + + wxMenu* editMenu = new wxMenu(); + editMenu->Append(Menu_Edit_Preferences, _("Preferences...")); + + wxMenu* helpMenu = new wxMenu(); + helpMenu->Append(wxID_ABOUT, _("About DVTool Reader")); + + wxMenuBar* menuBar = new wxMenuBar(); + menuBar->Append(fileMenu, _("File")); + menuBar->Append(editMenu, _("Edit")); + menuBar->Append(helpMenu, _("Help")); + + return menuBar; +} + +void CDVToolReaderFrame::showMessage(CMessageData* message) +{ + wxASSERT(message != NULL); + + CMessageEvent event(message, MESSAGE_EVENT); + + AddPendingEvent(event); +} + +void CDVToolReaderFrame::showHeader(CHeaderData* header) +{ + CHeaderEvent event(header, HEADER_EVENT); + + AddPendingEvent(event); +} + +void CDVToolReaderFrame::error(const wxString& error) +{ + CErrorEvent event(error, ERROR_EVENT); + + AddPendingEvent(event); +} + +void CDVToolReaderFrame::onQuit(wxCommandEvent& event) +{ + Close(false); +} + +void CDVToolReaderFrame::onDVTOOLOpen(wxCommandEvent& event) +{ + wxFileDialog dialog(this, _("Select a DVTOOL File"), wxEmptyString, wxEmptyString, _("DVTOOL file (*.dvtool)|*.dvtool|All files (*.*)|*.*")); + if (dialog.ShowModal() != wxID_OK) + return; + + wxString fileName = dialog.GetPath(); + + CDVTOOLFileReader* reader = new CDVTOOLFileReader; + bool res = reader->open(fileName); + if (!res) { + wxMessageDialog dialog(this, _("Cannot find the file, or the file is corrupt."), _("DVTool Reader Error"), wxICON_ERROR); + dialog.ShowModal(); + delete reader; + return; + } + + res = ::wxGetApp().setReader(reader); + if (!res) { + wxMessageDialog dialog(this, _("Cannot process the file."), _("DVTool Reader Error"), wxICON_ERROR); + dialog.ShowModal(); + delete reader; + return; + } + + fileName = dialog.GetFilename(); + m_fileName->SetLabel(fileName); +} + +void CDVToolReaderFrame::onAMBEOpen(wxCommandEvent& event) +{ + wxFileDialog dialog(this, _("Select an AMBE File"), wxEmptyString, wxEmptyString, _("AMBE file (*.ambe)|*.ambe|All files (*.*)|*.*")); + if (dialog.ShowModal() != wxID_OK) + return; + + wxString fileName = dialog.GetPath(); + + CAMBEFileReader* reader = new CAMBEFileReader; + bool res = reader->open(fileName); + if (!res) { + wxMessageDialog dialog(this, _("Cannot find the file, or the file is corrupt."), _("DVTool Reader Error"), wxICON_ERROR); + dialog.ShowModal(); + delete reader; + return; + } + + res = ::wxGetApp().setReader(reader); + if (!res) { + wxMessageDialog dialog(this, _("Cannot process the file."), _("DVTool Reader Error"), wxICON_ERROR); + dialog.ShowModal(); + delete reader; + return; + } + + fileName = dialog.GetFilename(); + m_fileName->SetLabel(fileName); +} + +void CDVToolReaderFrame::onPreferences(wxCommandEvent& event) +{ + DONGLE_TYPE type; + wxString device, address; + unsigned int port; + ::wxGetApp().getDongle(type, device, address, port); + + wxString soundcard; + ::wxGetApp().getSoundcard(soundcard); + + bool bleep; + ::wxGetApp().getBleep(bleep); + + CDVToolReaderPreferences dialog1(this, -1, type, device, address, port, soundcard, bleep); + if (dialog1.ShowModal() != wxID_OK) + return; + + type = dialog1.getType(); + device = dialog1.getDevice(); + address = dialog1.getAddress(); + port = dialog1.getPort(); + soundcard = dialog1.getSoundcard(); + bleep = dialog1.getBleep(); + + ::wxGetApp().setDongle(type, device, address, port); + ::wxGetApp().setSoundcard(soundcard); + ::wxGetApp().setBleep(bleep); + + wxMessageDialog dialog2(this, _("The changes made will not take effect\nuntil the application is restarted"), _("DVTool Reader Information"), wxICON_INFORMATION); + dialog2.ShowModal(); +} + +void CDVToolReaderFrame::onAbout(wxCommandEvent& event) +{ + wxAboutDialogInfo info; + info.AddDeveloper(wxT("Jonathan Naylor, G4KLX")); + info.SetCopyright(wxT("(C) 2009-2014 using GPL v2 or later")); + info.SetName(APPLICATION_NAME); + info.SetVersion(VERSION); + info.SetDescription(_("This program reads .ambe and .dvtool files created and displays\nthe enclosed information and plays the encoded audio.")); + + ::wxAboutBox(info); +} + +void CDVToolReaderFrame::onClose(wxCloseEvent& event) +{ + Destroy(); +} + +void CDVToolReaderFrame::onMessage(wxEvent& event) +{ + CMessageEvent& msgEvent = dynamic_cast(event); + + CMessageData* message = msgEvent.getMessageData(); + wxASSERT(message != NULL); + + wxString msg = message->getMsgText(); + + m_message->SetLabel(msg); + + delete message; +} + +void CDVToolReaderFrame::onHeader(wxEvent& event) +{ + CHeaderEvent& hdrEvent = dynamic_cast(event); + + CHeaderData* header = hdrEvent.getHeaderData(); + + if (header != NULL) { + wxDateTime dateTime = header->getTime(); + wxString hrdDateTime = dateTime.FormatISODate() + wxT(" ") + dateTime.FormatISOTime(); + + wxString urCall = header->getYourCall(); + m_your->SetLabel(urCall); + + wxString myCall = header->getMyCall1(); + + wxString myCall2 = header->getMyCall2(); + if (!myCall2.IsSameAs(wxT(" "))) { + myCall.Append(wxT("/")); + myCall.Append(myCall2); + } + + m_my->SetLabel(myCall); + + wxString rpt1Call = header->getRptCall1(); + m_rpt1->SetLabel(rpt1Call); + + wxString rpt2Call = header->getRptCall2(); + m_rpt2->SetLabel(rpt2Call); + + wxString flags; + flags.Printf(wxT("%02X %02X %02X"), header->getFlag1(), header->getFlag2(), header->getFlag3()); + m_flags->SetLabel(flags); + + m_message->SetLabel(wxEmptyString); + + delete header; + } else { + m_fileName->SetLabel(wxEmptyString); + + m_your->SetLabel(wxEmptyString); + m_my->SetLabel(wxEmptyString); + m_rpt1->SetLabel(wxEmptyString); + m_rpt2->SetLabel(wxEmptyString); + m_flags->SetLabel(wxEmptyString); + m_message->SetLabel(wxEmptyString); + } +} + +void CDVToolReaderFrame::onError(wxEvent& event) +{ + CErrorEvent& errEvent = dynamic_cast(event); + + wxString text = errEvent.getText(); + + wxMessageDialog dialog(this, text, _("DVTool Reader Error"), wxICON_ERROR); + dialog.ShowModal(); +} diff --git a/AMBETools/DVToolReader/DVToolReaderFrame.h b/AMBETools/DVToolReader/DVToolReaderFrame.h new file mode 100755 index 0000000..adc1ff0 --- /dev/null +++ b/AMBETools/DVToolReader/DVToolReaderFrame.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2009,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVToolReaderFrame_H +#define DVToolReaderFrame_H + +#include "DVToolReaderDefs.h" +#include "MessageData.h" +#include "HeaderData.h" + +#include + +class CDVToolReaderFrame : public wxFrame { +public: + CDVToolReaderFrame(const wxString& title = wxEmptyString); + virtual ~CDVToolReaderFrame(); + + virtual void onDVTOOLOpen(wxCommandEvent& event); + virtual void onAMBEOpen(wxCommandEvent& event); + virtual void onQuit(wxCommandEvent& event); + + virtual void onPreferences(wxCommandEvent& event); + + virtual void onAbout(wxCommandEvent& event); + + virtual void onClose(wxCloseEvent& event); + + virtual void onMessage(wxEvent& event); + virtual void onHeader(wxEvent& event); + virtual void onError(wxEvent& event); + + virtual void showMessage(CMessageData* message); + virtual void showHeader(CHeaderData* header); + virtual void error(const wxString& error); + +private: + wxStaticText* m_fileName; + wxStaticText* m_your; + wxStaticText* m_my; + wxStaticText* m_rpt1; + wxStaticText* m_rpt2; + wxStaticText* m_flags; + wxStaticText* m_message; + + DECLARE_EVENT_TABLE() + + wxMenuBar* createMenuBar(); +}; + +#endif diff --git a/AMBETools/DVToolReader/DVToolReaderFrame.o b/AMBETools/DVToolReader/DVToolReaderFrame.o new file mode 100644 index 0000000..c338090 Binary files /dev/null and b/AMBETools/DVToolReader/DVToolReaderFrame.o differ diff --git a/AMBETools/DVToolReader/DVToolReaderPreferences.cpp b/AMBETools/DVToolReader/DVToolReaderPreferences.cpp new file mode 100755 index 0000000..41e85c4 --- /dev/null +++ b/AMBETools/DVToolReader/DVToolReaderPreferences.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DVToolReaderPreferences.h" +#include "DVToolReaderDefs.h" + +#include + +CDVToolReaderPreferences::CDVToolReaderPreferences(wxWindow* parent, int id, DONGLE_TYPE type, const wxString& device, const wxString& address, unsigned int port, const wxString& soundcard, bool bleep) : +wxDialog(parent, id, wxString(_("DVTool Reader Preferences")), wxDefaultPosition, wxDefaultSize, wxRESIZE_BORDER | wxDEFAULT_DIALOG_STYLE), +m_soundcard(NULL), +m_dongle(NULL), +m_bleep(NULL) +{ + wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL); + + wxNotebook* noteBook = new wxNotebook(this, -1); + + m_soundcard = new CSoundcardSet(noteBook, -1, APPLICATION_NAME, soundcard, false, true); + noteBook->AddPage(m_soundcard, _("Sound Card"), true); + + m_dongle = new CDongleSet(noteBook, -1, APPLICATION_NAME, type, device, address, port); + noteBook->AddPage(m_dongle, _("Dongle"), false); + + m_bleep = new CBleepSet(noteBook, -1, APPLICATION_NAME, bleep); + noteBook->AddPage(m_bleep, _("Bleep"), false); + + mainSizer->Add(noteBook, 1, wxALL | wxGROW, BORDER_SIZE); + + mainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALL | wxALIGN_RIGHT, BORDER_SIZE); + + SetAutoLayout(true); + Layout(); + + mainSizer->Fit(this); + mainSizer->SetSizeHints(this); + + SetSizer(mainSizer); +} + +CDVToolReaderPreferences::~CDVToolReaderPreferences() +{ +} + +bool CDVToolReaderPreferences::Validate() +{ + if (!m_soundcard->Validate()) + return false; + + if (!m_dongle->Validate()) + return false; + + return m_bleep->Validate(); +} + +DONGLE_TYPE CDVToolReaderPreferences::getType() const +{ + return m_dongle->getType(); +} + +wxString CDVToolReaderPreferences::getDevice() const +{ + return m_dongle->getDevice(); +} + +wxString CDVToolReaderPreferences::getAddress() const +{ + return m_dongle->getAddress(); +} + +unsigned int CDVToolReaderPreferences::getPort() const +{ + return m_dongle->getPort(); +} + +wxString CDVToolReaderPreferences::getSoundcard() const +{ + return m_soundcard->getWriteDevice(); +} + +bool CDVToolReaderPreferences::getBleep() const +{ + return m_bleep->getBleep(); +} diff --git a/AMBETools/DVToolReader/DVToolReaderPreferences.h b/AMBETools/DVToolReader/DVToolReaderPreferences.h new file mode 100755 index 0000000..7bf837a --- /dev/null +++ b/AMBETools/DVToolReader/DVToolReaderPreferences.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVToolReaderPreferences_H +#define DVToolReaderPreferences_H + +#include + +#include "SoundcardSet.h" +#include "DongleSet.h" +#include "BleepSet.h" + +class CDVToolReaderPreferences : public wxDialog { +public: + CDVToolReaderPreferences(wxWindow* parent, int id, DONGLE_TYPE type, const wxString& device, const wxString& address, unsigned int port, const wxString& soundcard, bool bleep); + virtual ~CDVToolReaderPreferences(); + + virtual bool Validate(); + + virtual DONGLE_TYPE getType() const; + virtual wxString getDevice() const; + virtual wxString getAddress() const; + virtual unsigned int getPort() const; + + virtual wxString getSoundcard() const; + + virtual bool getBleep() const; + +private: + CSoundcardSet* m_soundcard; + CDongleSet* m_dongle; + CBleepSet* m_bleep; +}; + +#endif diff --git a/AMBETools/DVToolReader/DVToolReaderPreferences.o b/AMBETools/DVToolReader/DVToolReaderPreferences.o new file mode 100644 index 0000000..eba2070 Binary files /dev/null and b/AMBETools/DVToolReader/DVToolReaderPreferences.o differ diff --git a/AMBETools/DVToolReader/DVToolReaderThread.cpp b/AMBETools/DVToolReader/DVToolReaderThread.cpp new file mode 100755 index 0000000..dede3ab --- /dev/null +++ b/AMBETools/DVToolReader/DVToolReaderThread.cpp @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2009,2010,2012,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DVToolReaderThread.h" + +#include "DVToolReaderApp.h" +#include "MessageData.h" +#include "HeaderData.h" + +CDVToolReaderThread::CDVToolReaderThread() : +wxThread(wxTHREAD_JOINABLE), +m_reader(NULL), +m_soundcard(NULL), +m_dongle(NULL), +m_slowDataDecoder(), +m_stopped(true), +m_audioBuffer(DSTAR_AUDIO_BLOCK_SIZE * 30U), +m_killed(false) +{ +} + +CDVToolReaderThread::~CDVToolReaderThread() +{ +} + +void* CDVToolReaderThread::Entry() +{ + // Wait here until we have the essentials to run + while (!m_killed && (m_dongle == NULL || m_soundcard == NULL)) + Sleep(500UL); // 1/2 sec + + if (m_killed) + return NULL; + + m_dongle->Create(); + m_dongle->SetPriority(100U); + m_dongle->Run(); + + while (!m_killed) { + if (m_reader != NULL) + processFile(); + + Sleep(500UL); // 1/2 sec + } + + m_soundcard->close(); + delete m_soundcard; + + m_dongle->kill(); + + return NULL; +} + +void CDVToolReaderThread::kill() +{ + m_killed = true; +} + +void CDVToolReaderThread::decodeCallback(const wxFloat32* audio, unsigned int length) +{ + m_audioBuffer.addData(audio, length); +} + +bool CDVToolReaderThread::setReader(IFileReader* reader) +{ + wxASSERT(reader != NULL); + + wxLogMessage(wxT("Processing file - %s"), reader->getFileName().c_str()); + + if (!m_stopped) { + wxLogError(wxT("Already processing a file")); + return false; + } + + if (m_dongle == NULL || m_soundcard == NULL) { + wxLogError(wxT("No Dongle and/or Soundcard has been set")); + return false; + } + + if (m_reader != NULL) { + m_reader->close(); + delete m_reader; + } + + m_reader = reader; + + return true; +} + + +void CDVToolReaderThread::setSoundCard(CSoundCardReaderWriter* soundcard) +{ + wxASSERT(soundcard != NULL); + + if (!m_stopped) { + soundcard->close(); + delete soundcard; + return; + } + + if (m_soundcard != NULL) { + m_soundcard->close(); + delete m_soundcard; + } + + m_soundcard = soundcard; +} + +void CDVToolReaderThread::setDongle(CDongleThread* dongle) +{ + wxASSERT(dongle != NULL); + + if (!m_stopped) { + dongle->kill(); + return; + } + + if (m_dongle != NULL) + m_dongle->kill(); + + m_dongle = dongle; +} + +void CDVToolReaderThread::setBleep(bool on) +{ + if (m_dongle != NULL) + m_dongle->setBleep(on); +} + +void CDVToolReaderThread::processFile() +{ + m_stopped = false; + + DVTFR_TYPE type; + unsigned char header[RADIO_HEADER_LENGTH_BYTES]; + unsigned int n = m_reader->read(header, RADIO_HEADER_LENGTH_BYTES, type); + if (n == 0U) { + // Release the input file + m_reader->close(); + delete m_reader; + m_reader = NULL; + return; + } + + if (type == DVTFR_HEADER) + processHeader(header); + + // Clear any state that may be hanging around + m_slowDataDecoder.reset(); + + m_dongle->setDecode(); + + for (;;) { + if (m_killed) { + m_dongle->setIdle(); + m_reader->close(); + delete m_reader; + return; + } + + unsigned int space = m_dongle->getDecodeSpace(); + if (space >= VOICE_FRAME_LENGTH_BYTES) { + DVTFR_TYPE type; + unsigned char frame[RADIO_HEADER_LENGTH_BYTES]; + unsigned int n = m_reader->read(frame, RADIO_HEADER_LENGTH_BYTES, type); + + // End of file? + if (n == 0U || type != DVTFR_DETAIL) + break; + + if (n != DV_FRAME_LENGTH_BYTES && n != VOICE_FRAME_LENGTH_BYTES) { + wxLogError(wxT("Invalid frame size of %u in the file"), n); + ::wxGetApp().error(_("Invalid frame size in the file.")); + break; + } + + // Only process slow data if we have any + if (n == DV_FRAME_LENGTH_BYTES) { + // Don't pass data re-sync to the slow data processor + if (::memcmp(frame + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES) != 0) + processSlowData(frame + VOICE_FRAME_LENGTH_BYTES); + else + m_slowDataDecoder.sync(); + } + + m_dongle->writeDecode(frame, VOICE_FRAME_LENGTH_BYTES); + } + + Sleep(FRAME_TIME_MS); + } + + Sleep(FRAME_TIME_MS * 30U); + + // Clear the GUI + ::wxGetApp().showHeader(NULL); + + // Release the input file + m_reader->close(); + delete m_reader; + m_reader = NULL; + + wxLogMessage(wxT("Finished processing the file")); + + m_stopped = true; + + m_dongle->setIdle(); +} + +void CDVToolReaderThread::processHeader(const unsigned char* buffer) +{ + // Tell the GUI about the header, we assume that it's valid + CHeaderData* header = new CHeaderData(buffer, RADIO_HEADER_LENGTH_BYTES, false); + + wxLogMessage(wxT("Header decoded - My: %s/%s Your: %s Rpt1: %s Rpt2: %s Flags: %02X %02X %02X"), header->getMyCall1().c_str(), header->getMyCall2().c_str(), header->getYourCall().c_str(), header->getRptCall1().c_str(), header->getRptCall2().c_str(), header->getFlag1(), header->getFlag2(), header->getFlag3()); + + ::wxGetApp().showHeader(header); +} + +void CDVToolReaderThread::processSlowData(const unsigned char* buffer) +{ + m_slowDataDecoder.addData(buffer); + + CMessageData* message = m_slowDataDecoder.getMessageData(); + if (message != NULL) + ::wxGetApp().showMessage(message); +} + +void CDVToolReaderThread::callback(const wxFloat32* input, wxFloat32* output, unsigned int nSamples, int id) +{ + ::memset(output, 0x00, nSamples * sizeof(wxFloat32)); + m_audioBuffer.getData(output, nSamples); +} diff --git a/AMBETools/DVToolReader/DVToolReaderThread.h b/AMBETools/DVToolReader/DVToolReaderThread.h new file mode 100755 index 0000000..2f53bdf --- /dev/null +++ b/AMBETools/DVToolReader/DVToolReaderThread.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVToolReaderThread_H +#define DVToolReaderThread_H + +#include "SoundCardReaderWriter.h" +#include "SlowDataDecoder.h" +#include "DecodeCallback.h" +#include "AudioCallback.h" +#include "DStarDefines.h" +#include "DongleThread.h" +#include "RingBuffer.h" +#include "FileReader.h" + +#include + +class CDVToolReaderThread : public wxThread, public IAudioCallback, public IDecodeCallback { +public: + CDVToolReaderThread(); + virtual ~CDVToolReaderThread(); + + virtual void callback(const wxFloat32* input, wxFloat32* output, unsigned int nSamples, int id); + + virtual void decodeCallback(const wxFloat32* audio, unsigned int length); + + virtual void setBleep(bool on); + virtual bool setReader(IFileReader* reader); + virtual void setSoundCard(CSoundCardReaderWriter* soundcard); + virtual void setDongle(CDongleThread* dongle); + + virtual void* Entry(); + virtual void kill(); + +private: + IFileReader* m_reader; + CSoundCardReaderWriter* m_soundcard; + CDongleThread* m_dongle; + CSlowDataDecoder m_slowDataDecoder; + bool m_stopped; + CRingBuffer m_audioBuffer; + bool m_killed; + + void processFile(); + void processHeader(const unsigned char* buffer); + void processSlowData(const unsigned char* buffer); + void processAudio(const unsigned char* buffer); +}; + +#endif diff --git a/AMBETools/DVToolReader/DVToolReaderThread.o b/AMBETools/DVToolReader/DVToolReaderThread.o new file mode 100644 index 0000000..013e5f8 Binary files /dev/null and b/AMBETools/DVToolReader/DVToolReaderThread.o differ diff --git a/AMBETools/DVToolReader/Makefile b/AMBETools/DVToolReader/Makefile new file mode 100755 index 0000000..e090910 --- /dev/null +++ b/AMBETools/DVToolReader/Makefile @@ -0,0 +1,33 @@ +all: dvtoolreader + +CFLAGS := -I../Common $(CFLAGS) + +OBJS := DVToolReaderApp.o DVToolReaderFrame.o DVToolReaderPreferences.o DVToolReaderThread.o + +dvtoolreader: $(OBJS) + $(CC) $(LDFLAGS) -o dvtoolreader $(OBJS) ../Common/Common.a $(LIBS) + +DVToolReaderApp.o: DVToolReaderApp.cpp DVToolReaderApp.h DVToolReaderThread.h DVToolReaderFrame.h DVToolReaderDefs.h ../Common/FileReader.h \ + ../Common/DStarDefines.h ../Common/MessageData.h ../Common/DongleSet.h ../Common/HeaderData.h ../Common/Logger.h ../Common/Version.h \ + ../Common/DongleThread.h ../Common/DV3000Controller.h ../Common/DVDongleController.h ../Common/AMBE3000Thread.h ../Common/DVDongleThread.h + $(CC) $(CFLAGS) -c DVToolReaderApp.cpp + +DVToolReaderFrame.o: DVToolReaderFrame.cpp DVToolReaderFrame.h DVToolReaderPreferences.h DVToolReaderDefs.h DVToolReaderApp.h ../Common/AMBEFileReader.h \ + ../Common/DVTOOLFileReader.h ../Common/MessageEvent.h ../Common/DStarDefines.h ../Common/MessageEvent.h ../Common/HeaderEvent.h \ + ../Common/MessageData.h ../Common/ErrorEvent.h ../Common/HeaderData.h ../Common/Version.h ../Common/FileReader.h + $(CC) $(CFLAGS) -c DVToolReaderFrame.cpp + +DVToolReaderPreferences.o: DVToolReaderPreferences.cpp DVToolReaderPreferences.h DVToolReaderDefs.h ../Common/SoundcardSet.h \ + ../Common/DongleSet.h ../Common/BleepSet.h + $(CC) $(CFLAGS) -c DVToolReaderPreferences.cpp + +DVToolReaderThread.o: DVToolReaderThread.cpp DVToolReaderThread.h DVToolReaderDefs.h DVToolReaderApp.h ../Common/DStarDefines.h \ + ../Common/SoundCardReaderWriter.h ../Common/SlowDataDecoder.h ../Common/FileReader.h ../Common/AudioCallback.h ../Common/MessageData.h \ + ../Common/RingBuffer.h ../Common/HeaderData.h ../Common/Bleeper.h ../Common/DongleThread.h ../Common/DecodeCallback.h + $(CC) $(CFLAGS) -c DVToolReaderThread.cpp + +install: dvtoolreader + install -g bin -o root -m 0775 dvtoolreader $(BINDIR) + +clean: + rm -f core dvtoolreader *.o *~ *.bak diff --git a/AMBETools/DVToolReader/dvtoolreader b/AMBETools/DVToolReader/dvtoolreader new file mode 100755 index 0000000..fb2de75 Binary files /dev/null and b/AMBETools/DVToolReader/dvtoolreader differ diff --git a/AMBETools/DVToolWriter/DVToolWriter.vcproj b/AMBETools/DVToolWriter/DVToolWriter.vcproj new file mode 100755 index 0000000..7df91f6 --- /dev/null +++ b/AMBETools/DVToolWriter/DVToolWriter.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AMBETools/DVToolWriter/DVToolWriterApp.cpp b/AMBETools/DVToolWriter/DVToolWriterApp.cpp new file mode 100755 index 0000000..20b1a71 --- /dev/null +++ b/AMBETools/DVToolWriter/DVToolWriterApp.cpp @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2009,2010,2012,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DVToolWriterApp.h" + +#include "DVDongleController.h" +#include "DV3000Controller.h" +#include "AMBE3000Thread.h" +#include "DVDongleThread.h" +#include "DStarDefines.h" +#include "HeaderData.h" +#include "Version.h" +#include "Logger.h" + +#include +#include + +IMPLEMENT_APP(CDVToolWriterApp) + +const wxString KEY_CALLSIGN1 = wxT("/callsign1"); +const wxString KEY_CALLSIGN2 = wxT("/callsign2"); +const wxString KEY_SOUND_DEVICE = wxT("/soundDevice"); +const wxString KEY_DONGLE_TYPE = wxT("/dongleType"); +const wxString KEY_DONGLE_DEVICE = wxT("/dongleDevice"); +const wxString KEY_DONGLE_ADDRESS = wxT("/dongleAddress"); +const wxString KEY_DONGLE_PORT = wxT("/donglePort"); + +const wxString DEFAULT_CALLSIGN1 = wxEmptyString; +const wxString DEFAULT_CALLSIGN2 = wxEmptyString; +const wxString DEFAULT_SOUND_DEVICE = wxEmptyString; +const DONGLE_TYPE DEFAULT_DONGLE_TYPE = DT_DVDONGLE; +const wxString DEFAULT_DONGLE_DEVICE = wxEmptyString; +const wxString DEFAULT_DONGLE_ADDRESS = wxEmptyString; +const unsigned int DEFAULT_DONGLE_PORT = 2460L; + + +CDVToolWriterApp::CDVToolWriterApp() : +wxApp(), +m_frame(NULL), +m_thread(NULL), +m_callsign1(), +m_callsign2() +{ +} + +CDVToolWriterApp::~CDVToolWriterApp() +{ +} + +bool CDVToolWriterApp::OnInit() +{ + SetVendorName(VENDOR_NAME); + + wxFileName loggerName(wxFileName::GetHomeDir(), LOG_FILE_NAME, wxT("log")); + wxLog* log = new CLogger(loggerName.GetFullPath()); + wxLog::SetActiveTarget(log); + + m_frame = new CDVToolWriterFrame(APPLICATION_NAME + wxT(" - ") + VERSION); + m_frame->Show(); + + SetTopWindow(m_frame); + + wxLogInfo(wxT("Starting ") + APPLICATION_NAME + wxT(" - ") + VERSION); + + // Log the SVN revsion and the version of wxWidgets and the Operating System + wxLogInfo(SVNREV); + wxLogInfo(wxT("Using wxWidgets %d.%d.%d on %s"), wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER, ::wxGetOsDescription().c_str()); + + createThread(); + + return wxApp::OnInit(); +} + +int CDVToolWriterApp::OnExit() +{ + wxLogInfo(APPLICATION_NAME + wxT(" is exiting")); + + m_thread->kill(); + m_thread->Wait(); + delete m_thread; + + return 0; +} + +#if defined(__WXDEBUG__) +void CDVToolWriterApp::OnAssertFailure(const wxChar* file, int line, const wxChar* func, const wxChar* cond, const wxChar* msg) +{ + wxLogFatalError(wxT("Assertion failed on line %d in file %s and function %s: %s %s"), line, file, func, cond, msg); +} +#endif + +void CDVToolWriterApp::error(const wxString& text) const +{ + m_frame->error(text); +} + +void CDVToolWriterApp::showFinished() const +{ + m_frame->showFinished(); +} + +void CDVToolWriterApp::getCallsign(wxString& callsign1, wxString& callsign2) const +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + profile->Read(KEY_CALLSIGN1, &callsign1, DEFAULT_CALLSIGN1); + profile->Read(KEY_CALLSIGN2, &callsign2, DEFAULT_CALLSIGN2); + + wxLogInfo(wxT("Callsign set to %s/%s"), callsign1.c_str(), callsign2.c_str()); + + delete profile; +} + +void CDVToolWriterApp::setCallsign(const wxString& callsign1, const wxString& callsign2) +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + profile->Write(KEY_CALLSIGN1, callsign1); + profile->Write(KEY_CALLSIGN2, callsign2); + profile->Flush(); + + wxLogInfo(wxT("Callsign set to %s/%s"), callsign1.c_str(), callsign2.c_str()); + + delete profile; +} + +void CDVToolWriterApp::getSoundcard(wxString& device) const +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + profile->Read(KEY_SOUND_DEVICE, &device, DEFAULT_SOUND_DEVICE); + + wxLogInfo(wxT("Soundcard set to %s"), device.c_str()); + + delete profile; +} + +void CDVToolWriterApp::setSoundcard(const wxString& device) +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + profile->Write(KEY_SOUND_DEVICE, device); + profile->Flush(); + + wxLogInfo(wxT("Soundcard set to %s"), device.c_str()); + + delete profile; +} + +void CDVToolWriterApp::getDongle(DONGLE_TYPE& type, wxString& device, wxString& address, unsigned int& port) const +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + long temp; + profile->Read(KEY_DONGLE_TYPE, &temp, long(DEFAULT_DONGLE_TYPE)); + type = DONGLE_TYPE(temp); + + profile->Read(KEY_DONGLE_DEVICE, &device, DEFAULT_DONGLE_DEVICE); + + profile->Read(KEY_DONGLE_ADDRESS, &address, DEFAULT_DONGLE_ADDRESS); + + profile->Read(KEY_DONGLE_PORT, &temp, long(DEFAULT_DONGLE_PORT)); + port = (unsigned int)temp; + + wxLogInfo(wxT("Dongle type: %d, device: %s, address: %s:%u"), int(type), device.c_str(), address.c_str(), port); + + delete profile; +} + +void CDVToolWriterApp::setDongle(DONGLE_TYPE type, const wxString& device, const wxString& address, unsigned int port) +{ + wxConfigBase* profile = new wxConfig(APPLICATION_NAME); + wxASSERT(profile != NULL); + + profile->Write(KEY_DONGLE_TYPE, long(type)); + profile->Write(KEY_DONGLE_DEVICE, device); + profile->Write(KEY_DONGLE_ADDRESS, address); + profile->Write(KEY_DONGLE_PORT, long(port)); + profile->Flush(); + + wxLogInfo(wxT("Dongle type: %d, device: %s, address: %s:%u"), int(type), device.c_str(), address.c_str(), port); + + delete profile; +} + +bool CDVToolWriterApp::processFile(CWAVFileReader* reader, const wxString& your, const wxString& rpt1, const wxString& rpt2, const wxString& text, IFileWriter* writer) +{ + wxASSERT(writer != NULL); + + if (m_callsign1.IsEmpty() || m_callsign2.IsEmpty() || your.IsEmpty() || rpt1.IsEmpty() || rpt2.IsEmpty()) + return false; + + CHeaderData* header = new CHeaderData(m_callsign1, m_callsign2, your, rpt1, rpt2); + + return m_thread->processFile(reader, header, text, writer); +} + +bool CDVToolWriterApp::processAudio(const wxString& your, const wxString& rpt1, const wxString& rpt2, const wxString& text, IFileWriter* writer) +{ + wxASSERT(writer != NULL); + + if (m_callsign1.IsEmpty() || m_callsign2.IsEmpty() || your.IsEmpty() || rpt1.IsEmpty() || rpt2.IsEmpty()) + return false; + + CHeaderData* header = new CHeaderData(m_callsign1, m_callsign2, your, rpt1, rpt2); + + return m_thread->processAudio(header, text, writer); +} + +void CDVToolWriterApp::processAudio() +{ + m_thread->processAudio(); +} + +void CDVToolWriterApp::createThread() +{ + m_thread = new CDVToolWriterThread; + m_thread->Create(); + m_thread->Run(); + + getCallsign(m_callsign1, m_callsign2); + + DONGLE_TYPE type; + wxString device, address; + unsigned int port; + getDongle(type, device, address, port); + + CDongleThread* dongle = NULL; + + switch (type) { + case DT_DVDONGLE: + if (!device.IsEmpty()) + dongle = new CDVDongleThread(new CDVDongleController(device)); + break; + case DT_DV3000: + if (!address.IsEmpty() && port > 0U) + dongle = new CAMBE3000Thread(new CDV3000Controller(address, port)); + break; + default: + error(_("Invalid Dongle type specified")); + break; + } + + if (dongle != NULL) { + dongle->setEncodeCallback(m_thread); + dongle->setBleep(false); + + bool res = dongle->open(); + if (!res) + error(_("Can't find the AMBE Dongle on the port specified")); + else + m_thread->setDongle(dongle); + } + + getSoundcard(device); + + if (!device.IsEmpty()) { +#if defined(__WINDOWS__) + CSoundCardReaderWriter* soundcard = new CSoundCardReaderWriter(device, wxEmptyString, DSTAR_RADIO_SAMPLE_RATE, DSTAR_RADIO_BLOCK_SIZE); +#else + CSoundCardReaderWriter* soundcard = new CSoundCardReaderWriter(device, wxEmptyString, DSTAR_RADIO_SAMPLE_RATE, 64U); +#endif + soundcard->setCallback(m_thread, 0); + + bool res = soundcard->open(); + if (!res) + error(_("Cannot open the sound card")); + else + m_thread->setSoundCard(soundcard); + } +} diff --git a/AMBETools/DVToolWriter/DVToolWriterApp.h b/AMBETools/DVToolWriter/DVToolWriterApp.h new file mode 100755 index 0000000..29d4ff3 --- /dev/null +++ b/AMBETools/DVToolWriter/DVToolWriterApp.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVToolWriterApp_H +#define DVToolWriterApp_H + +#include "DVToolWriterThread.h" +#include "DVToolWriterFrame.h" +#include "HeaderData.h" +#include "FileWriter.h" +#include "DongleSet.h" + +#include + +class CDVToolWriterApp : public wxApp { + +public: + CDVToolWriterApp(); + virtual ~CDVToolWriterApp(); + + virtual bool OnInit(); + virtual int OnExit(); + + // This is overridden because dialog boxes from threads are bad news +#if defined(__WXDEBUG__) + virtual void OnAssertFailure(const wxChar* file, int line, const wxChar* func, const wxChar* cond, const wxChar* msg); +#endif + virtual void error(const wxString& text) const; + + virtual void showFinished() const; + + virtual void setCallsign(const wxString& call1, const wxString& call2); + virtual void getCallsign(wxString& call1, wxString& call2) const; + + virtual void setSoundcard(const wxString& device); + virtual void getSoundcard(wxString& device) const; + + virtual void setDongle(DONGLE_TYPE type, const wxString& device, const wxString& address, unsigned int port); + virtual void getDongle(DONGLE_TYPE& type, wxString& device, wxString& address, unsigned int& port) const; + + virtual bool processFile(CWAVFileReader* reader, const wxString& your, const wxString& rpt1, const wxString& rpt2, const wxString& text, IFileWriter* writer); + + virtual bool processAudio(const wxString& your, const wxString& rpt1, const wxString& rpt2, const wxString& text, IFileWriter* writer); + virtual void processAudio(); + +private: + CDVToolWriterFrame* m_frame; + CDVToolWriterThread* m_thread; + wxString m_callsign1; + wxString m_callsign2; + + void createThread(); +}; + +DECLARE_APP(CDVToolWriterApp) + +#endif diff --git a/AMBETools/DVToolWriter/DVToolWriterApp.o b/AMBETools/DVToolWriter/DVToolWriterApp.o new file mode 100644 index 0000000..00b52a0 Binary files /dev/null and b/AMBETools/DVToolWriter/DVToolWriterApp.o differ diff --git a/AMBETools/DVToolWriter/DVToolWriterDefs.h b/AMBETools/DVToolWriter/DVToolWriterDefs.h new file mode 100755 index 0000000..68c1e70 --- /dev/null +++ b/AMBETools/DVToolWriter/DVToolWriterDefs.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVToolWriterDefs_H +#define DVToolWriterDefs_H + +#include + +const unsigned int LONG_CALLSIGN_WIDTH = 80U; +const unsigned int SHORT_CALLSIGN_WIDTH = 50U; + +const unsigned int BORDER_SIZE = 5U; +const unsigned int LABEL_WIDTH = 60U; +const unsigned int CONTROL_WIDTH = 100U; +const unsigned int MIC_WIDTH = 30U; + +const unsigned int INFO_WIDTH = 690U; +const unsigned int INFO_HEIGHT = 160U; + +const unsigned int HEARD_WIDTH = 690U; +const unsigned int HEARD_HEIGHT = 300U; + +const unsigned int DATETIME_WIDTH = 125U; +const unsigned int CALLSIGN_WIDTH = 90U; +const unsigned int MESSAGE_WIDTH = 200U; + +const wxString LOG_FILE_NAME = wxT("DVToolWriter"); + +const wxString APPLICATION_NAME = wxT("DVTool Writer"); + +#endif diff --git a/AMBETools/DVToolWriter/DVToolWriterFrame.cpp b/AMBETools/DVToolWriter/DVToolWriterFrame.cpp new file mode 100755 index 0000000..ee43d55 --- /dev/null +++ b/AMBETools/DVToolWriter/DVToolWriterFrame.cpp @@ -0,0 +1,407 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DVToolWriterPreferences.h" +#include "DVToolWriterFrame.h" +#include "DVTOOLFileWriter.h" +#include "DVToolWriterApp.h" +#include "AMBEFileWriter.h" +#include "DStarDefines.h" +#include "MessageEvent.h" +#include "HeaderEvent.h" +#include "ErrorEvent.h" +#include "Version.h" + +#include +#include + +unsigned char startImage[] = { + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, +}; + +unsigned char startAlpha[] = { + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, 0x00U, + 0x00U, 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, 0x00U, + 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, + 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, + 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, + 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, + 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, + 0x00U, 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, 0x00U, + 0x00U, 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, +}; + +unsigned char stopImage[] = { + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U +}; + +enum { + Menu_File_File = 6000, + + Menu_Edit_Preferences, + + Button_Start, + Button_Stop +}; + +DEFINE_EVENT_TYPE(ERROR_EVENT) +DEFINE_EVENT_TYPE(FINISHED_EVENT) + +BEGIN_EVENT_TABLE(CDVToolWriterFrame, wxFrame) + EVT_MENU(Menu_File_File, CDVToolWriterFrame::onOpen) + EVT_MENU(wxID_EXIT, CDVToolWriterFrame::onQuit) + + EVT_MENU(Menu_Edit_Preferences, CDVToolWriterFrame::onPreferences) + + EVT_MENU(wxID_ABOUT, CDVToolWriterFrame::onAbout) + + EVT_CLOSE(CDVToolWriterFrame::onClose) + + EVT_BUTTON(Button_Start, CDVToolWriterFrame::onStart) + EVT_BUTTON(Button_Stop, CDVToolWriterFrame::onStop) + + EVT_CUSTOM(ERROR_EVENT, wxID_ANY, CDVToolWriterFrame::onError) + EVT_CUSTOM(FINISHED_EVENT, wxID_ANY, CDVToolWriterFrame::onFinished) +END_EVENT_TABLE() + +CDVToolWriterFrame::CDVToolWriterFrame(const wxString& title) : +wxFrame(NULL, -1, title), +m_format(NULL), +m_recording(NULL), +m_your(NULL), +m_rpt1(NULL), +m_rpt2(NULL), +m_message(NULL) +{ + SetMenuBar(createMenuBar()); + + wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL); + + wxPanel* panel = new wxPanel(this); + + wxGridBagSizer* panelSizer = new wxGridBagSizer(BORDER_SIZE, BORDER_SIZE); + + wxStaticText* formatLabel = new wxStaticText(panel, -1, _("Format:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(formatLabel, wxGBPosition(0, 0), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_format = new wxChoice(panel, -1, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1)); + m_format->Append(wxT(".dvtool")); + m_format->Append(wxT(".ambe")); + panelSizer->Add(m_format, wxGBPosition(0, 1), wxDefaultSpan, wxALL, BORDER_SIZE); + m_format->SetSelection(0); + + wxImage* start = new wxImage(15, 15, startImage, startAlpha, true); + wxImage* stop = new wxImage(15, 15, stopImage, true); + + wxStaticText* micLabel = new wxStaticText(panel, -1, _("Microphone:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(micLabel, wxGBPosition(0, 2), wxDefaultSpan, wxALL, BORDER_SIZE); + + wxBoxSizer* micSizer = new wxBoxSizer(wxHORIZONTAL); + + wxButton* startButton = new wxBitmapButton(panel, Button_Start, wxBitmap(*start), wxDefaultPosition, wxSize(MIC_WIDTH, -1), wxALIGN_RIGHT); + micSizer->Add(startButton, wxALL, BORDER_SIZE); + + wxButton* stopButton = new wxBitmapButton(panel, Button_Stop, wxBitmap(*stop), wxDefaultPosition, wxSize(MIC_WIDTH, -1), wxALIGN_RIGHT); + micSizer->Add(stopButton, wxALL, BORDER_SIZE); + + panelSizer->Add(micSizer, wxGBPosition(0, 3), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_recording = new wxStaticText(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(m_recording, wxGBPosition(0, 5), wxDefaultSpan, wxALL, BORDER_SIZE); + + wxStaticText* yourLabel = new wxStaticText(panel, -1, _("Your:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(yourLabel, wxGBPosition(1, 0), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_your = new CCallsignTextCtrl(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1)); + m_your->SetMaxLength(LONG_CALLSIGN_LENGTH); + panelSizer->Add(m_your, wxGBPosition(1, 1), wxDefaultSpan, wxALL, BORDER_SIZE); + + wxStaticText* rpt1Label = new wxStaticText(panel, -1, _("RPT1:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(rpt1Label, wxGBPosition(1, 2), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_rpt1 = new CCallsignTextCtrl(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1)); + m_rpt1->SetMaxLength(LONG_CALLSIGN_LENGTH); + panelSizer->Add(m_rpt1, wxGBPosition(1, 3), wxDefaultSpan, wxALL, BORDER_SIZE); + + wxStaticText* rpt2Label = new wxStaticText(panel, -1, _("RPT2:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(rpt2Label, wxGBPosition(1, 4), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_rpt2 = new CCallsignTextCtrl(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(CONTROL_WIDTH, -1)); + m_rpt2->SetMaxLength(LONG_CALLSIGN_LENGTH); + panelSizer->Add(m_rpt2, wxGBPosition(1, 5), wxDefaultSpan, wxALL, BORDER_SIZE); + + wxStaticText* messageLabel = new wxStaticText(panel, -1, _("Message:"), wxDefaultPosition, wxSize(LABEL_WIDTH, -1), wxALIGN_RIGHT); + panelSizer->Add(messageLabel, wxGBPosition(2, 0), wxDefaultSpan, wxALL, BORDER_SIZE); + + m_message = new wxTextCtrl(panel, -1, wxEmptyString, wxDefaultPosition, wxSize(CONTROL_WIDTH * 2U + LABEL_WIDTH + BORDER_SIZE * 6U, -1), wxALIGN_LEFT); + m_message->SetMaxLength(MESSAGE_LENGTH); + panelSizer->Add(m_message, wxGBPosition(2, 1), wxGBSpan(1, 3), wxALL, BORDER_SIZE); + + panel->SetSizer(panelSizer); + panelSizer->SetSizeHints(panel); + + mainSizer->Add(panel); + + SetSizer(mainSizer); + mainSizer->SetSizeHints(this); +} + +CDVToolWriterFrame::~CDVToolWriterFrame() +{ +} + +wxMenuBar* CDVToolWriterFrame::createMenuBar() +{ + wxMenu* fileMenu = new wxMenu(); + fileMenu->Append(Menu_File_File, _("Open WAV File...")); + fileMenu->AppendSeparator(); + fileMenu->Append(wxID_EXIT, _("Exit")); + + wxMenu* editMenu = new wxMenu(); + editMenu->Append(Menu_Edit_Preferences, _("Preferences...")); + + wxMenu* helpMenu = new wxMenu(); + helpMenu->Append(wxID_ABOUT, _("About DVTool Writer")); + + wxMenuBar* menuBar = new wxMenuBar(); + menuBar->Append(fileMenu, _("File")); + menuBar->Append(editMenu, _("Edit")); + menuBar->Append(helpMenu, _("Help")); + + return menuBar; +} + +void CDVToolWriterFrame::error(const wxString& error) +{ + CErrorEvent event(error, ERROR_EVENT); + + AddPendingEvent(event); +} + +void CDVToolWriterFrame::showFinished() +{ + wxCommandEvent event(FINISHED_EVENT); + + AddPendingEvent(event); +} + +void CDVToolWriterFrame::onQuit(wxCommandEvent& event) +{ + Close(false); +} + +void CDVToolWriterFrame::onOpen(wxCommandEvent& event) +{ + wxFileDialog dialog(this, _("Select a WAV File"), wxEmptyString, wxEmptyString, _("WAV file (*.wav)|*.wav|All files (*.*)|*.*")); + if (dialog.ShowModal() != wxID_OK) + return; + + wxString fileName = dialog.GetPath(); + + CWAVFileReader* reader = new CWAVFileReader(fileName, DSTAR_RADIO_BLOCK_SIZE); + bool res = reader->open(); + if (!res) { + wxMessageDialog dialog(this, _("Cannot find the file, or the file is corrupt."), _("DVTool Writer Error"), wxICON_ERROR); + dialog.ShowModal(); + delete reader; + return; + } + + unsigned int sampleRate = reader->getSampleRate(); + if (sampleRate != 48000U) { + wxMessageDialog dialog(this, _("Invalid WAV file sample rate, not equal to 48000 sps."), _("DVTool Writer Error"), wxICON_ERROR); + dialog.ShowModal(); + delete reader; + return; + } + + unsigned int channels = reader->getChannels(); + if (channels != 1U) { + wxMessageDialog dialog(this, _("Wrong number of channels in the WAV file."), _("DVTool Writer Error"), wxICON_ERROR); + dialog.ShowModal(); + delete reader; + return; + } + + wxDateTime dateTime = wxDateTime::Now(); + + IFileWriter* writer = NULL; + switch (m_format->GetSelection()) { + case 0: + writer = new CDVTOOLFileWriter(dateTime.Format(wxT("%Y%m%d-%H%M%S.dvtool"))); + break; + case 1: + writer = new CAMBEFileWriter(dateTime.Format(wxT("%Y%m%d-%H%M%S.ambe"))); + break; + default: + break; + } + + if (writer == NULL) { + wxMessageDialog dialog(this, _("No output file format specified."), _("DVTool Writer Error"), wxICON_ERROR); + dialog.ShowModal(); + delete reader; + return; + } + + res = ::wxGetApp().processFile(reader, m_your->GetValue(), m_rpt1->GetValue(), m_rpt2->GetValue(), m_message->GetValue(), writer); + if (!res) { + wxMessageDialog dialog(this, _("Cannot process the file."), _("DVTool Writer Error"), wxICON_ERROR); + dialog.ShowModal(); + delete reader; + } +} + +void CDVToolWriterFrame::onStart(wxCommandEvent& event) +{ + wxDateTime dateTime = wxDateTime::Now(); + + IFileWriter* writer = NULL; + switch (m_format->GetSelection()) { + case 0: + writer = new CDVTOOLFileWriter(dateTime.Format(wxT("%Y%m%d-%H%M%S.dvtool"))); + break; + case 1: + writer = new CAMBEFileWriter(dateTime.Format(wxT("%Y%m%d-%H%M%S.ambe"))); + break; + default: + break; + } + + if (writer == NULL) { + wxMessageDialog dialog(this, _("No output file format specified."), _("DVTool Writer Error"), wxICON_ERROR); + dialog.ShowModal(); + return; + } + + bool res = ::wxGetApp().processAudio(m_your->GetValue(), m_rpt1->GetValue(), m_rpt2->GetValue(), m_message->GetValue(), writer); + if (!res) { + wxMessageDialog dialog(this, _("Cannot process the audio."), _("DVTool Writer Error"), wxICON_ERROR); + dialog.ShowModal(); + return; + } + + m_recording->SetLabel(_("Recording")); +} + +void CDVToolWriterFrame::onStop(wxCommandEvent& event) +{ + ::wxGetApp().processAudio(); + + m_recording->SetLabel(wxEmptyString); +} + +void CDVToolWriterFrame::onPreferences(wxCommandEvent& event) +{ + wxString callsign1, callsign2; + ::wxGetApp().getCallsign(callsign1, callsign2); + + DONGLE_TYPE type; + wxString device, address; + unsigned int port; + ::wxGetApp().getDongle(type, device, address, port); + + wxString soundcard; + ::wxGetApp().getSoundcard(soundcard); + + CDVToolWriterPreferences dialog1(this, -1, callsign1, callsign2, type, device, address, port, soundcard); + if (dialog1.ShowModal() != wxID_OK) + return; + + callsign1 = dialog1.getCallsign1(); + callsign2 = dialog1.getCallsign2(); + type = dialog1.getType(); + device = dialog1.getDevice(); + address = dialog1.getAddress(); + port = dialog1.getPort(); + soundcard = dialog1.getSoundcard(); + + ::wxGetApp().setCallsign(callsign1, callsign2); + ::wxGetApp().setDongle(type, device, address, port); + ::wxGetApp().setSoundcard(soundcard); + + wxMessageDialog dialog2(this, _("The changes made will not take effect\nuntil the application is restarted"), _("DVTool Writer Information"), wxICON_INFORMATION); + dialog2.ShowModal(); +} + +void CDVToolWriterFrame::onAbout(wxCommandEvent& event) +{ + wxAboutDialogInfo info; + info.AddDeveloper(wxT("Jonathan Naylor, G4KLX")); + info.SetCopyright(wxT("(C) 2014 using GPL v2 or later")); + info.SetName(APPLICATION_NAME); + info.SetVersion(VERSION); + info.SetDescription(_("This program writes .ambe and .dvtool files created and displays\nthe enclosed information and plays the AMBE audio.")); + + ::wxAboutBox(info); +} + +void CDVToolWriterFrame::onClose(wxCloseEvent& event) +{ + Destroy(); +} + +void CDVToolWriterFrame::onError(wxEvent& event) +{ + CErrorEvent& errEvent = dynamic_cast(event); + + wxString text = errEvent.getText(); + + wxMessageDialog dialog(this, text, _("DVTool Writer Error"), wxICON_ERROR); + dialog.ShowModal(); +} + +void CDVToolWriterFrame::onFinished(wxEvent& event) +{ + wxMessageDialog dialog(this, _("The file has finished processing."), _("DVTool Writer Information"), wxICON_INFORMATION); + dialog.ShowModal(); +} diff --git a/AMBETools/DVToolWriter/DVToolWriterFrame.h b/AMBETools/DVToolWriter/DVToolWriterFrame.h new file mode 100755 index 0000000..6257fb3 --- /dev/null +++ b/AMBETools/DVToolWriter/DVToolWriterFrame.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2009,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVToolWriterFrame_H +#define DVToolWriterFrame_H + +#include "CallsignTextCtrl.h" +#include "DVToolWriterDefs.h" +#include "MessageData.h" +#include "HeaderData.h" + +#include + +class CDVToolWriterFrame : public wxFrame { +public: + CDVToolWriterFrame(const wxString& title = wxEmptyString); + virtual ~CDVToolWriterFrame(); + + virtual void onQuit(wxCommandEvent& event); + + virtual void onPreferences(wxCommandEvent& event); + + virtual void onAbout(wxCommandEvent& event); + + virtual void onClose(wxCloseEvent& event); + + virtual void onOpen(wxCommandEvent& event); + + virtual void onStart(wxCommandEvent& event); + + virtual void onStop(wxCommandEvent& event); + + virtual void onError(wxEvent& event); + + virtual void error(const wxString& error); + + virtual void showFinished(); + + virtual void onFinished(wxEvent& event); + +private: + wxChoice* m_format; + wxStaticText* m_recording; + CCallsignTextCtrl* m_your; + CCallsignTextCtrl* m_rpt1; + CCallsignTextCtrl* m_rpt2; + wxTextCtrl* m_message; + + DECLARE_EVENT_TABLE() + + wxMenuBar* createMenuBar(); +}; + +#endif diff --git a/AMBETools/DVToolWriter/DVToolWriterFrame.o b/AMBETools/DVToolWriter/DVToolWriterFrame.o new file mode 100644 index 0000000..9f2dde9 Binary files /dev/null and b/AMBETools/DVToolWriter/DVToolWriterFrame.o differ diff --git a/AMBETools/DVToolWriter/DVToolWriterPreferences.cpp b/AMBETools/DVToolWriter/DVToolWriterPreferences.cpp new file mode 100755 index 0000000..4bc79bf --- /dev/null +++ b/AMBETools/DVToolWriter/DVToolWriterPreferences.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DVToolWriterPreferences.h" +#include "DVToolWriterDefs.h" + +#include + +CDVToolWriterPreferences::CDVToolWriterPreferences(wxWindow* parent, int id, const wxString& callsign1, const wxString& callsign2, DONGLE_TYPE type, const wxString& device, const wxString& address, unsigned int port, const wxString& soundcard) : +wxDialog(parent, id, wxString(_("DVTool Writer Preferences")), wxDefaultPosition, wxDefaultSize, wxRESIZE_BORDER | wxDEFAULT_DIALOG_STYLE), +m_callsign(NULL), +m_soundcard(NULL), +m_dongle(NULL) +{ + wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL); + + wxNotebook* noteBook = new wxNotebook(this, -1); + + m_callsign = new CCallsignSet(noteBook, -1, APPLICATION_NAME, callsign1, callsign2); + noteBook->AddPage(m_callsign, _("Callsign"), true); + + m_soundcard = new CSoundcardSet(noteBook, -1, APPLICATION_NAME, soundcard, true, false); + noteBook->AddPage(m_soundcard, _("Sound Card"), false); + + m_dongle = new CDongleSet(noteBook, -1, APPLICATION_NAME, type, device, address, port); + noteBook->AddPage(m_dongle, _("Dongle"), false); + + mainSizer->Add(noteBook, 1, wxALL | wxGROW, BORDER_SIZE); + + mainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALL | wxALIGN_RIGHT, BORDER_SIZE); + + SetAutoLayout(true); + Layout(); + + mainSizer->Fit(this); + mainSizer->SetSizeHints(this); + + SetSizer(mainSizer); +} + +CDVToolWriterPreferences::~CDVToolWriterPreferences() +{ +} + +bool CDVToolWriterPreferences::Validate() +{ + if (!m_callsign->Validate()) + return false; + + if (!m_soundcard->Validate()) + return false; + + return m_dongle->Validate(); +} + +wxString CDVToolWriterPreferences::getCallsign1() const +{ + return m_callsign->getCallsign1(); +} + +wxString CDVToolWriterPreferences::getCallsign2() const +{ + return m_callsign->getCallsign2(); +} + +DONGLE_TYPE CDVToolWriterPreferences::getType() const +{ + return m_dongle->getType(); +} + +wxString CDVToolWriterPreferences::getDevice() const +{ + return m_dongle->getDevice(); +} + +wxString CDVToolWriterPreferences::getAddress() const +{ + return m_dongle->getAddress(); +} + +unsigned int CDVToolWriterPreferences::getPort() const +{ + return m_dongle->getPort(); +} + +wxString CDVToolWriterPreferences::getSoundcard() const +{ + return m_soundcard->getReadDevice(); +} diff --git a/AMBETools/DVToolWriter/DVToolWriterPreferences.h b/AMBETools/DVToolWriter/DVToolWriterPreferences.h new file mode 100755 index 0000000..3a97c45 --- /dev/null +++ b/AMBETools/DVToolWriter/DVToolWriterPreferences.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVToolWriterPreferences_H +#define DVToolWriterPreferences_H + +#include + +#include "SoundcardSet.h" +#include "CallsignSet.h" +#include "DongleSet.h" + +class CDVToolWriterPreferences : public wxDialog { +public: + CDVToolWriterPreferences(wxWindow* parent, int id, const wxString& callsign1, const wxString& callsign2, DONGLE_TYPE type, const wxString& device, const wxString& address, unsigned int port, const wxString& soundcard); + virtual ~CDVToolWriterPreferences(); + + virtual bool Validate(); + + virtual wxString getCallsign1() const; + virtual wxString getCallsign2() const; + virtual DONGLE_TYPE getType() const; + virtual wxString getDevice() const; + virtual wxString getAddress() const; + virtual unsigned int getPort() const; + + virtual wxString getSoundcard() const; + +private: + CCallsignSet* m_callsign; + CSoundcardSet* m_soundcard; + CDongleSet* m_dongle; +}; + +#endif diff --git a/AMBETools/DVToolWriter/DVToolWriterPreferences.o b/AMBETools/DVToolWriter/DVToolWriterPreferences.o new file mode 100644 index 0000000..ed981bb Binary files /dev/null and b/AMBETools/DVToolWriter/DVToolWriterPreferences.o differ diff --git a/AMBETools/DVToolWriter/DVToolWriterThread.cpp b/AMBETools/DVToolWriter/DVToolWriterThread.cpp new file mode 100755 index 0000000..cbaa98d --- /dev/null +++ b/AMBETools/DVToolWriter/DVToolWriterThread.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2009,2010,2012,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DVToolWriterThread.h" + +#include "DVToolWriterApp.h" +#include "MessageData.h" +#include "HeaderData.h" + +CDVToolWriterThread::CDVToolWriterThread() : +wxThread(wxTHREAD_JOINABLE), +m_soundcard(NULL), +m_dongle(NULL), +m_encoder(), +m_stopped(true), +m_reader(NULL), +m_writer(NULL), +m_audioBuffer(DSTAR_AUDIO_BLOCK_SIZE * 30U), +m_count(0U), +m_killed(false) +{ +} + +CDVToolWriterThread::~CDVToolWriterThread() +{ +} + +void* CDVToolWriterThread::Entry() +{ + // Wait here until we have the essentials to run + while (!m_killed && (m_dongle == NULL || m_soundcard == NULL)) + Sleep(500UL); // 1/2 sec + + if (m_killed) + return NULL; + + m_dongle->Create(); + m_dongle->SetPriority(100U); + m_dongle->Run(); + + while (!m_killed) { + if (m_writer != NULL && m_reader != NULL) + processFile(); + + if (m_writer != NULL && m_reader == NULL) + processSoundcard(); + + Sleep(500UL); // 1/2 sec + } + + m_soundcard->close(); + delete m_soundcard; + + m_dongle->kill(); + + return NULL; +} + +void CDVToolWriterThread::kill() +{ + m_killed = true; +} + +void CDVToolWriterThread::encodeCallback(const unsigned char* ambe, unsigned int length) +{ + if (m_writer == NULL) + return; + + unsigned char frame[DV_FRAME_LENGTH_BYTES]; + + ::memcpy(frame, ambe, VOICE_FRAME_LENGTH_BYTES); + + if (m_count == 0U) + ::memcpy(frame + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES); + else + m_encoder.getData(frame + VOICE_FRAME_LENGTH_BYTES); + + m_count++; + if (m_count >= 21U) + m_count = 0U; + + m_writer->writeFrame(frame, DV_FRAME_LENGTH_BYTES); +} + +bool CDVToolWriterThread::processFile(CWAVFileReader* reader, CHeaderData* header, const wxString& text, IFileWriter* writer) +{ + wxASSERT(reader != NULL); + wxASSERT(header != NULL); + wxASSERT(writer != NULL); + + wxLogMessage(wxT("Processing file - %s"), reader->getFilename().c_str()); + + if (!m_stopped) { + wxLogError(wxT("Already processing a file")); + return false; + } + + if (m_dongle == NULL) { + wxLogError(wxT("No Dongle has been set")); + return false; + } + + if (m_reader != NULL) { + m_reader->close(); + delete m_reader; + } + + if (m_writer != NULL) { + m_writer->close(); + delete m_writer; + } + + wxLogMessage(wxT("Writing file - %s"), writer->getFilename().c_str()); + + bool ret = writer->open(); + if (!ret) { + wxLogError(wxT("Cannot open the file for writing")); + return false; + } + + writer->writeHeader(*header); + + m_encoder.reset(); + m_encoder.setMessageData(text); + m_encoder.setHeaderData(*header); + + delete header; + + m_reader = reader; + m_writer = writer; + + return true; +} + +bool CDVToolWriterThread::processAudio(CHeaderData* header, const wxString& text, IFileWriter* writer) +{ + wxASSERT(header != NULL); + wxASSERT(writer != NULL); + + if (!m_stopped) { + wxLogError(wxT("Already processing a file")); + return false; + } + + if (m_dongle == NULL) { + wxLogError(wxT("No Dongle has been set")); + return false; + } + + if (m_writer != NULL) { + m_writer->close(); + delete m_writer; + } + + wxLogMessage(wxT("Writing file - %s"), writer->getFilename().c_str()); + + bool ret = writer->open(); + if (!ret) { + wxLogError(wxT("Cannot open the file for writing")); + return false; + } + + writer->writeHeader(*header); + + m_encoder.reset(); + m_encoder.setMessageData(text); + m_encoder.setHeaderData(*header); + + delete header; + + m_writer = writer; + + return true; +} + +void CDVToolWriterThread::processAudio() +{ + m_stopped = true; +} + +void CDVToolWriterThread::setSoundCard(CSoundCardReaderWriter* soundcard) +{ + wxASSERT(soundcard != NULL); + + if (!m_stopped) { + soundcard->close(); + delete soundcard; + return; + } + + if (m_soundcard != NULL) { + m_soundcard->close(); + delete m_soundcard; + } + + m_soundcard = soundcard; +} + +void CDVToolWriterThread::setDongle(CDongleThread* dongle) +{ + wxASSERT(dongle != NULL); + + if (!m_stopped) { + dongle->kill(); + return; + } + + if (m_dongle != NULL) + m_dongle->kill(); + + m_dongle = dongle; +} + +void CDVToolWriterThread::processFile() +{ + m_stopped = false; + + m_count = 0U; + + m_dongle->setEncode(); + + for (;;) { + if (m_killed) { + m_dongle->setIdle(); + m_reader->close(); + m_writer->close(); + delete m_reader; + delete m_writer; + m_reader = NULL; + m_writer = NULL; + return; + } + + unsigned int space = m_dongle->getEncodeSpace(); + if (space >= DSTAR_RADIO_BLOCK_SIZE) { + wxFloat32 audio[DSTAR_RADIO_BLOCK_SIZE]; + ::memset(audio, 0x00U, DSTAR_RADIO_BLOCK_SIZE * sizeof(wxFloat32)); + unsigned int n = m_reader->read(audio, DSTAR_RADIO_BLOCK_SIZE); + + m_dongle->writeEncode(audio, DSTAR_RADIO_BLOCK_SIZE); + + // End of file? + if (n != DSTAR_RADIO_BLOCK_SIZE) + break; + } + + Sleep(FRAME_TIME_MS); + } + + Sleep(FRAME_TIME_MS * 30U); + + // Release the input file + m_reader->close(); + delete m_reader; + m_reader = NULL; + + // Release the output file + m_writer->close(); + delete m_writer; + m_writer = NULL; + + ::wxGetApp().showFinished(); + + wxLogMessage(wxT("Finished processing the file")); + + m_stopped = true; + + m_dongle->setIdle(); +} + +void CDVToolWriterThread::processSoundcard() +{ + m_stopped = false; + + m_count = 0U; + + m_dongle->setEncode(); + + for (;;) { + if (m_killed) { + m_dongle->setIdle(); + m_writer->close(); + delete m_writer; + m_writer = NULL; + return; + } + + if (m_stopped) + break; + + unsigned int size = m_audioBuffer.dataSpace(); + if (size >= DSTAR_RADIO_BLOCK_SIZE) { + wxFloat32 audio[DSTAR_RADIO_BLOCK_SIZE]; + unsigned int n = m_audioBuffer.getData(audio, DSTAR_RADIO_BLOCK_SIZE); + m_dongle->writeEncode(audio, n); + } + + Sleep(FRAME_TIME_MS / 4U); + } + + Sleep(FRAME_TIME_MS * 30U); + + // Release the output file + m_writer->close(); + delete m_writer; + m_writer = NULL; + + wxLogMessage(wxT("Finished processing from the sound card")); + + m_stopped = true; + + m_dongle->setIdle(); +} + +void CDVToolWriterThread::callback(const wxFloat32* input, wxFloat32* output, unsigned int nSamples, int id) +{ + if (m_writer != NULL && m_reader == NULL) + m_audioBuffer.addData(input, nSamples); +} diff --git a/AMBETools/DVToolWriter/DVToolWriterThread.h b/AMBETools/DVToolWriter/DVToolWriterThread.h new file mode 100755 index 0000000..a57a7bf --- /dev/null +++ b/AMBETools/DVToolWriter/DVToolWriterThread.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2009,2010,2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVToolWriterThread_H +#define DVToolWriterThread_H + +#include "SoundCardReaderWriter.h" +#include "SlowDataEncoder.h" +#include "EncodeCallback.h" +#include "WAVFileReader.h" +#include "AudioCallback.h" +#include "DStarDefines.h" +#include "DongleThread.h" +#include "RingBuffer.h" +#include "FileWriter.h" +#include "HeaderData.h" + +#include + +class CDVToolWriterThread : public wxThread, public IAudioCallback, public IEncodeCallback { +public: + CDVToolWriterThread(); + virtual ~CDVToolWriterThread(); + + virtual void callback(const wxFloat32* input, wxFloat32* output, unsigned int nSamples, int id); + + virtual void encodeCallback(const unsigned char* ambe, unsigned int length); + + virtual bool processFile(CWAVFileReader* reader, CHeaderData* header, const wxString& text, IFileWriter* writer); + + virtual bool processAudio(CHeaderData* header, const wxString& text, IFileWriter* writer); + virtual void processAudio(); + + virtual void setSoundCard(CSoundCardReaderWriter* soundcard); + virtual void setDongle(CDongleThread* dongle); + + virtual void* Entry(); + virtual void kill(); + +private: + CSoundCardReaderWriter* m_soundcard; + CDongleThread* m_dongle; + CSlowDataEncoder m_encoder; + bool m_stopped; + CWAVFileReader* m_reader; + IFileWriter* m_writer; + CRingBuffer m_audioBuffer; + unsigned int m_count; + bool m_killed; + + void processFile(); + void processSoundcard(); +}; + +#endif diff --git a/AMBETools/DVToolWriter/DVToolWriterThread.o b/AMBETools/DVToolWriter/DVToolWriterThread.o new file mode 100644 index 0000000..6a249a7 Binary files /dev/null and b/AMBETools/DVToolWriter/DVToolWriterThread.o differ diff --git a/AMBETools/DVToolWriter/Makefile b/AMBETools/DVToolWriter/Makefile new file mode 100755 index 0000000..29056f2 --- /dev/null +++ b/AMBETools/DVToolWriter/Makefile @@ -0,0 +1,34 @@ +all: dvtoolwriter + +CFLAGS := -I../Common $(CFLAGS) + +OBJS := DVToolWriterApp.o DVToolWriterFrame.o DVToolWriterPreferences.o DVToolWriterThread.o + +dvtoolwriter: $(OBJS) + $(CC) $(LDFLAGS) -o dvtoolwriter $(OBJS) ../Common/Common.a $(LIBS) + +DVToolWriterApp.o: DVToolWriterApp.cpp DVToolWriterApp.h DVToolWriterThread.h DVToolWriterFrame.h DVToolWriterDefs.h ../Common/FileReader.h \ + ../Common/DStarDefines.h ../Common/DongleSet.h ../Common/HeaderData.h ../Common/Logger.h ../Common/Version.h \ + ../Common/DongleThread.h ../Common/DV3000Controller.h ../Common/DVDongleController.h ../Common/AMBE3000Thread.h ../Common/DVDongleThread.h + $(CC) $(CFLAGS) -c DVToolWriterApp.cpp + +DVToolWriterFrame.o: DVToolWriterFrame.cpp DVToolWriterFrame.h DVToolWriterPreferences.h DVToolWriterDefs.h DVToolWriterApp.h ../Common/AMBEFileWriter.h \ + ../Common/DVTOOLFileWriter.h ../Common/MessageEvent.h ../Common/DStarDefines.h ../Common/HeaderData.h ../Common/Version.h ../Common/FileWriter.h \ + ../Common/CallsignTextCtrl.h + $(CC) $(CFLAGS) -c DVToolWriterFrame.cpp + +DVToolWriterPreferences.o: DVToolWriterPreferences.cpp DVToolWriterPreferences.h DVToolWriterDefs.h ../Common/SoundcardSet.h \ + ../Common/DongleSet.h ../Common/CallsignSet.h + $(CC) $(CFLAGS) -c DVToolWriterPreferences.cpp + +DVToolWriterThread.o: DVToolWriterThread.cpp DVToolWriterThread.h DVToolWriterDefs.h DVToolWriterApp.h ../Common/DStarDefines.h \ + ../Common/SoundCardReaderWriter.h ../Common/SlowDataEncoder.h ../Common/FileWriter.h ../Common/AudioCallback.h ../Common/MessageData.h \ + ../Common/RingBuffer.h ../Common/HeaderData.h ../Common/Bleeper.h ../Common/DongleThread.h ../Common/EncodeCallback.h ../Common/HeaderData.h \ + ../Common/WAVFileReader.h + $(CC) $(CFLAGS) -c DVToolWriterThread.cpp + +install: dvtoolwriter + install -g bin -o root -m 0775 dvtoolwriter $(BINDIR) + +clean: + rm -f core dvtoolwriter *.o *~ *.bak diff --git a/AMBETools/DVToolWriter/dvtoolwriter b/AMBETools/DVToolWriter/dvtoolwriter new file mode 100755 index 0000000..2ffebec Binary files /dev/null and b/AMBETools/DVToolWriter/dvtoolwriter differ diff --git a/AMBETools/Makefile b/AMBETools/Makefile new file mode 100755 index 0000000..9fd4a4a --- /dev/null +++ b/AMBETools/Makefile @@ -0,0 +1,46 @@ +# Makefile +# make Digital Voice on Linux (Ubuntu) +# Jonathan Naylor, March 2009 + +include settings.mk + +all: DVToolReader/dvtoolreader DVToolWriter/dvtoolwriter ambe2wav/ambe2wav dvtool2wav/dvtool2wav wav2ambe/wav2ambe wav2dvtool/wav2dvtool + +DVToolReader/dvtoolreader: Common/Common.a + make -C DVToolReader + +DVToolWriter/dvtoolwriter: Common/Common.a + make -C DVToolWriter + +ambe2wav/ambe2wav: Common/Common.a + make -C ambe2wav + +dvtool2wav/dvtool2wav: Common/Common.a + make -C dvtool2wav + +wav2ambe/wav2ambe: Common/Common.a + make -C wav2ambe + +wav2dvtool/wav2dvtool: Common/Common.a + make -C wav2dvtool + +Common/Common.a: + make -C Common + +install: all + make -C DVToolReader install + make -C DVToolWriter install + make -C ambe2wav install + make -C dvtool2wav install + make -C wav2ambe install + make -C wav2dvtool install + +clean: + rm -f core *~ *.bak + make -C Common clean + make -C DVToolReader clean + make -C DVToolWriter clean + make -C ambe2wav clean + make -C dvtool2wav clean + make -C wav2ambe clean + make -C wav2dvtool clean diff --git a/AMBETools/ambe2wav/Makefile b/AMBETools/ambe2wav/Makefile new file mode 100755 index 0000000..0bd2910 --- /dev/null +++ b/AMBETools/ambe2wav/Makefile @@ -0,0 +1,19 @@ +all: ambe2wav + +CFLAGS := -I../Common $(CFLAGS) + +OBJS := ambe2wav.o + +ambe2wav: $(OBJS) + $(CC) $(LDFLAGS) -o ambe2wav $(OBJS) ../Common/Common.a $(LIBS) + +ambe2wav.o: ambe2wav.cpp ambe2wav.h ../Common/WAVFileWriter.h ../Common/DStarDefines.h ../Common/HeaderData.h ../Common/Version.h ../Common/DecodeCallback.h \ + ../Common/DongleThread.h ../Common/DV3000Controller.h ../Common/DVDongleController.h ../Common/AMBE3000Thread.h ../Common/DVDongleThread.h \ + ../Common/AMBEFileReader.h + $(CC) $(CFLAGS) -c ambe2wav.cpp + +install: ambe2wav + install -g bin -o root -m 0775 ambe2wav $(BINDIR) + +clean: + rm -f core ambe2wav *.o *~ *.bak diff --git a/AMBETools/ambe2wav/ambe2wav b/AMBETools/ambe2wav/ambe2wav new file mode 100755 index 0000000..7f390d4 Binary files /dev/null and b/AMBETools/ambe2wav/ambe2wav differ diff --git a/AMBETools/ambe2wav/ambe2wav.cpp b/AMBETools/ambe2wav/ambe2wav.cpp new file mode 100755 index 0000000..2c31c75 --- /dev/null +++ b/AMBETools/ambe2wav/ambe2wav.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "ambe2wav.h" + +#include "AMBE3000Thread.h" +#include "DVDongleThread.h" +#include "DStarDefines.h" +#include "HeaderData.h" +#include "Version.h" + +#include + +const wxString APPLICATION_NAME = wxT("DVTool Reader"); + +const wxString KEY_DONGLE_TYPE = wxT("/dongleType"); +const wxString KEY_DONGLE_DEVICE = wxT("/dongleDevice"); +const wxString KEY_DONGLE_ADDRESS = wxT("/dongleAddress"); +const wxString KEY_DONGLE_PORT = wxT("/donglePort"); + +const DONGLE_TYPE DEFAULT_DONGLE_TYPE = DT_DVDONGLE; +const wxString DEFAULT_DONGLE_DEVICE = wxEmptyString; +const wxString DEFAULT_DONGLE_ADDRESS = wxEmptyString; +const unsigned int DEFAULT_DONGLE_PORT = 2460L; + +int main(int argc, char** argv) +{ + if (argc < 3) { + ::fprintf(stderr, "Usage: ambe2wav \n"); + return 1; + } + + ::wxInitialize(); + + wxString inFile = wxString(argv[1U], wxConvLocal); + wxString outFile = wxString(argv[2U], wxConvLocal); + + CAMBEFileReader* reader = new CAMBEFileReader; + bool ret = reader->open(inFile); + if (!ret) { + delete reader; + ::wxUninitialize(); + ::fprintf(stderr, "ambe2wav: unable to open the input file - %s\n", argv[1U]); + return 1; + } + + CWAVFileWriter* writer = new CWAVFileWriter(outFile, DSTAR_RADIO_SAMPLE_RATE, 1U, 16U, DSTAR_RADIO_BLOCK_SIZE); + ret = writer->open(); + if (!ret) { + delete reader; + delete writer; + ::wxUninitialize(); + ::fprintf(stderr, "ambe2wav: unable to open the output file - %s\n", argv[2U]); + return 1; + } + +#if defined(__WXMSW__) + wxRegConfig profile(APPLICATION_NAME, VENDOR_NAME, wxEmptyString, wxEmptyString, wxCONFIG_USE_LOCAL_FILE); +#else + wxFileConfig profile(APPLICATION_NAME, VENDOR_NAME, wxEmptyString, wxEmptyString, wxCONFIG_USE_LOCAL_FILE); +#endif + + long temp; + profile.Read(KEY_DONGLE_TYPE, &temp, long(DEFAULT_DONGLE_TYPE)); + DONGLE_TYPE type = DONGLE_TYPE(temp); + + wxString device; + profile.Read(KEY_DONGLE_DEVICE, &device, DEFAULT_DONGLE_DEVICE); + + wxString address; + profile.Read(KEY_DONGLE_ADDRESS, &address, DEFAULT_DONGLE_ADDRESS); + + unsigned int port; + profile.Read(KEY_DONGLE_PORT, &temp, long(DEFAULT_DONGLE_PORT)); + port = (unsigned int)temp; + + CDongleThread* dongle = NULL; + + switch (type) { + case DT_DVDONGLE: + if (!device.IsEmpty()) + dongle = new CDVDongleThread(new CDVDongleController(device)); + break; + case DT_DV3000: + if (!address.IsEmpty() && port > 0U) + dongle = new CAMBE3000Thread(new CDV3000Controller(address, port)); + break; + default: + delete reader; + delete writer; + ::wxUninitialize(); + ::fprintf(stderr, "ambe2wav: invalid Dongle type specified\n"); + return 1; + } + + ambe2wav program(dongle, reader, writer); + + dongle->setDecodeCallback(&program); + dongle->setBleep(false); + + ret = dongle->open(); + if (!ret) { + delete reader; + delete writer; + delete dongle; + ::wxUninitialize(); + ::fprintf(stderr, "ambe2wav: couldn't find the Dongle on the port specified\n"); + return 1; + } + + program.run(); + + ::wxUninitialize(); + + return 0; +} + +ambe2wav::ambe2wav(CDongleThread* dongle, CAMBEFileReader* reader, CWAVFileWriter* writer) : +m_dongle(dongle), +m_reader(reader), +m_writer(writer) +{ + wxASSERT(dongle != NULL); + wxASSERT(reader != NULL); + wxASSERT(writer != NULL); +} + +ambe2wav::~ambe2wav() +{ +} + +void ambe2wav::decodeCallback(const wxFloat32* audio, unsigned int length) +{ + if (m_writer == NULL) + return; + + m_writer->write(audio, length); +} + +void ambe2wav::run() +{ + m_dongle->Create(); + m_dongle->SetPriority(100U); + m_dongle->Run(); + + m_dongle->setDecode(); + + for (;;) { + unsigned int space = m_dongle->getDecodeSpace(); + if (space >= VOICE_FRAME_LENGTH_BYTES) { + DVTFR_TYPE type; + unsigned char frame[RADIO_HEADER_LENGTH_BYTES]; + unsigned int n = m_reader->read(frame, RADIO_HEADER_LENGTH_BYTES, type); + + // End of file? + if (n == 0U || type != DVTFR_DETAIL) + break; + + if (n != DV_FRAME_LENGTH_BYTES && n != VOICE_FRAME_LENGTH_BYTES) + break; + + m_dongle->writeDecode(frame, VOICE_FRAME_LENGTH_BYTES); + } + + ::wxMilliSleep(FRAME_TIME_MS); + } + + ::wxMilliSleep(FRAME_TIME_MS * 30U); + + // Release the input file + m_reader->close(); + delete m_reader; + m_reader = NULL; + + // Release the output file + m_writer->close(); + delete m_writer; + m_writer = NULL; + + m_dongle->setIdle(); + m_dongle->kill(); +} diff --git a/AMBETools/ambe2wav/ambe2wav.h b/AMBETools/ambe2wav/ambe2wav.h new file mode 100755 index 0000000..69a1e72 --- /dev/null +++ b/AMBETools/ambe2wav/ambe2wav.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if !defined(AMBE2WAV_H) +#define AMBE2WAV + +#include "AMBEFileReader.h" +#include "DecodeCallback.h" +#include "WAVFileWriter.h" +#include "DongleThread.h" + +#include + +class ambe2wav : public IDecodeCallback { +public: + ambe2wav(CDongleThread* dongle, CAMBEFileReader* reader, CWAVFileWriter* writer); + virtual ~ambe2wav(); + + virtual void decodeCallback(const wxFloat32* audio, unsigned int length); + + virtual void run(); + +private: + CDongleThread* m_dongle; + CAMBEFileReader* m_reader; + CWAVFileWriter* m_writer; +}; + +#endif diff --git a/AMBETools/ambe2wav/ambe2wav.o b/AMBETools/ambe2wav/ambe2wav.o new file mode 100644 index 0000000..2186d6b Binary files /dev/null and b/AMBETools/ambe2wav/ambe2wav.o differ diff --git a/AMBETools/ambe2wav/ambe2wav.vcproj b/AMBETools/ambe2wav/ambe2wav.vcproj new file mode 100755 index 0000000..ad12b1c --- /dev/null +++ b/AMBETools/ambe2wav/ambe2wav.vcproj @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AMBETools/dvtool2wav/Makefile b/AMBETools/dvtool2wav/Makefile new file mode 100755 index 0000000..f2c4851 --- /dev/null +++ b/AMBETools/dvtool2wav/Makefile @@ -0,0 +1,19 @@ +all: dvtool2wav + +CFLAGS := -I../Common $(CFLAGS) + +OBJS := dvtool2wav.o + +dvtool2wav: $(OBJS) + $(CC) $(LDFLAGS) -o dvtool2wav $(OBJS) ../Common/Common.a $(LIBS) + +dvtool2wav.o: dvtool2wav.cpp dvtool2wav.h ../Common/WAVFileWriter.h ../Common/DStarDefines.h ../Common/HeaderData.h ../Common/Version.h ../Common/DecodeCallback.h \ + ../Common/DongleThread.h ../Common/DV3000Controller.h ../Common/DVDongleController.h ../Common/AMBE3000Thread.h ../Common/DVDongleThread.h \ + ../Common/DVTOOLFileReader.h + $(CC) $(CFLAGS) -c dvtool2wav.cpp + +install: dvtool2wav + install -g bin -o root -m 0775 dvtool2wav $(BINDIR) + +clean: + rm -f core dvtool2wav *.o *~ *.bak diff --git a/AMBETools/dvtool2wav/dvtool2wav b/AMBETools/dvtool2wav/dvtool2wav new file mode 100755 index 0000000..692ad68 Binary files /dev/null and b/AMBETools/dvtool2wav/dvtool2wav differ diff --git a/AMBETools/dvtool2wav/dvtool2wav.cpp b/AMBETools/dvtool2wav/dvtool2wav.cpp new file mode 100755 index 0000000..2c2e22e --- /dev/null +++ b/AMBETools/dvtool2wav/dvtool2wav.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dvtool2wav.h" + +#include "AMBE3000Thread.h" +#include "DVDongleThread.h" +#include "DStarDefines.h" +#include "HeaderData.h" +#include "Version.h" + +#include + +const wxString APPLICATION_NAME = wxT("DVTool Reader"); + +const wxString KEY_DONGLE_TYPE = wxT("/dongleType"); +const wxString KEY_DONGLE_DEVICE = wxT("/dongleDevice"); +const wxString KEY_DONGLE_ADDRESS = wxT("/dongleAddress"); +const wxString KEY_DONGLE_PORT = wxT("/donglePort"); + +const DONGLE_TYPE DEFAULT_DONGLE_TYPE = DT_DVDONGLE; +const wxString DEFAULT_DONGLE_DEVICE = wxEmptyString; +const wxString DEFAULT_DONGLE_ADDRESS = wxEmptyString; +const unsigned int DEFAULT_DONGLE_PORT = 2460L; + +int main(int argc, char** argv) +{ + if (argc < 3) { + ::fprintf(stderr, "Usage: dvtool2wav \n"); + return 1; + } + + ::wxInitialize(); + + wxString inFile = wxString(argv[1U], wxConvLocal); + wxString outFile = wxString(argv[2U], wxConvLocal); + + CDVTOOLFileReader* reader = new CDVTOOLFileReader; + bool ret = reader->open(inFile); + if (!ret) { + delete reader; + ::wxUninitialize(); + ::fprintf(stderr, "dvtool2wav: unable to open the input file - %s\n", argv[1U]); + return 1; + } + + CWAVFileWriter* writer = new CWAVFileWriter(outFile, DSTAR_RADIO_SAMPLE_RATE, 1U, 16U, DSTAR_RADIO_BLOCK_SIZE); + ret = writer->open(); + if (!ret) { + delete reader; + delete writer; + ::wxUninitialize(); + ::fprintf(stderr, "dvtool2wav: unable to open the output file - %s\n", argv[2U]); + return 1; + } + +#if defined(__WXMSW__) + wxRegConfig profile(APPLICATION_NAME, VENDOR_NAME, wxEmptyString, wxEmptyString, wxCONFIG_USE_LOCAL_FILE); +#else + wxFileConfig profile(APPLICATION_NAME, VENDOR_NAME, wxEmptyString, wxEmptyString, wxCONFIG_USE_LOCAL_FILE); +#endif + + long temp; + profile.Read(KEY_DONGLE_TYPE, &temp, long(DEFAULT_DONGLE_TYPE)); + DONGLE_TYPE type = DONGLE_TYPE(temp); + + wxString device; + profile.Read(KEY_DONGLE_DEVICE, &device, DEFAULT_DONGLE_DEVICE); + + wxString address; + profile.Read(KEY_DONGLE_ADDRESS, &address, DEFAULT_DONGLE_ADDRESS); + + unsigned int port; + profile.Read(KEY_DONGLE_PORT, &temp, long(DEFAULT_DONGLE_PORT)); + port = (unsigned int)temp; + + CDongleThread* dongle = NULL; + + switch (type) { + case DT_DVDONGLE: + if (!device.IsEmpty()) + dongle = new CDVDongleThread(new CDVDongleController(device)); + break; + case DT_DV3000: + if (!address.IsEmpty() && port > 0U) + dongle = new CAMBE3000Thread(new CDV3000Controller(address, port)); + break; + default: + delete reader; + delete writer; + ::wxUninitialize(); + ::fprintf(stderr, "dvtool2wav: invalid Dongle type specified\n"); + return 1; + } + + dvtool2wav program(dongle, reader, writer); + + dongle->setDecodeCallback(&program); + dongle->setBleep(false); + + ret = dongle->open(); + if (!ret) { + delete reader; + delete writer; + delete dongle; + ::wxUninitialize(); + ::fprintf(stderr, "dvtool2wav: couldn't find the Dongle on the port specified\n"); + return 1; + } + + program.run(); + + ::wxUninitialize(); + + return 0; +} + +dvtool2wav::dvtool2wav(CDongleThread* dongle, CDVTOOLFileReader* reader, CWAVFileWriter* writer) : +m_dongle(dongle), +m_reader(reader), +m_writer(writer) +{ + wxASSERT(dongle != NULL); + wxASSERT(reader != NULL); + wxASSERT(writer != NULL); +} + +dvtool2wav::~dvtool2wav() +{ +} + +void dvtool2wav::decodeCallback(const wxFloat32* audio, unsigned int length) +{ + if (m_writer == NULL) + return; + + m_writer->write(audio, length); +} + +void dvtool2wav::run() +{ + DVTFR_TYPE type; + unsigned char header[RADIO_HEADER_LENGTH_BYTES]; + unsigned int n = m_reader->read(header, RADIO_HEADER_LENGTH_BYTES, type); + if (n == 0U) { + // Release the files + m_reader->close(); + m_writer->close(); + delete m_reader; + delete m_writer; + delete m_dongle; + return; + } + + m_dongle->Create(); + m_dongle->SetPriority(100U); + m_dongle->Run(); + + m_dongle->setDecode(); + + for (;;) { + unsigned int space = m_dongle->getDecodeSpace(); + if (space >= VOICE_FRAME_LENGTH_BYTES) { + DVTFR_TYPE type; + unsigned char frame[RADIO_HEADER_LENGTH_BYTES]; + unsigned int n = m_reader->read(frame, RADIO_HEADER_LENGTH_BYTES, type); + + // End of file? + if (n == 0U || type != DVTFR_DETAIL) + break; + + if (n != DV_FRAME_LENGTH_BYTES && n != VOICE_FRAME_LENGTH_BYTES) + break; + + m_dongle->writeDecode(frame, VOICE_FRAME_LENGTH_BYTES); + } + + ::wxMilliSleep(FRAME_TIME_MS); + } + + ::wxMilliSleep(FRAME_TIME_MS * 30U); + + // Release the input file + m_reader->close(); + delete m_reader; + m_reader = NULL; + + // Release the output file + m_writer->close(); + delete m_writer; + m_writer = NULL; + + m_dongle->setIdle(); + m_dongle->kill(); +} diff --git a/AMBETools/dvtool2wav/dvtool2wav.h b/AMBETools/dvtool2wav/dvtool2wav.h new file mode 100755 index 0000000..96685d1 --- /dev/null +++ b/AMBETools/dvtool2wav/dvtool2wav.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if !defined(DVTOOL2WAV_H) +#define DVTOOL2WAV + +#include "DVTOOLFileReader.h" +#include "DecodeCallback.h" +#include "WAVFileWriter.h" +#include "DongleThread.h" + +#include + +class dvtool2wav : public IDecodeCallback { +public: + dvtool2wav(CDongleThread* dongle, CDVTOOLFileReader* reader, CWAVFileWriter* writer); + virtual ~dvtool2wav(); + + virtual void decodeCallback(const wxFloat32* audio, unsigned int length); + + virtual void run(); + +private: + CDongleThread* m_dongle; + CDVTOOLFileReader* m_reader; + CWAVFileWriter* m_writer; +}; + +#endif diff --git a/AMBETools/dvtool2wav/dvtool2wav.o b/AMBETools/dvtool2wav/dvtool2wav.o new file mode 100644 index 0000000..7562b42 Binary files /dev/null and b/AMBETools/dvtool2wav/dvtool2wav.o differ diff --git a/AMBETools/dvtool2wav/dvtool2wav.vcproj b/AMBETools/dvtool2wav/dvtool2wav.vcproj new file mode 100755 index 0000000..4ede70c --- /dev/null +++ b/AMBETools/dvtool2wav/dvtool2wav.vcproj @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AMBETools/package.mk b/AMBETools/package.mk new file mode 100755 index 0000000..e69de29 diff --git a/AMBETools/package_default.mk b/AMBETools/package_default.mk new file mode 100755 index 0000000..2872aed --- /dev/null +++ b/AMBETools/package_default.mk @@ -0,0 +1,2 @@ +# Copy to package.mk to create no package + diff --git a/AMBETools/settings.mk b/AMBETools/settings.mk new file mode 100755 index 0000000..2e86d0f --- /dev/null +++ b/AMBETools/settings.mk @@ -0,0 +1,24 @@ +# Makefile-include +# +# Build the Digital Voice software on Linux with default settings (x86) +# + +export BINDIR := "/usr/local/bin" +export DATADIR := "/usr/local/etc" +export DESKTOPDIR := "/usr/local/share/applications" +export PNGDIR := "/usr/local/share/pixmaps" + +# +# Change your architecture here +# +# export ARCH := pentium +export ARCH := x86-64 + + +export CC := $(shell wx-config --cxx) + +export LIBS := -lportaudio -lusb-1.0 $(shell wx-config --libs adv,core) + +export CFLAGS := -g -O2 -Wall -Wno-non-virtual-dtor -Wno-strict-aliasing -march=$(ARCH) -DDATA_DIR='$(DATADIR)' -DBIN_DIR='$(BINDIR)' $(shell wx-config --cxxflags) + +export LDFLAGS := -g diff --git a/AMBETools/settings_debian_amd64.mk b/AMBETools/settings_debian_amd64.mk new file mode 100755 index 0000000..effc63a --- /dev/null +++ b/AMBETools/settings_debian_amd64.mk @@ -0,0 +1,12 @@ +# Makefile-include +# +# Build the ircDDB Gateway software on Debian Linux with default settings (amd64) +# Hans-J. Barthen, DL5DI, 2013-01-20 +# Rename this file to settings.mk before you compile the source for the Debian amd64 platform +# + export DATADIR := "/usr/local/etc" + export BINDIR := $(DESTDIR)/usr/local/bin + export CC := $(shell wx-config --cxx) + export LDFLAGS := -g + export CFLAGS := -g -O2 -m64 -Wall -Wno-non-virtual-dtor -Wno-strict-aliasing -DDATA_DIR='$(DATADIR)' -DBIN_DIR='$(BINDIR)' $(shell wx-config --cxxflags) + export LIBS := -lportaudio -lusb-1.0 $(shell wx-config --libs adv,core) diff --git a/AMBETools/settings_debian_arm.mk b/AMBETools/settings_debian_arm.mk new file mode 100755 index 0000000..3630923 --- /dev/null +++ b/AMBETools/settings_debian_arm.mk @@ -0,0 +1,12 @@ +# Makefile-include +# +# Special settings for Emdebian Compile for ARM processor, John Hays, June 2012 +# modified by Hans-J. Barthen, DL5DI, 2012-09-07 +# Rename this file to settings.mk before you compile the source for the Debian armel platform +# + export DATADIR := "/usr/local/etc" + export BINDIR := "$(DESTDIR)/usr/local/bin" + export CC := arm-linux-gnueabi-g++ + export LDFLAGS := -g -L/usr/arm-linux-gnueabi/lib + export CFLAGS := -g -O2 -Wall -Wno-non-virtual-dtor -Wno-strict-aliasing -Wno-psabi -DDATA_DIR='$(DATADIR)' -DBIN_DIR='$(BINDIR)' -I/usr/arm-linux-gnueabi/include -I/usr/arm-linux-gnueabi/lib/wx/include/gtk2-unicode-release-2.8 -I/usr/arm-linux-gnueabi/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -pthread + export LIBS := -lportaudio -lusb-1.0 $(shell wx-config --libs adv,core) diff --git a/AMBETools/settings_debian_armel.mk b/AMBETools/settings_debian_armel.mk new file mode 100755 index 0000000..dcb4cfc --- /dev/null +++ b/AMBETools/settings_debian_armel.mk @@ -0,0 +1,13 @@ +# Makefile-include +# +# Special settings for Emdebian Compile for ARM processor, John Hays, June 2012 +# modified by Hans-J. Barthen, DL5DI, 2012-09-07 +# Rename this file to settings.mk before you compile the source for the Debian armel platform +# + export DEB_HOST_GNU_TYPE := arm-linux-gnueabi + export DATADIR := "/usr/local/etc" + export BINDIR := "$(DESTDIR)/usr/local/bin" + export CC := $(DEB_HOST_GNU_TYPE)-g++ + export LDFLAGS := -g -Xlinker -rpath-link /lib/$(DEB_HOST_GNU_TYPE) -Xlinker -rpath-link /usr/lib/$(DEB_HOST_GNU_TYPE) + export CFLAGS := -g -O2 -Wall -Wno-non-virtual-dtor -Wno-strict-aliasing -Wno-psabi -DDATA_DIR='$(DATADIR)' -DBIN_DIR='$(BINDIR)' -I/usr/include/$(DEB_HOST_GNU_TYPE) -I/usr/$(DEB_HOST_GNU_TYPE)/include -I/usr/include -I/usr/lib/$(DEB_HOST_GNU_TYPE)/wx/include/gtk2-unicode-release-2.8 -I/usr/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -pthread + export LIBS := -L/usr/lib/$(DEB_HOST_GNU_TYPE) -L/usr/$(DEB_HOST_GNU_TYPE)/lib -lportaudio -lusb-1.0 -lwx_gtk2u_adv-2.8 -lwx_gtk2u_core-2.8 -lwx_baseu-2.8 -pthread diff --git a/AMBETools/settings_debian_armhf.mk b/AMBETools/settings_debian_armhf.mk new file mode 100755 index 0000000..992cb74 --- /dev/null +++ b/AMBETools/settings_debian_armhf.mk @@ -0,0 +1,13 @@ +# Makefile-include +# +# Special settings for Emdebian Compile for ARM processor, John Hays, June 2012 +# modified by Hans-J. Barthen, DL5DI, 2012-09-07 +# Rename this file to settings.mk before you compile the source for the Debian armel platform +# + export DEB_HOST_GNU_TYPE := arm-linux-gnueabihf + export DATADIR := "/usr/local/etc" + export BINDIR := "$(DESTDIR)/usr/local/bin" + export CC := $(DEB_HOST_GNU_TYPE)-g++ + export LDFLAGS := -g -Xlinker -rpath-link /lib/$(DEB_HOST_GNU_TYPE) -Xlinker -rpath-link /usr/lib/$(DEB_HOST_GNU_TYPE) + export CFLAGS := -g -O2 -Wall -Wno-non-virtual-dtor -Wno-strict-aliasing -Wno-psabi -DDATA_DIR='$(DATADIR)' -DBIN_DIR='$(BINDIR)' -I/usr/include/$(DEB_HOST_GNU_TYPE) -I/usr/$(DEB_HOST_GNU_TYPE)/include -I/usr/include -I/usr/$(DEB_HOST_GNU_TYPE)/lib/wx/include/gtk2-unicode-release-2.8 -I/usr/$(DEB_HOST_GNU_TYPE)/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -pthread + export LIBS := -lportaudio -lusb-1.0 -L/usr/lib/$(DEB_HOST_GNU_TYPE) -L/usr/$(DEB_HOST_GNU_TYPE)/lib -lwx_gtk2u_adv-2.8 -lwx_gtk2u_core-2.8 -lwx_baseu-2.8 -pthread diff --git a/AMBETools/settings_debian_i386.mk b/AMBETools/settings_debian_i386.mk new file mode 100755 index 0000000..cce737a --- /dev/null +++ b/AMBETools/settings_debian_i386.mk @@ -0,0 +1,12 @@ +# Makefile-include +# +# Build the ircDDB Gateway software on Debian Linux with default settings (x86) +# Hans-J. Barthen, DL5DI, 2012-09-08 +# Rename this file to settings.mk before you compile the source for the Debian i386 platform +# + export DATADIR := "/usr/local/etc" + export BINDIR := $(DESTDIR)/usr/bin + export CC := $(shell wx-config --cxx) + export LDFLAGS := -g + export CFLAGS := -g -O2 -m32 -Wall -Wno-non-virtual-dtor -Wno-strict-aliasing -DDATA_DIR='$(DATADIR)' -DBIN_DIR='$(BINDIR)' $(shell wx-config --cxxflags) + export LIBS := -lportaudio -lusb-1.0 $(shell wx-config --libs adv,core) diff --git a/AMBETools/settings_default.mk b/AMBETools/settings_default.mk new file mode 100755 index 0000000..1b6b260 --- /dev/null +++ b/AMBETools/settings_default.mk @@ -0,0 +1,24 @@ +# Makefile-include +# +# Build the Digital Voice software on Linux with default settings (x86) +# + +export BINDIR := "/usr/local/bin" +export DATADIR := "/usr/local/etc" +export DESKTOPDIR := "/usr/local/share/applications" +export PNGDIR := "/usr/local/share/pixmaps" + +# +# Change your architecture here +# +# export ARCH := pentium +export ARCH := x86-64 + + +export CC := $(shell wx-config --cxx) + +export LIBS := -lportaudio -lusb $(shell wx-config --libs adv,core) + +export CFLAGS := -g -O2 -Wall -Wno-non-virtual-dtor -Wno-strict-aliasing -march=$(ARCH) -DDATA_DIR='$(DATADIR)' -DBIN_DIR='$(BINDIR)' $(shell wx-config --cxxflags) + +export LDFLAGS := -g diff --git a/AMBETools/settings_raspbian_armhf.mk b/AMBETools/settings_raspbian_armhf.mk new file mode 100755 index 0000000..9661e4b --- /dev/null +++ b/AMBETools/settings_raspbian_armhf.mk @@ -0,0 +1,12 @@ +# Makefile-include +# +# Settings for Raspbian Wheezy compile in qemu-debootstrap environment +# Hans-J. Barthen, DL5DI 2013-01-21 +# Rename this file to settings.mk before you compile the source for the Raspbian platform +# + export DATADIR := "/usr/local/etc" + export BINDIR := "$(DESTDIR)/usr/bin" + export CC := $(shell wx-config --cxx) + export LDFLAGS := -g + export CFLAGS := -g -O2 -march=armv6 -mfpu=vfp -mfloat-abi=hard -Wall -Wno-non-virtual-dtor -Wno-strict-aliasing -Wno-psabi -DDATA_DIR='$(DATADIR)' -DBIN_DIR='$(BINDIR)' -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -pthread $(shell wx-config --cxxflags) + export LIBS := -lportaudio -lusb-1.0 $(shell wx-config --libs adv,core) diff --git a/AMBETools/settings_rpi.mk b/AMBETools/settings_rpi.mk new file mode 100755 index 0000000..420fa97 --- /dev/null +++ b/AMBETools/settings_rpi.mk @@ -0,0 +1,11 @@ +# Makefile-include +# +# Special settings for Emdebian Compile for ARM processor, John Hays, June 2012 +# Rename this file to settings.mk before you compile the source for the RaspberryPi platform +# + export DATADIR := "/usr/local/etc" + export BINDIR := "$(DESTDIR)/usr/local/bin" + export CC := arm-linux-gnueabi-g++ + export LDFLAGS := -g -L/usr/arm-linux-gnueabi/lib + export CFLAGS := -g -O2 -Wall -Wno-non-virtual-dtor -Wno-strict-aliasing -Wno-psabi -DDATA_DIR='$(DATADIR)' -DBIN_DIR='$(BINDIR)' -I/usr/arm-linux-gnueabi/include -I/usr/arm-linux-gnueabi/lib/wx/include/gtk2-unicode-release-2.8 -I/usr/arm-linux-gnueabi/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -pthread + export LIBS := -lportaudio -lusb-1.0 $(shell wx-config --libs adv,core) diff --git a/AMBETools/wav2ambe/Makefile b/AMBETools/wav2ambe/Makefile new file mode 100755 index 0000000..ad6d7f9 --- /dev/null +++ b/AMBETools/wav2ambe/Makefile @@ -0,0 +1,19 @@ +all: wav2ambe + +CFLAGS := -I../Common $(CFLAGS) + +OBJS := wav2ambe.o + +wav2ambe: $(OBJS) + $(CC) $(LDFLAGS) -o wav2ambe $(OBJS) ../Common/Common.a $(LIBS) + +wav2ambe.o: wav2ambe.cpp wav2ambe.h ../Common/WAVFileReader.h ../Common/DStarDefines.h ../Common/Version.h ../Common/EncodeCallback.h \ + ../Common/DongleThread.h ../Common/DV3000Controller.h ../Common/DVDongleController.h ../Common/AMBE3000Thread.h ../Common/DVDongleThread.h \ + ../Common/AMBEFileWriter.h ../Common/Version.h + $(CC) $(CFLAGS) -c wav2ambe.cpp + +install: wav2ambe + install -g bin -o root -m 0775 wav2ambe $(BINDIR) + +clean: + rm -f core wav2ambe *.o *~ *.bak diff --git a/AMBETools/wav2ambe/wav2ambe b/AMBETools/wav2ambe/wav2ambe new file mode 100755 index 0000000..a4fa1c9 Binary files /dev/null and b/AMBETools/wav2ambe/wav2ambe differ diff --git a/AMBETools/wav2ambe/wav2ambe.cpp b/AMBETools/wav2ambe/wav2ambe.cpp new file mode 100755 index 0000000..5c698a3 --- /dev/null +++ b/AMBETools/wav2ambe/wav2ambe.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "wav2ambe.h" + +#include "AMBE3000Thread.h" +#include "DVDongleThread.h" +#include "DStarDefines.h" +#include "Version.h" + +#include + +const wxString APPLICATION_NAME = wxT("DVTool Writer"); + +const wxString KEY_DONGLE_TYPE = wxT("/dongleType"); +const wxString KEY_DONGLE_DEVICE = wxT("/dongleDevice"); +const wxString KEY_DONGLE_ADDRESS = wxT("/dongleAddress"); +const wxString KEY_DONGLE_PORT = wxT("/donglePort"); + +const DONGLE_TYPE DEFAULT_DONGLE_TYPE = DT_DVDONGLE; +const wxString DEFAULT_DONGLE_DEVICE = wxEmptyString; +const wxString DEFAULT_DONGLE_ADDRESS = wxEmptyString; +const unsigned int DEFAULT_DONGLE_PORT = 2460L; + +int main(int argc, char** argv) +{ + if (argc < 3) { + ::fprintf(stderr, "Usage: wav2ambe \n"); + return 1; + } + + ::wxInitialize(); + + wxString inFile = wxString(argv[1U], wxConvLocal); + wxString outFile = wxString(argv[2U], wxConvLocal); + + CWAVFileReader* reader = new CWAVFileReader(inFile, DSTAR_RADIO_BLOCK_SIZE); + bool ret = reader->open(); + if (!ret) { + delete reader; + ::wxUninitialize(); + ::fprintf(stderr, "wav2ambe: unable to open the input file - %s\n", argv[1U]); + return 1; + } + + unsigned int sampleRate = reader->getSampleRate(); + if (sampleRate != 48000U) { + delete reader; + ::wxUninitialize(); + ::fprintf(stderr, "wav2ambe: invalid sample rate in the input file - %s\n", argv[1U]); + return 1; + } + + unsigned int channels = reader->getChannels(); + if (channels != 1U) { + delete reader; + ::wxUninitialize(); + ::fprintf(stderr, "wav2ambe: invalid number of channels in the input file - %s\n", argv[1U]); + return 1; + } + + CAMBEFileWriter* writer = new CAMBEFileWriter(outFile); + ret = writer->open(); + if (!ret) { + delete reader; + delete writer; + ::wxUninitialize(); + ::fprintf(stderr, "wav2ambe: unable to open the output file - %s\n", argv[2U]); + return 1; + } + +#if defined(__WXMSW__) + wxRegConfig profile(APPLICATION_NAME, VENDOR_NAME, wxEmptyString, wxEmptyString, wxCONFIG_USE_LOCAL_FILE); +#else + wxFileConfig profile(APPLICATION_NAME, VENDOR_NAME, wxEmptyString, wxEmptyString, wxCONFIG_USE_LOCAL_FILE); +#endif + + long temp; + profile.Read(KEY_DONGLE_TYPE, &temp, long(DEFAULT_DONGLE_TYPE)); + DONGLE_TYPE type = DONGLE_TYPE(temp); + + wxString device; + profile.Read(KEY_DONGLE_DEVICE, &device, DEFAULT_DONGLE_DEVICE); + + wxString address; + profile.Read(KEY_DONGLE_ADDRESS, &address, DEFAULT_DONGLE_ADDRESS); + + unsigned int port; + profile.Read(KEY_DONGLE_PORT, &temp, long(DEFAULT_DONGLE_PORT)); + port = (unsigned int)temp; + + CDongleThread* dongle = NULL; + + switch (type) { + case DT_DVDONGLE: + if (!device.IsEmpty()) + dongle = new CDVDongleThread(new CDVDongleController(device)); + break; + case DT_DV3000: + if (!address.IsEmpty() && port > 0U) + dongle = new CAMBE3000Thread(new CDV3000Controller(address, port)); + break; + default: + delete reader; + delete writer; + ::wxUninitialize(); + ::fprintf(stderr, "wav2ambe: invalid Dongle type specified\n"); + return 1; + } + + wav2ambe program(dongle, reader, writer); + + dongle->setEncodeCallback(&program); + dongle->setBleep(false); + + ret = dongle->open(); + if (!ret) { + delete reader; + delete writer; + delete dongle; + ::wxUninitialize(); + ::fprintf(stderr, "wav2ambe: couldn't find the Dongle on the port specified\n"); + return 1; + } + + program.run(); + + ::wxUninitialize(); + + return 0; +} + +wav2ambe::wav2ambe(CDongleThread* dongle, CWAVFileReader* reader, CAMBEFileWriter* writer) : +m_dongle(dongle), +m_reader(reader), +m_writer(writer) +{ + wxASSERT(dongle != NULL); + wxASSERT(reader != NULL); + wxASSERT(writer != NULL); +} + +wav2ambe::~wav2ambe() +{ +} + +void wav2ambe::encodeCallback(const unsigned char* ambe, unsigned int length) +{ + if (m_writer == NULL) + return; + + m_writer->writeFrame(ambe, length); +} + +void wav2ambe::run() +{ + m_dongle->Create(); + m_dongle->SetPriority(100U); + m_dongle->Run(); + + m_dongle->setEncode(); + + for (;;) { + unsigned int space = m_dongle->getEncodeSpace(); + if (space >= DSTAR_RADIO_BLOCK_SIZE) { + wxFloat32 audio[DSTAR_RADIO_BLOCK_SIZE]; + ::memset(audio, 0x00U, DSTAR_RADIO_BLOCK_SIZE * sizeof(wxFloat32)); + unsigned int n = m_reader->read(audio, DSTAR_RADIO_BLOCK_SIZE); + + m_dongle->writeEncode(audio, DSTAR_RADIO_BLOCK_SIZE); + + // End of file? + if (n != DSTAR_RADIO_BLOCK_SIZE) + break; + } + + ::wxMilliSleep(FRAME_TIME_MS); + } + + ::wxMilliSleep(FRAME_TIME_MS * 30U); + + // Release the input file + m_reader->close(); + delete m_reader; + m_reader = NULL; + + // Release the output file + m_writer->close(); + delete m_writer; + m_writer = NULL; + + m_dongle->setIdle(); + m_dongle->kill(); +} diff --git a/AMBETools/wav2ambe/wav2ambe.h b/AMBETools/wav2ambe/wav2ambe.h new file mode 100755 index 0000000..1713538 --- /dev/null +++ b/AMBETools/wav2ambe/wav2ambe.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if !defined(WAV2AMBE_H) +#define WAV2AMBE + +#include "EncodeCallback.h" +#include "AMBEFileWriter.h" +#include "WAVFileReader.h" +#include "DongleThread.h" + +#include + +class wav2ambe : public IEncodeCallback { +public: + wav2ambe(CDongleThread* dongle, CWAVFileReader* reader, CAMBEFileWriter* writer); + virtual ~wav2ambe(); + + virtual void encodeCallback(const unsigned char* ambe, unsigned int length); + + virtual void run(); + +private: + CDongleThread* m_dongle; + CWAVFileReader* m_reader; + CAMBEFileWriter* m_writer; +}; + +#endif diff --git a/AMBETools/wav2ambe/wav2ambe.o b/AMBETools/wav2ambe/wav2ambe.o new file mode 100644 index 0000000..3339863 Binary files /dev/null and b/AMBETools/wav2ambe/wav2ambe.o differ diff --git a/AMBETools/wav2ambe/wav2ambe.vcproj b/AMBETools/wav2ambe/wav2ambe.vcproj new file mode 100755 index 0000000..3c613ce --- /dev/null +++ b/AMBETools/wav2ambe/wav2ambe.vcproj @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AMBETools/wav2dvtool/Makefile b/AMBETools/wav2dvtool/Makefile new file mode 100755 index 0000000..5430004 --- /dev/null +++ b/AMBETools/wav2dvtool/Makefile @@ -0,0 +1,19 @@ +all: wav2dvtool + +CFLAGS := -I../Common $(CFLAGS) + +OBJS := wav2dvtool.o + +wav2dvtool: $(OBJS) + $(CC) $(LDFLAGS) -o wav2dvtool $(OBJS) ../Common/Common.a $(LIBS) + +wav2dvtool.o: wav2dvtool.cpp wav2dvtool.h ../Common/WAVFileReader.h ../Common/DStarDefines.h ../Common/HeaderData.h ../Common/Version.h ../Common/EncodeCallback.h \ + ../Common/DongleThread.h ../Common/DV3000Controller.h ../Common/DVDongleController.h ../Common/AMBE3000Thread.h ../Common/DVDongleThread.h \ + ../Common/DVTOOLFileWriter.h ../Common/SlowDataEncoder.h ../Common/Version.h + $(CC) $(CFLAGS) -c wav2dvtool.cpp + +install: wav2dvtool + install -g bin -o root -m 0775 wav2dvtool $(BINDIR) + +clean: + rm -f core wav2dvtool *.o *~ *.bak diff --git a/AMBETools/wav2dvtool/wav2dvtool b/AMBETools/wav2dvtool/wav2dvtool new file mode 100755 index 0000000..9fafff4 Binary files /dev/null and b/AMBETools/wav2dvtool/wav2dvtool differ diff --git a/AMBETools/wav2dvtool/wav2dvtool.cpp b/AMBETools/wav2dvtool/wav2dvtool.cpp new file mode 100755 index 0000000..00e6842 --- /dev/null +++ b/AMBETools/wav2dvtool/wav2dvtool.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "wav2dvtool.h" + +#include "AMBE3000Thread.h" +#include "DVDongleThread.h" +#include "DStarDefines.h" +#include "HeaderData.h" +#include "Version.h" + +#include + +const wxString APPLICATION_NAME = wxT("DVTool Writer"); + +const wxString KEY_CALLSIGN1 = wxT("/callsign1"); +const wxString KEY_CALLSIGN2 = wxT("/callsign2"); +const wxString KEY_DONGLE_TYPE = wxT("/dongleType"); +const wxString KEY_DONGLE_DEVICE = wxT("/dongleDevice"); +const wxString KEY_DONGLE_ADDRESS = wxT("/dongleAddress"); +const wxString KEY_DONGLE_PORT = wxT("/donglePort"); + +const wxString DEFAULT_CALLSIGN1 = wxEmptyString; +const wxString DEFAULT_CALLSIGN2 = wxEmptyString; +const DONGLE_TYPE DEFAULT_DONGLE_TYPE = DT_DVDONGLE; +const wxString DEFAULT_DONGLE_DEVICE = wxEmptyString; +const wxString DEFAULT_DONGLE_ADDRESS = wxEmptyString; +const unsigned int DEFAULT_DONGLE_PORT = 2460L; + +int main(int argc, char** argv) +{ + if (argc < 7) { + ::fprintf(stderr, "Usage: wav2dvtool \n"); + return 1; + } + + ::wxInitialize(); + + wxString inFile = wxString(argv[1U], wxConvLocal); + wxString your = wxString(argv[2U], wxConvLocal); + wxString rpt1 = wxString(argv[3U], wxConvLocal); + wxString rpt2 = wxString(argv[4U], wxConvLocal); + wxString message = wxString(argv[5U], wxConvLocal); + wxString outFile = wxString(argv[6U], wxConvLocal); + + CWAVFileReader* reader = new CWAVFileReader(inFile, DSTAR_RADIO_BLOCK_SIZE); + bool ret = reader->open(); + if (!ret) { + delete reader; + ::wxUninitialize(); + ::fprintf(stderr, "wav2dvtool: unable to open the input file - %s\n", argv[1U]); + return 1; + } + + unsigned int sampleRate = reader->getSampleRate(); + if (sampleRate != 48000U) { + delete reader; + ::wxUninitialize(); + ::fprintf(stderr, "wav2dvtool: invalid sample rate in the input file - %s\n", argv[1U]); + return 1; + } + + unsigned int channels = reader->getChannels(); + if (channels != 1U) { + delete reader; + ::wxUninitialize(); + ::fprintf(stderr, "wav2dvtool: invalid number of channels in the input file - %s\n", argv[1U]); + return 1; + } + + CDVTOOLFileWriter* writer = new CDVTOOLFileWriter(outFile); + ret = writer->open(); + if (!ret) { + delete reader; + delete writer; + ::wxUninitialize(); + ::fprintf(stderr, "wav2dvtool: unable to open the output file - %s\n", argv[6U]); + return 1; + } + +#if defined(__WXMSW__) + wxRegConfig profile(APPLICATION_NAME, VENDOR_NAME, wxEmptyString, wxEmptyString, wxCONFIG_USE_LOCAL_FILE); +#else + wxFileConfig profile(APPLICATION_NAME, VENDOR_NAME, wxEmptyString, wxEmptyString, wxCONFIG_USE_LOCAL_FILE); +#endif + + wxString callsign1; + profile.Read(KEY_CALLSIGN1, &callsign1, DEFAULT_CALLSIGN1); + + wxString callsign2; + profile.Read(KEY_CALLSIGN2, &callsign2, DEFAULT_CALLSIGN2); + + long temp; + profile.Read(KEY_DONGLE_TYPE, &temp, long(DEFAULT_DONGLE_TYPE)); + DONGLE_TYPE type = DONGLE_TYPE(temp); + + wxString device; + profile.Read(KEY_DONGLE_DEVICE, &device, DEFAULT_DONGLE_DEVICE); + + wxString address; + profile.Read(KEY_DONGLE_ADDRESS, &address, DEFAULT_DONGLE_ADDRESS); + + unsigned int port; + profile.Read(KEY_DONGLE_PORT, &temp, long(DEFAULT_DONGLE_PORT)); + port = (unsigned int)temp; + + CDongleThread* dongle = NULL; + + switch (type) { + case DT_DVDONGLE: + if (!device.IsEmpty()) + dongle = new CDVDongleThread(new CDVDongleController(device)); + break; + case DT_DV3000: + if (!address.IsEmpty() && port > 0U) + dongle = new CAMBE3000Thread(new CDV3000Controller(address, port)); + break; + default: + delete reader; + delete writer; + ::wxUninitialize(); + ::fprintf(stderr, "wav2dvtool: invalid Dongle type specified\n"); + return 1; + } + + CHeaderData header(callsign1, callsign2, your, rpt1, rpt2); + + CSlowDataEncoder* encoder = new CSlowDataEncoder; + encoder->setHeaderData(header); + encoder->setMessageData(message); + + writer->writeHeader(header); + + wav2dvtool program(dongle, reader, writer, encoder); + + dongle->setEncodeCallback(&program); + dongle->setBleep(false); + + ret = dongle->open(); + if (!ret) { + delete reader; + delete writer; + delete dongle; + delete encoder; + ::wxUninitialize(); + ::fprintf(stderr, "wav2dvtool: couldn't find the Dongle on the port specified\n"); + return 1; + } + + program.run(); + + ::wxUninitialize(); + + return 0; +} + +wav2dvtool::wav2dvtool(CDongleThread* dongle, CWAVFileReader* reader, CDVTOOLFileWriter* writer, CSlowDataEncoder* encoder) : +m_dongle(dongle), +m_reader(reader), +m_writer(writer), +m_encoder(encoder), +m_count(0U) +{ + wxASSERT(dongle != NULL); + wxASSERT(reader != NULL); + wxASSERT(writer != NULL); + wxASSERT(encoder != NULL); +} + +wav2dvtool::~wav2dvtool() +{ +} + +void wav2dvtool::encodeCallback(const unsigned char* ambe, unsigned int length) +{ + if (m_writer == NULL) + return; + + unsigned char frame[DV_FRAME_LENGTH_BYTES]; + + ::memcpy(frame, ambe, VOICE_FRAME_LENGTH_BYTES); + + if (m_count == 0U) + ::memcpy(frame + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES); + else + m_encoder->getData(frame + VOICE_FRAME_LENGTH_BYTES); + + m_count++; + if (m_count >= 21U) + m_count = 0U; + + m_writer->writeFrame(frame, DV_FRAME_LENGTH_BYTES); +} + +void wav2dvtool::run() +{ + m_count = 0U; + + m_dongle->Create(); + m_dongle->SetPriority(100U); + m_dongle->Run(); + + m_dongle->setEncode(); + + for (;;) { + unsigned int space = m_dongle->getEncodeSpace(); + if (space >= DSTAR_RADIO_BLOCK_SIZE) { + wxFloat32 audio[DSTAR_RADIO_BLOCK_SIZE]; + ::memset(audio, 0x00U, DSTAR_RADIO_BLOCK_SIZE * sizeof(wxFloat32)); + unsigned int n = m_reader->read(audio, DSTAR_RADIO_BLOCK_SIZE); + + m_dongle->writeEncode(audio, DSTAR_RADIO_BLOCK_SIZE); + + // End of file? + if (n != DSTAR_RADIO_BLOCK_SIZE) + break; + } + + ::wxMilliSleep(FRAME_TIME_MS); + } + + ::wxMilliSleep(FRAME_TIME_MS * 30U); + + // Release the input file + m_reader->close(); + delete m_reader; + m_reader = NULL; + + // Release the output file + m_writer->close(); + delete m_writer; + m_writer = NULL; + + delete m_encoder; + m_encoder = NULL; + + m_dongle->setIdle(); + m_dongle->kill(); +} diff --git a/AMBETools/wav2dvtool/wav2dvtool.h b/AMBETools/wav2dvtool/wav2dvtool.h new file mode 100755 index 0000000..e65fc3b --- /dev/null +++ b/AMBETools/wav2dvtool/wav2dvtool.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 by Jonathan Naylor G4KLX + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if !defined(WAV2DVTOOL_H) +#define WAV2DVTOOL + +#include "DVTOOLFileWriter.h" +#include "SlowDataEncoder.h" +#include "EncodeCallback.h" +#include "WAVFileReader.h" +#include "DongleThread.h" + +#include + +class wav2dvtool : public IEncodeCallback { +public: + wav2dvtool(CDongleThread* dongle, CWAVFileReader* reader, CDVTOOLFileWriter* writer, CSlowDataEncoder* encoder); + virtual ~wav2dvtool(); + + virtual void encodeCallback(const unsigned char* ambe, unsigned int length); + + virtual void run(); + +private: + CDongleThread* m_dongle; + CWAVFileReader* m_reader; + CDVTOOLFileWriter* m_writer; + CSlowDataEncoder* m_encoder; + unsigned int m_count; +}; + +#endif diff --git a/AMBETools/wav2dvtool/wav2dvtool.o b/AMBETools/wav2dvtool/wav2dvtool.o new file mode 100644 index 0000000..281fd04 Binary files /dev/null and b/AMBETools/wav2dvtool/wav2dvtool.o differ diff --git a/AMBETools/wav2dvtool/wav2dvtool.vcproj b/AMBETools/wav2dvtool/wav2dvtool.vcproj new file mode 100755 index 0000000..65a609c --- /dev/null +++ b/AMBETools/wav2dvtool/wav2dvtool.vcproj @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README b/README new file mode 100755 index 0000000..0c5e32f --- /dev/null +++ b/README @@ -0,0 +1,67 @@ +# playnews v0.8 - WA3DSP 11/2015 +# +# Script to download ARRL News or ARN and divide into 2.5 minute segments with breaks. +# Includes voice messages before play, at breaks, and after play. +# This script can be configured for global playback! +# DO NOT run this on a multi-node connected circuit without consideration. +# Change MODE to localplay for strictly local node play. +# +# This code is written to work on the hamvoip.org BBB/RPi2 Allstar releases +# All required packages are pre-installed on those systems. +# +# For proper operation holdofftelem in rpt.conf should either not be defined or +# defined as =0 This stops keyups from delaying the news during its playing +# +# You can run this script from a cron job or from the command line at least +# 15 minutes before the defined run time (TIME value) but it can be scheduled +# anytime within 24 hours prior to the run time. +# +# cron example - +# +# Prime news for play every Tuesday at 8:30PM - actual playtime set by defined +# comand line TIME parameter. If Playtime is 9PM (2100) +# This would send pre warnings at 8:50 and 8:55 PM. +# +# Start a cron job every tuesday at 8:30 PM to run at 9 PM the same day +# and play ARRL news on node 40000, globally +# +# 30 20 * * 2 /etc/asterisk/playnews ARRL 21:00 40000 G &> /dev/null 2>&1 +# +# Play ARN news on Thursday at 7PM on node 40000, Start playnews at 6 PM, Play locally +# +# 00 18 * * 4 /etc/asterisk/playnews ARN 19:00 40000 L &> /dev/null 2>&1 + +# The audio files ARRLstart5, ARRLstart10, ARRLstart, ARRLcontinue, ARRLstop +# and ARNstart, ARNstart10, ARNstart, ARNcontinue, ARNstop +# are supplied but could be customized for your needs. The audio +# files must be in the directory defined by VOICEDIR +# +# ARRLstart10 or ARNstart10 - voice message at ten minutes before start +# ARRLstart5 or ARNstart5 - voice message at five minutes before start +# ARRLstart or ARNstart - voice message at start of play +# ARRLcontinue or ARNcontinue - voice message at breaks +# ARRLstop or ARNstop - voice message at end of play +# +# v0.8 update +# +# - added check for downloaded MP3 filesize. Playnews will not +# play if size is less than 100K. On holidays ARRL only has +# small html file that gets downloaded. +# +# v0.7 updates +# +# - Added TMPDIR user settable variable +# +# v0.6 updates +# - Now requires that all parameters be entered +# except mode which defualts to global +# - More parameter checking added +# - Time can be set to "NOW" for immediate start +# +# Command line format - playnews ARRL|ARN 21:00|NOW 40000 L|G +# Options are ARRL or ARN news, specific 24 hour time or "NOW" +# and local "L" or Global "G" play modes. +# +# DO NOT use the the "NOW" time parameter in a cron !!! + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/SendMail/SendMail-2.09.zip b/SendMail/SendMail-2.09.zip new file mode 100755 index 0000000..969a834 Binary files /dev/null and b/SendMail/SendMail-2.09.zip differ diff --git a/SendMail/SendMail.cfg b/SendMail/SendMail.cfg new file mode 100755 index 0000000..a4a1fce --- /dev/null +++ b/SendMail/SendMail.cfg @@ -0,0 +1,21 @@ +################################################################### +## Configuration Items +# $Id: SendMail.cfg 74 2011-04-20 19:55:19Z $ + +# Set if you want debugging +debug=OFF # use 'ON' for debugging, 'OFF' for no debugging + +# smtp server information, port may be different. +smtp_server=mail.isp.org # your isp smtp server +smtp_port=2525 # common ports, 25, 2525, check w/isp + +# if smtp server requires authentication, here is the account/password variables +AuthReq=YES # 'YES' or 'NO' here +AuthLogin=test@myisp.org # not used, if $AuthReq='NO' +AuthPass=p@assword + +# Sender (From: ) +Sender=chris@myisp.org # Sender defined in email. Some smtp + # servers expect a valid name found + # on account. +############## End of configuration ####################### diff --git a/SendMail/SendMail.cfg.RPMNEW b/SendMail/SendMail.cfg.RPMNEW new file mode 100755 index 0000000..a4a1fce --- /dev/null +++ b/SendMail/SendMail.cfg.RPMNEW @@ -0,0 +1,21 @@ +################################################################### +## Configuration Items +# $Id: SendMail.cfg 74 2011-04-20 19:55:19Z $ + +# Set if you want debugging +debug=OFF # use 'ON' for debugging, 'OFF' for no debugging + +# smtp server information, port may be different. +smtp_server=mail.isp.org # your isp smtp server +smtp_port=2525 # common ports, 25, 2525, check w/isp + +# if smtp server requires authentication, here is the account/password variables +AuthReq=YES # 'YES' or 'NO' here +AuthLogin=test@myisp.org # not used, if $AuthReq='NO' +AuthPass=p@assword + +# Sender (From: ) +Sender=chris@myisp.org # Sender defined in email. Some smtp + # servers expect a valid name found + # on account. +############## End of configuration ####################### diff --git a/SendMail/SendMail.pl b/SendMail/SendMail.pl new file mode 100755 index 0000000..3bb6512 --- /dev/null +++ b/SendMail/SendMail.pl @@ -0,0 +1,169 @@ +#!/usr/bin/perl +# +# SendMail.pl -- This is a simple SendMail.pm module +# to send a mail. +# $Id: SendMail.pl 74 2011-04-20 19:55:19Z $ + +use warnings; +use strict; +use SendMail 2.09; + +# config stuff +my $value; +my $debug; +my $smtp_server; +my $smtp_port; +my $AuthReq; +my $AuthLogin; +my $AuthPass; +my $Sender; + +# main +my @body_data = ; +my $numArgs = $#ARGV + 1; +my $EAddr; +my $SubJect; +my $sm; +my $argnum; + +# Read Configuation File +open(CFG, "/home/irlp/custom/SendMail/SendMail.cfg") || die("Could not open file!"); +while () { + s/#.*//; # ignore comments by erasing them + next if /^(\s)*$/; # skip blank lines + chomp; + next unless my($key,$value) = split /=/; + # s/^"//, s/"$// for $key, $value; + s/^"//,s/"$// for $key, $value; + + #remove whitespaces "value=ON " + $value =~ s/(^\s+|\s+$)//g; + + # simple parse + if ($key eq 'debug') { + $debug=$value; + } elsif ($key eq 'smtp_server') { + $smtp_server=$value; + } elsif ($key eq 'smtp_port') { + $smtp_port=$value; + } elsif ($key eq 'AuthReq') { + $AuthReq=$value; + } elsif ($key eq 'AuthLogin') { + $AuthLogin=$value; + } elsif ($key eq 'AuthPass') { + $AuthPass=$value; + } elsif ($key eq 'Sender') { + $Sender=$value; + } +} +close CFG; + +if ($debug eq 'ON') { + print "== Debug Start ================\n"; + print "debug=[$debug] \n"; + print "smtp_server=[$smtp_server] \n"; + print "smtp_port=[$smtp_port] \n"; + print "AuthReq=[$AuthReq] \n"; + print "AuthLogin=[$AuthLogin] \n"; + print "AuthPass=[$AuthPass] \n"; + print "Sender=[$Sender] \n\n"; +} + +# check minimal required variables smtp_server, smtp_org, Sender + + +## debug info +if ($debug eq 'ON') { + print "============================\n"; + print "$numArgs command-line arguments:\n"; + + foreach $argnum (0 .. $#ARGV) { + print " $argnum -- $ARGV[$argnum]\n"; + } +} + +## if no arguments, exit with syntax rule +if ($numArgs == 0) { + print "Command Syntax...\n"; + exit 0; +} + +# if argv 0 = -s then argv1 is the subject, if not subject=blank + +if ($ARGV[0] eq '-s') { + $SubJect = $ARGV[1]; + $EAddr = $ARGV[2]; +} else { + # else set subject to blank, and set email address + $SubJect = ""; + $EAddr = $ARGV[0]; +} + +## debug stuff +if ($debug eq 'ON') { + print "============================\n"; + if ($numArgs == 2) { + print "ArgV1: $ARGV[1]\n"; + } + print "Subject is: $SubJect \n"; + print "Email Address is $EAddr \n"; +} + +# +# Create the object without any arguments, # i.e. localhost is the default SMTP server. +# +$sm = new SendMail("$smtp_server", $smtp_port); + +## Set SMTP AUTH login profile. +if ($AuthReq eq 'YES') { + $sm->setAuth($sm->AUTHLOGIN, "$AuthLogin", "$AuthPass"); +} + +## Turn on debugging in SendMail Module +# +if ($debug eq 'ON') { + # We set the debug mode "ON". + # + $sm->setDebug($sm->ON); +} else { + $sm->setDebug($sm->OFF); +} + +# +# We set the sender. +# +$sm->From("<$Sender>"); + +## Set the Subject +# +$sm->Subject("$SubJect"); + +## use argument for address +# +$sm->To("<$EAddr>"); + +## use STDIN for body of text +# +$sm->setMailBody("@body_data"); + +### Not used +# +# Attach a testing image. +# +## $sm->Attach("./welcome.gif"); + +## Check if the mail sent successfully or not. +# +if ($sm->sendMail() != 0) { + print $sm->{'error'}."\n"; + exit -1; +} + +# +# Mail sent successfully. +# +if ($debug eq 'ON') { + print "==Debug End ====================\n"; +} + +exit 0; diff --git a/WxRpt_ug/parsing_list.txt b/WxRpt_ug/parsing_list.txt new file mode 100755 index 0000000..4a5fea1 --- /dev/null +++ b/WxRpt_ug/parsing_list.txt @@ -0,0 +1,21 @@ +neighborhood +city +state +elevation +observation_time +temperature_string +temp_f +relative_humidity +wind_string +wind_dir +wind_degrees +wind_mph +wind_gust_mph +pressure_in +dewpoint_f +heat_index_f +windchill_f +precip_1hr_string +precip_1hr_in +precip_today_string +precip_today_in diff --git a/WxRpt_ug/saved_pressure.var b/WxRpt_ug/saved_pressure.var new file mode 100644 index 0000000..4d30f53 --- /dev/null +++ b/WxRpt_ug/saved_pressure.var @@ -0,0 +1,2 @@ +# Last Updated: 2017.03.22.2258 +pressure_in= diff --git a/WxRpt_ug/trend b/WxRpt_ug/trend new file mode 100755 index 0000000..e779ff1 --- /dev/null +++ b/WxRpt_ug/trend @@ -0,0 +1,40 @@ +#!/bin/sh +# +# pressure trending, called by cron, every 6 hours. +# +# "saved_pressure.var" is created by getWxRpt_ug + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# if Weather Underground _STN not an argument, then use what is defined in configure file. + +if [ "$1" = "" ] ; then + WX_UNDERGRND_STN=${WX_UNDERGRND_STN} +else + WX_UNDERGRND_STN=$1 +fi + +# report/working dirs +UG_WX_WRKING_DIR=${CUSTOM}/WxRpt_ug/${WX_UNDERGRND_STN} + +if [ ! -d $UG_WX_WRKING_DIR ] ; then + echo "Directory $UG_WX_WRKING_DIR not found!" + echo + exit +fi + +if [ ! -f $UG_WX_WRKING_DIR/trend_pressure.var ] ; then + cp $UG_WX_WRKING_DIR/saved_pressure.var $UG_WX_WRKING_DIR/trend_pressure.var + exit 0 +else + cp $UG_WX_WRKING_DIR/trend_pressure.var $UG_WX_WRKING_DIR/old_pressure.var + rm $UG_WX_WRKING_DIR/trend_pressure.var +fi + diff --git a/WxRpt_ug/var.src b/WxRpt_ug/var.src new file mode 100644 index 0000000..87163a3 --- /dev/null +++ b/WxRpt_ug/var.src @@ -0,0 +1,21 @@ +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" +="" diff --git a/beacon_no b/beacon_no new file mode 100755 index 0000000..d00491f --- /dev/null +++ b/beacon_no @@ -0,0 +1 @@ +1 diff --git a/cat b/cat new file mode 100755 index 0000000..474357b --- /dev/null +++ b/cat @@ -0,0 +1,8 @@ +PING google.com (216.58.217.142) 56(84) bytes of data. +64 bytes from iad23s43-in-f142.1e100.net (216.58.217.142): icmp_seq=1 ttl=52 time=28.1 ms +64 bytes from iad23s43-in-f142.1e100.net (216.58.217.142): icmp_seq=2 ttl=52 time=36.6 ms +64 bytes from iad23s43-in-f142.1e100.net (216.58.217.142): icmp_seq=3 ttl=52 time=30.6 ms + +--- google.com ping statistics --- +3 packets transmitted, 3 received, 0% packet loss, time 2001ms +rtt min/avg/max/mdev = 28.145/31.816/36.687/3.594 ms diff --git a/clearWxAlerts b/clearWxAlerts new file mode 100755 index 0000000..d6f7097 --- /dev/null +++ b/clearWxAlerts @@ -0,0 +1,43 @@ +#!/bin/bash +# +# clearWxAlert +# +# $Id: clearWxAlerts 61 2011-01-30 16:08:13Z $ +# Clears and removes playWxAlertBg lockfiles. This script should be used +# when debugging or during a force clear of alerts. The main function +# is to remove all of the playWxAlertBg programs, remove all lock files. +# + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# Variables +WXALERTDIR=${WXALERT_SPOOLDIR} + +# Check if any playWxAlertBg files are running, if so, killem +echo -n "Stopping Weather Alert Messages..." +killall playWxAlertBg &> /dev/null 2>&1 +echo " Done." + + +# cleanup the lock files +echo -n "Removing lock files from /tmp..." +rm -f /tmp/playWxAlertBg-lock &> /dev/null 2>&1 +echo " Done." + +# clean up the Alert directories +echo -n "Cleaning up the alert weather directories..." +rm -f $WXALERTDIR/*/* &> /dev/null 2>&1 +echo " Done." + +# clean up the tmp Wx Directories +echo -n "Removing temporary files in /tmp/wx.." +rm -f /tmp/wx/*/* &> /dev/null 2>&1 +echo " Done." + diff --git a/disable_wx_alertmsg b/disable_wx_alertmsg new file mode 100755 index 0000000..f198548 --- /dev/null +++ b/disable_wx_alertmsg @@ -0,0 +1,27 @@ +#!/bin/bash +# +# Disable weather alert messages +# by adding $LOCAL/no_wxalert_msg file +# $Id: disable_wx_alertmsg 51 2009-06-16 02:43:41Z $ + + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +if [ ! -f $LOCAL/no_wxalert_msg ] ; then + touch $LOCAL/no_wxalert_msg +fi + +if [ $TEXT2SPEECH = "cepstral" ] ; then + $BIN/key + $SWIFTBIN -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL ".. weather alert messages disabled.." + $BIN/unkey +fi + +exit 0 diff --git a/downloadnews b/downloadnews new file mode 100755 index 0000000..e5d6600 --- /dev/null +++ b/downloadnews @@ -0,0 +1,148 @@ +#!/bin/bash +# +# Script to download ARRL News or ARN and divide into 2.5 minute segments with breaks. +# Includes voice messages before play, at breaks, and after play. +# This script can be configured for global playback! +# DO NOT run this on a multi-node connected circuit without consideration. +# Change MODE to localplay for strictly local node play. +# +# You can run this script from a cron job or from the command line at least +# 15 minutes before the defined run time (TIME value) but it can be scheduled +# anytime within 24 hours prior to the run time. +# +# cron example - +# +# Prime news for play every Tuesday at 8:30PM - actual playtime set by defined +# comand line TIME parameter. If Playtime is 9PM (2100) +# This would send pre warnings at 8:50 and 8:55 PM. +# +# Start a cron job every tuesday at 8:30 PM to run at 9 PM the same day +# and play ARRL news on node 40000, globally +# +# 30 20 * * 2 /etc/asterisk/playnews ARRL 21:00 40000 G &> /dev/null 2>&1 +# +# Play ARN news on Thursday at 7PM on node 40000, Start playnews at 6 PM, Play locally +# +# 00 18 * * 4 /etc/asterisk/playnews ARN 19:00 40000 L &> /dev/null 2>&1 + +# The audio files ARRLstart5, ARRLstart10, ARRLstart, ARRLcontinue, ARRLstop +# and ARNstart, ARNstart10, ARNstart, ARNcontinue, ARNstop +# are supplied but could be customized for your needs. The audio +# files must be in the directory defined by VOICEDIR +# +# ARRLstart10 or ARNstart10 - voice message at ten minutes before start +# ARRLstart5 or ARNstart5 - voice message at five minutes before start +# ARRLstart or ARNstart - voice message at start of play +# ARRLcontinue or ARNcontinue - voice message at breaks +# ARRLstop or ARNstop - voice message at end of play +# +# v0.8 update +# +# - added check for downloaded MP3 filesize. Playnews will not +# play if size is less than 100K. On holidays ARRL only has +# small html file that gets downloaded. +# +# v0.7 updates +# +# - Added TMPDIR user settable variable +# +# v0.6 updates +# - Now requires that all parameters be entered +# except mode which defualts to global +# - More parameter checking added +# - Time can be set to "NOW" for immediate start +# +# DO NOT use the the "NOW" time parameter in a cron !!! + +# The following variable needs to be set if different for your install +# +# VOICEDIR - Directory for playnews voice files +# Usually in the same directory as the playnews script + +VOICEDIR="/home/irlp/custom/voice" + +# TMPDIR - Directory for temporary file storage +# Note if at all possible this should not be on the SD card. +# Use of /tmp or a USB mounted stick is preferred +# Note that the BBB may not have enough memory in /tmp to process + +TMPDIR="/tmp" + +# End User defines + +if [ ! -f $VOICEDIR/ARNstart ] + then + echo "playnews voice files not found - check VOICEDIR in script" + exit 1 +fi + +# NEWSTYPE is either ARRL or ARN, Always required as parameter 1 +# +if [ -z "$1" ] + then + echo "No Play type given - ARN or ARRL" + exit 1 + else + NEWSTYPE=${1} + if [ "$NEWSTYPE" != "ARN" ] && [ "$NEWSTYPE" != "ARRL" ] + then + echo "Play type must be ARRL or ARN" + exit 1 + fi +fi + +# Time to start - 24 hour time - required 2nd command line parameter +# Time example 03:19 = 3:19 AM, 22:45 = 10:45 PM +# +if [ ${2} != "NOW" ] && [[ ! $2 =~ ^[0-9][0-9]:[0-9][0-9]$ ]] + then + echo "No Time supplied - Enter 24 hour time to play as 00:00 - (7 PM = 19:00)" + exit 1 +fi +TIME=$2 + +# Download Newsline or ARRL and convert to wav +rm -f $TMPDIR/$NEWSTYPE.mp3 +echo "Starting Download of $NEWSTYPE Audio News @ $(date +%H:%M:%S)" + +if [ $NEWSTYPE == "ARN" ] + then +# Timeout set to 15 seconds with 4 retries. Set the timeout longer for slow circuits. + wget -T 15 --tries=4 -r -O $TMPDIR/$NEWSTYPE.mp3 https://www.arnewsline.org/s/news.mp3 +else +# not ARN so get ARRL + wget -T 15 --tries=4 -r -O $TMPDIR/$NEWSTYPE.mp3 http://www.arrl.org/files/file/News/Audio%20News/AAN-$(date --date="last friday" +%Y-%m-%d).mp3 +fi + +if [ -f $TMPDIR/$NEWSTYPE.mp3 ]; + then + echo "Download complete @ $(date +%H:%M:%S)" +else + echo "Download failed" + exit 0 +fi + +# On holidays ARRL does not put out a news MP3. Instead there is a +# shorter HTML file. The following routine checks for this and +# exits if there is no valid MP3 file. + +filesize=$(wc -c <$TMPDIR/$NEWSTYPE.mp3) +if [ $filesize -lt 100000 ] + then + echo "File size too small for play" + exit 0 +fi + +echo "Converting from MP3 to individual ulaw format files" + +#Convert mp3 to a wav file +lame -h --decode $TMPDIR/$NEWSTYPE.mp3 $TMPDIR/$NEWSTYPE2.wav +sox -v 0.1 $TMPDIR/$NEWSTYPE2.wav -r 48000 $TMPDIR/$NEWSTYPE.wav +#ffmpeg -i $TMPDIR/$NEWSTYPE.mp3 -y -ac 1 -ar 48000 $TMPDIR/$NEWSTYPE.wav + + /usr/local/bin/wav2dvtool $TMPDIR/$NEWSTYPE.wav CQCQCQ N8MFN__B N8MFN__G "AMATEUR RADIO $NEWSTYPE" $TMPDIR/$NEWSTYPE.dvtool + #/bin/cp $TMPDIR/$NEWSTYPE.dvtool $TMPDIR/"$NEWSTYPE"RNLB.dvtool + #/bin/cp $TMPDIR/$NEWSTYPE.dvtool $TMPDIR/"$NEWSTYPE"RNLC.dvtool + +exit 0 + diff --git a/downloadnews.save b/downloadnews.save new file mode 100755 index 0000000..98b2b34 --- /dev/null +++ b/downloadnews.save @@ -0,0 +1,170 @@ +#!/bin/bash +# +# Script to download ARRL News or ARN and divide into 2.5 minute segments with breaks. +# Includes voice messages before play, at breaks, and after play. +# This script can be configured for global playback! +# DO NOT run this on a multi-node connected circuit without consideration. +# Change MODE to localplay for strictly local node play. +# +# You can run this script from a cron job or from the command line at least +# 15 minutes before the defined run time (TIME value) but it can be scheduled +# anytime within 24 hours prior to the run time. +# +# cron example - +# +# Prime news for play every Tuesday at 8:30PM - actual playtime set by defined +# comand line TIME parameter. If Playtime is 9PM (2100) +# This would send pre warnings at 8:50 and 8:55 PM. +# +# Start a cron job every tuesday at 8:30 PM to run at 9 PM the same day +# and play ARRL news on node 40000, globally +# +# 30 20 * * 2 /etc/asterisk/playnews ARRL 21:00 40000 G &> /dev/null 2>&1 +# +# Play ARN news on Thursday at 7PM on node 40000, Start playnews at 6 PM, Play locally +# +# 00 18 * * 4 /etc/asterisk/playnews ARN 19:00 40000 L &> /dev/null 2>&1 + +# The audio files ARRLstart5, ARRLstart10, ARRLstart, ARRLcontinue, ARRLstop +# and ARNstart, ARNstart10, ARNstart, ARNcontinue, ARNstop +# are supplied but could be customized for your needs. The audio +# files must be in the directory defined by VOICEDIR +# +# ARRLstart10 or ARNstart10 - voice message at ten minutes before start +# ARRLstart5 or ARNstart5 - voice message at five minutes before start +# ARRLstart or ARNstart - voice message at start of play +# ARRLcontinue or ARNcontinue - voice message at breaks +# ARRLstop or ARNstop - voice message at end of play +# +# v0.8 update +# +# - added check for downloaded MP3 filesize. Playnews will not +# play if size is less than 100K. On holidays ARRL only has +# small html file that gets downloaded. +# +# v0.7 updates +# +# - Added TMPDIR user settable variable +# +# v0.6 updates +# - Now requires that all parameters be entered +# except mode which defualts to global +# - More parameter checking added +# - Time can be set to "NOW" for immediate start +# +# DO NOT use the the "NOW" time parameter in a cron !!! + +# The following variable needs to be set if different for your install +# +# VOICEDIR - Directory for playnews voice files +# Usually in the same directory as the playnews script + +VOICEDIR="/home/irlp/custom/voice" + +# TMPDIR - Directory for temporary file storage +# Note if at all possible this should not be on the SD card. +# Use of /tmp or a USB mounted stick is preferred +# Note that the BBB may not have enough memory in /tmp to process + +TMPDIR="/tmp" + +# End User defines + +if [ ! -f $VOICEDIR/ARNstart ] + then + echo "playnews voice files not found - check VOICEDIR in script" + exit 1 +fi + +# NEWSTYPE is either ARRL or ARN, Always required as parameter 1 +# +if [ -z "$1" ] + then + echo "No Play type given - ARN or ARRL" + exit 1 + else + NEWSTYPE=${1} + if [ "$NEWSTYPE" != "ARN" ] && [ "$NEWSTYPE" != "ARRL" ] + then + echo "Play type must be ARRL or ARN" + exit 1 + fi +fi + +# Time to start - 24 hour time - required 2nd command line parameter +# Time example 03:19 = 3:19 AM, 22:45 = 10:45 PM +# +if [ ${2} != "NOW" ] && [[ ! $2 =~ ^[0-9][0-9]:[0-9][0-9]$ ]] + then + echo "No Time supplied - Enter 24 hour time to play as 00:00 - (7 PM = 19:00)" + exit 1 +fi +TIME=$2 + +# Download Newsline or ARRL and convert to wav +rm -f $TMPDIR/$NEWSTYPE.mp3 +echo "Starting Download of $NEWSTYPE Audio News @ $(date +%H:%M:%S)" + +if [ $NEWSTYPE == "ARN" ] + then +# Timeout set to 15 seconds with 4 retries. Set the timeout longer for slow circuits. + wget -T 15 --tries=4 -r -O $TMPDIR/$NEWSTYPE.mp3 http://www.arnewsline.org/storage/audio/news.mp3 +else +# not ARN so get ARRL + wget -T 15 --tries=4 -r -O $TMPDIR/$NEWSTYPE.mp3 http://www.arrl.org/files/file/News/Audio%20News/AAN-$(date --date="last friday" +%Y-%m-%d).mp3 +fi + +if [ -f $TMPDIR/$NEWSTYPE.mp3 ]; + then + echo "Download complete @ $(date +%H:%M:%S)" +else + echo "Download failed" + exit 0 +fi + +# On holidays ARRL does not put out a news MP3. Instead there is a +# shorter HTML file. The following routine checks for this and +# exits if there is no valid MP3 file. + +filesize=$(wc -c <$TMPDIR/$NEWSTYPE.mp3) +if [ $filesize -lt 100000 ] + then + echo "File size too small for play" + exit 0 +fi + +echo "Converting from MP3 to individual ulaw format files" + +#Convert mp3 to a wav file +#lame -h --decode $TMPDIR/$NEWSTYPE.mp3 $TMPDIR/"$NEWSTYPE"2.wav +ffmpeg -i $TMPDIR/$NEWSTYPE.mp3 -y -ac 1 -ar 48000 +$TMPDIR/"$NEWSTYPE"2.wav + +# Get the length of the file in seconds +LENGTH=`soxi -D $TMPDIR/$NEWSTYPE2.wav` + +#echo $LENGTH +START=0 + +# 2.5 minute = 150 seconds +INCREMENT=150 +# Calculate number of segments +MAXPART=`echo $LENGTH/$INCREMENT | bc` +let "MAXPART += 1" +PART="1" +echo "$MAXPART" > /tmp/"$NEWSTYPE"_MAXPART + +# Divide into 2.5 minute segments +while [ "$PART" -le "$MAXPART" ]; do + sox --temp $TMPDIR $TMPDIR/$NEWSTYPE2.wav $TMPDIR/$NEWSTYPE.part$PART.wav trim $START $INCREMENT + echo "Creating $TMPDIR/$NEWSTYPE.part$PART.wav" + INCREMENT=155 + START=$(($START-5+$INCREMENT)) +# echo "$PART - $START - $INCREMENT $(($START+$INCREMENT))" +# let "PART += 1" + /usr/local/bin/wav2dvtool $TMPDIR/$NEWSTYPE.part$PART.wav CQCQCQ KD8TUZ_B W8RNL__G "AMATEUR RADIO $NEWSTYPE" $TMPDIR/$NEWSTYPE.part$PART.dvtool + let "PART += 1" +done + +exit 0 + diff --git a/downloadnews2 b/downloadnews2 new file mode 100755 index 0000000..9be226c --- /dev/null +++ b/downloadnews2 @@ -0,0 +1,169 @@ +#!/bin/bash +# +# Script to download ARRL News or ARN and divide into 2.5 minute segments with breaks. +# Includes voice messages before play, at breaks, and after play. +# This script can be configured for global playback! +# DO NOT run this on a multi-node connected circuit without consideration. +# Change MODE to localplay for strictly local node play. +# +# You can run this script from a cron job or from the command line at least +# 15 minutes before the defined run time (TIME value) but it can be scheduled +# anytime within 24 hours prior to the run time. +# +# cron example - +# +# Prime news for play every Tuesday at 8:30PM - actual playtime set by defined +# comand line TIME parameter. If Playtime is 9PM (2100) +# This would send pre warnings at 8:50 and 8:55 PM. +# +# Start a cron job every tuesday at 8:30 PM to run at 9 PM the same day +# and play ARRL news on node 40000, globally +# +# 30 20 * * 2 /etc/asterisk/playnews ARRL 21:00 40000 G &> /dev/null 2>&1 +# +# Play ARN news on Thursday at 7PM on node 40000, Start playnews at 6 PM, Play locally +# +# 00 18 * * 4 /etc/asterisk/playnews ARN 19:00 40000 L &> /dev/null 2>&1 + +# The audio files ARRLstart5, ARRLstart10, ARRLstart, ARRLcontinue, ARRLstop +# and ARNstart, ARNstart10, ARNstart, ARNcontinue, ARNstop +# are supplied but could be customized for your needs. The audio +# files must be in the directory defined by VOICEDIR +# +# ARRLstart10 or ARNstart10 - voice message at ten minutes before start +# ARRLstart5 or ARNstart5 - voice message at five minutes before start +# ARRLstart or ARNstart - voice message at start of play +# ARRLcontinue or ARNcontinue - voice message at breaks +# ARRLstop or ARNstop - voice message at end of play +# +# v0.8 update +# +# - added check for downloaded MP3 filesize. Playnews will not +# play if size is less than 100K. On holidays ARRL only has +# small html file that gets downloaded. +# +# v0.7 updates +# +# - Added TMPDIR user settable variable +# +# v0.6 updates +# - Now requires that all parameters be entered +# except mode which defualts to global +# - More parameter checking added +# - Time can be set to "NOW" for immediate start +# +# DO NOT use the the "NOW" time parameter in a cron !!! + +# The following variable needs to be set if different for your install +# +# VOICEDIR - Directory for playnews voice files +# Usually in the same directory as the playnews script + +VOICEDIR="/home/irlp/custom/voice" + +# TMPDIR - Directory for temporary file storage +# Note if at all possible this should not be on the SD card. +# Use of /tmp or a USB mounted stick is preferred +# Note that the BBB may not have enough memory in /tmp to process + +TMPDIR="/tmp" + +# End User defines + +if [ ! -f $VOICEDIR/ARNstart ] + then + echo "playnews voice files not found - check VOICEDIR in script" + exit 1 +fi + +# NEWSTYPE is either ARRL or ARN, Always required as parameter 1 +# +if [ -z "$1" ] + then + echo "No Play type given - ARN or ARRL" + exit 1 + else + NEWSTYPE=${1} + if [ "$NEWSTYPE" != "ARN" ] && [ "$NEWSTYPE" != "ARRL" ] + then + echo "Play type must be ARRL or ARN" + exit 1 + fi +fi + +# Time to start - 24 hour time - required 2nd command line parameter +# Time example 03:19 = 3:19 AM, 22:45 = 10:45 PM +# +if [ ${2} != "NOW" ] && [[ ! $2 =~ ^[0-9][0-9]:[0-9][0-9]$ ]] + then + echo "No Time supplied - Enter 24 hour time to play as 00:00 - (7 PM = 19:00)" + exit 1 +fi +TIME=$2 + +# Download Newsline or ARRL and convert to wav +rm -f $TMPDIR/$NEWSTYPE.mp3 +echo "Starting Download of $NEWSTYPE Audio News @ $(date +%H:%M:%S)" + +if [ $NEWSTYPE == "ARN" ] + then +# Timeout set to 15 seconds with 4 retries. Set the timeout longer for slow circuits. + wget -T 15 --tries=4 -r -O $TMPDIR/$NEWSTYPE.mp3 http://www.arnewsline.org/storage/audio/news.mp3 +else +# not ARN so get ARRL + wget -T 15 --tries=4 -r -O $TMPDIR/$NEWSTYPE.mp3 http://www.arrl.org/files/file/News/Audio%20News/AAN-$(date --date="last friday" +%Y-%m-%d).mp3 +fi + +if [ -f $TMPDIR/$NEWSTYPE.mp3 ]; + then + echo "Download complete @ $(date +%H:%M:%S)" +else + echo "Download failed" + exit 0 +fi + +# On holidays ARRL does not put out a news MP3. Instead there is a +# shorter HTML file. The following routine checks for this and +# exits if there is no valid MP3 file. + +filesize=$(wc -c <$TMPDIR/$NEWSTYPE.mp3) +if [ $filesize -lt 100000 ] + then + echo "File size too small for play" + exit 0 +fi + +echo "Converting from MP3 to individual ulaw format files" + +#Convert mp3 to a wav file +#lame -h --decode $TMPDIR/$NEWSTYPE.mp3 $TMPDIR/$NEWSTYPE2.wav +ffmpeg -i $TMPDIR/$NEWSTYPE.mp3 -y -ac 1 -ar 48000 $TMPDIR/$NEWSTYPE2.wav + +# Get the length of the file in seconds +LENGTH=`soxi -D $TMPDIR/$NEWSTYPE2.wav` + +#echo $LENGTH +START=0 + +# 2.5 minute = 150 seconds +INCREMENT=150 +# Calculate number of segments +MAXPART=`echo $LENGTH/$INCREMENT | bc` +let "MAXPART += 1" +PART="1" +echo "$MAXPART" > /tmp/"$NEWSTYPE"_MAXPART + +# Divide into 2.5 minute segments +while [ "$PART" -le "$MAXPART" ]; do + sox --temp $TMPDIR $TMPDIR/$NEWSTYPE2.wav $TMPDIR/$NEWSTYPE.part$PART.wav trim $START $INCREMENT + echo "Creating $TMPDIR/$NEWSTYPE.part$PART.wav" + INCREMENT=155 + START=$(($START-5+$INCREMENT)) +# echo "$PART - $START - $INCREMENT $(($START+$INCREMENT))" +# let "PART += 1" + /usr/local/bin/wav2dvtool $TMPDIR/$NEWSTYPE.part$PART.wav CQCQCQ KD8TUZ_B KD8TUZ_G "AMATEUR RADIO $NEWSTYPE" $TMPDIR/$NEWSTYPE.part$PART.dvtool + let "PART += 1" +done + +exit 0 + diff --git a/dstartext b/dstartext new file mode 100755 index 0000000..75d9c0e --- /dev/null +++ b/dstartext @@ -0,0 +1,84 @@ +#!/bin/bash +# + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# Check Arguments... +# has only one argument, county info +if [ "$#" = "1" ] ; then + COUNTY=$1 + COUNTY_NAME="" +fi + +# has two arguments, county info and county name +if [ "$#" = "2" ] ; then + COUNTY=$1 + COUNTY_NAME=$2 +fi + +# if no arguments, then use what is defined in configure file. +if [ "$1" = "" ] ; then + # extract County Information and County Name + COUNTY_NAME=`echo $COUNTY | awk 'BEGIN { FS="," } { print $2} '` + COUNTY=`echo $COUNTY | awk 'BEGIN { FS="," } { print $1} '` + # if name is empty, then use COUNTY + if [ "$COUNTY_NAME" = "" ] ; then + COUNTY_NAME=$COUNTY + fi +fi + +if [ "$COUNTY" = "NOTSET" ] || [ "$COUNTY" = "" ] ; then + echo "ERROR - The COUNTY variable in ${CUSTOM}/wx_scripts.conf is not set" + echo "or missing, aborting..." + exit 1 +fi + +sed -f /wxtext_conv1.sed ${WXALERT_SPOOLDIR}/${COUNTY}/plist.txt > ${WXALERT_SPOOLDIR}/${COUNTY}/conv_plist.txt + +PLIST=${WXALERT_SPOOLDIR}/${COUNTY}/conv_plist.txt +#PLIST=./plist.txt + +LINES=`wc -l $PLIST | awk '{print $1}'` + +#Starting Count +FILECOUNT=1 + +for STEPS in `seq 1 $LINES` +do + + CONV_LINE=`sed -n "$STEPS p" $PLIST` + bea[$STEPS]=`echo $CONV_LINE | awk 'BEGIN { FS = "issued"} ; {print $1}'` + + iss[$STEPS]=`echo $CONV_LINE | awk 'BEGIN { FS = "issued"} ; {print $2}' | awk 'BEGIN {FS = "until" } ; {print $1}'` + + unt[$STEPS]=`echo $CONV_LINE | awk 'BEGIN { FS = "issued" } ; { print $2 }' | awk 'BEGIN { FS = "until" } ; { print $2 }' | awk 'BEGIN {FS = "by" } ; { print $1 }'` + + echo ${bea[$STEPS]} > ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon${FILECOUNT} + FILECOUNT=`expr $FILECOUNT + 1` + + echo "issued ${iss[$STEPS]}" > ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon${FILECOUNT} + FILECOUNT=`expr $FILECOUNT + 1` + + if [ -n "${unt[$STEPS]}" ] ; then + echo "until ${unt[$STEPS]}" > ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon${FILECOUNT} + FILECOUNT=`expr $FILECOUNT + 1` + fi + echo +# echo ${bea[$STEPS]} +# echo "issued ${iss[$STEPS]}" +# if [ -n "${unt[$STEPS]}" ] ; then +# echo "until ${unt[$STEPS]}" +# fi +# echo + +done + +echo + diff --git a/dstartx b/dstartx new file mode 100755 index 0000000..8695e62 --- /dev/null +++ b/dstartx @@ -0,0 +1,87 @@ +#!/bin/bash +# +# Script to rotate Allstar Voice IDs, by K0KN 9/2012, last updated 3-8-2013 +# +# Usage - Place numbered ID files in the IDBASE folder in sequential +# order. For example, id1.ulaw, id2.ulaw, id3.ulaw and so forth +# up to the IDMAX number specified. If 8 files are used, for +# example, set IDMAX to 8. +# +# ID is the file specified in RPT.conf for your voice ID. +# + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# Check Arguments... +# has only one argument, county info +if [ "$#" = "1" ] ; then + COUNTY=$1 + COUNTY_NAME="" +fi + +# has two arguments, county info and county name +if [ "$#" = "2" ] ; then + COUNTY=$1 + COUNTY_NAME=$2 +fi + +# if no arguments, then use what is defined in configure file. +if [ "$1" = "" ] ; then + # extract County Information and County Name + COUNTY_NAME=`echo $COUNTY | awk 'BEGIN { FS="," } { print $2} '` + COUNTY=`echo $COUNTY | awk 'BEGIN { FS="," } { print $1} '` + # if name is empty, then use COUNTY + if [ "$COUNTY_NAME" = "" ] ; then + COUNTY_NAME=$COUNTY + fi +fi + +if [ "$COUNTY" = "NOTSET" ] || [ "$COUNTY" = "" ] ; then + echo "ERROR - The COUNTY variable in ${CUSTOM}/wx_scripts.conf is not set" + echo "or missing, aborting..." + exit 1 +fi + +#CUSTOM=${WXALERT_SPOOLDIR}/${COUNTY} +#touch $CUSTOM/beacon_no +#echo "0" >> $CUSTOM/beacon_no +# Read current ID number from file +IDTOUSE=$(sed -n ""$RAN_ID"p" "$CUSTOM"/beacon_no) +IDMAX=$(ls ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon* | wc -l) + +while [ $IDTOUSE != $IDMAX ] +do +CUSTOM=${WXALERT_SPOOLDIR}/${COUNTY} +IDBASE=${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon # base file names +#IDMAX=$(ls ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon* | wc -l) # max ID number + +if [ ! -f $CUSTOM/beacon_no ] ; then + echo "0" >> $CUSTOM/beacon_no +else +echo +fi + +# Read current ID number from file +IDTOUSE=$(sed -n ""$RAN_ID"p" "$CUSTOM"/beacon_no) + +# Increment Variable +IDTOUSE=$(( $IDTOUSE + 1 )) + +echo $IDTOUSE > "${WXALERT_SPOOLDIR}/${COUNTY}"/beacon_no +/usr/local/bin/texttransmit KD8TUZ_B -file ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon${IDTOUSE} +sleep 25 + +done + + IDTOUSE=0 + echo $IDTOUSE > "${WXALERT_SPOOLDIR}/${COUNTY}"/beacon_no + +exit 0 + diff --git a/dstartx.save b/dstartx.save new file mode 100755 index 0000000..06bd912 --- /dev/null +++ b/dstartx.save @@ -0,0 +1,75 @@ +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# Check Arguments... +# has only one argument, county info +if [ "$#" = "1" ] ; then + COUNTY=$1 + COUNTY_NAME="" +fi + +# has two arguments, county info and county name +if [ "$#" = "2" ] ; then + COUNTY=$1 + COUNTY_NAME=$2 +fi + +# if no arguments, then use what is defined in configure file. +if [ "$1" = "" ] ; then + # extract County Information and County Name + COUNTY_NAME=`echo $COUNTY | awk 'BEGIN { FS="," } { print $2} '` + COUNTY=`echo $COUNTY | awk 'BEGIN { FS="," } { print $1} '` + # if name is empty, then use COUNTY + if [ "$COUNTY_NAME" = "" ] ; then + COUNTY_NAME=$COUNTY + fi +fi + +if [ "$COUNTY" = "NOTSET" ] || [ "$COUNTY" = "" ] ; then + echo "ERROR - The COUNTY variable in ${CUSTOM}/wx_scripts.conf is not set" + echo "or missing, aborting..." + exit 1 +fi + +#CUSTOM=${WXALERT_SPOOLDIR}/${COUNTY} +#touch $CUSTOM/beacon_no +#echo "0" >> $CUSTOM/beacon_no +# Read current ID number from file +IDTOUSE=$(sed -n ""$RAN_ID"p" "$CUSTOM"/beacon_no) +IDMAX=$(ls ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon* | wc -l) + +while [ $IDTOUSE != $IDMAX ] +do +CUSTOM=${WXALERT_SPOOLDIR}/${COUNTY} +IDBASE=${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon # base file names +#IDMAX=$(ls ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon* | wc -l) # max ID number + +if [ ! -f $CUSTOM/beacon_no ] ; then + echo "0" >> $CUSTOM/beacon_no +else +echo +fi + +# Read current ID number from file +IDTOUSE=$(sed -n ""$RAN_ID"p" "$CUSTOM"/beacon_no) + +# Increment Variable +IDTOUSE=$(( $IDTOUSE + 1 )) + +echo $IDTOUSE > "${WXALERT_SPOOLDIR}/${COUNTY}"/beacon_no +/usr/local/bin/texttransmit KD8TUZ_B -file ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon${IDTOUSE} +sleep 25 + +done + + IDTOUSE=0 + echo $IDTOUSE > "${WXALERT_SPOOLDIR}/${COUNTY}"/beacon_no + +exit 0 + diff --git a/enable_wx_alertmsg b/enable_wx_alertmsg new file mode 100755 index 0000000..fa5a029 --- /dev/null +++ b/enable_wx_alertmsg @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Disable weather alert messages +# by adding $LOCAL/no_wxalert_msg file +# $Id: enable_wx_alertmsg 70 2011-02-27 22:30:57Z $ + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +if [ -f $LOCAL/no_wxalert_msg ] ; then + rm $LOCAL/no_wxalert_msg +fi + +if [ $TEXT2SPEECH = "cepstral" ] ; then + $BIN/key + $SWIFTBIN -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL ".. weather alert messages enabled.." + $BIN/unkey +fi + +exit 0 diff --git a/getWxAlert b/getWxAlert new file mode 100755 index 0000000..a38754b --- /dev/null +++ b/getWxAlert @@ -0,0 +1,503 @@ + +#!/bin/bash +# +# $Id: getWxAlert 85 2012-07-21 23:13:23Z $ +# +# Change the method of updating alerts. Check if summary is different instead +# of the entire url download. This should help prevent updating alert beacons +# that are unnecessary. +# +# Added a check to see if the download failed, if so abort and log. Also +# changed the wget options for retry=10. +# +# Spool Directory should contain the alert.info, pre/post converted files, +# no_alert, and alert summary +# +DEBUG="0" # debug levels 0 = no debug + # level 1 = save alerts + # level 2 = detailed info + + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# Check Arguments... +# has only one argument, county info +if [ "$#" = "1" ] ; then + COUNTY=$1 + COUNTY_NAME="" +fi + +# has two arguments, county info and county name +if [ "$#" = "2" ] ; then + COUNTY=$1 + COUNTY_NAME=$2 +fi + +# if no arguments, then use what is defined in configure file. +if [ "$1" = "" ] ; then + # extract County Information and County Name + COUNTY_NAME=`echo $COUNTY | awk 'BEGIN { FS="," } { print $2} '` + COUNTY=`echo $COUNTY | awk 'BEGIN { FS="," } { print $1} '` + # if name is empty, then use COUNTY + if [ "$COUNTY_NAME" = "" ] ; then + COUNTY_NAME=$COUNTY + fi +fi + +if [ "$COUNTY" = "NOTSET" ] || [ "$COUNTY" = "" ] ; then + echo "ERROR - The COUNTY variable in ${CUSTOM}/wx_scripts.conf is not set" + echo "or missing, aborting..." + exit 1 +fi + +if [ "$COUNTY" = "help" ] ; then # If no arguments + echo "Usage getWxAlert " + echo " where =State County, for example: WIC002" + echo " See http://alerts.weather.gov/ for more informaton" + echo + echo " Or you can edit the wx_scripts.conf file to include the COUNTY variable." + echo + exit 1 +fi + +if [ -z $TEXT2SPEECH ] ; then + echo "TEXT2SPEECH value not defined. Please edit wx_scripts_conf file." + exit 1 +fi + +if [ ! -d /tmp/wx/$COUNTY ] ; then + mkdir -p /tmp/wx/$COUNTY +fi + +####### Functions ###### +# Send message to LOGFILE +function debug2 () { + MESSAGE="${0##*/} DEBUG: $@" + echo "$MESSAGE" + if [ -n "$LOGFILE" ]; then + echo "`date '+%b %d %Y %T %z'` $MESSAGE" >> $LOGFILE + fi +} + +function send_email () { +for EADDR in `echo $EMAIL | sed 's/,/ /g'` ; do + + # summary version + # $MAIL -s "Weather Alert for $COUNTY_NAME" $EADDR < /tmp/wx/$COUNTY/pre_conv_alert_summary.txt + + # full alert info + cp /tmp/wx/$COUNTY/pre_alert.txt /tmp/wx/$COUNTY/email_alert.txt + # append the alert to the header + cat /tmp/wx/$COUNTY/pre_full_alert_info.txt >> /tmp/wx/$COUNTY/email_alert.txt + # mail it + $MAIL -s "Weather Alert for $COUNTY_NAME" $EADDR < /tmp/wx/$COUNTY/email_alert.txt + +done +} + +# Convert URL to file +#function geturldata () { +# # supply URL +# # Alternative method of getting url information: +# ##/usr/bin/lynx -dump $URL$COUNTY > /tmp/wx/$COUNTY/alert.info +# +# $WGET -t 10 -w 10 --cache=off --random-wait -q $URL$COUNTY -O - > /tmp/wx/$COUNTY/alert.info +# # -t 10 retries, -w 10 sec between +# # turn cache off at server +#} + +###### End of Functions ###### +PLIST="$CUSTOM/wx_alert_product.txt" # Product list file and directory +# URL="http://www.weather.gov/alerts-beta/wwaatmget.php?x=" # URL to RSS data +#URL="https://alerts.weather.gov/cap/wwaatmget.php?x=" # URL to RSS data +URL="https://api.weather.gov/alerts/active.atom?zone=" # URL to RSS data +DATE=`date +%Y.%m.%d.\%H\%M` +NO_WXALERT_MSG=$LOCAL/no_wxalert_msg + +MAILDIR="/tmp/wx/$COUNTY" # Mail log file +MAILLOG="$MAILDIR/spotter_mail.log" # Mail log file +#MAIL=/bin/mail # mail binary +MAIL="$CUSTOM/SendMail/SendMail.pl" # Perl SendMail script + +CRIT_TYPES=`cat $CUSTOM/wx_critical_alerts.txt` +NORM_TYPES=`cat $CUSTOM/wx_normal_alerts.txt` + +#----------------------------- Main program ---------------------- + +if [ ! -d $WXALERT_SPOOLDIR/$COUNTY ] ; then + mkdir -p $WXALERT_SPOOLDIR/$COUNTY +fi + +if [ ! -d /tmp/wx/$COUNTY ] ; then + mkdir -p /tmp/wx/$COUNTY +fi + +cd $WXALERT_SPOOLDIR/$COUNTY + +ALERT_DL="" +CHKCNT=0 +# loop until get proper response, if after 5 attempts notify +while [ -z "$ALERT_DL" ] ; do + + if [ $CHKCNT -gt 5 ] ; then + log "ERROR: $URL is not responding for getWxAlert - ${COUNTY}" + log " Possible issue with nws.gov server or internet connection" + ls -l /tmp/wx/$COUNTY/alert.info + exit 1 + fi + + # Alternative method of getting url information: + ##/usr/bin/lynx -dump $URL$COUNTY > /tmp/wx/$COUNTY/alert.info + + $WGET -t 10 -w 10 --cache=off --random-wait -q $URL$COUNTY -O - > /tmp/wx/$COUNTY/alert.info + # -t 10 retries, -w 10 sec between + # turn cache off at server + + # place data in variable to see if contains data + ALERT_DL="`head -1 /tmp/wx/$COUNTY/alert.info`" + let CHKCNT=$CHKCNT+1 + # delay before retrying + sleep 4 +done + +# process the downloaded information +cat /tmp/wx/$COUNTY/alert.info | \ + grep "title>" | + sed '//,/<\/title/!d' | \ + sed 's/<title>//' | sed 's/<\/title>//' | \ + egrep -v "Current Watches" > wx_new.txt + +# get full summary URL Link +FULL_SUMMARY_URL=`cat /tmp/wx/$COUNTY/alert.info | egrep "<id>|</id>" | sed 's/<id>//' | sed 's/<\/id>//'` + +# Extract Alert from url information: +ALERT=`cat /tmp/wx/$COUNTY/alert.info | egrep "<title>|" | sed 's///' | sed 's/<\/title>//'| sed 's/\(by NWS*\).*/\1/' | sed 's/by NWS//'` + +# Extract Summary from url information: +SUMMARY=`cat /tmp/wx/$COUNTY/alert.info | egrep "<summary>|</summary>" | sed 's/<summary>//' | sed 's/<\/summary>//'` + +# Debug stuff, print values for $ALERT and SUMMARY +if [ "$DEBUG" = "2" ] ; then + echo + debug2 "************START**************************" + debug2 "NWS_URL=$URL" + debug2 "FULL_SUMMARY_URL=$FULL_SUMMARY_URL" + debug2 "CHKCNT=$CHKCNT" + debug2 "ALERT=$ALERT" + debug2 "SUMMARY=$SUMMARY" + debug2 "COUNTY=$COUNTY" + debug2 "COUNTY_NAME=$COUNTY_NAME" +fi + +# Full_alert +echo "$ALERT ... $SUMMARY" > alert_summary.txt + +#if the download failed, alert_summary.txt has only " ... ", then log and exit. +if [ "$DEBUG" = "2" ] ; then + DWNCHK=`cat alert_summary.txt` + echo + debug2 "dwnload chk:$DWNCHK" +fi +if [ "`cat alert_summary.txt`" == " ... " ] ; then + log "ERROR: Failed to download alert correct data from ${COUNTY}" + log " Verify $COUNTY is valid or URL has not changed." + exit 1 +fi + +# check if no active watches, if so clean up any alerts and create +# no watches message for summary. +if ( grep "no active watches" wx_new.txt &> /dev/null ) ; then + + # skip all of this if no_alert file is present indicating audio generated + if [ ! -f no_alerts.txt ] ; then + rm -f *.ul # Remove all alerts, audio files + rm -f alert.txt + rm -f *.dvtool + rm -f conv_* +# /usr/local/bin/remotecontrold kd8tuz_b unlink +# ssh rep.w8rnl.com "remotecontrold w8rnl__c unlink" +# ssh rep.w8rnl.com "remotecontrold w8rnl__a unlink" + + # alert_summary.txt and alert_pre_summary.txt must match, or will + # generate an alert +## + cp alert_summary.txt alert_prev_summary.txt + cp wx_new.txt no_alerts.txt # After clean up, create + # "no active warnings file + + # setup the no warnings message, append file with county info, the + # create audio +## + echo "for $COUNTY_NAME, $COUNTY" >> no_alerts.txt + + if [ $TEXT2SPEECH = "festival" ] ; then + $TEXT2WAVE -F 8000 -otype ulaw no_alerts.txt -o COMPLETE_ALERT.ul + else + $TEXT2WAVE -m text -f no_alerts.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o COMPLETE_ALERT.ul + fi + + ############################## + # save a history of alerts + # mv over to saved directory + # Save alert Information + + if [ "$DEBUG" = "1" ] ; then + if [ ! -f alert.txt ] && [ -f /tmp/wx/$COUNTY/pre_conv_alert_summary.txt ] ; then + # make sure directory is created + if [ ! -d saved/$DATE ] ; then + mkdir -p saved/$DATE + fi + # now save files + cp /tmp/wx/$COUNTY/*.txt saved/$DATE/. + fi + fi + fi # < if [ -f no_alerts.txt ] + exit 0 # Done, now exit. +fi + +log "Checking for Wx Alert updates for $COUNTY" +# Skip if files are the same, alerts are active, but nothing has changed. +if ! diff -q alert_summary.txt alert_prev_summary.txt &> /dev/null; then + + # New Alerts are found. + log "New Wx Alerts for $COUNTY" + cp alert_summary.txt alert_prev_summary.txt # make the files the same now + rm -f alert.txt *.raw no_alerts.txt # and remove old alerts + # remove email alert file + if [ -f /tmp/wx/${COUNTY}/email_alert.txt ] ; then + rm -f /tmp/wx/${COUNTY}/email_alert.txt + fi + # remove the old plist.txt file. + if [ -f plist.txt ] ; then + cp plist.txt /tmp/. + rm plist.txt + fi + + # create the alert file + echo "$ALERT" > alert.txt + + # Create the product list which is tested against + # if product not found, will leave a null file. This is tested against + # at end of script, see ref#1 + while read PRODUCT; do # Check for alert products + # appending the 1st matching, ignore case + grep -i -m 1 "^$PRODUCT" wx_new.txt + done < $PLIST >> plist.txt # line to alert.txt file + + ################################################################# + # Pre Conversions file creation. + ################################################################# + + ############################# + # create pre_alert.txt file (input to post conversion) + # + #set up header of the alert file + echo ". . Weather Alert. for $COUNTY_NAME" > /tmp/wx/$COUNTY/a_tmp.txt + + # check the alert types, critical/normal + if [ "$DEBUG" = "2" ] ; then + debug2 "********* WXALERT_BEACON=[$WXALERT_BEACON] **********" + fi + # Setup TYPES of alerts to trigger on depending upon WXALERT_BEACON Variable + if [ "$WXALERT_BEACON" = "C" ] ; then + TYPES=$CRIT_TYPES + else + TYPES=$NORM_TYPES + fi + + # Set flag + CRIT_BEACON_FLAG="N" + SAVEIFS=$IFS + IFS=$(echo -en "\n\b") + if [ "$DEBUG" = "2" ] ; then + debug2 "TYPES= $TYPES" + fi + + # check for matching TYPES in alert + for TYPE in $TYPES + do + ## added space to avoid the first line being seen as an alert + ## this may need to be changed as follows: + # egrep -v "Current Watches" alert.txt > alert1.txt + # mv alert1.txt alert + ## if grep -i "$TYPE" alert.txt >> /tmp/wx/$COUNTY/a_tmp.txt; then # Extract matching alerts + + if grep -i "$TYPE " alert.txt >> /tmp/wx/$COUNTY/a_tmp.txt; then # Extract matching alerts + echo ".." >> /tmp/wx/$COUNTY/a_tmp.txt + log "Get Wx Alert INFO for $COUNTY: $TYPE" + # set critical beacon flag, if a match + CRIT_BEACON_FLAG="Y" + fi + done + IFS=$SAVEIFS + + # rename to pre_alert.txt + mv /tmp/wx/$COUNTY/a_tmp.txt /tmp/wx/$COUNTY/pre_alert.txt + + ############################# + # create pre_conv_alert_summmary.txt (input to post conversion) + # insert weather header/trailer to full alert txt + echo ". . Weather Alert Summary for county $COUNTY_NAME." > /tmp/wx/$COUNTY/a_tmp.txt + cat alert_summary.txt >> /tmp/wx/$COUNTY/a_tmp.txt + + # copy tmp.txt over for post conversion + cp /tmp/wx/$COUNTY/a_tmp.txt /tmp/wx/$COUNTY/pre_conv_alert_summary.txt + +# Remove since we want to have the email text with the full alert +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +## if [ "$FULL_ALERT" = "Y" ] ; then + + ALERT_DL="" + CHKCNT=0 + # loop until get proper response, if after 5 attempts notify + while [ -z "$ALERT_DL" ] ; do + + if [ $CHKCNT -gt 5 ] ; then + log "ERROR: $URL is not responding for getWxAlert - ${COUNTY}" + log " Possible issue with nws.gov server or internet connection" + ls -l /tmp/wx/$COUNTY/alert.info + exit 1 + fi + + + ############################## + # Create the raw full Summary File + $WGET -t 10 -w 10 --cache=off --random-wait -q $FULL_SUMMARY_URL -O - > /tmp/wx/$COUNTY/full_alert_info.txt + # -t 10 retries, -w 10 sec between + # turn cache off at server + + # place data in variable to see if contains data + ALERT_DL="`head -1 /tmp/wx/$COUNTY/alert.info`" + let CHKCNT=$CHKCNT+1 + # delay before retrying + sleep 4 + done + + # Create full summary from URL file + # setup pre_converted full alert message + # cp /tmp/wx/$COUNTY/pre_conv_alert_summary.txt /tmp/wx/$COUNTY/pre_full_alert_info.txt + cat /tmp/wx/$COUNTY/full_alert_info.txt | sed '/<description>/,/<\/description/!d' | \ + sed 's/<description>//' | \ + sed 's/<\/description>//' > /tmp/wx/$COUNTY/pre_full_alert_info.txt + +# fi +# end ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + # additional debug info + if [ "$DEBUG" = "2" ] ; then + debug2 "**************************************************************" + debug2 "**alert's don't match**" + debug2 "==============================================================" + debug2 "alert_summary file:" + debug2 " /home/irlp/audio/custom/wx/alert/${COUNTY}/alert_summary.txt" + debug2 "==============================================================" + debug2 "alert_prev_summary.txt file:" + debug2 " /home/irlp/audio/custom/wx/alert/${COUNTY}/alert_prev_summary.txt" + debug2 "==============================================================" + debug2 "pre_full_alert_info.txt file:" + debug2 " /tmp/wx/${COUNTY}/pre_full_alert_info.txt" + debug2 "**************************************************************" + debug2 + fi + + ################################################################# + # Post Conversions + # You must edit wxtext_conv.sed file to perform the post conversion. + ################################################################# + + ############################# + # pre_alert txt file to conv_alert.txt + sed -f ${CUSTOM}/wxtext_conv.sed /tmp/wx/$COUNTY/pre_alert.txt > conv_alert.txt + # conv_alert summary txt file to conv_alert_summary.txt + sed -f ${CUSTOM}/wxtext_conv.sed /tmp/wx/$COUNTY/pre_conv_alert_summary.txt > conv_alert_summary.txt + /home/irlp/custom/dstartext + + # full alert text + if [ "$FULL_ALERT" = "Y" ] ; then + ############################# + # pre_full_alert_info file to conv + sed -f ${CUSTOM}/wxtext_conv.sed /tmp/wx/$COUNTY/pre_full_alert_info.txt > conv_full_alert_info.txt + fi + + ################################################################# + # create the audio files + ################################################################# + + if [ $TEXT2SPEECH = "festival" ] ; then + #$TEXT2WAVE -F 48000 -otype wav conv_alert.txt -o ALERT.wav + # $TEXT2WAVE -F 8000 -otype ulaw conv_alert_summary.txt -o COMPLETE_ALERT.ul +# cd $WXALERT_SPOOLDIR/$COUNTY + # /usr/bin/espeak conv_alert.txt ALERT + #ffmpeg -i conv_alert.wav -y -ar 48000 ALERT.wav + if [ "$COUNTY" = "OHC017" ] ; then + pico2wave -w conv_alert.wav "$(cat conv_alert.txt)" + sox conv_alert.wav -r 48000 ALERT.wav bass -3 + /usr/local/bin/wav2dvtool ALERT.wav N8MFN/ALERT N8MFN__B N8MFN__G "Weather Alert" ALERT.dvtool +# scp /custom/wx/alert/OHC017/ALERT.dvtool root@rep.w8rnl.com:/root/weather.dvtool + # full alert text + fi + if [ "$FULL_ALERT" = "Y" ] ; then + $TEXT2WAVE -F 8000 -scale 1 -otype ulaw conv_full_alert_info.txt -o FULLCOMPLETE_ALERT.ul + fi + else + $TEXT2WAVE -m text -f conv_alert.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o ALERT.ul + $TEXT2WAVE -m text -f conv_alert_summary.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o COMPLETE_ALERT.ul + # full alert text + if [ "$FULL_ALERT" = "Y" ] ; then + $TEXT2WAVE -m text -f conv_full_alert_info.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o FULLCOMPLETE_ALERT.ul + fi + fi + + #clean up + rm -f /tmp/wx/$COUNTY/a_tmp.txt + + # check if file exists and size gt zero, if not email/play weather (ref#1) + if [ -s plist.txt ]; then + # Email Alerts if $EMAIL defined. + if [ ! -z "$EMAIL" ] ; then + send_email + echo -e "\nMail sent on $DATE" >> $MAILLOG + fi + # if WXALERT_BEACON is set to Yes, then place playWxAlertBg into + # background + # + # Beacon needs to be Y -or- (beacon C -and- Crit_Beacon flag yes) + if [ "$DEBUG" = "2" ] ; then + echo "WXALERT_BEACON = $WXALERT_BEACON, CRIT_BEACON_FLAG=$CRIT_BEACON_FLAG" + fi + if [ $WXALERT_BEACON = "Y" ] || ([ $WXALERT_BEACON = "C" ] && [ $CRIT_BEACON_FLAG = "Y" ]) ; then + # first kill any left over process + # get PID and kill it + if [ -f $WXALERT_SPOOLDIR/$COUNTY/playWxAlertBg.pid ] ; then + kill `cat < playWxAlertBg.pid` + fi + # if $LOCAL/no_wxalert_msg file is present, remove it to start + # new weather alert msg + if [ -f $NO_WXALERT_MSG ] ; then + rm $NO_WXALERT_MSG + fi + # call playWxAlert and place in background + log "Launching playWxAlertBg..." +# curl -X POST --silent --data-urlencode "payload={\"text\": \"$(cat /custom/wx/alert/$COUNTY/alert.txt | sed "s/\"/'/g")\"}" "$2" https://hooks.slack.com/services/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 +# curl -X POST --silent --data-urlencode "payload={\"text\": \"$(cat /custom/wx/alert/$COUNTY/alert.txt | sed "s/\"/'/g")\"}" "$2" https://hooks.slack.com/services/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 +# curl -X POST --silent --data-urlencode "payload={\"text\": \"$(cat /custom/wx/alert/OHC017/alert.txt | sed "s/\"/'/g")\"}" "$2" https://hooks.slack.com/services/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 + + # /usr/local/bin/remotecontrold kd8tuz_b link never xrf093_c +# ssh rep.w8rnl.com "remotecontrold w8rnl__a link never xrf093_c" +# ssh rep.w8rnl.com "remotecontrold w8rnl__b link never xrf093_c" +# ssh rep.w8rnl.com "remotecontrold w8rnl__c link never xrf093_c" + sleep 10 + $CUSTOM/playWxAlertBg $COUNTY & + fi + fi # -s plist.txt +fi + +exit 0 + diff --git a/getWxAlert.save b/getWxAlert.save new file mode 100755 index 0000000..5ad0fbf --- /dev/null +++ b/getWxAlert.save @@ -0,0 +1,487 @@ +#!/bin/bash +# +# $Id: getWxAlert 85 2012-07-21 23:13:23Z $ +# +# Change the method of updating alerts. Check if summary is different instead +# of the entire url download. This should help prevent updating alert beacons +# that are unnecessary. +# +# Added a check to see if the download failed, if so abort and log. Also +# changed the wget options for retry=10. +# +# Spool Directory should contain the alert.info, pre/post converted files, +# no_alert, and alert summary +# +DEBUG="0" # debug levels 0 = no debug + # level 1 = save alerts + # level 2 = detailed info + + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# Check Arguments... +# has only one argument, county info +if [ "$#" = "1" ] ; then + COUNTY=$1 + COUNTY_NAME="" +fi + +# has two arguments, county info and county name +if [ "$#" = "2" ] ; then + COUNTY=$1 + COUNTY_NAME=$2 +fi + +# if no arguments, then use what is defined in configure file. +if [ "$1" = "" ] ; then + # extract County Information and County Name + COUNTY_NAME=`echo $COUNTY | awk 'BEGIN { FS="," } { print $2} '` + COUNTY=`echo $COUNTY | awk 'BEGIN { FS="," } { print $1} '` + # if name is empty, then use COUNTY + if [ "$COUNTY_NAME" = "" ] ; then + COUNTY_NAME=$COUNTY + fi +fi + +if [ "$COUNTY" = "NOTSET" ] || [ "$COUNTY" = "" ] ; then + echo "ERROR - The COUNTY variable in ${CUSTOM}/wx_scripts.conf is not set" + echo "or missing, aborting..." + exit 1 +fi + +if [ "$COUNTY" = "help" ] ; then # If no arguments + echo "Usage getWxAlert <county>" + echo " where <county>=State County, for example: WIC002" + echo " See http://alerts.weather.gov/ for more informaton" + echo + echo " Or you can edit the wx_scripts.conf file to include the COUNTY variable." + echo + exit 1 +fi + +if [ -z $TEXT2SPEECH ] ; then + echo "TEXT2SPEECH value not defined. Please edit wx_scripts_conf file." + exit 1 +fi + +if [ ! -d /tmp/wx/$COUNTY ] ; then + mkdir -p /tmp/wx/$COUNTY +fi + +####### Functions ###### +# Send message to LOGFILE +function debug2 () { + MESSAGE="${0##*/} DEBUG: $@" + echo "$MESSAGE" + if [ -n "$LOGFILE" ]; then + echo "`date '+%b %d %Y %T %z'` $MESSAGE" >> $LOGFILE + fi +} + +function send_email () { +for EADDR in `echo $EMAIL | sed 's/,/ /g'` ; do + + # summary version + # $MAIL -s "Weather Alert for $COUNTY_NAME" $EADDR < /tmp/wx/$COUNTY/pre_conv_alert_summary.txt + + # full alert info + cp /tmp/wx/$COUNTY/pre_alert.txt /tmp/wx/$COUNTY/email_alert.txt + # append the alert to the header + cat /tmp/wx/$COUNTY/pre_full_alert_info.txt >> /tmp/wx/$COUNTY/email_alert.txt + # mail it + $MAIL -s "Weather Alert for $COUNTY_NAME" $EADDR < /tmp/wx/$COUNTY/email_alert.txt + +done +} + +# Convert URL to file +#function geturldata () { +# # supply URL +# # Alternative method of getting url information: +# ##/usr/bin/lynx -dump $URL$COUNTY > /tmp/wx/$COUNTY/alert.info +# +# $WGET -t 10 -w 10 --cache=off --random-wait -q $URL$COUNTY -O - > /tmp/wx/$COUNTY/alert.info +# # -t 10 retries, -w 10 sec between +# # turn cache off at server +#} + +###### End of Functions ###### +PLIST="$CUSTOM/wx_alert_product.txt" # Product list file and directory +# URL="http://www.weather.gov/alerts-beta/wwaatmget.php?x=" # URL to RSS data +URL="http://alerts.weather.gov/cap/wwaatmget.php?x=" # URL to RSS data +DATE=`date +%Y.%m.%d.\%H\%M` +NO_WXALERT_MSG=$LOCAL/no_wxalert_msg + +MAILDIR="/tmp/wx/$COUNTY" # Mail log file +MAILLOG="$MAILDIR/spotter_mail.log" # Mail log file +#MAIL=/bin/mail # mail binary +MAIL="$CUSTOM/SendMail/SendMail.pl" # Perl SendMail script + +CRIT_TYPES=`cat $CUSTOM/wx_critical_alerts.txt` +NORM_TYPES=`cat $CUSTOM/wx_normal_alerts.txt` + +#----------------------------- Main program ---------------------- + +if [ ! -d $WXALERT_SPOOLDIR/$COUNTY ] ; then + mkdir -p $WXALERT_SPOOLDIR/$COUNTY +fi + +if [ ! -d /tmp/wx/$COUNTY ] ; then + mkdir -p /tmp/wx/$COUNTY +fi + +cd $WXALERT_SPOOLDIR/$COUNTY + +ALERT_DL="" +CHKCNT=0 +# loop until get proper response, if after 5 attempts notify +while [ -z "$ALERT_DL" ] ; do + + if [ $CHKCNT -gt 5 ] ; then + log "ERROR: $URL is not responding for getWxAlert - ${COUNTY}" + log " Possible issue with nws.gov server or internet connection" + ls -l /tmp/wx/$COUNTY/alert.info + exit 1 + fi + + # Alternative method of getting url information: + ##/usr/bin/lynx -dump $URL$COUNTY > /tmp/wx/$COUNTY/alert.info + + $WGET -t 10 -w 10 --cache=off --random-wait -q $URL$COUNTY -O - > /tmp/wx/$COUNTY/alert.info + # -t 10 retries, -w 10 sec between + # turn cache off at server + + # place data in variable to see if contains data + ALERT_DL="`head -1 /tmp/wx/$COUNTY/alert.info`" + let CHKCNT=$CHKCNT+1 + # delay before retrying + sleep 4 +done + +# process the downloaded information +cat /tmp/wx/$COUNTY/alert.info | \ + grep "title>" | + sed '/<title>/,/<\/title/!d' | \ + sed 's/<title>//' | sed 's/<\/title>//' | \ + egrep -v "Current Watches" > wx_new.txt + +# get full summary URL Link +FULL_SUMMARY_URL=`cat /tmp/wx/$COUNTY/alert.info | egrep "<id>|</id>" | sed 's/<id>//' | sed 's/<\/id>//'` + +# Extract Alert from url information: +ALERT=`cat /tmp/wx/$COUNTY/alert.info | egrep "<title>|" | sed 's///' | sed 's/<\/title>//'| sed 's/\(by NWS*\).*/\1/' | sed 's/by NWS//'` + +# Extract Summary from url information: +SUMMARY=`cat /tmp/wx/$COUNTY/alert.info | egrep "<summary>|</summary>" | sed 's/<summary>//' | sed 's/<\/summary>//'` + +# Debug stuff, print values for $ALERT and SUMMARY +if [ "$DEBUG" = "2" ] ; then + echo + debug2 "************START**************************" + debug2 "NWS_URL=$URL" + debug2 "FULL_SUMMARY_URL=$FULL_SUMMARY_URL" + debug2 "CHKCNT=$CHKCNT" + debug2 "ALERT=$ALERT" + debug2 "SUMMARY=$SUMMARY" + debug2 "COUNTY=$COUNTY" + debug2 "COUNTY_NAME=$COUNTY_NAME" +fi + +# Full_alert +echo "$ALERT ... $SUMMARY" > alert_summary.txt + +#if the download failed, alert_summary.txt has only " ... ", then log and exit. +if [ "$DEBUG" = "2" ] ; then + DWNCHK=`cat alert_summary.txt` + echo + debug2 "dwnload chk:$DWNCHK" +fi +if [ "`cat alert_summary.txt`" == " ... " ] ; then + log "ERROR: Failed to download alert correct data from ${COUNTY}" + log " Verify $COUNTY is valid or URL has not changed." + exit 1 +fi + +# check if no active watches, if so clean up any alerts and create +# no watches message for summary. +if ( grep "no active watches" wx_new.txt &> /dev/null ) ; then + + # skip all of this if no_alert file is present indicating audio generated + if [ ! -f no_alerts.txt ] ; then + rm -f *.ul # Remove all alerts, audio files + rm -f alert.txt + rm -f *.dvtool + rm -f conv_* + /usr/local/bin/remotecontrold kd8tuz_b unlink + + # alert_summary.txt and alert_pre_summary.txt must match, or will + # generate an alert +## + cp alert_summary.txt alert_prev_summary.txt + cp wx_new.txt no_alerts.txt # After clean up, create + # "no active warnings file + + # setup the no warnings message, append file with county info, the + # create audio +## + echo "for $COUNTY_NAME, $COUNTY" >> no_alerts.txt + + if [ $TEXT2SPEECH = "festival" ] ; then + $TEXT2WAVE -F 8000 -scale 2.0 -otype ulaw no_alerts.txt -o COMPLETE_ALERT.ul -eval "(voice_ked_diphone)" + else + $TEXT2WAVE -m text -f no_alerts.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o COMPLETE_ALERT.ul + fi + + ############################## + # save a history of alerts + # mv over to saved directory + # Save alert Information + + if [ "$DEBUG" = "1" ] ; then + if [ ! -f alert.txt ] && [ -f /tmp/wx/$COUNTY/pre_conv_alert_summary.txt ] ; then + # make sure directory is created + if [ ! -d saved/$DATE ] ; then + mkdir -p saved/$DATE + fi + # now save files + cp /tmp/wx/$COUNTY/*.txt saved/$DATE/. + fi + fi + fi # < if [ -f no_alerts.txt ] + exit 0 # Done, now exit. +fi + +log "Checking for Wx Alert updates for $COUNTY" +# Skip if files are the same, alerts are active, but nothing has changed. +if ! diff -q alert_summary.txt alert_prev_summary.txt &> /dev/null; then + + # New Alerts are found. + log "New Wx Alerts for $COUNTY" + cp alert_summary.txt alert_prev_summary.txt # make the files the same now + rm -f alert.txt *.raw no_alerts.txt # and remove old alerts + # remove email alert file + if [ -f /tmp/wx/${COUNTY}/email_alert.txt ] ; then + rm -f /tmp/wx/${COUNTY}/email_alert.txt + fi + # remove the old plist.txt file. + if [ -f plist.txt ] ; then + cp plist.txt /tmp/. + rm plist.txt + fi + + # create the alert file + echo "$ALERT" > alert.txt + + # Create the product list which is tested against + # if product not found, will leave a null file. This is tested against + # at end of script, see ref#1 + while read PRODUCT; do # Check for alert products + # appending the 1st matching, ignore case + grep -i -m 1 "^$PRODUCT" wx_new.txt + done < $PLIST >> plist.txt # line to alert.txt file + + ################################################################# + # Pre Conversions file creation. + ################################################################# + + ############################# + # create pre_alert.txt file (input to post conversion) + # + #set up header of the alert file + echo ". . Weather Alert. for $COUNTY_NAME" > /tmp/wx/$COUNTY/a_tmp.txt + + # check the alert types, critical/normal + if [ "$DEBUG" = "2" ] ; then + debug2 "********* WXALERT_BEACON=[$WXALERT_BEACON] **********" + fi + # Setup TYPES of alerts to trigger on depending upon WXALERT_BEACON Variable + if [ "$WXALERT_BEACON" = "C" ] ; then + TYPES=$CRIT_TYPES + else + TYPES=$NORM_TYPES + fi + + # Set flag + CRIT_BEACON_FLAG="N" + SAVEIFS=$IFS + IFS=$(echo -en "\n\b") + if [ "$DEBUG" = "2" ] ; then + debug2 "TYPES= $TYPES" + fi + + # check for matching TYPES in alert + for TYPE in $TYPES + do + ## added space to avoid the first line being seen as an alert + ## this may need to be changed as follows: + # egrep -v "Current Watches" alert.txt > alert1.txt + # mv alert1.txt alert + ## if grep -i "$TYPE" alert.txt >> /tmp/wx/$COUNTY/a_tmp.txt; then # Extract matching alerts + + if grep -i "$TYPE " alert.txt >> /tmp/wx/$COUNTY/a_tmp.txt; then # Extract matching alerts + echo ".." >> /tmp/wx/$COUNTY/a_tmp.txt + log "Get Wx Alert INFO for $COUNTY: $TYPE" + # set critical beacon flag, if a match + CRIT_BEACON_FLAG="Y" + fi + done + IFS=$SAVEIFS + + # rename to pre_alert.txt + mv /tmp/wx/$COUNTY/a_tmp.txt /tmp/wx/$COUNTY/pre_alert.txt + + ############################# + # create pre_conv_alert_summmary.txt (input to post conversion) + # insert weather header/trailer to full alert txt + echo ". . Weather Alert Summary for county $COUNTY_NAME." > /tmp/wx/$COUNTY/a_tmp.txt + cat alert_summary.txt >> /tmp/wx/$COUNTY/a_tmp.txt + + # copy tmp.txt over for post conversion + cp /tmp/wx/$COUNTY/a_tmp.txt /tmp/wx/$COUNTY/pre_conv_alert_summary.txt + +# Remove since we want to have the email text with the full alert +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +## if [ "$FULL_ALERT" = "Y" ] ; then + + ALERT_DL="" + CHKCNT=0 + # loop until get proper response, if after 5 attempts notify + while [ -z "$ALERT_DL" ] ; do + + if [ $CHKCNT -gt 5 ] ; then + log "ERROR: $URL is not responding for getWxAlert - ${COUNTY}" + log " Possible issue with nws.gov server or internet connection" + ls -l /tmp/wx/$COUNTY/alert.info + exit 1 + fi + + + ############################## + # Create the raw full Summary File + $WGET -t 10 -w 10 --cache=off --random-wait -q $FULL_SUMMARY_URL -O - > /tmp/wx/$COUNTY/full_alert_info.txt + # -t 10 retries, -w 10 sec between + # turn cache off at server + + # place data in variable to see if contains data + ALERT_DL="`head -1 /tmp/wx/$COUNTY/alert.info`" + let CHKCNT=$CHKCNT+1 + # delay before retrying + sleep 4 + done + + # Create full summary from URL file + # setup pre_converted full alert message + # cp /tmp/wx/$COUNTY/pre_conv_alert_summary.txt /tmp/wx/$COUNTY/pre_full_alert_info.txt + cat /tmp/wx/$COUNTY/full_alert_info.txt | sed '/<description>/,/<\/description/!d' | \ + sed 's/<description>//' | \ + sed 's/<\/description>//' > /tmp/wx/$COUNTY/pre_full_alert_info.txt + +# fi +# end ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + # additional debug info + if [ "$DEBUG" = "2" ] ; then + debug2 "**************************************************************" + debug2 "**alert's don't match**" + debug2 "==============================================================" + debug2 "alert_summary file:" + debug2 " /home/irlp/audio/custom/wx/alert/${COUNTY}/alert_summary.txt" + debug2 "==============================================================" + debug2 "alert_prev_summary.txt file:" + debug2 " /home/irlp/audio/custom/wx/alert/${COUNTY}/alert_prev_summary.txt" + debug2 "==============================================================" + debug2 "pre_full_alert_info.txt file:" + debug2 " /tmp/wx/${COUNTY}/pre_full_alert_info.txt" + debug2 "**************************************************************" + debug2 + fi + + ################################################################# + # Post Conversions + # You must edit wxtext_conv.sed file to perform the post conversion. + ################################################################# + + ############################# + # pre_alert txt file to conv_alert.txt + sed -f ${CUSTOM}/wxtext_conv.sed /tmp/wx/$COUNTY/pre_alert.txt > conv_alert.txt + # conv_alert summary txt file to conv_alert_summary.txt + sed -f ${CUSTOM}/wxtext_conv.sed /tmp/wx/$COUNTY/pre_conv_alert_summary.txt > conv_alert_summary.txt + /home/irlp/custom/dstartext + + # full alert text + if [ "$FULL_ALERT" = "Y" ] ; then + ############################# + # pre_full_alert_info file to conv + sed -f ${CUSTOM}/wxtext_conv.sed /tmp/wx/$COUNTY/pre_full_alert_info.txt > conv_full_alert_info.txt + fi + + ################################################################# + # create the audio files + ################################################################# + + if [ $TEXT2SPEECH = "festival" ] ; then + $TEXT2WAVE -F 8000 -scale 2.0 -otype ulaw conv_alert.txt -o ALERT.ul -eval "(voice_ked_diphone)" + # $TEXT2WAVE -F 8000 -scale 2.0 -otype ulaw conv_alert_summary.txt -o COMPLETE_ALERT.ul -eval "(voice_ked_diphone)" + ffmpeg -i ALERT.wav -y -ar 48000 + +# cd $WXALERT_SPOOLDIR/$COUNTY + # /usr/bin/espeak conv_alert.txt ALERT + # full alert text + if [ "$FULL_ALERT" = "Y" ] ; then + $TEXT2WAVE -F 8000 -scale 1 -otype ulaw conv_full_alert_info.txt -o FULLCOMPLETE_ALERT.ul -eval "(voice_ked_diphone)" + fi + else + $TEXT2WAVE -m text -f conv_alert.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o ALERT.ul + $TEXT2WAVE -m text -f conv_alert_summary.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o COMPLETE_ALERT.ul + # full alert text + if [ "$FULL_ALERT" = "Y" ] ; then + $TEXT2WAVE -m text -f conv_full_alert_info.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o FULLCOMPLETE_ALERT.ul + fi + fi + + #clean up + rm -f /tmp/wx/$COUNTY/a_tmp.txt + + # check if file exists and size gt zero, if not email/play weather (ref#1) + if [ -s plist.txt ]; then + # Email Alerts if $EMAIL defined. + if [ ! -z "$EMAIL" ] ; then + send_email + echo -e "\nMail sent on $DATE" >> $MAILLOG + fi + # if WXALERT_BEACON is set to Yes, then place playWxAlertBg into + # background + # + # Beacon needs to be Y -or- (beacon C -and- Crit_Beacon flag yes) + if [ "$DEBUG" = "2" ] ; then + echo "WXALERT_BEACON = $WXALERT_BEACON, CRIT_BEACON_FLAG=$CRIT_BEACON_FLAG" + fi + if [ $WXALERT_BEACON = "Y" ] || ([ $WXALERT_BEACON = "C" ] && [ $CRIT_BEACON_FLAG = "Y" ]) ; then + # first kill any left over process + # get PID and kill it + if [ -f $WXALERT_SPOOLDIR/$COUNTY/playWxAlertBg.pid ] ; then + kill `cat < playWxAlertBg.pid` + fi + # if $LOCAL/no_wxalert_msg file is present, remove it to start + # new weather alert msg + if [ -f $NO_WXALERT_MSG ] ; then + rm $NO_WXALERT_MSG + fi + # call playWxAlert and place in background + log "Launching playWxAlertBg..." + /usr/local/bin/remotecontrold kd8tuz_b link never ref039_C + sleep 10 + $CUSTOM/playWxAlertBg $COUNTY & + fi + fi # -s plist.txt +fi + +exit 0 + diff --git a/getWxAlert.save.1 b/getWxAlert.save.1 new file mode 100755 index 0000000..a3ca068 --- /dev/null +++ b/getWxAlert.save.1 @@ -0,0 +1,199 @@ +#!/bin/bash +# +# $Id: getWxAlert 85 2012-07-21 23:13:23Z $ +# +# Change the method of updating alerts. Check if summary is different instead +# of the entire url download. This should help prevent updating alert beacons +# that are unnecessary. +# +# Added a check to see if the download failed, if so abort and log. Also +# changed the wget options for retry=10. +# +# Spool Directory should contain the alert.info, pre/post converted files, +# no_alert, and alert summary +# +DEBUG="0" # debug levels 0 = no debug + # level 1 = save alerts + # level 2 = detailed info + + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# Check Arguments... +# has only one argument, county info +if [ "$#" = "1" ] ; then + COUNTY=$1 + COUNTY_NAME="" +fi + +# has two arguments, county info and county name +if [ "$#" = "2" ] ; then + COUNTY=$1 + COUNTY_NAME=$2 +fi + +# if no arguments, then use what is defined in configure file. +if [ "$1" = "" ] ; then + # extract County Information and County Name + COUNTY_NAME=`echo $COUNTY | awk 'BEGIN { FS="," } { print $2} '` + COUNTY=`echo $COUNTY | awk 'BEGIN { FS="," } { print $1} '` + # if name is empty, then use COUNTY + if [ "$COUNTY_NAME" = "" ] ; then + COUNTY_NAME=$COUNTY + fi +fi + +if [ "$COUNTY" = "NOTSET" ] || [ "$COUNTY" = "" ] ; then + echo "ERROR - The COUNTY variable in ${CUSTOM}/wx_scripts.conf is not set" + echo "or missing, aborting..." + exit 1 +fi + +if [ "$COUNTY" = "help" ] ; then # If no arguments + echo "Usage getWxAlert <county>" + echo " where <county>=State County, for example: WIC002" + echo " See http://alerts.weather.gov/ for more informaton" + echo + echo " Or you can edit the wx_scripts.conf file to include the COUNTY variable." + echo + exit 1 +fi + +if [ -z $TEXT2SPEECH ] ; then + echo "TEXT2SPEECH value not defined. Please edit wx_scripts_conf file." + exit 1 +fi + +if [ ! -d /tmp/wx/$COUNTY ] ; then + mkdir -p /tmp/wx/$COUNTY +fi + +####### Functions ###### +# Send message to LOGFILE +function debug2 () { + MESSAGE="${0##*/} DEBUG: $@" + echo "$MESSAGE" + if [ -n "$LOGFILE" ]; then + echo "`date '+%b %d %Y %T %z'` $MESSAGE" >> $LOGFILE + fi +} + +function send_email () { +for EADDR in `echo $EMAIL | sed 's/,/ /g'` ; do + + # summary version + # $MAIL -s "Weather Alert for $COUNTY_NAME" $EADDR < /tmp/wx/$COUNTY/pre_conv_alert_summary.txt + + # full alert info + cp /tmp/wx/$COUNTY/pre_alert.txt /tmp/wx/$COUNTY/email_alert.txt + # append the alert to the header + cat /tmp/wx/$COUNTY/pre_full_alert_info.txt >> /tmp/wx/$COUNTY/email_alert.txt + # mail it + $MAIL -s "Weather Alert for $COUNTY_NAME" $EADDR < /tmp/wx/$COUNTY/email_alert.txt + +done +} + +# Convert URL to file +#function geturldata () { +# # supply URL +# # Alternative method of getting url information: +# ##/usr/bin/lynx -dump $URL$COUNTY > /tmp/wx/$COUNTY/alert.info +# +# $WGET -t 10 -w 10 --cache=off --random-wait -q $URL$COUNTY -O - > /tmp/wx/$COUNTY/alert.info +# # -t 10 retries, -w 10 sec between +# # turn cache off at server +#} + +###### End of Functions ###### +PLIST="$CUSTOM/wx_alert_product.txt" # Product list file and directory +# URL="http://www.weather.gov/alerts-beta/wwaatmget.php?x=" # URL to RSS data +URL="http://alerts.weather.gov/cap/wwaatmget.php?x=" # URL to RSS data +DATE=`date +%Y.%m.%d.\%H\%M` +NO_WXALERT_MSG=$LOCAL/no_wxalert_msg + +MAILDIR="/tmp/wx/$COUNTY" # Mail log file +MAILLOG="$MAILDIR/spotter_mail.log" # Mail log file +#MAIL=/bin/mail # mail binary +MAIL="$CUSTOM/SendMail/SendMail.pl" # Perl SendMail script + +CRIT_TYPES=`cat $CUSTOM/wx_critical_alerts.txt` +NORM_TYPES=`cat $CUSTOM/wx_normal_alerts.txt` + +#----------------------------- Main program ---------------------- + +if [ ! -d $WXALERT_SPOOLDIR/$COUNTY ] ; then + mkdir -p $WXALERT_SPOOLDIR/$COUNTY +fi + +if [ ! -d /tmp/wx/$COUNTY ] ; then + mkdir -p /tmp/wx/$COUNTY +fi + +cd $WXALERT_SPOOLDIR/$COUNTY + +ALERT_DL="" +CHKCNT=0 +# loop until get proper response, if after 5 attempts notify +while [ -z "$ALERT_DL" ] ; do + + if [ $CHKCNT -gt 5 ] ; then + log "ERROR: $URL is not responding for getWxAlert - ${COUNTY}" + log " Possible issue with nws.gov server or internet connection" + ls -l /tmp/wx/$COUNTY/alert.info + exit 1 + fi + + # Alternative method of getting url information: + ##/usr/bin/lynx -dump $URL$COUNTY > /tmp/wx/$COUNTY/alert.info + + $WGET -t 10 -w 10 --cache=off --random-wait -q $URL$COUNTY -O - > /tmp/wx/$COUNTY/alert.info + # -t 10 retries, -w 10 sec between + # turn cache off at server + + # place data in variable to see if contains data + ALERT_DL="`head -1 /tmp/wx/$COUNTY/alert.info`" + let CHKCNT=$CHKCNT+1 + # delay before retrying + sleep 4 +done + +# process the downloaded information +cat /tmp/wx/$COUNTY/alert.info | \ + grep "title>" |sed '/<title>/,/<\/title/!d' | \ + sed 's/<title>//' | sed 's/<\/title>//' | \ + egrep -v "Current Watches" > wx_new.txt + +# get full summary URL Link +FULL_SUMMARY_URL=`cat /tmp/wx/$COUNTY/alert.info | egrep "<id>|</id>" | sed 's/<id>//' | sed 's/<\/id>//'` + +# Extract Alert from url information: +ALERT=`cat /tmp/wx/$COUNTY/alert.info | egrep "<title>|" | sed 's///' | sed 's/<\/title>//'| sed 's/\(by NWS*\).*/\1/' | sed 's/by NWS//'` + +# Extract Summary from url information: +SUMMARY=`cat /tmp/wx/$COUNTY/alert.info | egrep "<summary>|</summary>" | sed 's/<summary>//' | sed 's/<\/summary>//'` + +# Debug stuff, print values for $ALERT and SUMMARY +if [ "$DEBUG" = "2" ] ; then + echo + debug2 "************START**************************" + debug2 "NWS_URL=$URL" + debug2 "FULL_SUMMARY_URL=$FULL_SUMMARY_URL" + debug2 "CHKCNT=$CHKCNT" + debug2 "ALERT=$ALERT" + debug2 "SUMMARY=$SUMMARY" + debug2 "COUNTY=$COUNTY" + debug2 "COUNTY_NAME=$COUNTY_NAME" +fi + +# Full_alert +echo "$ALERT ... $SUMMARY" > alert_summary.txt + +#if the download failed, alert_summary.txt has only " ... ", then log and exit. diff --git a/getWxAlert.save.2 b/getWxAlert.save.2 new file mode 100755 index 0000000..d8d4e9a --- /dev/null +++ b/getWxAlert.save.2 @@ -0,0 +1,486 @@ +#!/bin/bash +# +# $Id: getWxAlert 85 2012-07-21 23:13:23Z $ +# +# Change the method of updating alerts. Check if summary is different instead +# of the entire url download. This should help prevent updating alert beacons +# that are unnecessary. +# +# Added a check to see if the download failed, if so abort and log. Also +# changed the wget options for retry=10. +# +# Spool Directory should contain the alert.info, pre/post converted files, +# no_alert, and alert summary +# +DEBUG="0" # debug levels 0 = no debug + # level 1 = save alerts + # level 2 = detailed info + + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# Check Arguments... +# has only one argument, county info +if [ "$#" = "1" ] ; then + COUNTY=$1 + COUNTY_NAME="" +fi + +# has two arguments, county info and county name +if [ "$#" = "2" ] ; then + COUNTY=$1 + COUNTY_NAME=$2 +fi + +# if no arguments, then use what is defined in configure file. +if [ "$1" = "" ] ; then + # extract County Information and County Name + COUNTY_NAME=`echo $COUNTY | awk 'BEGIN { FS="," } { print $2} '` + COUNTY=`echo $COUNTY | awk 'BEGIN { FS="," } { print $1} '` + # if name is empty, then use COUNTY + if [ "$COUNTY_NAME" = "" ] ; then + COUNTY_NAME=$COUNTY + fi +fi + +if [ "$COUNTY" = "NOTSET" ] || [ "$COUNTY" = "" ] ; then + echo "ERROR - The COUNTY variable in ${CUSTOM}/wx_scripts.conf is not set" + echo "or missing, aborting..." + exit 1 +fi + +if [ "$COUNTY" = "help" ] ; then # If no arguments + echo "Usage getWxAlert <county>" + echo " where <county>=State County, for example: WIC002" + echo " See http://alerts.weather.gov/ for more informaton" + echo + echo " Or you can edit the wx_scripts.conf file to include the COUNTY variable." + echo + exit 1 +fi + +if [ -z $TEXT2SPEECH ] ; then + echo "TEXT2SPEECH value not defined. Please edit wx_scripts_conf file." + exit 1 +fi + +if [ ! -d /tmp/wx/$COUNTY ] ; then + mkdir -p /tmp/wx/$COUNTY +fi + +####### Functions ###### +# Send message to LOGFILE +function debug2 () { + MESSAGE="${0##*/} DEBUG: $@" + echo "$MESSAGE" + if [ -n "$LOGFILE" ]; then + echo "`date '+%b %d %Y %T %z'` $MESSAGE" >> $LOGFILE + fi +} + +function send_email () { +for EADDR in `echo $EMAIL | sed 's/,/ /g'` ; do + + # summary version + # $MAIL -s "Weather Alert for $COUNTY_NAME" $EADDR < /tmp/wx/$COUNTY/pre_conv_alert_summary.txt + + # full alert info + cp /tmp/wx/$COUNTY/pre_alert.txt /tmp/wx/$COUNTY/email_alert.txt + # append the alert to the header + cat /tmp/wx/$COUNTY/pre_full_alert_info.txt >> /tmp/wx/$COUNTY/email_alert.txt + # mail it + $MAIL -s "Weather Alert for $COUNTY_NAME" $EADDR < /tmp/wx/$COUNTY/email_alert.txt + +done +} + +# Convert URL to file +#function geturldata () { +# # supply URL +# # Alternative method of getting url information: +# ##/usr/bin/lynx -dump $URL$COUNTY > /tmp/wx/$COUNTY/alert.info +# +# $WGET -t 10 -w 10 --cache=off --random-wait -q $URL$COUNTY -O - > /tmp/wx/$COUNTY/alert.info +# # -t 10 retries, -w 10 sec between +# # turn cache off at server +#} + +###### End of Functions ###### +PLIST="$CUSTOM/wx_alert_product.txt" # Product list file and directory +# URL="http://www.weather.gov/alerts-beta/wwaatmget.php?x=" # URL to RSS data +URL="http://alerts.weather.gov/cap/wwaatmget.php?x=" # URL to RSS data +DATE=`date +%Y.%m.%d.\%H\%M` +NO_WXALERT_MSG=$LOCAL/no_wxalert_msg + +MAILDIR="/tmp/wx/$COUNTY" # Mail log file +MAILLOG="$MAILDIR/spotter_mail.log" # Mail log file +#MAIL=/bin/mail # mail binary +MAIL="$CUSTOM/SendMail/SendMail.pl" # Perl SendMail script + +CRIT_TYPES=`cat $CUSTOM/wx_critical_alerts.txt` +NORM_TYPES=`cat $CUSTOM/wx_normal_alerts.txt` + +#----------------------------- Main program ---------------------- + +if [ ! -d $WXALERT_SPOOLDIR/$COUNTY ] ; then + mkdir -p $WXALERT_SPOOLDIR/$COUNTY +fi + +if [ ! -d /tmp/wx/$COUNTY ] ; then + mkdir -p /tmp/wx/$COUNTY +fi + +cd $WXALERT_SPOOLDIR/$COUNTY + +ALERT_DL="" +CHKCNT=0 +# loop until get proper response, if after 5 attempts notify +while [ -z "$ALERT_DL" ] ; do + + if [ $CHKCNT -gt 5 ] ; then + log "ERROR: $URL is not responding for getWxAlert - ${COUNTY}" + log " Possible issue with nws.gov server or internet connection" + ls -l /tmp/wx/$COUNTY/alert.info + exit 1 + fi + + # Alternative method of getting url information: + ##/usr/bin/lynx -dump $URL$COUNTY > /tmp/wx/$COUNTY/alert.info + + $WGET -t 10 -w 10 --cache=off --random-wait -q $URL$COUNTY -O - > /tmp/wx/$COUNTY/alert.info + # -t 10 retries, -w 10 sec between + # turn cache off at server + + # place data in variable to see if contains data + ALERT_DL="`head -1 /tmp/wx/$COUNTY/alert.info`" + let CHKCNT=$CHKCNT+1 + # delay before retrying + sleep 4 +done + +# process the downloaded information +cat /tmp/wx/$COUNTY/alert.info | \ + grep "title>" |sed '/<title>/,/<\/title/!d' | \ + sed 's/<title>//' | sed 's/<\/title>//' | \ + egrep -v "Current Watches" > wx_new.txt + +# get full summary URL Link +FULL_SUMMARY_URL=`cat /tmp/wx/$COUNTY/alert.info | egrep "<id>|</id>" | sed 's/<id>//' | sed 's/<\/id>//'` + +# Extract Alert from url information: +ALERT=`cat /tmp/wx/$COUNTY/alert.info | egrep "<title>|" | sed 's///' | sed 's/<\/title>//'| sed 's/\(by NWS*\).*/\1/' | sed 's/by NWS//'` + +# Extract Summary from url information: +SUMMARY=`cat /tmp/wx/$COUNTY/alert.info | egrep "<summary>|</summary>" | sed 's/<summary>//' | sed 's/<\/summary>//'` + +# Debug stuff, print values for $ALERT and SUMMARY +if [ "$DEBUG" = "2" ] ; then + echo + debug2 "************START**************************" + debug2 "NWS_URL=$URL" + debug2 "FULL_SUMMARY_URL=$FULL_SUMMARY_URL" + debug2 "CHKCNT=$CHKCNT" + debug2 "ALERT=$ALERT" + debug2 "SUMMARY=$SUMMARY" + debug2 "COUNTY=$COUNTY" + debug2 "COUNTY_NAME=$COUNTY_NAME" +fi + +# Full_alert +echo "$ALERT ... $SUMMARY" > alert_summary.txt + +#if the download failed, alert_summary.txt has only " ... ", then log and exit. +if [ "$DEBUG" = "2" ] ; then + DWNCHK=`cat alert_summary.txt` + echo + debug2 "dwnload chk:$DWNCHK" +fi +if [ "`cat alert_summary.txt`" == " ... " ] ; then + log "ERROR: Failed to download alert correct data from ${COUNTY}" + log " Verify $COUNTY is valid or URL has not changed." + exit 1 +fi + +# check if no active watches, if so clean up any alerts and create +# no watches message for summary. +if ( grep "no active watches" wx_new.txt &> /dev/null ) ; then + + # skip all of this if no_alert file is present indicating audio generated + if [ ! -f no_alerts.txt ] ; then + rm -f *.ul # Remove all alerts, audio files + rm -f alert.txt + rm -f *.dvtool + rm -f conv_* + /usr/local/bin/remotecontrold kd8tuz_b unlink + + # alert_summary.txt and alert_pre_summary.txt must match, or will + # generate an alert +## + cp alert_summary.txt alert_prev_summary.txt + cp wx_new.txt no_alerts.txt # After clean up, create + # "no active warnings file + + # setup the no warnings message, append file with county info, the + # create audio +## + echo "for $COUNTY_NAME, $COUNTY" >> no_alerts.txt + + if [ $TEXT2SPEECH = "festival" ] ; then + $TEXT2WAVE -F 8000 -scale 2.0 -otype ulaw no_alerts.txt -o COMPLETE_ALERT.ul -eval "(voice_ked_diphone)" + else + $TEXT2WAVE -m text -f no_alerts.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o COMPLETE_ALERT.ul + fi + + ############################## + # save a history of alerts + # mv over to saved directory + # Save alert Information + + if [ "$DEBUG" = "1" ] ; then + if [ ! -f alert.txt ] && [ -f /tmp/wx/$COUNTY/pre_conv_alert_summary.txt ] ; then + # make sure directory is created + if [ ! -d saved/$DATE ] ; then + mkdir -p saved/$DATE + fi + # now save files + cp /tmp/wx/$COUNTY/*.txt saved/$DATE/. + fi + fi + fi # < if [ -f no_alerts.txt ] + exit 0 # Done, now exit. +fi + +log "Checking for Wx Alert updates for $COUNTY" +# Skip if files are the same, alerts are active, but nothing has changed. +if ! diff -q alert_summary.txt alert_prev_summary.txt &> /dev/null; then + + # New Alerts are found. + log "New Wx Alerts for $COUNTY" + cp alert_summary.txt alert_prev_summary.txt # make the files the same now + rm -f alert.txt *.raw no_alerts.txt # and remove old alerts + # remove email alert file + if [ -f /tmp/wx/${COUNTY}/email_alert.txt ] ; then + rm -f /tmp/wx/${COUNTY}/email_alert.txt + fi + # remove the old plist.txt file. + if [ -f plist.txt ] ; then + cp plist.txt /tmp/. + rm plist.txt + fi + + # create the alert file + echo "$ALERT" > alert.txt + + # Create the product list which is tested against + # if product not found, will leave a null file. This is tested against + # at end of script, see ref#1 + while read PRODUCT; do # Check for alert products + # appending the 1st matching, ignore case + grep -i -m 1 "^$PRODUCT" wx_new.txt + done < $PLIST >> plist.txt # line to alert.txt file + + ################################################################# + # Pre Conversions file creation. + ################################################################# + + ############################# + # create pre_alert.txt file (input to post conversion) + # + #set up header of the alert file + echo ". . Weather Alert. for $COUNTY_NAME" > /tmp/wx/$COUNTY/a_tmp.txt + + # check the alert types, critical/normal + if [ "$DEBUG" = "2" ] ; then + debug2 "********* WXALERT_BEACON=[$WXALERT_BEACON] **********" + fi + # Setup TYPES of alerts to trigger on depending upon WXALERT_BEACON Variable + if [ "$WXALERT_BEACON" = "C" ] ; then + TYPES=$CRIT_TYPES + else + TYPES=$NORM_TYPES + fi + + # Set flag + CRIT_BEACON_FLAG="N" + SAVEIFS=$IFS + IFS=$(echo -en "\n\b") + if [ "$DEBUG" = "2" ] ; then + debug2 "TYPES= $TYPES" + fi + + # check for matching TYPES in alert + for TYPE in $TYPES + do + ## added space to avoid the first line being seen as an alert + ## this may need to be changed as follows: + # egrep -v "Current Watches" alert.txt > alert1.txt + # mv alert1.txt alert + ## if grep -i "$TYPE" alert.txt >> /tmp/wx/$COUNTY/a_tmp.txt; then # Extract matching alerts + + if grep -i "$TYPE " alert.txt >> /tmp/wx/$COUNTY/a_tmp.txt; then # Extract matching alerts + echo ".." >> /tmp/wx/$COUNTY/a_tmp.txt + log "Get Wx Alert INFO for $COUNTY: $TYPE" + # set critical beacon flag, if a match + CRIT_BEACON_FLAG="Y" + fi + done + IFS=$SAVEIFS + + # rename to pre_alert.txt + mv /tmp/wx/$COUNTY/a_tmp.txt /tmp/wx/$COUNTY/pre_alert.txt + + ############################# + # create pre_conv_alert_summmary.txt (input to post conversion) + # insert weather header/trailer to full alert txt + echo ". . Weather Alert Summary for county $COUNTY_NAME." > /tmp/wx/$COUNTY/a_tmp.txt + cat alert_summary.txt >> /tmp/wx/$COUNTY/a_tmp.txt + + # copy tmp.txt over for post conversion + cp /tmp/wx/$COUNTY/a_tmp.txt /tmp/wx/$COUNTY/pre_conv_alert_summary.txt + +# Remove since we want to have the email text with the full alert +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +## if [ "$FULL_ALERT" = "Y" ] ; then + + ALERT_DL="" + CHKCNT=0 + # loop until get proper response, if after 5 attempts notify + while [ -z "$ALERT_DL" ] ; do + + if [ $CHKCNT -gt 5 ] ; then + log "ERROR: $URL is not responding for getWxAlert - ${COUNTY}" + log " Possible issue with nws.gov server or internet connection" + ls -l /tmp/wx/$COUNTY/alert.info + exit 1 + fi + + + ############################## + # Create the raw full Summary File + $WGET -t 10 -w 10 --cache=off --random-wait -q $FULL_SUMMARY_URL -O - > /tmp/wx/$COUNTY/full_alert_info.txt + # -t 10 retries, -w 10 sec between + # turn cache off at server + + # place data in variable to see if contains data + ALERT_DL="`head -1 /tmp/wx/$COUNTY/alert.info`" + let CHKCNT=$CHKCNT+1 + # delay before retrying + sleep 4 + done + + # Create full summary from URL file + # setup pre_converted full alert message + # cp /tmp/wx/$COUNTY/pre_conv_alert_summary.txt /tmp/wx/$COUNTY/pre_full_alert_info.txt + cat /tmp/wx/$COUNTY/full_alert_info.txt | sed '/<description>/,/<\/description/!d' | \ + sed 's/<description>//' | \ + sed 's/<\/description>//' > /tmp/wx/$COUNTY/pre_full_alert_info.txt + +# fi +# end ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + # additional debug info + if [ "$DEBUG" = "2" ] ; then + debug2 "**************************************************************" + debug2 "**alert's don't match**" + debug2 "==============================================================" + debug2 "alert_summary file:" + debug2 " /home/irlp/audio/custom/wx/alert/${COUNTY}/alert_summary.txt" + debug2 "==============================================================" + debug2 "alert_prev_summary.txt file:" + debug2 " /home/irlp/audio/custom/wx/alert/${COUNTY}/alert_prev_summary.txt" + debug2 "==============================================================" + debug2 "pre_full_alert_info.txt file:" + debug2 " /tmp/wx/${COUNTY}/pre_full_alert_info.txt" + debug2 "**************************************************************" + debug2 + fi + + ################################################################# + # Post Conversions + # You must edit wxtext_conv.sed file to perform the post conversion. + ################################################################# + + ############################# + # pre_alert txt file to conv_alert.txt + sed -f ${CUSTOM}/wxtext_conv.sed /tmp/wx/$COUNTY/pre_alert.txt > conv_alert.txt + # conv_alert summary txt file to conv_alert_summary.txt + sed -f ${CUSTOM}/wxtext_conv.sed /tmp/wx/$COUNTY/pre_conv_alert_summary.txt > conv_alert_summary.txt + /home/irlp/custom/dstartext + + # full alert text + if [ "$FULL_ALERT" = "Y" ] ; then + ############################# + # pre_full_alert_info file to conv + sed -f ${CUSTOM}/wxtext_conv.sed /tmp/wx/$COUNTY/pre_full_alert_info.txt > conv_full_alert_info.txt + fi + + ################################################################# + # create the audio files + ################################################################# + + if [ $TEXT2SPEECH = "festival" ] ; then + $TEXT2WAVE -F 8000 -scale 2.0 -otype wav conv_alert.txt -o conv_alert.wav + # $TEXT2WAVE -F 8000 -scale 2.0 -otype ulaw conv_alert_summary.txt -o COMPLETE_ALERT.ul -eval "(voice_ked_diphone)" +# cd $WXALERT_SPOOLDIR/$COUNTY + # /usr/bin/espeak conv_alert.txt ALERT + ffmpeg -i conv_alert.wav -y -ar 48000 ALERT.wav + /usr/local/bin/wav2dvtool ALERT.wav KD8TUZ/ALERT KD8TUZ_B KD8TUZ_G "Weather Alert" ALERT.dvtool + # full alert text + if [ "$FULL_ALERT" = "Y" ] ; then + $TEXT2WAVE -F 8000 -scale 1 -otype ulaw conv_full_alert_info.txt -o FULLCOMPLETE_ALERT.ul -eval "(voice_ked_diphone)" + fi + else + $TEXT2WAVE -m text -f conv_alert.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o ALERT.ul + $TEXT2WAVE -m text -f conv_alert_summary.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o COMPLETE_ALERT.ul + # full alert text + if [ "$FULL_ALERT" = "Y" ] ; then + $TEXT2WAVE -m text -f conv_full_alert_info.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o FULLCOMPLETE_ALERT.ul + fi + fi + + #clean up + rm -f /tmp/wx/$COUNTY/a_tmp.txt + + # check if file exists and size gt zero, if not email/play weather (ref#1) + if [ -s plist.txt ]; then + # Email Alerts if $EMAIL defined. + if [ ! -z "$EMAIL" ] ; then + send_email + echo -e "\nMail sent on $DATE" >> $MAILLOG + fi + # if WXALERT_BEACON is set to Yes, then place playWxAlertBg into + # background + # + # Beacon needs to be Y -or- (beacon C -and- Crit_Beacon flag yes) + if [ "$DEBUG" = "2" ] ; then + echo "WXALERT_BEACON = $WXALERT_BEACON, CRIT_BEACON_FLAG=$CRIT_BEACON_FLAG" + fi + if [ $WXALERT_BEACON = "Y" ] || ([ $WXALERT_BEACON = "C" ] && [ $CRIT_BEACON_FLAG = "Y" ]) ; then + # first kill any left over process + # get PID and kill it + if [ -f $WXALERT_SPOOLDIR/$COUNTY/playWxAlertBg.pid ] ; then + kill `cat < playWxAlertBg.pid` + fi + # if $LOCAL/no_wxalert_msg file is present, remove it to start + # new weather alert msg + if [ -f $NO_WXALERT_MSG ] ; then + rm $NO_WXALERT_MSG + fi + # call playWxAlert and place in background + log "Launching playWxAlertBg..." + /usr/local/bin/remotecontrold kd8tuz_b link never ref039_C + sleep 10 + $CUSTOM/playWxAlertBg $COUNTY & + fi + fi # -s plist.txt +fi + +exit 0 + diff --git a/getWxFor b/getWxFor new file mode 100755 index 0000000..6668326 --- /dev/null +++ b/getWxFor @@ -0,0 +1,92 @@ +#!/bin/sh +# +##################################################################### +# filename: getWxFor +# +# description: Uses festival text-to-speech synthesiser to convert +# weather data to audio and save as a ul file. +# +# usage: getWxFor +# +# 2006/06/20 w0anm Original Release +# +# $Id: getWxFor 46 2009-04-10 04:27:25Z $ +###################################################################### + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# if ZONE not an argument, then use what is defined in configure file. +if [ "$1" = "" ] ; then + ZONE_FOR=$ZONE +else + ZONE_FOR=$1 +fi +if [ ! -d $WXFOR_SPOOLDIR/$ZONE_FOR ] ; then + mkdir -p $WXFOR_SPOOLDIR/$ZONE_FOR +fi + +# Local noaa forecast text link +# setup ZONE_FOR variable to convert to lower case and extract state +LC_ZONE=`echo $ZONE_FOR | tr 'A-Z' 'a-z'` +STATE=`echo $LC_ZONE | awk 'BEGIN { FS="z" } { print $1} '` + +# set URL for wget. This is the url where the forcasts originate. +URL="http://tgftp.nws.noaa.gov/data/forecasts/zone/${STATE}/${LC_ZONE}.txt" + +WX_TXT="wx_forecast.txt" +WX_TXT_TMP="wx_forecast.tmp" +WX_TXT_TMP2="wx_forecast2.tmp" + +#----------------------------- Main program ----------------------------- + +echo Downloading.... +cd $WXFOR_SPOOLDIR/$ZONE_FOR +wget $URL +echo Done.... +mv ohz070.txt $WX_TXT_TMP + +# delete the first 10 lines before converting +TOTAL_LINE=`wc $WX_TXT_TMP | awk '{print $1}'` +LINE_DISP=`expr $TOTAL_LINE - 10` + +# sed -f ${CUSTOM}/wxtext_conv.sed $WX_TXT_TMP > $WX_TXT + +tail -${LINE_DISP} $WX_TXT_TMP | sed "s/\./\. /g ; s/0S/0's/g ; s/\$\$\$/. end of message . . . /g" | sed -f ${CUSTOM}/wxtext_conv.sed > $WX_TXT + + +# Do standard conversion.. +# first convert to lower case +cat $WX_TXT | tr 'A-Z' 'a-z' > $WX_TXT_TMP + +sed -f ${CUSTOM}/wxtext_conv.sed $WX_TXT_TMP > $WX_TXT_TMP2 + +# add heater and cat file +echo "Weather forecast for $ZONE..." > $WX_TXT_TMP +cat $WX_TXT_TMP $WX_TXT_TMP2 > $WX_TXT + +# clean up temp files +rm $WX_TXT_TMP $WX_TXT_TMP2 + +# convert + +if [ $TEXT2SPEECH = "festival" ] ; then + # $TEXT2WAVE -F 8000 -scale 0.5 -otype ulaw $WX_TXT -o forecast.ul -eval "(voice_ked_diphone)" + $TEXT2WAVE -otype wav -o forecast.wav $WXTXT + ffmpeg -i forecast.wav -y -ar 48000 forecast1.wav + /usr/local/bin/wav2dvtool forecast1.wav KD8TUZ_REPORT KD8TUZ_B KD8TUZ_G "Hamilton Forecast Report" forecast.dvtool +fi + +if [ $TEXT2SPEECH = "cepstral" ] ; then + $TEXT2WAVE -m text -f $WX_TXT -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o forecast.ul +fi + +exit 0 + +# EOF diff --git a/getWxHaz b/getWxHaz new file mode 100755 index 0000000..ce5207c --- /dev/null +++ b/getWxHaz @@ -0,0 +1,24 @@ +#!/bin/bash +# +# +# +# +cd /tmp/ +rm wx_* +rm haz* +wget -O haz_tmp.txt http://tgftp.nws.noaa.gov/data/raw/fl/flus41.kiln.hwo.iln.txt + +#tail -n +22 haz_tmp.txt > wx_haz_tmp.txt +sed '/DAY/,$!d' haz_tmp.txt > haz_tmp1.txt +sed '/$$/,$d' haz_tmp1.txt > wx_haz_tmp.txt +sed -i '1s/^/This is the Hazardous Weather Outlook for Butler County. /' wx_haz_tmp.txt +sed -f /wxtext_conv.sed wx_haz_tmp.txt > wx_haz.txt + +pico2wave -w wx_haz_tmp.wav "$(cat wx_haz.txt)" +#text2wave -F 48000 -otype wav wx_haz.txt -o wx_haz.wav +ffmpeg -i wx_haz_tmp.wav -ar 48000 wx_haz.wav +sox -v -0.5 wx_haz_tmp.wav -r 48000 wx_haz.wav treble +6 +/usr/local/bin/wav2dvtool wx_haz.wav KD8TUZ/HAZD KD8TUZ_B KD8TUZ_G "Hazardous WX Outlook" wx_haz.dvtool + + +exit 0 diff --git a/getWxRpt b/getWxRpt new file mode 100755 index 0000000..8c65e89 --- /dev/null +++ b/getWxRpt @@ -0,0 +1,91 @@ +#!/bin/bash +##################################################################### +# filename: getWxRpt +# +# description: Uses festival text-to-speech synthesiser to convert +# weather data to audio and save as a ul file. +# +# usage: getWxRpt +# +# history: +# 2004/08/18 kc6hur Original Release +# +# Modified by w0anm +# $Id: getWxRpt 46 2009-04-10 04:27:25Z $ +###################################################################### +LOGFILE=/tmp/wx1.txt +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# if ICAO_STN not an argument, then use what is defined in configure file. +if [ "$1" = "" ] ; then + ICAO_LIST=$ICAO_STN +else + ICAO_LIST=$1 +fi + +# WXTXT="$WXDIR/report/$ICAO.txt" +# WXTXT_TMP="/tmp/$ICAO.txt" +# WXAUD="$WXDIR/report/$ICAO.ul" +# WXURL="http://weather.noaa.gov/pub/data/observations/metar/stations/$ICAO.TXT" + +if [ ! -d $WXDIR/report ] ; then + mkdir -p $WXDIR/report +fi + + +#----------------------------------------------------------------------- +# Get the METAR weather string and convert it to a text file. + +for ICAO in $ICAO_LIST ; do + log "Get METAR for $ICAO" + WXTXT="$WXDIR/report/$ICAO.txt" + WXTXT_TMP="/tmp/$ICAO.txt" + WXAUD="$WXDIR/report/$ICAO" + +WXURL="http://tgftp.nws.noaa.gov/data/observations/metar/stations/$ICAO.TXT" + + ## rm -f $WXTXT &>/dev/null + + /usr/bin/wget -q -O - $WXURL > /tmp/wx_metar + + if `/usr/bin/wget -q -O - $WXURL | /metar2text > $WXTXT 2>> $LOGFILE` ; then + log "Error getting METAR for $ICAO" + exit 0 + else + log "Got METAR for $ICAO" + fi + # Fix any formating issues: + sed -f /wxtext_conv.sed $WXTXT > $WXTXT_TMP +# echo "end of report. . . " >> $WXTXT_TMP + cp $WXTXT_TMP $WXTXT + + # Convert text output into a ul file. + # + if [ -f $WXTXT ] ; then + if [ $TEXT2SPEECH = "festival" ] ; then + #$TEXT2WAVE -F 48000 -otype wav -o $WXAUD1.wav $WXTXT + #ffmpeg -i $WXAUD.wav -y -ar 48000 $WXAUD1.wav + pico2wave -w $WXAUD.wav "$(cat $WXTXT)" + sox --norm -V -v 0.1 $WXAUD.wav -r 48000 $WXAUD1.wav + /usr/local/bin/wav2dvtool $WXAUD1.wav KD8TUZ_REPORT KD8TUZ_B KD8TUZ_G "Hamilton WX Report" $WXAUD.dvtool + + # sourced out audio files + #echo "$WXTXT" + #espeak $WXTXT $WXAUD + fi + if [ $TEXT2SPEECH = "cepstral" ] ; then + $TEXT2WAVE -m text -f $WXTXT -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o $WXAUD.new + fi + #mv $WXTXT_TMP $WXTXT + #log "$WXAUD has been saved" + #rm -f $WXTXT &>/dev/null + fi +done +exit 0 diff --git a/getWxRpt_ug b/getWxRpt_ug new file mode 100755 index 0000000..3d66f07 --- /dev/null +++ b/getWxRpt_ug @@ -0,0 +1,185 @@ +#/bin/bash +# + +# load up configuration variables +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source /wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# if Weather Underground _STN not an argument, then use what is defined in confi gure file. +if [ "$1" = "" ] ; then + WX_UNDERGRND_STN=${WX_UNDERGRND_STN} +else + WX_UNDERGRND_STN=$1 +fi + +# Various files and directories + +# report/working dirs +UG_WX_DIR=/custom/wx/report_ug/${WX_UNDERGRND_STN} +UG_WX_PAR_DIR=/custom/WxRpt_ug +UG_WX_WRKING_DIR=/custom/WxRpt_ug/${WX_UNDERGRND_STN} + +# make sure custom audio wx directory is created +if [ ! -d $UG_WX_DIR ] ; then + mkdir -p $UG_WX_DIR +fi + +# make sure custom working wx directory is created +if [ ! -d $UG_WX_WRKING_DIR ] ; then + mkdir -p $UG_WX_WRKING_DIR +fi + +# parsing_list.txt file lists weather items to capture +P_LIST=$UG_WX_PAR_DIR/parsing_list.txt + +# weather underground web information. ID value is important +# ID set from wx_scripts.conf +URL="http://api.wunderground.com/weatherstation/WXCurrentObXML.asp?ID=${WX_UNDERGRND_STN}" + +# get date info for last update information +DATE=`date +%Y.%m.%d.\%H\%M` + +#----------------------------- Main program ----------------------------- + +# clean up first +rm -f $UG_WX_WRKING_DIR/var.src $UG_WX_DIR/pre_current_wx.txt $UG_WX_DIR/conv_current_wx.txt $UG_WX_DIR/working_current_wx.ul + +# Get weather information +$WGET -q $URL -O - > ${UG_WX_DIR}/${WX_UNDERGRND_STN}.xml + +# parse the list and extract the variables +for ITEM in `cat "$P_LIST" | awk '{ print $1 }'` + do + VARIABLE=`grep -m 1 $ITEM ${UG_WX_DIR}/${WX_UNDERGRND_STN}.xml | awk 'BEGIN { FS = "<" } { print $2 } ' | sed 's/>/ /g' | awk '{ print $1}'` + + VALUE=`grep -m 1 $ITEM ${UG_WX_DIR}/${WX_UNDERGRND_STN}.xml | awk ' BEGIN { FS = "/" } { print $1 }'| awk 'BEGIN { FS = ">" } { print $2 } ' | awk ' BEGIN { FS = "<" } { print $1 }'` + + echo "${VARIABLE}=\"${VALUE}\"" >> $UG_WX_WRKING_DIR/var.src + +done + +# initialize the variables (import them) +source $UG_WX_WRKING_DIR/var.src + +# Save current pressure and get current pressure trend for pressure info +cur_pressure_in=$pressure_in + +if [ -f $UG_WX_WRKING_DIR/old_pressure.var ] ; then + # get old "saved pressure_in" value, for pressure trends + # this is created by crontab every 4 hours. + source $UG_WX_WRKING_DIR/old_pressure.var + + # convert to integer (may change to *100) + cur_pressure=`echo "${cur_pressure_in}*100" | bc` + pressure=`echo "${pressure_in}*100" | bc` + + # convert to integer + cur_pressure=${cur_pressure/\.*} + pressure=${pressure/\.*} + + # see if pressure is rising or falling... + if [ $cur_pressure -gt $pressure ]; then + pressure_trend="rising" + fi + if [ $cur_pressure -lt $pressure ]; then + pressure_trend="falling" + fi + if [ $cur_pressure -eq $pressure ]; then + pressure_trend="steady" + fi +fi + + +# Build the wx report... +# Intro info and time recorded +echo ". . This is the ${CALL_SPACED} node weather report for $neighborhood , $city . " >> $UG_WX_DIR/pre_current_wx.txt +echo "$observation_time," >> $UG_WX_DIR/pre_current_wx.txt + +# Wind Info +if [ "$wind_string" = "Calm" ] ; then + echo "the wind was calm." >> $UG_WX_DIR/pre_current_wx.txt + ##echo "wind_string=$wind_string, wind_mph=$wind_mph, wind_gust_mph=$wind_gust_mph" +else + case $wind_dir in + NNE) wind_dir="north north east" ;; + NE) wind_dir="north east" ;; + ENE) wind_dir="east north east" ;; + + ESE) wind_dir="east south east" ;; + SE) wind_dir="south east" ;; + SSE) wind_dir="south south east" ;; + + SSW) wind_dir="south south west" ;; + SW) wind_dir="south west" ;; + WSW) wind_dir="west south west" ;; + + WNW) wind_dir="west north west" ;; + NW) wind_dir="north west" ;; + NNW) wind_dir="north north west" ;; + esac + + echo "the wind was blowing at a speed of ${wind_mph} miles per hour from ${wind_dir} with wind gusts up to ${wind_gust_mph} miles per hour. " >> $UG_WX_DIR/pre_current_wx.txt + +fi + +# Temp and Dewpoint Info +echo "The temperature was ${temp_f} degrees with a dewpoint of ${dewpoint_f} degrees." >> $UG_WX_DIR/pre_current_wx.txt + +# Windchill +if [ ${windchill_f} ] ; then + echo "the wind chill was at ${windchill_f} degrees." >> $UG_WX_DIR/pre_current_wx.txt +fi + +# Pressure and pressure trend +echo "The pressure was ${pressure_trend} at ${cur_pressure_in} inches of mercury. " >> $UG_WX_DIR/pre_current_wx.txt + +# Humidity info +echo "The relative humidity was $relative_humidity percent." >> $UG_WX_DIR/pre_current_wx.txt + +# Finally, Precipatation Data +if [ "$precip_today_in" != "0.00" ] ; then + echo "Total precipatation today was ${precip_today_in} inches, precipatation in the last hour was ${precip_1hr_in} inches." >> $UG_WX_DIR/pre_current_wx.txt +fi + +# store current pressure + +echo "# Last Updated: $DATE" > $UG_WX_WRKING_DIR/saved_pressure.var +echo "pressure_in=$cur_pressure_in" >> $UG_WX_WRKING_DIR/saved_pressure.var + +# end of message +echo "end of message. ." >> $UG_WX_DIR/pre_current_wx.txt + +############################# +# Post Conversions +# You must edit wxtext_conv.sed file to perform the post conversion. +############################## +# alert txt file to conv_alert.txt +sed -f ${CUSTOM}/wxtext_conv.sed $UG_WX_DIR/pre_current_wx.txt > $UG_WX_DIR/conv_current_wx.txt + +############################## +# create the audio file +if [ $TEXT2SPEECH = "festival" ] ; then + $TEXT2WAVE -F 8000 -scale 0.5 -otype ulaw $UG_WX_DIR/conv_current_wx.txt -o $UG_WX_DIR/working_current_wx.ul -eval "(voice_ked_diphone)" +else + $TEXT2WAVE -m text -f $UG_WX_DIR/conv_current_wx.txt -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o $UG_WX_DIR/working_current_wx.ul +fi + +# Since it takes time to create the working_current_wx.ul, copy it over when finished. + +cp $UG_WX_DIR/working_current_wx.ul $UG_WX_DIR/current_wx.ul + +rm $UG_WX_DIR/working_current_wx.ul + +# Notes: +# create a file that has the items that you want to capture and used +# for example: +## value equivalent in speech +# temp_f "temperature is" +# +# create a text file based upon the above file and store. Use a for/loop +# to run through the text file. + diff --git a/getWxSkywarn b/getWxSkywarn new file mode 100755 index 0000000..9a32413 --- /dev/null +++ b/getWxSkywarn @@ -0,0 +1,137 @@ +#!/bin/sh +# +# get_skywarn - Used to parse hazardous weather outlook web page for +# Skywarn activation. Designed to be run from crond once an hour. +# +# (c) 2006 Timothy Miller WB0RXX -- Released under GPL v2 +# +# Modified by W0ANM +# $Id: getWxSkywarn 79 2011-04-22 18:19:55Z $ +###################################################################### +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# if ZONE not an argument, then use what is defined in configure file. +if [ "$1" = "" ] ; then + ZONE=$ZONE +else + ZONE=$1 +fi + +# Check Arguments... +# has only one argument, county info +if [ "$#" = "1" ] ; then + COUNTY=$1 + COUNTY_NAME=$1 +fi + +# has two arguments, county info and county name +if [ "$#" = "2" ] ; then + COUNTY=$1 + COUNTY_NAME=$2 +fi + +# if no arguments, then use what is defined in configure file. +if [ "$1" = "" ] ; then + # extract County Information and County Name + COUNTY_NAME=`echo $COUNTY | awk 'BEGIN { FS="," } { print $2} '` + COUNTY=`echo $COUNTY | awk 'BEGIN { FS="," } { print $1} '` + # if name is empty, then use COUNTY + if [ "$COUNTY_NAME" = "" ] ; then + COUNTY_NAME=$COUNTY + fi +fi + +if [ "$COUNTY" = "NOTSET" ] || [ "$COUNTY" = "" ] ; then + echo "ERROR - The COUNTY variable in ${CUSTOM}/wx_scripts.conf is not set" + echo "or missing, aborting..." + exit 1 +fi + +#---------------------------- Command variables ------------------------ +CP="/bin/cp" # Location of binaries +DATE="/bin/date" # +DIFF="/usr/bin/diff" # +GREP="/bin/grep" # +HEAD="/usr/bin/head" # +LYNX="/usr/bin/lynx" # +# MAIL="/bin/mail" # +MAIL="/home/irlp/custom/SendMail/SendMail.pl" # SendMail script +SED="/bin/sed" # +TAIL="/usr/bin/tail" # +TR="/usr/bin/tr" # + +#---------------------------- User variables ---------------------------- +MAILDIR="/tmp/$ZONE" # Mail log file +TMPDIR="/home/irlp/audio/custom/wx/skywarn/$ZONE" # Temp directory +WXSKY_SPOOLDIR=$TMPDIR # Skywarn spooldir +COUNTY="MNC053" # NWS county + +#--------------------------- Static variables --------------------------- + +NOTNEEDED="WILL NOT BE NEEDED" # Spotters not needed string #1 +NOTANTICIPATED="IS NOT ANTICIPATED" # Spotters not needed string #2 +HWO_TXT="$TMPDIR/hwo.txt" # Hazardous wx outlook outfile +SPOTTER=".SPOTTER INFORMATION" # Spotter info string +SPOTTER_OLD="$WXSKY_SPOOLDIR/spotter.old" # Old spotter outfile +SPOTTER_TXT="$WXSKY_SPOOLDIR/spotter.txt" # Spotter outfile +URL="http://www.crh.noaa.gov/showsigwx.php?warnzone=$ZONE&warncounty=$COUNTY&product1=Hazardous+Weather+Outlook" + +#--------------------------- Functions --------------------------- +function send_email () { +for EADDR in `echo $EMAIL | sed 's/,/ /g'` ; do + $MAIL -s "SkyWarn for $COUNTY_NAME" $EADDR < $SPOTTER_TXT +done +} + +#----------------------------- Main program ----------------------------- + +if [ -z $TEXT2SPEECH ] ; then + echo "TEXT2SPEECH value not defined. Please edit wx_scripts_conf file." + exit 1 +fi + +# check if directories are present, if not create. +if [ ! -d $WXSKY_SPOOLDIR ] ; then + mkdir -p $WXSKY_SPOOLDIR +fi +if [ ! -d $MAILDIR ] ; then + mkdir -p $MAILDIR +fi + +$LYNX -dump -nolist $URL > $HWO_TXT # Fetch NWS data + +$GREP -i -A 6 "^$SPOTTER" $HWO_TXT | \ +$TR '\n' ' ' | $SED 's/\.\.\./*/; s/\$\$/\*\*/g' | \ +$TR '*' '\n' | $HEAD -2 | $TAIL -1 > $SPOTTER_TXT + +if ! $DIFF -q $SPOTTER_OLD $SPOTTER_TXT &> /dev/null; then + $CP $SPOTTER_TXT $SPOTTER_OLD + if ( [ -s $SPOTTER_TXT ] && \ + $GREP -v "$NOTNEEDED" $SPOTTER_TXT &>/dev/null && \ + $GREP -v "$NOTANTICIPATED" $SPOTTER_TXT &>/dev/null ); then + if [ ! -z "$EMAIL" ] ; then + send_email + log "Spotter mail sent for $ZONE, $COUNTY" + fi + # create the audio file + if [ $TEXT2SPEECH = "festival" ] ; then + $TEXT2WAVE -F 8000 -scale 3.5 -otype ulaw $SPOTTER_TXT -o $TMPDIR/spotter.ul + else + $TEXT2WAVE -f $SPOTTER_TXT -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o $TMPDIR/spotter.ul + fi + + else + if [ $TEXT2SPEECH = "festival" ] ; then + $TEXT2WAVE -F 8000 -scale 3.5 -otype ulaw $SPOTTER_TXT -o $TMPDIR/spotter.ul + else + $TEXT2WAVE -m text "Spotter Activation is not needed at this time.." -p audio/encoding=ulaw,audio/sampling-rate=8000,audio/volume=$SWIFT_VOL -o $TMPDIR/spotter.ul + fi + fi +fi diff --git a/index.html b/index.html new file mode 100755 index 0000000..b154523 --- /dev/null +++ b/index.html @@ -0,0 +1,8 @@ +<html> +<head> + <title>AT&T + + + AT&T + + diff --git a/index.html.1 b/index.html.1 new file mode 100755 index 0000000..b154523 --- /dev/null +++ b/index.html.1 @@ -0,0 +1,8 @@ + + + AT&T + + + AT&T + + diff --git a/metar2text b/metar2text new file mode 100755 index 0000000..dd64a94 --- /dev/null +++ b/metar2text @@ -0,0 +1,1112 @@ +#!/usr/bin/perl -w +######################################################################## +# +# filename: metar2text +# +# description: A PERL program that will read a METAR from the STDIN and +# produce a human readable report. Multiple languages are +# supported by having all language dependent information +# in a seperate file. Thus that is the only files that must +# be changed to support a different language. The main +# engine contained here does not need to be modified. +# +# One advantage of this program over GEO:METAR is that +# program allows international information to be processed +# and this one provides a much more comprehensive report. +# If you want to create your own report, ALL of the +# of the decoded data is available +# +# formulas: Wind Chill - T = temp F; V = wind speed MPH +# Valid for V >= 3 and T <= 45 +# WC = 35.74 + 0.6215T - 35.75(V^0.16) + 0.4275T(V^0.16) +# +# Heat Index - T = temp F; RH = Relative Humidity +# Valid for T >= 80 and RH >= 40 +# HI = -42.379 + 2.0491523T + 10.14333127RH -0.22475541TRH +# - (6.83783 * 10^-3)T^2 - (5.48171 * 10^-2)RH^2 +# + (1.22874 * 10^-3)T^2RH + (8.5282 * 10^-4)TRH^2 +# - (1.99 * 10^-6)T^2RH^2 +# +# Relative Humidity - T = temp C; Td = dew point C +# RH = (((112 - (0.1T) + Td) / (112 + (0.9T)))**8)*100.0 +# +# history: +# 20040818 kc6hur Alpha release +# 20060903 kc6hur 0.10 New formulas for Relative Humidity, +# Wind Chill and added Heat Index. Provide +# better personalization of report. +# +# $Id: metar2text 31 2009-01-05 02:52:02Z $" +######################################################################## + +package METAR; + +## Required Modules + +use 5.005; +use strict; +use vars qw($AUTOLOAD $VERSION); +use Carp 'cluck'; +use Date::Manip qw(ParseDate UnixDate); +use Time::Local; +# use exported CALL_SPACED variable (from wx_scripts.conf) +use Env qw(CALL_SPACED); + +my $VERSION = '0.10'; + +## +## Language dependent data +## + +######################################################################## +## These tables contain all of the "words" used to generate the final +## printed report. In order to provide, international support, all that +## is necessary is to change the data in these tables. +######################################################################## + +my %_weather_types = ( + MI => ' shallow', + PR => ' partial', + BC => ' patches', + DR => ' low drifting', ## drizzle + BL => ' blowing', + SH => ' shower(s)', + TS => ' thunderstorm', + FZ => ' freezing', + + DZ => ' drizzle', + RA => ' rain', + SN => ' snow', + SG => ' snow grains', + IC => ' ice crystals', + PE => ' ice pellets', + GR => ' hail', + GS => ' small hail and or snow pellets', + UP => ' unknown', + + BR => ' mist', + FG => ' fog', + FU => ' smoke', + VA => ' volcanic ash', + DU => ' widespread dust', ## dust + SA => ' sand', + HZ => ' haze', + PY => ' spray', + + PO => ' well-developed dust sand whirls', + SQ => ' squalls', + FC => ' funnel cloud (tornado/waterspout)', + SS => ' sand storm', + DS => ' dust storm' +); + +my %_cloud_condition = ( + SKC => 'was clear', + CLR => 'was clear', + VV => 'was vertical visibility', + FEW => 'were a few', + SCT => 'were scattered', + BKN => 'were broken', + OVC => 'was overcast', +); + +my %_cloud_coverage = ( + SKC => '0', + CLR => '0', + VV => '8/8', + FEW => '1/8 - 2/8', + SCT => '3/8 - 4/8', + BKN => '5/7 - 7/8', + OVC => '8/8', +); + +my @_wind_dir = ( + 'North', + 'North Northeast', + 'Northeast', + 'East Northeast', + 'East', + 'East Southeast', + 'Southeast', + 'South Southeast', + 'South', + 'South Southwest', + 'Southwest', + 'West Southwest', + 'West', + 'West Northwest', + 'Northwest', + 'North Northwest', + 'North'); + +my %_units = ( + english_height => 'feet', + english_depth => 'inches', + english_distance => 'miles', + english_speed => 'miles per hour', + english_pressure => 'inches of mercury', + english_temperature => 'degrees', + metric_height => 'meters', + metric_depth => 'millimeters', + metric_distance => 'kilometers', + metric_speed => 'meters per second', + metric_pressure => 'hecto-pascals', + metric_temperature => 'celcius', +); + +my %_strings = ( + no_data => 'Sorry! There is no data available for %s.', + mm_inches => '%s %s', + precip_a_trace => 'a trace', + precip_there_was => ' There was %s of precipitation ', + sky_str_format1 => ' There %s at a height of %s %s', + sky_str_format2 => ', %s at a height of %s %s and %s at a height of %s %s', + sky_str_format3 => ' and %s at a height of %s %s', + sky_str_clear => ' The sky was clear', + sky_cavok => ' There were no clouds below %s.', + clouds => ' clouds', + clouds_cb => ' cumulonimbus clouds', + clouds_tcu => ' towering cumulus clouds', + visibility_format => ' The visibility was %s %s.', + wind_str_format1 => 'blowing at a speed of %s %s', + wind_str_format2 => ', with gusts to %s %s,', + wind_str_format3 => ' from %s', + wind_str_calm => 'calm', + wind_vrb_long => 'variable directions', + windchill => ', the windchill was %s %s', + rel_humidity => ' The relative humidity was %s%%.', + heat_index => ', the heat index was %s %s', + precip_last_hour => 'in the last hour. ', + precip_last_6_hours => 'in the last 3 to 6 hours. ', + precip_last_24_hours => 'in the last 24 hours. ', + precip_snow => ' There is %s %s of snow on the ground.', + temp_min_max_6_hours => ' The high and low temperatures over the last 6 hours were %s and %s %s.', + temp_max_6_hours => ' The high temperature over the last 6 hours was %s %s.', + temp_min_6_hours => ' The low temperature over the last 6 hours was %s %s.', + temp_min_max_24_hours => ' The high and low temperatures over the last 24 hours were %s and %s %s.', + runway_vis => ' The visibility for runway %s is %s meters (%s feet).', + runway_vis_min_max => ' The visibility for runway %s varies between %s meters (%s feet) and %s meters (%s feet).', + light => ' light', + moderate => ' moderate', + Heavy => ' heavy', + nearby => ' nearby', + current_weather => ' The weather condition was%s.', + barometric_pressure => ' and the pressure was %s %s', + pretty_print_format => 'This is the %s node weather report for the %s. At %s, the wind was %s. The temperature was %s %s%s%s.%s%s%s%s%s%s%s', +); + +## +## +## + +my $_weather_types_pat = join("|", keys(%_weather_types)); + +######################################################################## +## +## DEFINE THE METAR METHODS +## +######################################################################## + +## +## Constructor. +## + +sub new +{ + my $this = shift; + my $class = ref($this) || $this; + my $self = {}; + + $self->{version} = $VERSION; + $self->{metar} = undef; + $self->{station} = undef; + $self->{type} = undef; + $self->{time} = undef; + $self->{mod} = undef; + $self->{wind_dir_deg} = undef; + $self->{wind_dir_txt} = undef; + $self->{wind_meters_per_second} = undef; + $self->{wind_knots} = undef; + $self->{wind_miles_per_hour} = undef; + $self->{wind_gust_meters_per_second} = undef; + $self->{wind_gust_knots} = undef; + $self->{wind_gust_miles_per_hour} = undef; + $self->{wind_var_beg} = undef; + $self->{wind_var_end} = undef; + $self->{visibility_miles} = undef; + $self->{visibility_km} = undef; + $self->{runway_nr} = undef; + $self->{runway_vis_ft} = undef; + $self->{runway_vis_meter} = undef; + $self->{runway_vis_ft_min} = undef; + $self->{runway_vis_meter_min} = undef; + $self->{runway_vis_ft_max} = undef; + $self->{runway_vis_meter_max} = undef; + $self->{weather} = undef; + $self->{cloud_layer1_condition} = undef; + $self->{cloud_layer1_coverage} = undef; + $self->{cloud_layer1_altitude_ft} = undef; + $self->{cloud_layer1_altitude_m} = undef; + $self->{cloud_layer2_condition} = undef; + $self->{cloud_layer2_coverage} = undef; + $self->{cloud_layer2_altitude_ft} = undef; + $self->{cloud_layer2_altitude_m} = undef; + $self->{cloud_layer3_condition} = undef; + $self->{cloud_layer3_coverage} = undef; + $self->{cloud_layer3_altitude_ft} = undef; + $self->{cloud_layer3_altitude_m} = undef; + $self->{dew_c} = undef; + $self->{dew_f} = undef; + $self->{altimeter_inhg} = undef; + $self->{altimeter_mmhg} = undef; + $self->{altimeter_hpa} = undef; + $self->{altimeter_atm} = undef; + $self->{temp_c} = undef; + $self->{temp_f} = undef; + $self->{temp_c_max6h} = undef; + $self->{temp_f_max6h} = undef; + $self->{temp_c_min6h} = undef; + $self->{temp_f_min6h} = undef; + $self->{temp_c_max24h} = undef; + $self->{temp_f_max24h} = undef; + $self->{temp_c_min24h} = undef; + $self->{temp_f_min24h} = undef; + $self->{precip_in} = undef; + $self->{precip_mm} = undef; + $self->{precip_6h_in} = undef; + $self->{precip_6h_mm} = undef; + $self->{precip_24h_in} = undef; + $self->{precip_24h_mm} = undef; + $self->{snow_in} = undef; + $self->{snow_mm} = undef; + $self->{rel_humidity} = undef; + $self->{humidex_c} = undef; + $self->{humidex_f} = undef; + $self->{windchill_f} = undef; + $self->{windchill_c} = undef; + $self->{heat_index_f} = undef; + $self->{heat_index_c} = undef; +# +# Set the value of units to 'english' or 'metric' +# + $self->{units} = 'english'; + $self->{hrs24} = 0; # 0=12hr, 1=24hr + $self->{debug} = 0; # 0=nodebug, 1=debug + + bless $self, $class; + return $self; +} + +######################################################################## +## Read the METAR, process it, load up the METAR object and return the +## original METAR +## + +sub fetch_metar { + # + # Fetches a new METER from STDIN and parses it + # The new METAR is returned. + # + my $self = shift; + my $metar = ''; + + while () { + chomp; + $metar = $_ if (/^([A-Z]{4,4}) /i); + } + $self->{metar} = $metar; + _process($self); + + return $self->{metar}; +} + +######################################################################## +## Autoload for access methods to stuff in %fields hash. +## + +sub AUTOLOAD { + my $self = shift; + + if (not ref $self) { + cluck "bad AUTOLOAD for obj [$self]"; + } + + if ($AUTOLOAD =~ /.*::(.*)/) { + my $key = $1; + + ## Check for the items... + + if (exists $self->{$key}) { + return $self->{$key}; + } else { + return undef; + } + } else { + warn "strange AUTOLOAD problem!"; + return undef; + } +} + +######################################################################## +## Get current version number. +## + +sub version { + my $self = shift; + return $self->{version}; +} + + +######################################################################## +## Get site id +## + +sub getstnid { + my $self = shift; + return $self->{site}; +} + +######################################################################## +## Process the METAR. +## +## This function decodes a raw METAR. +## +sub _process +{ + my $self = shift; + my $temp_visibility_miles = ''; + my $cloud_layers = 0; + my $remarks = 0; + + ## Assume standard report by default + + $self->{type} = "METAR"; + print STDERR "DEBUG: metar $self->{metar}\n" if $self->{debug}; + + foreach (split(/\s+/, $self->{metar})) { + + print STDERR "DEBUG: token [$_]..." if $self->{debug}; + + if (! $remarks) { + ## + ## Type of Report + ## + + if (/^(METAR|SPECI)$/i) { + print STDERR "Type of Report.\n" if $self->{debug}; + $self->{type} = $1; + } + + ## + ## Station Identifier + ## + ## Changed to check all 4 letters. Used to required K as the + ## first letter but this would break the program when used + ## to process data for non-USA weather. + ## + elsif ((! defined $self->{site}) && (/^([A-Z]{4,4})$/i)) { + print STDERR "Station Identifier.\n" if $self->{debug}; + $self->{site} = $1; + } + + ## + ## Date and Time of Report + ## + elsif (/^(\d{2})(\d{2})(\d{2})Z$/i) { + print STDERR "Date and Time of Report.\n" if $self->{debug}; + $self->{time} = timegm("00",$3,$2,$1,(gmtime)[4],(gmtime)[5]+1900); + } + + ## + ## Report Modifier + ## + elsif (/^(AUTO|COR|RTD|CC[A-Z]|RR[A-Z])$/i) { + print STDERR "Report Modifier.\n" if $self->{debug}; + $self->{report_mod} = $1; + } + + ## + ## Wind Group + ## + elsif (/^(\d{2,3}|VRB)(\d{2,3})(G(\d{2,3}))?(KT|MPS|KMH)$/i) { + print STDERR "Wind Group.\n" if $self->{debug}; + my $windunit = $5; + # + # now get the actual values + # + if ( $1 eq 'VRB' ) { + $self->{wind_deg} = $_strings{wind_vrb_long}; + $self->{wind_dir_text} = $_strings{wind_vrb_long}; + } else { + $self->{wind_deg} = $1; + $self->{wind_dir_text} = $_wind_dir[int(($1/22.5)+0.5)]; + } + ($self->{wind_meters_per_second}, + $self->{wind_knots}, + $self->{wind_miles_per_hour}) = conv_speed($2, $windunit); + if (defined $3) { + # + # We have a report with information about gusting. + # + ($self->{wind_gust_meters_per_second}, + $self->{wind_gust_knots}, + $self->{wind_gust_miles_per_hour}) = conv_speed($4, $windunit); + } + } + + ## + ## Wind Group - Variable Wind Direction + ## + elsif (/^(\d{3})V(\d{3})$/i) { + print STDERR "Wind Group - Variable Wind Direction.\n" if $self->{debug}; + $self->{wind_var_beg} = $1; + $self->{wind_var_end} = $2; + } + + ## + ## Visibility Group + ## in meters (4 digits only) + ## + elsif (/^(\d{4})$/i) { + if ( $1 == "9999" ) { + # + # Visibility Group Special Case + # + print STDERR "Visibility Group (>10 km).\n" if $self->{debug}; + $self->{visibility_miles} = '>6.2'; + $self->{visibility_km} = '>10'; + } else { + # + # Visibility Group Normal Case + print STDERR "Visibility Group (meters).\n" if $self->{debug}; + $self->{visibility_km} = $1 / 1000; + $self->{visibility_miles} = $self->{visibility_km} / 1.609344; + } + } + + ## + ## Visibility Group - Whole Miles + ## Save this token so that it can be used with Visibility Group below. + ## + elsif (/^M?\d$/i) { + print STDERR "Visibility Group (Whole miles).\n" if $self->{debug}; + $temp_visibility_miles = $_; + } + + ## + ## Visibility Group - Whole or Fractional Miles + ## + ## 2 3 4 + elsif (/^((\d)(\/))?(\d*)SM$/i) { + print STDERR "Visibility Group (Whole/Fractional miles).\n" if $self->{debug}; + + my $vis_miles = ((defined $3) && ($3 eq '/')) ? $2 / $4 : $4; + + if (($temp_visibility_miles)[0] eq 'M') { + $self->{visibility_miles} = '<'.$vis_miles; + $self->{visibility_km} = '<'.($vis_miles * 1.609344); + } else { + $self->{visibility_miles} = $vis_miles; + $self->{visibility_km} = $vis_miles * 1.609344; + } + } + + ## + ## CAVOK: used when the visibility is greater than 10 km, + ## the lowest cloud-base is at 5000 and there is no + ## significant weather. + ## + elsif (/^CAVOK$/i) { + print STDERR "is visibility information.\n" if $self->{debug}; + $self->{visibility_km} = '>10'; + $self->{visibility_miles} = '>6.2'; + $self->{cloud_layer1_condition} = 'CAVOK'; + } + + ## + ## Runway Visual Range Group + ## + elsif (/^R(\d{2}[RLC]?)\/([MP]?\d{4})V(P?\d{4})FT$/i) { + print STDERR "is runway visual information.\n" if $self->{debug}; + } + + ## + ## Present Weather Group + ## + elsif (/^(-|\+|VC)?($_weather_types_pat)+$/i) { + print STDERR "Present Weather Group.\n" if $self->{debug}; + my $part = $_; + if ($part =~ /-/) { + $self->{weather} .= $_strings{light}; + $part = substr($part, 1); + } elsif ($part =~ /\+/) { + $self->{weather} .= $_strings{heavy}; + } elsif (substr($part, 0, 2) =~ /VC/) { + $self->{weather} .= $_strings{nearby}; + $part = substr($part, 2); + } else { + $self->{weather} .= $_strings{moderate}; + } + + while (my $bite=substr($part, 0, 2)) { + $self->{weather} .= $_weather_types{$bite}; + $part = substr($part, 2); + } + } + + ## + ## Sky Condition Group + ## There can be up to three of these groups + ## + elsif (/^(CLR|SKC)$/i) { + print STDERR "Sky Condition Group.\n" if $self->{debug}; + $cloud_layers++; + + $self->{'cloud_layer'.$cloud_layers.'_condition'} = $1; + $self->{'cloud_layer'.$cloud_layers.'_coverage'} = $1; + } + + ## + ## Sky Condition Group + ## We found a(nother) cloud-layer group. There can be up to + ## thrre of these groups. + elsif (/^(VV|FEW|SCT|BKN|OVC)(\d{3})(CB|TCU)?$/i) { + print STDERR "Sky Condition Group.\n" if $self->{debug}; + $cloud_layers++; + if ((defined $3) && ($3 eq 'CB')) { + $self->{'cloud_layer'.$cloud_layers.'_condition'} = $_cloud_condition{$1} . $_strings{clouds_cb}; + } elsif ((defined $3) && ($3 eq 'TCU')) { + $self->{'cloud_layer'.$cloud_layers.'_condition'} = $_cloud_condition{$1} . $_strings{clouds_tcu}; + } else { + $self->{'cloud_layer'.$cloud_layers.'_condition'} = $_cloud_condition{$1} . (($1 eq 'OVC') ? '' : $_strings{clouds}); + } + $self->{'cloud_layer'.$cloud_layers.'_coverage'} = $_cloud_coverage{$1}; + $self->{'cloud_layer'.$cloud_layers.'_altitude_ft'} = $2 * 100; + $self->{'cloud_layer'.$cloud_layers.'_altitude_m'} = $2 * 30.48; + } + + ## + ## Temperature/Dew Point Group + ## + elsif (/^(M?\d{1,2})\/(M?\d{1,2})?$/i) { + print STDERR "Temperature/Dew Point Group.\n" if $self->{debug}; + my $temp_c = $1; + my $dew_c = $2 if (defined $2); + $temp_c =~ s/^M/-/; + $dew_c =~ s/^M/-/ if (defined $dew_c); + ($self->{temp_c}, $self->{temp_f}) = conv_temp($temp_c); + ($self->{dew_c}, $self->{dew_f}) = conv_temp($dew_c) if (defined $dew_c); + } + + ## + ## Altimeter + ## + elsif (/^A(\d{4})$/i) { + print STDERR "Altimeter.\n" if $self->{debug}; + $self->{altimeter_inhg} = $1 / 100; + $self->{altimeter_mmhg} = $1 * 0.254; + $self->{altimeter_hpa} = $1 * 0.33863881578947; + $self->{altimeter_atm} = $1 * 3.3421052631579e-4; + } + + ## + ## Remarks + ## + elsif (/^RMK$/i) { + print STDERR "Begin Remarks Section.\n" if $self->{debug}; + $remarks = 1; + } + + ## + ## Unknown Token + ## + else { + print STDERR "Unknown Token.\n" if $self->{debug}; + } + + } else { + ## + ## Now processing REMarks + ## + print STDERR "RMK..." if $self->{debug}; + ## + ## Hourly Temperature and Dew Point + ## + if (/^T(\d{4})(\d{4})?$/i) { + print STDERR "Hourly Temperature and Dew Point.\n" if $self->{debug}; + ($self->{temp_c}, $self->{temp_f}) = conv_coded_temp($1); + ($self->{dew_c}, $self->{dew_f}) = conv_coded_temp($2) if (defined $2); + } + + ## + ## 6-Hourly Maximum Temperature + ## + elsif (/^1(\d{4})$/i) { + print STDERR "6-Hourly Maximum Temperature.\n" if $self->{debug}; + ($self->{temp_max6h_c}, $self->{temp_max6h_f}) = conv_coded_temp($1); + } + + ## + ## 6-Hourly Minimum Temperature + ## + elsif (/^2(\d{4})$/i) { + print STDERR "6-Hourly Minimum Temperature.\n" if $self->{debug}; + ($self->{temp_min6h_c}, $self->{temp_min6h_f}) = conv_coded_temp($1); + } + + ## + ## 24-Hour Maximum and Minimum Temperature + ## + elsif (/^4(\d{4})(\d{4})$/i) { + print STDERR "24-Hour Maximum and Minimum Temperature.\n" if $self->{debug}; + ($self->{temp_max24h_c}, $self->{temp_max24h_f}) = conv_coded_temp($1); + ($self->{temp_min24h_c}, $self->{temp_min24h_f}) = conv_coded_temp($2); + } + + ## + ## 3-Hourly Pressure Tendancy + ## + elsif (/^5(\d{4})$/i) { + print STDERR "3-Hourly Pressure Tendancy.\n" if $self->{debug}; + } + + ## + ## Hourly Precipitation Amount + ## (stored as inches) + ## + elsif (/^P(\d{4})$/i) { + print STDERR "Hourly Precipitation Amount.\n" if $self->{debug}; + $self->{precip_in} = $1 / 100; + $self->{precip_mm} = $1 * 0.254; + } + + ## + ## 3- and 6-Hour Precipitation Amount + ## (store as inches) + ## + elsif (/^6(\d{4})$/i) { + print STDERR "3- and 6-Hour Precipitation Amount.\n" if $self->{debug}; + $self->{precip_6h_in} = $1 / 100; + $self->{precip_6h_mm} = $1 * 0.254; + } + + ## + ## 24-Hour Precipitation Amount + ## (store as inches) + ## + elsif (/^7(\d{4})$/i) { + print STDERR "24-Hour Precipitation Amount.\n" if $self->{debug}; + $self->{precip_24h_in} = $1 / 100; + $self->{precip_24h_mm} = $1 * 0.254; + } + + ## + ## Snow Depth on Ground + ## + elsif (/^4\/(\d{3})$/i) { + print STDERR "Snow Depth on Ground.\n" if $self->{debug}; + $self->{snow_in} = $1; + $self->{snow_mm} = $1 * 25.4; + } + + ## + ## Type of Automated Station + ## + elsif (/^AO(1|2)$/i) { + print STDERR "Type of Automated Station.\n" if $self->{debug}; + } + + ## + ## SEA Level Pressure + ## + elsif (/^SLP(\d{3}|NO)/i) { + print STDERR "Sea Level Pressure.\n" if $self->{debug}; + } + + ## + ## unknown. + ## + else { + print STDERR "is unknown token.\n" if $self->{debug}; + } + } + } + ## + ## All done processing the data in the METAR + ## + ## Process Derived Values + ## + + ## + ## Relative Humidity + ## + if (defined $self->{dew_c}) { + $self->{rel_humidity} = (((112 - (0.1 * $self->{temp_c}) + $self->{dew_c}) / ((112 + (0.9 * $self->{temp_c}))))**8)*100.0; + } + + ## + ## Heat Index + ## + if ((defined $self->{rel_humidity}) && (defined $self->{temp_f}) && ($self->{temp_f} >= 80) && ($self->{rel_humidity} >= 40)) { + my $T = $self->{temp_f}; + my $R = $self->{rel_humidity}; + $self->{heat_index_f} = -42.379 + (2.0491423 * $T) + (10.14333127 * $R) - (0.22475541 * $T * $R) - ((6.83783 * (10 ** -3)) * ($T ** 2)) - ((5.48171 * (10 ** -2)) * ($R ** 2)) + ((1.22874 * (10 ** -3)) * ($T ** 2) * $R) + ((8.5282 * (10 ** -4)) * $T * ($R ** 2)) - ((1.99 * (10 ** -6)) * ($T ** 2) * ($R ** 2)); + $self->{heat_index_c} = ($self->{heat_index_f} - 32) * 0.556; + } + + ## + ## Windchill + ## + if ((defined $self->{temp_f}) && ($self->{temp_f} <= 45) && ($self->{wind_miles_per_hour} >= 3)) { + my $wf = $self->{wind_miles_per_hour} ** 0.16; + $self->{windchill_f} = 35.74 + (0.6215 * $self->{temp_f}) - (35.75 * $wf) + (0.4275 * $self->{temp_f} * $wf); + $self->{windchill_c} = ($self->{windchill_f} - 32) * 0.556; + } + +} + +######################################################################## +## Translate the precipitation values. If there there was precipitation +## but the amount was unmeasurable, then report "trace" for amount. +## +sub pretty_print_precip { + my $self = shift; + my $precip_mm = shift; + my $precip_in = shift; + + print STDERR "DEBUG: Translate precipitation: \"$precip_mm\" mm, \"$precip_in\" in.\n" if $self->{debug}; + my $amount = (($precip_mm > 0) ? sprintf($_strings{mm_inches}, + (($self->{units} eq 'metric') ? $precip_mm : $precip_in), + $_units{$self->{units}.'_depth'}) + : $_strings{precip_a_trace}); + + return sprintf($_strings{precip_there_was}, $amount); +} + +######################################################################## +## Returns a string with a "human readable" text which is a translation +## of the data contained in the METAR. +## +sub pretty_print { + + my $self = shift; + my $location_str = shift; + + if (!$self->{metar}) { + return sprintf($_strings{no_data}, $location_str); + } + + ## + ## Time + ## + my $minutes_old = int((time() - $self->{time}) / 60 + 0.5); + my $min = (localtime($self->{time}))[1]; + my $hrs = (localtime($self->{time}))[2]; + if ((! $self->{hrs24}) && ($hrs > 12)) { + $hrs -= 12; + } + my $lcltime_str = sprintf("%02s:%02s",$hrs,$min); + + ## + ## Barometric Pressure + ## + my $pressure_str = ''; + if (defined $self->{altimeter_inhg}) { + $pressure_str = sprintf($_strings{barometric_pressure}, + (($self->{units} eq 'metric') ? int($self->{altimeter_hpa} * 100 + 0.5) / 100 + : $self->{altimeter_inhg}), + $_units{$self->{units}.'_pressure'}); + } + + ## + ## Cloud Layers + ## + my $sky_str; + if ((defined $self->{cloud_layer1_condition}) && ($self->{cloud_layer1_condition} =~ /CAVOK/)) { + $sky_str = sprintf($_strings{sky_cavok}, (($self->{units} eq 'metric') ? "1,525 meters" : "5,000 feet")); + } elsif (defined $self->{cloud_layer1_altitude_ft}) { + $sky_str = sprintf($_strings{sky_str_format1}, + $self->{cloud_layer1_condition}, + (($self->{units} eq 'metric') ? int($self->{cloud_layer1_altitude_m} + 0.5) + : $self->{cloud_layer1_altitude_ft}), + $_units{$self->{units}.'_height'}); + if (defined $self->{cloud_layer2_altitude_ft}) { + if (defined $self->{cloud_layer3_altitude_ft}) { + $sky_str .= sprintf($_strings{sky_str_format2}, + $self->{cloud_layer2_condition}, + (($self->{units} eq 'metric') ? int($self->{cloud_layer2_altitude_m} + 0.5) + : $self->{cloud_layer2_altitude_ft}), + $_units{$self->{units}.'_height'}, + $self->{cloud_layer3_condition}, + (($self->{units} eq 'metric') ? int($self->{cloud_layer3_altitude_m} + 0.5) + : $self->{cloud_layer3_altitude_ft}), + $_units{$self->{units}.'_height'}); + } else { + $sky_str .= sprintf($_strings{sky_str_format3}, + $self->{cloud_layer2_condition}, + (($self->{units} eq 'metric') ? int($self->{cloud_layer2_altitude_m} + 0.5) + : $self->{cloud_layer2_altitude_ft}), + $_units{$self->{units}.'_height'}); + } + } + } else { + $sky_str = $_strings{sky_str_clear}; + } + $sky_str .= '.'; + + ## + ## Visibility + ## + my $visibility_str = ''; + if (defined $self->{visibility_miles}) { + if ($self->{visibility_miles} =~ /^>(.+)/) { + $visibility_str = sprintf($_strings{visibility_format}, + ($self->{units} eq 'metric') ? $self->{visibility_km} + : $self->{visibility_miles}, + $_units{$self->{units}.'_distance'}); + } else { + $visibility_str = sprintf($_strings{visibility_format}, + int((($self->{units} eq 'metric') ? $self->{visibility_km} + : $self->{visibility_miles}) + 0.5), + $_units{$self->{units}.'_distance'}); + } + } + + ## + ## Wind + ## + my $wind_str; + if ((defined $self->{wind_meters_per_second}) && ($self->{wind_meters_per_second} > 0)) { + $wind_str = sprintf($_strings{wind_str_format1}, + int((($self->{units} eq 'metric') ? $self->{wind_meters_per_second} + : $self->{wind_miles_per_hour}) + 0.5), + $_units{$self->{units}.'_speed'}); + if ((defined $self->{wind_gust_meters_per_second}) && ($self->{wind_gust_meters_per_second} > 0)) { + $wind_str .= sprintf($_strings{wind_str_format2}, + int((($self->{units} eq 'metric') ? $self->{wind_gust_meters_per_second} + : $self->{wind_gust_miles_per_hour}) + 0.5), + $_units{$self->{units}.'_speed'}); + } + $wind_str .= sprintf($_strings{wind_str_format3}, $self->{wind_dir_text}); + } else { + $wind_str = $_strings{wind_str_calm}; + } + + ## + ## Windchill + ## + my $feels_like_str = ''; + if (defined $self->{windchill_c}) { + $feels_like_str = sprintf($_strings{windchill}, + int((($self->{units} eq 'metric') ? $self->{windchill_c} + : $self->{windchill_f}) + 0.5), + $_units{$self->{units}.'_temperature'}); + } elsif (defined $self->{heat_index_f}) { + $feels_like_str = sprintf($_strings{heat_index}, + int((($self->{units} eq 'english') ? $self->{heat_index_f} + : $self->{heat_index_c}) + 0.5), + $_units{$self->{units}.'_temperature'}); + } + + ## + ## Relative Humidity + ## + my $rel_humidity_str = (defined $self->{rel_humidity}) ? sprintf($_strings{rel_humidity}, + int($self->{rel_humidity} + 0.5)) + : ''; + + ## + ## Precipitation + ## + my $precip_str = ''; + if (defined $self->{precip_in}) { + $precip_str = pretty_print_precip($self, int($self->{precip_mm} * 100 + 0.5) / 100, int($self->{precip_in} * 100 + 0.5) / 100) . + $_strings{precip_last_hour}; + } + if (defined $self->{precip_6h_in}) { + $precip_str .= pretty_print_precip($self, int($self->{precip_6h_mm} * 100 + 0.5) / 100, int($self->{precip_6h_in} * 100 + 0.5) / 100) . + $_strings{precip_last_6_hours}; + } + if (defined $self->{precip_24h_in}) { + $precip_str .= pretty_print_precip($self, int($self->{precip_24h_mm} * 100 + 0.5) / 100, int($self->{precip_24h_in} * 100 + 0.5) / 100) . + $_strings{precip_last_24_hours}; + } + if (defined $self->{snow_in}) { + $precip_str .= sprintf($_strings{precip_snow}, + int((($self->{units} eq 'metric') ? $self->{snow_mm} + : $self->{snow_in}) + 0.5), + $_units{$self->{units}.'_depth'}); + } + + ## + ## Min and Max Temperatures + ## + my $temp_str = ''; + if ((defined $self->{temp_max6h_c}) && (defined $self->{temp_min6h_c})) { + $temp_str .= sprintf($_strings{temp_min_max_6_hours}, + int((($self->{units} eq 'metric') ? $self->{temp_max6h_c} + : $self->{temp_max6h_f}) + 0.5), + int((($self->{units} eq 'metric') ? $self->{temp_min6h_c} + : $self->{temp_min6h_f}) + 0.5), + $_units{$self->{units}.'_temperature'}); + } else { + if (defined $self->{temp_max6h_c}) { + $temp_str .= sprintf($_strings{temp_max_6_hours}, + int((($self->{units} eq 'metric') ? $self->{temp_max6h_c} + : $self->{temp_max6h_f}) + 0.5), + $_units{$self->{units}.'_temperature'}); + } + if (defined $self->{temp_min6h_c}) { + $temp_str .= sprintf($_strings{temp_min_6_hours}, + int((($self->{units} eq 'metric') ? $self->{temp_max6h_c} + : $self->{temp_min6h_f}) + 0.5), + $_units{$self->{units}.'_temperature'}); + } + } + if (defined $self->{temp_max24h_c}) { + $temp_str .= sprintf($_strings{temp_min_max_24_hours}, + int((($self->{units} eq 'metric') ? $self->{temp_max24h_c} + : $self->{temp_max24h_f}) + 0.5), + int((($self->{units} eq 'metric') ? $self->{temp_min24h_c} + : $self->{temp_min24h_f}) + 0.5), + $_units{$self->{units}.'_temperature'}); + } + + ## + ## Runway information + ## + my $runway_str = ''; + if (defined $self->{runway_vis_meter}) { + $runway_str = sprintf($_strings{runway_vis}, + $self->{runway_nr}, + $self->{runway_vis_meter}, + $self->{runway_vis_ft}); + } + if (defined $self->{runway_vis_min_meter}) { + $runway_str .= sprintf($_strings{runway_vis_min_max}, + $self->{runway_nr}, + $self->{runway_vis_min_meter}, + $self->{runway_vis_min_ft}, + $self->{runway_vis_max_meter}, + $self->{runway_vis_max_ft}); + } + + ## + ## Current Weather + ## + my $weather_str = ''; + if (defined $self->{weather}) { + $weather_str = sprintf($_strings{current_weather}, $self->{weather}); + } + + return sprintf($_strings{pretty_print_format}, + $ENV{'CALL_SPACED'}, + $location_str, + $lcltime_str, + $wind_str, + int((($self->{units} eq 'metric') ? $self->{temp_c} : $self->{temp_f}) + 0.5), + $_units{$self->{units}.'_temperature'}, + $feels_like_str, + $pressure_str, + $rel_humidity_str, + $sky_str, + $visibility_str, + $runway_str, + $weather_str, + $precip_str, + $temp_str); +} + +######################################################################## +## Helper function to convert speed based on unit. +## Passed: speed and unit +## Returns: list of MPS,KTS,MPH +## +sub conv_speed { + my $speed = shift; + my $units = shift; + + my $kts = ''; + my $mps = ''; + my $mph = ''; + + if ($units =~ /KT/) { + $kts = $speed; + $mps = $speed * 0.51444; + $mph = $speed * 1.1507695060844667; + } + elsif ($units =~ /MPS/) { + $mps = $speed; + $kts = $speed / 0.51444; + $mph = $kts * 1.1507695060844667; + } + elsif ($units =~ /KMH/) { + $mps = $speed * 1000 / 3600; + $kts = $mps / 0.51444; + $mph = $kts * 1.1507695060844667; + } + return $mps, $kts, $mph; +} + +######################################################################## +## Helper function to convert temperature. +## Passed: temp_Celcius +## Returns: list of temp_Celsius and temp_Farenheit +## +sub conv_temp { + my $temp_c = shift; + my $temp_f = ($temp_c * (9/5)) + 32; + return $temp_c, $temp_f; +} + +######################################################################## +## Helper function to convert coded temperatures. +## Passed: coded temperature +## Returns: list of temp_Celcius and temp_Faenheit +## +sub conv_coded_temp { + my $temp = shift; + $temp =~ s/^1/-/; + my$temp_c = $temp / 10; + my $temp_f = $temp_c * (9/5) + 32; + return $temp_c, $temp_f; +} + +######################################################################## +######################################################################## +## +## MAIN PROGRAM +## +my $m = new METAR; + +$m->fetch_metar(); # Read METAR from STDIN and process it + +my $site = $m->getstnid(); # Retrieve the station ID (ICAO) + +if ($site) { + + if (! open ICAO, "< /home/irlp/custom/nsd_cccc.txt") { + print STDERR "Unable to open file nsd_cccc.txt\n"; + exit 0; + } + my ($icao,$blkno,$stnno,$location,$state,$country,$WMOREG,$stnlat,$stnlon,$ualat,$ualon,$stnelv,$uaelv,$RBSN); + my $found_ICAO = 0; + while () { # Find the Station Name + chomp; + ($icao,$blkno,$stnno,$location,$state,$country,$WMOREG,$stnlat,$stnlon,$ualat,$ualon,$stnelv,$uaelv,$RBSN) = split /\;/; + if ($icao =~ /$site/) { + $found_ICAO = 1; + last; + } + } + close ICAO; + exit 0 if (! $found_ICAO); + + $location =~ s/.*?,\s//; + + print $m->pretty_print($location) . "\n"; # Display METAR in natural language +} else { + print "Data for requested station is not available.\n"; +} +exit 1; + diff --git a/nsd_cccc.txt b/nsd_cccc.txt new file mode 100755 index 0000000..9d76fa0 --- /dev/null +++ b/nsd_cccc.txt @@ -0,0 +1,6519 @@ +AGGH;91;520;Honiara / Henderson;;Solomon Islands;5;09-25S;160-03E;;;8;9;P +AGGL;91;541;Santa Cruz;;Solomon Islands;5;10-42S;165-48E;10-42S;165-48E;23;24;P +AGGM;91;503;Munda;;Solomon Islands;5;08-20S;157-16E;;;6;6;P +ANAU;91;530;Nauru Airport;;Nauru;5;00-32S;166-55E;;;6;6; +AYMD;94;014;Madang;;Papua New Guinea;5;05-13S;145-47E;05-13S;145-47E;3;5;P +AYMO;--;---;Manus Island/Momote;;Papua New Guinea;5;02-03-43S;147-25-27E;;;4;; +AYPY;94;035;Moresby;;Papua New Guinea;5;09-26S;147-13E;09-26S;147-13E;38;49;P +AYWK;94;004;Wewak;;Papua New Guinea;5;03-34S;143-38E;;;6;;P +BGAM;04;360;Tasiilaq;;Greenland;6;65-36N;037-38W;65-36N;037-38W;50;52;P +BGAS;04;285;Angisoq;;Greenland;6;59-59N;045-12W;;;16;16; +BGAT;04;351;Aputiteeq;;Greenland;6;67-47N;032-18W;;;13;12; +BGBW;04;270;Narsarsuaq;;Greenland;6;61-10N;045-25W;61-11N;045-26W;34;32;P +BGCO;04;341;Constable Pynt;;Greenland;6;70-45N;022-39W;;;14;10; +BGDB;04;330;Daneborg;;Greenland;6;74-18N;020-13W;;;44;44; +BGDH;04;320;Danmarkshavn;;Greenland;6;76-46N;018-40W;76-46N;018-40W;11;12;P +BGEM;04;220;Egedesminde;;Greenland;6;68-42N;052-45W;68-42N;052-45W;43;41;P +BGFH;04;260;Frederikshaab;;Greenland;6;62-00N;049-40W;;;13;15;P +BGGD;04;261;Groennedal;;Greenland;6;61-14N;048-06W;;;35;32; +BGGH;04;250;Godthaab / Nuuk;;Greenland;6;64-10N;051-45W;;;80;70;P +BGHB;04;230;Holsteinsborg;;Greenland;6;66-55N;053-40W;;;12;9;P +BGJH;04;272;Julianehaab;;Greenland;6;60-43N;046-03W;;;32;34;P +BGJN;04;221;Jacobshavn Lufthavn;;Greenland;6;69-14N;051-04W;;;29;31; +BGKK;04;361;Kulusuk Lufthavn;;Greenland;6;65-35N;037-09W;;;35;37; +BGKT;04;340;Cape Tobin Automated Reporting Station ;;Greenland;6;70-25N;021-58W;70-25N;021-58W;41;41; +BGPC;04;390;Prins Christian Sund;;Greenland;6;60-03N;043-10W;;;88;75; +BGSC;04;339;Scoresbysund;;Greenland;6;70-29N;021-57W;70-29N;021-58W;65;69; +BGSF;04;231;Sdr Stroemfjord;;Greenland;6;67-01N;050-42W;67-00N;050-48W;50;53;P +BGTL;04;202;Thule A. B.;;Greenland;6;76-32N;068-45W;76-32N;068-45W;77;77;P +BIAR;04;063;Akureyri;;Iceland;6;65-41N;018-05W;;;23;27;P +BIEG;04;089;Egilsstadir;;Iceland;6;65-17N;014-24W;;;23;23; +BIGR;04;065;Grimsey;;Iceland;6;66-32N;018-01W;;;15;16; +BIHN;04;082;Akurnes;;Iceland;6;64-18N;015-13W;;;17;21;P +BIKF;04;018;Keflavikurflugvollur;;Iceland;6;63-58N;022-36W;63-58N;022-36W;52;54;P +BIRG;04;077;Raufarhofn;;Iceland;6;66-27N;015-57W;;;8;8;P +BIRK;04;030;Reykjavik;;Iceland;6;64-08N;021-54W;;;54;61;P +BIST;04;013;Stykkisholmur;;Iceland;6;65-05N;022-44W;;;8;8; +BIVM;04;048;Vestmannaeyjar;;Iceland;6;63-24N;020-17W;;;118;124;P +BIVO;04;085;Skjaldthingsstadir;;Iceland;6;65-42N;014-49W;;;44;48; +BIX1;--;---;Biloxi, Keesler Air Force Base, Navu;MS;United States;4;30-24-07N;088-55-04W;40-18-00N;088-08-00W;224;228; +BIX2;--;---;Biloxi, Keesler Air Force Base, Navu;MS;United States;4;30-24-34N;088-55-08W;30-24-34N;088-55-08W;7;10; +BIX3;--;---;Biloxi, Keesler Air Force Base, Navu;MS;United States;4;30-24-36N;088-55-09W;30-24-34N;088-55-08W;7;10; +CTPP;--;---;Camp Canargus;;Haiti;4;18-34N;072-19W;;;38;; +CWAC;71;483;Nitinat Lake Meteorological Aeronautical Presentation System ;;Canada;4;48-40N;124-50W;;;41;; +CWAD;--;---;Cape Mudge Light House ;;Canada;4;50-00N;125-12W;;;4;; +CWAE;--;---;Whistler ;;Canada;4;50-08N;122-57W;;;658;; +CWAF;71;426;Ile Rouge Meteorological Aeronautical Presentation System ;;Canada;4;48-05N;069-33W;;;5;; +CWAG;71;806;La Scie, Nfld.;;Canada;4;49-55N;055-40W;;;192;194;P +CWAH;71;410;Amherst, N. S.;;Canada;4;45-51N;064-16W;;;22;23;P +CWAJ;71;465;Erieau Meteorological Aeronautical Presentation System ;;Canada;4;42-15N;081-54W;;;178;; +CWAN;71;112;Amphitrite Point;;Canada;4;48-55N;125-33W;;;27;; +CWAQ;71;516;Coronach Spc;;Canada;4;49-03N;105-29W;;;756;; +CWAR;71;807;Argentia, Nfld;;Canada;4;47-18N;054-00W;47-17N;054-00W;16;16;P +CWAS;71;211;Pam Rocks;;Canada;4;49-29N;123-18W;;;;; +CWAU;--;---;Dryad Point Light House ;;Canada;4;52-11N;128-07W;;;4;; +CWAV;71;248;Sundre;;Canada;4;51-46N;114-41W;;;1114;; +CWAX;71;819;St. Anthony, Nfld.;;Canada;4;51-22N;055-38W;;;106;111;P +CWBA;71;122;Banff, Alta.;;Canada;4;51-11N;115-34W;;;1397;1384;P +CWBE;71;460;Killarney Meteorological Aeronautical Presentation System ;;Canada;4;45-58N;081-29W;;;196;; +CWBF;--;---;Burgeo Automated Reporting Station ;;Canada;4;47-37N;057-38W;;;12;; +CWBG;71;760;Big Creek ;;Canada;4;51-15N;123-05W;;;1670;; +CWBI;71;632;Britt, Ont.;;Canada;4;45-48N;080-32W;;;190;;P +CWBJ;71;162;Inner Whalebacks;;Canada;4;61-55N;113-44W;;;165;; +CWBK;71;415;Caribou Point Meteorological Aeronautical Presentation System ;;Canada;4;45-46N;062-41W;;;2;; +CWBL;71;143;Bachelors Island Automated Reporting Station ;;Canada;4;51-45N;099-54W;;;256;; +CWBM;71;230;Beaverlodge;;Canada;4;55-12N;119-24W;;;745;; +CWBO;71;457;Brooks Automatic Weather Reporting System ;;Canada;4;50-33N;111-51W;;;747;; +CWBR;71;049;B, R;;Canada;4;66-02N;091-50W;;;31;; +CWBT;71;512;Longue Point De Mingan, Que.;;Canada;4;50-16N;064-14W;;;11;; +CWBV;71;403;Beaven Island, N. S.;;Canada;4;44-49N;062-20W;;;14;10;P +CWBY;71;810;Port Menier, Que.;;Canada;4;49-50N;064-18W;;;53;53;P +CWBZ;71;712;St Anicet;;Canada;4;45-07N;074-17W;45-07N;074-17W;49;49; +CWCA;71;818;Cartwright, Nfld.;;Canada;4;53-42N;057-02W;;;14;14;P +CWCB;--;---;Nanakwa Shoals;;Canada;4;53-49N;128-50W;;;0;; +CWCD;71;513;Saskatoon Kernen;;Canada;4;52-09N;106-33W;;;510;; +CWCF;71;158;Berens River CS , Man.;;Canada;4;52-21N;097-02W;;;222;; +CWCH;71;748;Atikokan Automated Reporting Station ;;Canada;4;48-45N;091-37W;;;424;; +CWCI;71;433;Caribou Island, Ont.;;Canada;4;47-20N;085-50W;;;187;;P +CWCJ;71;750;Pukaskwa ;;Canada;4;48-36N;086-18W;;;206;; +CWCL;71;474;Clinton, B. C.;;Canada;4;51-09N;121-30W;;;1057;1057;P +CWCM;71;170;Carberry Mcdc;;Canada;4;49-54N;099-21W;;;384;; +CWCN;--;---;Malloch Dome Automatic Weather Reporting System ;;Canada;4;78-13N;101-03W;;;12;; +CWCO;71;270;Collingwood Automatic Weather Reporting System ;;Canada;4;44-30N;080-13W;;;180;; +CWCQ;--;---;Chatham Automatic Weather Reporting System ;;Canada;4;47-00N;065-28W;;;34;; +CWCS;--;---;Cote-Ste-Cath Mot;;Canada;4;45-25N;073-34W;;;17;; +CWCT;--;---;Coronation Automated Reporting Station ;;Canada;4;52-04N;111-28W;;;791;; +CWCU;71;436;Barrie, Ont.;;Canada;4;44-23N;079-47W;;;295;;P +CWCV;--;---;Nootka Lightstation, B. C.;;Canada;4;49-36N;126-37W;;;16;; +CWCX;71;056;Clut Lake Automated Reporting Station ;;Canada;4;66-00N;117-46W;;;185;; +CWCZ;--;---;Addenbrooke Island Light, B. C.;;Canada;4;51-36N;127-52W;;;21;; +CWDA;71;417;Englee Meteorological Aeronautical Presentation System ;;Canada;4;50-43N;056-07W;;;29;; +CWDB;71;967;Burwash Automatic Weather Reporting System ;;Canada;4;61-22N;139-03W;;;806;; +CWDC;71;076;Uranium City, Sask.;;Canada;4;59-34N;108-29W;;;318;318;P +CWDD;--;---;Belle River, Ont.;;Canada;4;42-18N;082-42W;;;184;; +CWDE;71;520;Lac Benoit;;Canada;4;51-33N;071-07W;;;549;; +CWDF;71;283;Oliphant \ Ont;;Canada;4;44-44N;081-17W;;;182;; +CWDH;71;185;Daniel's Harbour, Nfld;;Canada;4;50-14N;057-35W;;;18;19;P +CWDI;71;400;Badger, Nfld;;Canada;4;48-58N;056-04W;;;105;;P +CWDJ;71;514;Regina University;;Canada;4;50-24N;104-35W;;;573;; +CWDK;71;234;Claresholm Automatic Weather Reporting System ;;Canada;4;50-01N;113-38W;;;1012;; +CWDL;71;958;Dease Lake B. C.;;Canada;4;58-25N;130-00W;;;816;816;P +CWDM;71;814;Chevery, Que.;;Canada;4;50-28N;059-38W;;;6;6;P +CWDN;--;---;Wasaga Beach Automatic Weather Reporting System ;;Canada;4;44-31N;080-01W;;;182;; +CWDO;71;402;Twillingate Meteorological Aeronautical Presentation System ;;Canada;4;49-41N;054-48W;;;92;; +CWDP;71;521;Manouane-Est Automated Reporting Station ;;Canada;4;50-40N;070-32W;;;496;; +CWDQ;71;378;La Tuque;;Canada;4;47-25N;072-48W;;;169;; +CWDS;71;802;St. Lawrence, Nfld.;;Canada;4;46-55N;055-23W;;;46;49;P +CWDT;71;522;Chute Des Passes;;Canada;4;49-54N;071-15W;;;399;; +CWDU;71;235;Cop Upper;;Canada;4;51-05N;114-13W;;;1235;; +CWDV;71;435;Upsala, Ont.;;Canada;4;49-02N;090-28W;;;489;489;P +CWDZ;--;---;Drumheller East;;Canada;4;51-26N;112-40W;;;678;; +CWEA;71;448;Pinawa Automatic Weather Reporting System ;;Canada;4;50-11N;096-04W;;;268;; +CWEB;71;894;Estevan Point, B. C.;;Canada;4;49-23N;126-33W;;;7;;P +CWEC;71;751;Welcome Island;;Canada;4;48-22N;089-07W;;;209;; +CWEE;71;523;Chamouchouane Automatic Weather Reporting System;;Canada;4;49-17N;073-21W;;;305;; +CWEF;71;418;Saint Paul Island Meteorological Aeronautical Presentation System ;;Canada;4;47-14N;060-08W;;;26;; +CWEG;--;---;Alberta Weather Centre ;;Canada;4;53-30N;113-30W;;;;; +CWEH;71;131;Eastend Cypress, Sask;;Canada;4;49-26N;108-59W;;;1078;;P +CWEI;71;447;Melita, Man;;Canada;4;49-17N;100-59W;;;446;446;P +CWEJ;--;---;Bow Drill Iii;;Canada;4;47-12N;055-06W;;;0;; +CWEK;71;476;Grey Islet Meteorological Aeronautical Presentation System ;;Canada;4;54-35N;130-42W;;;8;; +CWEL;71;772;Entrance Island Automatic Weather Reporting System ;;Canada;4;49-13N;123-48W;;;5;; +CWEM;--;---;Egg Island Light;;Canada;4;51-15N;127-50W;;;14;; +CWEO;71;421;Lac Eon, Que;;Canada;4;51-52N;063-17W;;;561;561;P +CWEP;71;412;East Point, P. E. I;;Canada;4;46-27N;061-58W;;;11;13;P +CWEQ;71;443;Swan River, Man.;;Canada;4;52-07N;101-14W;;;335;335;P +CWER;71;424;Ile D'Orleans Automated Reporting Station ;;Canada;4;47-00N;070-49W;;;5;; +CWES;71;111;Cape Scott Light;;Canada;4;50-47N;128-26W;;;70;; +CWET;--;---;Egbert Meteorological Aeronautical Presentation System ;;Canada;4;44-14N;079-47W;;;251;; +CWEU;71;917;Eureka, N. W. T.;;Canada;4;79-59N;085-56W;79-59N;085-56W;10;10;P +CWEV;71;085;Ellice River Automated Reporting Station ;;Canada;4;67-42N;104-28W;;;42;; +CWEW;71;524;L'Assomption;;Canada;4;45-49N;073-26W;45-49N;073-26W;21;21; +CWEZ;71;473;Saturna Island Meteorological Aeronautical Presentation System ;;Canada;4;48-47N;123-03W;;;24;; +CWFD;71;094;Cape Dyer, N. W. T.;;Canada;4;66-35N;061-37W;;;393;393;P +CWFE;71;238;Elk Island National Park;;Canada;4;53-41N;112-52W;;;716;; +CWFF;71;456;Melfort Automatic Weather Reporting System ;;Canada;4;52-49N;104-36W;;;490;; +CWFG;71;478;Sartine Island Meteorological Aeronautical Presentation System ;;Canada;4;50-49N;128-54W;;;112;; +CWFH;--;---;St. Shotts;;Canada;4;46-43N;053-29W;;;143;; +CWFJ;71;153;Cardston Automated Reporting Station ;;Canada;4;49-12N;113-17W;;;1136;; +CWFL;71;073;Fort Reliance ;;Canada;4;62-43N;109-10W;;;164;; +CWFM;--;---;Chatham Point Lighthouse ;;Canada;4;50-20N;125-26W;;;23;; +CWFN;71;920;Cree Lake Meteorological Aeronautical Presentation System ;;Canada;4;57-21N;107-08W;57-21N;107-08W;495;497; +CWFP;--;---;Nain;;Canada;4;56-33N;061-42W;;;7;; +CWFQ;71;373;Frelighsburg;;Canada;4;45-03N;072-50W;;;152;; +CWFR;--;---;Horsefly River, B. C.;;Canada;4;52-17N;121-03W;;;846;; +CWFU;--;---;Little Macatina;;Canada;4;52-14N;061-19W;;;321;; +CWFW;71;829;Baie Comeau;;Canada;4;49-16N;068-09W;;;129;; +CWFX;71;055;Colville Lake;;Canada;4;67-02N;126-05W;;;259;; +CWFY;--;---;Conne River;;Canada;4;48-10N;055-29W;;;183;; +CWFZ;71;160;Fort Reliance, N. W. T.;;Canada;4;62-43N;109-11W;;;168;; +CWGB;71;769;Ballenas Island Automatic Weather Reporting System ;;Canada;4;49-21N;124-10W;;;5;; +CWGD;71;261;Goderich Automatic Weather Reporting System ;;Canada;4;43-46N;081-43W;;;214;; +CWGF;71;253;Garden River Automatic Weather Reporting System ;;Canada;4;58-41N;113-53W;;;241;; +CWGH;71;281;Grenadier Island ;;Canada;4;44-25N;075-51W;;;82;; +CWGJ;--;---;Montreal River Radar Site;;Canada;4;47-14N;084-31W;;;559;; +CWGL;71;282;Lagoon City ;;Canada;4;44-32N;079-13W;;;221;; +CWGM;71;154;Waterton Park Gate;;Canada;4;59-08N;113-48W;;;1296;; +CWGN;71;441;Gretna, Man.;;Canada;4;49-02N;097-34W;;;251;253;P +CWGP;71;777;Pemberton Automatic Weather Reporting System ;;Canada;4;50-18N;122-44W;;;204;; +CWGQ;71;736;Roquemaure;;Canada;4;48-38N;079-27W;;;269;; +CWGR;71;710;Iles-De-La-Madelein;;Canada;4;47-25N;061-48W;;;10;; +CWGT;71;781;Sisters Island Automatic Weather Reporting System ;;Canada;4;49-29N;124-26W;;;5;; +CWGU;71;857;Gypsumville;;Canada;4;51-40N;098-45W;;;265;; +CWGV;--;---;Carp Radar Site;;Canada;4;45-19N;076-00W;;;;; +CWGW;71;782;Sparwood Automatic Weather Reporting System ;;Canada;4;49-45N;114-54W;;;1137;; +CWGX;--;---;Gillam, Man.;;Canada;4;56-22N;094-42W;;;145;; +CWGY;71;240;Esther 1;;Canada;4;51-40N;110-12W;;;707;; +CWGZ;--;---;Grise Fiord Airport;;Canada;4;76-25N;082-54W;;;45;; +CWHA;71;241;Highvale;;Canada;4;53-27N;114-28W;;;747;; +CWHC;71;201;Vancouver Automatic Weather Reporting System ;;Canada;4;49-18N;123-07W;;;2;; +CWHE;71;239;Ellerslie;;Canada;4;53-25N;113-12W;;;694;; +CWHH;71;142;Hunters Point Mar;;Canada;4;53-02N;100-56W;;;256;; +CWHI;71;249;Three Hills;;Canada;4;51-42N;113-13W;;;907;; +CWHL;71;440;Holland Rock Automatic Weather Reporting System ;;Canada;4;54-10N;130-22W;;;5;; +CWHM;71;184;Varennes;;Canada;4;45-43N;073-23W;;;19;; +CWHN;--;---;Jimmy Lake ;;Canada;4;54-55N;109-57W;54-55N;109-58W;658;625; +CWHO;71;900;Hopedale Meteorological Aeronautical Presentation System ;;Canada;4;55-27N;060-14W;;;8;; +CWHP;71;423;Heath Point Meteorological Aeronautical Presentation System ;;Canada;4;49-05N;061-42W;;;4;; +CWHQ;71;389;Deschambaults , Que.;;Canada;4;46-41N;071-57W;;;55;; +CWHS;71;062;Bernard Harbour;;Canada;4;68-47N;114-50W;;;65;; +CWHT;71;505;Haines Junction;;Canada;4;60-46N;137-35W;;;599;; +CWHU;--;---;Star Brook;;Canada;4;48-35N;057-14W;;;290;; +CWHV;71;323;Beauceville;;Canada;4;46-12N;070-47W;;;229;; +CWHW;71;193;Comfort Cove, Nfld.;;Canada;4;49-16N;054-53W;;;96;99;P +CWHY;71;618;Mont-Orford;;Canada;4;45-19N;072-15W;;;851;; +CWIA;--;---;Saint Henri , Que.;;Canada;4;48-39N;071-51W;;;103;; +CWIC;71;074;Isachsen Meteorological Aeronautical Presentation System ;;Canada;4;78-47N;103-33W;;;58;; +CWID;71;087;Fort Providence;;Canada;4;61-19N;117-36W;;;161;; +CWIE;71;161;Indian River ;;Canada;4;64-23N;115-01W;;;478;; +CWIF;--;---;Quatsino Light Station ;;Canada;4;50-26N;128-02W;;;21;; +CWIG;--;---;Ile Aux Grues, Que.;;Canada;4;47-04N;070-32W;;;18;; +CWII;71;552;Victoria Beach ;;Canada;4;50-42N;096-34W;;;220;; +CWIJ;71;496;Lupin, N. W. T.;;Canada;4;65-46N;111-14W;;;500;500;P +CWIK;71;861;Broadview, Sask.;;Canada;4;50-23N;102-41W;50-23N;102-35W;598;602;P +CWIL;71;084;Hat Island, N. W. T.;;Canada;4;68-19N;100-05W;;;36;; +CWIM;--;---;Upsala Radar Site ;;Canada;4;49-02N;090-25W;;;480;; +CWIO;71;762;Iskut River ;;Canada;4;56-44N;131-40W;;;15;; +CWIP;71;390;Pointe Noire , Que.;;Canada;4;50-10N;066-26W;;;25;; +CWIQ;71;124;Primrose Lake ;;Canada;4;54-45N;110-03W;54-45N;110-03W;702;700; +CWIR;--;---;Victoria Marine ;;Canada;4;48-22N;123-45W;;;32;; +CWIS;71;319;Charlevoix CS , Que.;;Canada;4;47-17N;070-38W;;;719;; +CWIT;71;614;Saint Clothilde Automated Reporting Station ;;Canada;4;45-10N;073-41W;;;52;; +CWIU;--;---;Saint Gedeon, Que.;;Canada;4;48-29N;071-47W;;;103;; +CWIW;71;511;Watrous East Automated Reporting Station ;;Canada;4;51-40N;105-24W;;;526;; +CWIX;71;381;Mistook Automated Reporting Station ;;Canada;4;48-46N;071-43W;;;113;; +CWIY;--;---;St Leonard Automatic Weather Reporting System;;Canada;4;47-09N;067-49W;;;49;; +CWIZ;71;372;L'Acadie;;Canada;4;45-18N;073-21W;;;45;; +CWJA;71;888;Jasper, Alta.;;Canada;4;52-53N;118-04W;;;1061;1061;P +CWJB;71;392;Ste Foy CS , Que.;;Canada;4;47-18N;071-16W;;;91; +CWJC;71;923;Ennadai Lake Meteorological Aeronautical Presentation System ;;Canada;4;61-08N;100-54W;;;357;; +CWJD;71;858;Grand Rapids, Man.;;Canada;4;53-11N;099-16W;;;223;223;P +CWJG;--;---;Ivory Island Light;;Canada;4;52-16N;128-25W;;;10;; +CWJH;71;451;Southend Automatic Weather Reporting System ;;Canada;4;56-20N;103-17W;;;344;; +CWJI;71;487;Assiniboia Airport Automated Reporting Station;;Canada;4;49-44N;105-56W;;;724;; +CWJM;71;290;Upper Rideau Lake;;Canada;4;44-42N;076-18W;;;125;; +CWJN;71;501;Herschel Island Automatic Weather Reporting System ;;Canada;4;69-34N;138-55W;;;1;; +CWJO;71;617;Jonquiere Automated Reporting Station ;;Canada;4;48-25N;071-13W;;;133;; +CWJP;71;167;Porter Lake;;Canada;4;61-40N;108-25W;;;396;; +CWJR;71;770;Creston Automatic Weather Reporting System ;;Canada;4;49-05N;116-30W;;;646;; +CWJT;71;376;St Jovite Automatic Weather Reporting System ;;Canada;4;46-04N;074-32W;;;239;; +CWJU;71;899;Langara, B. C.;;Canada;4;54-15N;133-03W;;;41;41;P +CWJV;--;---;Vernon, B. C.;;Canada;4;50-14N;119-18W;;;556;; +CWJW;71;486;Jasper Warden Automated Reporting Station ;;Canada;4;52-56N;118-19W;52-56N;118-19W;1020;1020; +CWJX;71;459;Leader Airport Automatic Weather Reporting System ;;Canada;4;50-54N;109-30W;;;672;; +CWJY;71;507;Yathkyed Lake Meteorological Aeronautical Presentation System ;;Canada;4;62-42N;098-18W;;;148;; +CWJZ;71;499;Dubawnt Lake Meteorological Aeronautical Presentation System ;;Canada;4;63-14N;101-46W;;;237;; +CWKD;71;383;Bonnard 1, Que.;;Canada;4;50-44N;071-01W;;;497;; +CWKE;71;919;Pelly Bay;;Canada;4;68-26N;089-43W;;;326;; +CWKG;71;599;Kejimkujik 1, N. S.;;Canada;4;44-26N;065-12W;;;127;; +CWKH;71;774;Malahat Automatic Weather Reporting System ;;Canada;;48-35N;123-35W;;;366;; +CWKI;--;---;Kitimat;;Canada;4;54-03N;128-41W;;;13;; +CWKK;71;468;Katatota Island;;Canada;4;49-43N;088-20W;;;260;; +CWKM;71;046;Komakuk Beach, Y. T.;;Canada;4;69-37N;140-12W;;;13; +CWKO;71;135;Rockglen, Sask.;;Canada;4;49-10N;105-59W;;;915;917;P +CWKR;--;---;King Radar Site;;Canada;4;43-58N;079-34W;;;390;; +CWKS;--;---;Sikanni Chief, B. C.;;Canada;4;57-15N;122-43W;;;937;; +CWKU;--;---;Whiskey Automated Reporting Station ;;Canada;4;81-02N;076-57W;;;829;; +CWKV;--;---;Hope Slide;;Canada;4;49-17N;121-14W;;;674;; +CWKW;71;176;Cape Kakkiviak;;Canada;4;59-59N;064-10W;;;551;; +CWKX;71;222;Dease Lake Coastal Station;;Canada;4;58-25N;130-00W;;;816;; +CWLA;71;899;Langara, B. C.;;Canada;4;54-15N;133-08W;;;41; +CWLB;71;931;Lac La Biche, Alta.;;Canada;4;54-46N;112-01W;;;565;567;P +CWLC;--;---;Lucy Island, B. C.;;Canada;4;54-18N;130-36W;;;27;; +CWLE;71;455;Lucky Lake Automatic Weather Reporting System ;;Canada;4;50-57N;107-09W;;;665;; +CWLF;71;846;Lansdowne House ;;Canada;4;52-14N;087-53W;;;242;; +CWLG;71;164;Little Chicago;;Canada;4;67-12N;130-13W;;;63;; +CWLI;71;960;Liverpool Bay;;Canada;4;69-36N;130-54W;;;102;; +CWLM;71;200;Victoria Automatic Weather Reporting System ;;Canada;4;48-25N;123-19W;;;70;; +CWLO;71;853;Shilo;;Canada;4;49-47N;099-38W;49-47N;099-38W;373;373; +CWLP;71;485;Herbert Island Meteorological Aeronautical Presentation System ;;Canada;4;50-56N;127-38W;;;17;; +CWLQ;71;271;Nipissing;;Canada;4;46-19N;079-28W;;;204;; +CWLS;71;631;Mount Forest, Ont.;;Canada;4;43-59N;080-45W;;;415;;P +CWLT;71;082;Alert, N. W. T.;;Canada;4;82-30N;062-20W;82-30N;062-20W;63;66;P +CWLU;--;---;Lauzon, Que.;;Canada;4;46-50N;071-10W;;;20;; +CWLV;71;454;Waskesiu Lake Automated Reporting Station ;;Canada;4;53-55N;106-04W;;;569;; +CWLX;71;091;Longstaff Bluff, N. W. T.;;Canada;4;68-53N;075-08W;;;162;161;P +CWLY;71;891;Lytton, B. C.;;Canada;4;50-14N;121-35W;;;229;229;P +CWLZ;71;146;Candle Lake;;Canada;4;53-44N;105-16W;53-44N;105-16W;503;503; +CWMA;--;---;Masset A;;Canada;4;54-01N;132-07W;;;5;; +CWMD;--;---;Mould Bay Camp;;Canada;4;76-14N;119-19W;;;12;; +CWME;71;482;Cathedral Point Meteorological Aeronautical Presentation System ;;Canada;4;52-11N;127-28W;;;32;; +CWMH;71;817;Mary's Harbour, Nfld.;;Canada;4;52-18N;055-50W;;;10;11;P +CWMI;71;719;Miscou Island, N. B.;;Canada;4;48-01N;064-30W;;;3;4;P +CWMJ;71;721;Maniwaki;;Canada;4;46-17N;076-00W;;;200;; +CWMM;71;775;P. Meadows Coastal Station Automatic Weather Reporting System;;Canada;;49-12N;122-41W;;;5;; +CWMN;71;626;Mcgill Radar Site;;Canada;4;45-25N;073-56W;;;63;; +CWMP;71;168;Powder Lake;;Canada;4;61-03N;109-20W;;;396;; +CWMQ;71;453;Maplecreek Automatic Weather Reporting System ;;Canada;4;49-54N;109-28W;;;767;; +CWMR;--;---;Merry Island ;;Canada;4;49-28N;123-55W;;;8;; +CWMS;71;897;Mcinnes Island, B. C.;;Canada;4;52-16N;128-43W;;;25;26;P +CWMT;71;163;Lac La Martre;;Canada;4;63-09N;117-16W;;;271;; +CWMU;71;981;Rampart River Automatic Weather Reporting System ;;Canada;4;65-57N;130-28W;;;155;; +CWMV;71;986;St Charles Creek;;Canada;4;64-45N;124-13W;;;341;; +CWMW;71;722;Maniwaki, Que.;;Canada;4;46-23N;075-58W;46-22N;075-59W;170;173;P +CWMX;71;255;Mildred Lake;;Canada;4;57-32N;111-34W;;;310;; +CWMZ;71;438;Western Island Meteorological Aeronautical Presentation System ;;Canada;4;45-02N;080-22W;;;191;; +CWNB;71;466;S. E. Shoal Meteorological Aeronautical Presentation System ;;Canada;4;41-50N;082-28W;;;195;; +CWNC;71;431;Cobourg, Ont.;;Canada;4;43-57N;078-10W;;;78;78;P +CWND;71;502;Pelly Island Automatic Weather Reporting System ;;Canada;4;69-38N;135-26W;;;12;; +CWNE;--;---;North Point, Prince Edward Island;;Canada;4;47-05N;064-00W;;;15;; +CWNH;71;715;Riviere Du Loup, Que.;;Canada;4;47-48N;069-33W;;;148;148;P +CWNI;--;---;Nipterk Base;;Canada;4;69-37N;135-20W;;;10;; +CWNJ;--;---;Green Island Light Station - Heliport, B. C.;;Canada;4;54-34N;130-42W;;;12;; +CWNK;71;147;Carman U Of M;;Canada;4;49-30N;098-02W;;;268;; +CWNL;71;462;Great Duck Island;;Canada;4;45-38N;082-58W;;;183;; +CWNM;71;776;Nelson Automatic Weather Reporting System ;;Canada;4;49-30N;117-18W;;;535;; +CWNO;71;976;Satah River Automatic Weather Reporting System;;Canada;4;66-52N;134-12W;;;86;; +CWNP;71;216;Nakusp Automatic Weather Reporting System ;;Canada;;50-16N;117-49W;;;524;; +CWNQ;71;723;Nicolet Automatic Weather Reporting System ;;Canada;4;46-13N;072-39W;;;10;; +CWNR;71;245;Nakiska Ridgetop ;;Canada;4;50-57N;115-11W;;;2543;; +CWNT;71;250;Turtle Mountain;;Canada;4;49-35N;114-25W;;;2164;; +CWNW;71;982;Haldane River Automatic Weather Reporting System;;Canada;4;67-04N;121-06W;;;186;; +CWNX;71;763;Nechako River ;;Canada;4;53-41N;124-50W;;;715;; +CWNZ;71;832;Nagagami, Ont.;;Canada;4;49-45N;084-10W;;;259;263;P +CWOA;71;060;Camsell River, N. W. T.;;Canada;4;65-37N;118-07W;;;230;;P +CWOB;71;097;Brevoort Island;;Canada;4;63-20N;064-09W;;;367;; +CWOC;71;619;New Carlisle1;;Canada;4;48-01N;065-20W;;;47;; +CWOD;71;379;Normandin;;Canada;4;48-50N;072-33W;;;137;; +CWOE;71;116;Onefour Automatic Weather Reporting System ;;Canada;4;49-07N;110-28W;;;935;; +CWOH;71;720;Ste Agathe Des Mont;;Canada;4;46-03N;074-17W;;;395;; +CWOI;71;978;Ivvavik Park Automatic Weather Reporting System;;Canada;4;69-09N;140-09W;;;244;; +CWOK;71;450;Elbow Marine Aviation Reporting Station ;;Canada;4;51-08N;106-35W;;;595;; +CWOL;--;---;Sable Island Man ;;Canada;4;43-55N;059-55W;;;4;; +CWON;--;---;Dawson Automatic Weather Reporting System ;;Canada;4;64-03N;139-09W;;;370;; +CWOU;71;127;Primrose Lake 2;;Canada;4;54-47N;110-04W;54-47N;110-04W;606;606; +CWOY;--;---;Wynyard Marine Aviation Reporting Station ;;Canada;4;51-46N;104-13W;;;561;; +CWPA;71;979;Henderickson Automatic Weather Reporting System;;Canada;4;53-47N;118-26W;;;1542;; +CWPB;71;272;Beausoleil Island Automated Reporting Station ;;Canada;4;44-51N;079-52W;;;183;; +CWPC;71;463;Port Colborne Automated Reporting Station ;;Canada;4;42-52N;079-15W;;;184;; +CWPD;71;382;Parc Des Laurentid;;Canada;4;47-34N;071-14W;;;803;; +CWPE;--;---;Point Lepreau, N. B.;;Canada;4;45-04N;066-28W;;;1;; +CWPF;71;798;Esquimalt Harbour, B. C.;;Canada;4;48-26N;123-26W;;;3;; +CWPH;71;907;Inukjuak, Que;;Canada;4;58-27N;078-07W;58-27N;078-07W;3;6;P +CWPI;71;105;Pine Island Meteorological Aeronautical Presentation System ;;Canada;4;50-59N;127-44W;;;9;; +CWPJ;71;414;Point Escuminac Meteorological Aeronautical Presentation System ;;Canada;4;47-04N;064-48W;;;5;; +CWPK;71;726;Parent, Que.;;Canada;4;47-55N;074-37W;;;442;441;P +CWPL;71;845;Pickle Lake, Ont.;;Canada;4;51-27N;090-12W;51-27N;090-12W;389;386;P +CWPO;71;148;Pilot Mound, Man.;;Canada;4;49-12N;098-54W;;;470;470;P +CWPQ;71;675;Montreal-Est;;Canada;4;45-38N;070-33W;;;51;; +CWPR;71;032;Princeton Automatic Weather Reporting System ;;Canada;4;50-36N;120-31W;;;700;; +CWPS;71;464;Long Point Meteorological Aeronautical Presentation System ;;Canada;4;42-34N;080-03W;;;175;; +CWPU;71;050;Puntzi Mountain, B. C.;;Canada;4;52-07N;124-08W;;;910;910;P +CWPX;--;---;Cape Peel West, N. W. T.;;Canada;4;69-02N;107-49W;;;165;; +CWPY;--;---;Fort Chipewyan Automated Reporting Station ;;Canada;4;58-46N;111-08W;;;232;; +CWPZ;71;952;Burns Lake CS , B. C.;;Canada;4;54-23N;125-57W;;;713;; +CWQC;71;475;Port Alberni, B. C.;;Canada;4;49-15N;124-50W;;;2;2;P +CWQE;71;284;Toronto Headland;;Canada;4;43-37N;079-21W;;;87;; +CWQF;71;980;Rabbit Kettle Automated Reporting Station;;Canada;4;61-58N;127-13W;;;634;; +CWQG;71;151;Valcartier;;Canada;4;46-54N;071-30W;;;168;; +CWQH;71;611;Lennoxville;;Canada;4;45-22N;071-49W;;;181;; +CWQJ;--;---;Sedco 710;;Canada;4;46-30N;048-30W;;;0;; +CWQK;71;778;Race Rocks Automatic Weather Reporting System ;;Canada;4;48-18N;123-32W;;;5;; +CWQL;71;243;Lethbridge Automated Reporting Station ;;Canada;4;49-42N;112-47W;;;921;; +CWQM;71;186;Cap Rouge;;Canada;4;48-23N;070-32W;;;7;; +CWQO;71;385;Ile Bicquette, Que.;;Canada;4;48-24-56N;068-53-36W;;;7;; +CWQP;71;430;Point Petre , Ont.;;Canada;4;43-50N;077-09W;;;79;79;P +CWQQ;71;242;Lacombe Cda;;Canada;4;52-27N;113-45W;;;874;; +CWQR;71;375;Ile Aux Perroquets, Que.;;Canada;4;50-13-25N;064-12-30W;;;9;; +CWQS;71;472;Kindakun Rocks, B. C.;;Canada;4;53-19N;132-45W;;;14;14;P +CWQV;71;189;Puinte Claveau;;Canada;4;48-16N;070-07W;;;0;; +CWQW;71;374;Cape Whittle;;Canada;4;50-10N;060-04W;;;7;; +CWQY;71;963;Hanbury River Automated Reporting Station ;;Canada;4;63-35N;105-09W;;;317;; +CWQZ;--;---;Quesnel Automatic Weather Reporting System ;;Canada;4;53-02N;122-32W;;;545;; +CWRA;71;800;Cape Race, Nfld;;Canada;4;46-39N;053-04W;;;27;28;P +CWRD;71;246;Red Earth;;Canada;4;56-32N;115-16W;;;546;; +CWRF;71;918;Pelly Bay 1;;Canada;4;69-26N;089-44W;;;325;; +CWRH;71;972;Resolution Island, N. W. T.;;Canada;4;61-35N;64-39W;;;369;; +CWRJ;71;510;Rosetown East, Sask;;Canada;4;51-34N;107-55W;;;586;;P +CWRK;--;---;Bancroft Automatic Weather Reporting System;;Canada;4;45-04N;077-52W;;;331;; +CWRM;--;---;Rocky House Marine Aviation Reporting Station ;;Canada;4;52-26N;114-56W;;;988;; +CWRN;71;419;Hart Island Meteorological Aeronautical Presentation System ;;Canada;4;45-21N;060-59W;;;4;; +CWRO;71;477;Rose Spit Meteorological Aeronautical Presentation System ;;Canada;4;54-10N;131-40W;;;7;; +CWRP;71;956;Nicholson Peninsul ;;Canada;4;69-56N;128-58W;;;89;; +CWRQ;--;---;Trois Rivieres;;Canada;4;46-23N;072-37W;;;11;; +CWRT;71;236;Crowsnest;;Canada;4;49-38N;114-29W;;;1303;; +CWRU;71;479;Solander Island Meteorological Aeronautical Presentation System ;;Canada;4;50-07N;127-56W;;;99;; +CWRV;71;254;Camrose;;Canada;4;53-02N;112-49W;;;739;; +CWRW;71;416;Fourchu Head Meteorological Aeronautical Presentation System ;;Canada;4;45-43N;060-14W;;;10;; +CWRX;--;---;Rowley Island, N. W. T.;;Canada;4;69-04N;079-04W;;;41;; +CWRY;71;244;Milk River;;Canada;4;49-08N;112-03W;;;1050;; +CWRZ;71;429;Cap D'Espoir , Que.;;Canada;4;48-25N;064-19W;;;16;; +CWSA;71;600;Sable Island, N. S.;;Canada;4;43-56N;060-01W;43-56N;060-01W;4;4;P +CWSD;--;---;Summerside Automatic Weather Reporting System ;;Canada;4;46-26N;063-51W;;;24;; +CWSE;71;119;Edmonton Stony Plain Alta.;;Canada;4;53-32N;114-06W;53-33N;114-06W;766;766;P +CWSF;71;425;Cap Madeleine Meteorological Aeronautical Presentation System ;;Canada;4;49-15N;065-20W;;;29;; +CWSG;71;428;Cap Chat CS, Que.;;Canada;4;49-07N;066-39W;;;5;; +CWSH;71;247;Sousa Crk Avt ;;Canada;4;58-35N;118-30W;;;373;; +CWSI;71;527;Simcoe, Ont.;;Canada;4;42-51N;080-16W;;;241;;P +CWSK;71;207;Squamish Airport, B. C;;Canada;4;49-47N;123-10W;;;59;52;P +CWSL;71;218;Salmon Arm Automatic Weather Reporting System ;;Canada;;50-42N;119-17W;;;351;; +CWSO;--;---;Exeter Radar Site;;Canada;4;43-22N;081-23W;;;;; +CWSP;71;780;Sheringham Automatic Weather Reporting System ;;Canada;4;48-23N;123-55W;;;21;; +CWSQ;71;974;Aulvik National Park;;Canada;4;74-08N;119-59W;;;32;; +CWSR;71;133;Spiritwood West, Sask;;Canada;4;53-22N;107-33W;;;584;590;P +CWSS;71;607;St. Stephen, N. B.;;Canada;4;45-13N;067-15W;;;26;;P +CWST;71;713;La Pocatiere;;Canada;4;47-21N;070-02W;;;31;; +CWSV;--;---;Blue River Marine Aviation Reporting Station ;;Canada;4;52-06N;119-18W;;;683;; +CWSW;--;---;Sparwood / Elk Valley;;Canada;4;49-45N;114-53W;;;1138;; +CWSY;71;051;Sachs Harbour, N. W. T.;;Canada;4;72-00N;125-16W;72-00N;125-16W;88;88;P +CWSZ;71;442;Fisher Branch Marine Aviation Reporting Station ;;Canada;4;51-05N;097-33W;;;253;; +CWTA;71;612;Mc Tavish Automated Reporting Station ;;Canada;4;45-30N;073-35W;;;63;; +CWTB;71;901;Border, Que.;;Canada;4;55-20N;063-13W;;;479;479;P +CWTC;71;102;Ethelda Bay;;Canada;4;53-03N;129-41W;;;10;; +CWTD;71;490;Robertson Lake Automated Reporting Station ;;Canada;4;65-06N;102-26W;;;244;; +CWTE;71;166;Trout Lake;;Canada;4;60-26N;121-14W;;;498;; +CWTF;71;134;Beartooth Island;;Canada;4;59-13N;109-42W;;;238;; +CWTG;71;427;Pointe-Des-Monts , Que.;;Canada;4;49-19N;067-23W;;;5;; +CWTH;--;---;Tetsa River;;Canada;4;58-39N;124-14W;;;804;; +CWTI;--;---;Triple Island Light, B. C.;;Canada;4;54-18N;130-53W;;;21;; +CWTN;71;384;Cap Tourmente;;Canada;4;47-04N;070-48W;;;6;; +CWTO;71;638;Toronto Aes Hq ;;Canada;4;43-47N;079-28W;43-47N;079-28W;187;187; +CWTU;--;---;Tukialik Bay, Nfld.;;Canada;4;54-43N;058-21W;;;683;; +CWTY;71;724;Trois Rivieres;;Canada;4;46-21N;072-31W;;;6;; +CWTZ;--;---;Toronto Island;;Canada;4;43-38N;079-25W;;;77;; +CWUL;--;---;Quebec Fcst Office;;Canada;4;45-30N;073-41W;;;;; +CWUM;71;949;Faro, Y. T.;;Canada;4;62-14N;133-21W;;;717;717;P +CWUP;71;093;Cape Hooper, N. W. T.;;Canada;4;68-28N;066-48W;;;401;390;P +CWUR;71;398;Truro, N. S.;;Canada;4;45-22N;063-16W;;;40;;P +CWUS;71;768;Summerland Automatic Weather Reporting System ;;Canada;4;49-34N;119-39W;;;454;; +CWUT;71;150;Shoal Lake Airport Automated Reporting Station ;;Canada;4;50-27N;100-36W;;;561;; +CWUU;71;080;Mackar Inlet;;Canada;4;68-18N;085-40W;;;395;; +CWUW;71;092;Dewar Lakes, N. W. T.;;Canada;4;68-39N;071-10W;;;518;527;P +CWUX;71;388;La Baie , Que.;;Canada;4;48-18N;70-56W;;;135;; +CWUY;71;734;Rouyn;;Canada;4;48-15N;079-02W;;;318;; +CWVA;71;196;Bonavista, Nfld.;;Canada;4;48-40N;053-07W;;;25;27;P +CWVB;71;484;Bonilla Island Light;;Canada;4;53-30N;130-38W;;;16;; +CWVC;71;446;Swift Current Automatic Weather Reporting System ;;Canada;4;50-16N;107-44W;;;825;; +CWVD;71;096;Broughton Island;;Canada;4;67-32N;063-47W;;;584;; +CWVE;--;---;Valleyfield;;Canada;4;45-14N;074-06W;;;46;; +CWVF;--;---;Sand Heads CS, B. C.;;Canada;4;49-06N;123-18W;;;13;; +CWVH;71;052;Storm Hills , N. W. T.;;Canada;4;68-54N;133-56W;;;261;; +CWVI;71;458;Vegreville Automatic Weather Reporting System ;;Canada;4;53-37N;112-02W;;;639;; +CWVK;71;115;Vernon, B. C.;;Canada;4;50-14N;119-17W;;;555;556;P +CWVN;71;137;Val Marie Southeast, Sask;;Canada;4;49-04N;107-35W;;;785;785;P +CWVO;71;251;Vauxhall Cda;;Canada;4;50-03N;112-08W;;;779;; +CWVP;71;139;Cypress Hills Park;;Canada;4;49-39N;109-31W;;;1271;; +CWVQ;71;377;Ste Anne De Bell 1;;Canada;4;45-26N;073-56W;;;39;; +CWVT;71;077;Buffalo Narrows, Sask.;;Canada;4;55-50N;108-26W;;;434;434;P +CWVU;71;988;Brier Island, N. S.;;Canada;4;44-17-09N;066-20-48W;;;16;; +CWVV;--;---;Vic. Hartland Automatic Weather Reporting System;;Canada;4;48-32N;123-28W;;;154;; +CWVY;71;616;Villeroy Radar Site;;Canada;4;46-26N;071-56W;;;108;; +CWVZ;--;---;Ile Charron, Que.;;Canada;4;45-35N;073-30W;;;12;; +CWWA;71;784;W Vancouver Automatic Weather Reporting System ;;Canada;4;49-21N;123-11W;;;178;; +CWWB;71;437;Burlington Piers ;;Canada;4;43-18N;079-48W;;;77;; +CWWC;71;075;Collins Bay Automatic Weather Reporting System ;;Canada;4;58-11N;103-42W;;;492;; +CWWE;71;411;Western Head, N. S.;;Canada;4;43-59N;064-40W;;;9;;P +CWWF;71;452;Weyburn Automatic Weather Reporting System ;;Canada;4;49-42N;103-48W;;;589;; +CWWK;71;785;White Rock Automatic Weather Reporting System ;;Canada;4;49-01N;122-47W;;;15;; +CWWL;71;484;Bonilla Island Meteorological Aeronautical Presentation System ;;Canada;4;53-30N;130-38W;;;17;; +CWWM;--;---;Grant Automatic Weather Reporting System ;;Canada;4;82-30N;065-05W;;;1242;; +CWWN;71;434;Peawanuck Meteorological Aeronautical Presentation System ;;Canada;4;54-59N;085-26W;;;52;; +CWWO;71;252;Willow Creek;;Canada;4;53-23N;118-20W;;;1402;; +CWWP;71;444;Wasagaming, Man.;;Canada;4;50-39N;099-56W;;;626;627;P +CWWQ;71;945;Muncho Lake;;Canada;4;58-55N;125-46W;;;835;; +CWWS;71;445;George Island Meteorological Aeronautical Presentation System ;;Canada;4;52-48N;097-37W;;;223;; +CWWU;--;---;Ingenika Point;;Canada;4;56-48N;124-54W;;;680;; +CWWV;71;098;Killinek Meteorological Aeronautical Presentation System ;;Canada;4;60-25N;064-51W;;;31;; +CWWX;71;439;Cove Island Meteorological Aeronautical Presentation System ;;Canada;4;45-20N;081-44W;;;181;; +CWWZ;71;432;Port Weller, Ont.;;Canada;4;43-15N;079-13W;;;79;;P +CWXA;71;232;Bow Valley;;Canada;4;51-05N;115-04W;;;1298;; +CWXC;71;387;Onatchiway, Que.;;Canada;4;48-53N;071-02W;;;304;; +CWXH;71;562;Holberg, B. C.;;Canada;4;50-38N;128-07W;;;568;; +CWXI;--;---;Ferolle Point Meteorological Aeronautical Presentation System ;;Canada;4;51-01N;057-06W;;;8;; +CWXJ;--;---;Bull Arm Automatic Weather Reporting System;;Canada;4;47-49N;053-54W;;;119;; +CWXL;71;231;Bow Island;;Canada;4;49-38N;111-27W;;;838;; +CWXM;71;481;Helmcken Island Meteorological Aeronautical Presentation System ;;Canada;4;50-24N;125-52W;;;19;; +CWXO;--;---;Rowan Gorilla Iii;;Canada;4;43-53N;060-33W;;;44;; +CWXP;71;826;Pangnirtung;;Canada;4;66-09N;065-44W;;;23;; +CWXR;--;---;Croker River, N. W. T.;;Canada;4;69-16N;119-13W;;;69;; +CWXV;71;498;Back River Meteorological Aeronautical Presentation System ;;Canada;4;66-05N;096-30W;;;28;; +CWXW;71;183;Alexis River Meteorological Aeronautical Presentation System ;;Canada;4;52-39N;056-52W;;;43;; +CWYB;--;---;N. Bay Weather Office;;Canada;4;46-19N;079-27W;;;;; +CWYE;71;551;Outlook Pfra;;Canada;4;51-29N;107-03W;;;541;; +CWYG;--;---;Charlottetown;;Canada;4;46-14N;063-08W;;;50;; +CWYH;71;165;Rae Lakes;;Canada;4;64-07N;117-22W;;;231;; +CWYJ;71;783;Victoria University;;Canada;;48-27N;123-18W;;;60;; +CWYK;71;177;Cape Kiglapait, Nfld.;;Canada;4;57-08N;061-29W;;;834;; +CWYL;71;786;Yoho Park Automatic Weather Reporting System ;;Canada;;51-27N;116-20W;;;1615;; +CWYM;71;975;Cape Mercy;;Canada;4;64-57N;063-35W;;;583;; +CWYO;71;865;Wynyard, Sask.;;Canada;4;51-46N;104-12W;;;561;561;P +CWYY;71;215;Osoyoos Automatic Weather Reporting System ;;Canada;;49-02N;119-26W;;;283;; +CWZA;71;113;Agassiz Automated Reporting Station ;;Canada;;49-15N;121-46W;;;15;; +CWZB;71;197;Port-Aux-Basques, Nfld.;;Canada;4;47-34N;059-10W;47-34N;059-10W;40;40;P +CWZD;--;---;Scudder Point Meteorological Aeronautical Presentation System ;;Canada;4;52-27N;131-14W;;;5;; +CWZG;--;---;Banff Marine Aviation Reporting Station ;;Canada;4;51-12N;115-33W;;;1397;; +CWZL;--;---;Cumshewa Island Meteorological Aeronautical Presentation System ;;Canada;4;53-02N;131-36W;;;17;; +CWZM;--;---;Boat Bluff Light;;Canada;4;52-39N;128-31W;;;11;; +CWZN;71;408;Sagona Island Meteorological Aeronautical Presentation System ;;Canada;4;47-22N;055-48W;;;35;; +CWZO;--;---;Kelp Reefs, B. C.;;Canada;4;48-33N;123-14W;;;0;; +CWZQ;71;597;Grand Etang, N. S.;;Canada;4;46-33N;061-03W;;;13;; +CWZS;71;386;Amqui , Que.;;Canada;4;48-28N;067-26W;;;166;; +CWZT;71;550;Dauphin Coastal Station;;Canada;4;51-06N;100-03W;;;305;; +CWZV;71;048;Virginia Falls;;Canada;4;61-38N;125-48W;;;610;; +CWZW;--;---;Teslin Marine Aviation Reporting Station ;;Canada;4;60-10N;132-46W;;;705;; +CWZZ;71;804;Saglek Bay ;;Canada;4;58-20N;062-35W;;;483;; +CXBK;71;569;Bratts Lake, Sask.;;Canada;4;50-12N;104-42W;;580;; +CXBO;71;578;Beauport CS, Que.;;Canada;4;46-50N;071-12W;;;10;; +CXBP;--;---;Confederation Bridge, Prince Edward Island ;;Canada;4;46-14N;063-44W;;;54;; +CXCH;--;---;Cheticamp, N. S.;;Canada;4;46-39N;060-57W;;;44;; +CXCK;71;039;Carmacks CS, Y. T.;;Canada;4;62-07N;136-11W;;;632;; +CXDE;71;503;Deline , N. W. T.;;Canada;4;65-13N;123-26W;;;213;; +CXDI;71;573;Delhi CS, Ont.;;Canada;4;42-52N;080-33W;;;232;; +CXDW;71;840;Deerwood RCS , Man.;;Canada;4;49-24N;098-19W;;;341;; +CXEC;71;157;Edmonton Municipal CR10 , Alta.;;Canada;4;53-34N;113-31W;;;671;; +CXEG;71;155;Edmonton International CS , Alta.;;Canada;4;53-18N;113-36W;;;715;; +CXGH;71;577;Gimli Harbour CS, Man.;;Canada;4;50-37-52N;096-58-56W;;;217;; +CXHF;71;391;High Falls , Que.;;Canada;4;45-50N;075-39W;;;190;; +CXKT;71;605;Kentville , N. S.;;Canada;4;45-04N;064-29W;;;49;; +CXLC;71;680;Lower Carp Lake , N. W. T.;;Canada;4;63-36N;113-52W;;;373;; +CXLL;71;682;Lindberg Landing , N. W. T.;;Canada;4;61-07N;122-51W;;;183;; +CXMD;71;564;Morden CDA CS , Man.;;Canada;4;49-11N;098-05W;;;298;; +CXMI;--;---;McNabs Island , N. S.;;Canada;4;44-36N;063-32W;;;15;; +CXMM;71;585;Fort McMurray CS, Alta.;;Canada;4;56-39N;111-13W;;;369;; +CXMY;--;---;Malay Falls , N. S.;;Canada;4;44-59N;062-29W;;;40;; +CXNM;71;604;North Mountain , N. S.;;Canada;4;46-49N;060-40W;;;439;; +CXOX;71;586;La Ronge , Sask.;;Canada;4;55-09N;105-16W;;;378;; +CXPV;71;593;Prairie River, Alta;;Canada;4;58-37-20N;111-40-21W;;;212;; +CXQA;71;583;Qavvik Lake, N. W. T.;;Canada;4;68-15-28N;122-06-13W;;;530;; +CXRH;71;588;Rocky Harbour CS, Nfld.;;Canada;4;49-34N;057-53W;;;68;; +CXSH;71;370;Shawinigan CS , Que.;;Canada;4;46-35N;072-35W;;;110;; +CXSR;71;571;Spirit River Auto Station, Alta;;Canada;4;55-41-43N;119-14-03W;;;1015;; +CXSW;71;587;St. John's West CDA CS, Nfld.;;Canada;4;47-30-56N;052-47-05W;;;114;; +CXTN;71;492;Tuktut Nogait , N. W. T.;;Canada;4;69-11N;122-21W;;;552;; +CXTP;71;589;Terra Nova National Park CS, Nfld.;;Canada;4;48-33-25N;053-58-28W;;;107;; +CXTV;71;683;Trail Valley , N. W. T.;;Canada;4;68-45N;133-30W;;;85;; +CXWN;71;579;Winnipeg The Forks, Man.;;Canada;4;49-53N;097-08W;;;230;; +CXXX;71;073;Cluff Lake , Sask.;;Canada;4;58-23N;109-30W;;;339;; +CXZU;71;256;Whitecourt , Alta.;;Canada;4;54-09N;115-47W;;;785;; +CYAD;--;---;La Grande Iii Supplementary Aviation Weather Reporting Station ;;Canada;4;53-34N;076-12W;;;233;; +CYAH;71;823;La Grande Iv, Que.;;Canada;4;53-45N;073-40W;53-45N;073-40W;306;307;P +CYAJ;71;969;Komakuk Beach Airport;;Canada;4;69-35N;140-11W;;;7;; +CYAM;71;260;Sault Ste Marie, Ont.;;Canada;4;46-29N;084-30W;;;187;192;P +CYAS;--;---;Kangirsuk Supplementary Aviation Weather Reporting Station ;;Canada;4;60-01N;070-00W;;;117;; +CYAW;71;601;Shearwater, N. S.;;Canada;4;44-38N;063-30W;44-38N;063-30W;51;51;P +CYAY;--;---;Saint Anthony Airport;;Canada;4;51-24N;056-05W;;;28;; +CYAZ;71;106;Tofino Airport;;Canada;4;49-05N;125-46W;;;24;; +CYBB;--;---;Pelly Bay Airport;;Canada;4;68-32N;089-49W;;;15;; +CYBC;71;187;Baie Comeau, Que.;;Canada;4;49-08N;068-12W;;;21;22;P +CYBD;71;206;Bella Coola Airport ;;Canada;4;52-23N;126-35W;;;35;; +CYBG;71;727;Bagotville, Que.;;Canada;4;48-20N;071-00W;48-20N;071-00W;159;159;P +CYBK;71;926;Baker Lake, N. W. T.;;Canada;4;64-18N;096-05W;64-18N;096-00W;18;18;P +CYBL;--;---;Campbell River Airport;;Canada;4;49-57N;125-16W;;;106;; +CYBN;--;---;Borden, Ont.;;Canada;4;44-15N;079-55W;;;223;; +CYBR;71;140;Brandon, Man.;;Canada;4;49-55N;099-57W;;;409;409;P +CYBU;71;130;Nipawin, Sask.;;Canada;4;53-20N;104-00W;;;372;372;P +CYBV;71;859;Berens River Airport;;Canada;4;52-21N;097-02W;;;222;; +CYBW;--;---;Calgary / Springbank;;Canada;4;51-06N;114-22W;;;1200;; +CYBX;71;808;Blanc Sablon, Que.;;Canada;4;51-27N;057-11W;;;30;36;P +CYCA;--;---;Cartwright Man ;;Canada;4;53-41N;057-02W;;;12;; +CYCB;71;925;Cambridge Bay, N. W. T.;;Canada;4;69-06N;105-07W;69-08N;105-04W;23;27;P +CYCD;71;890;Nanaimo Airport;;Canada;4;49-03N;123-52W;;;28;; +CYCG;71;884;Castlegar Airport;;Canada;4;49-18N;117-38W;49-18N;117-38W;495;495; +CYCH;71;717;Chatham Can-Mil ;;Canada;4;47-00N;065-27W;47-01N;065-27W;31;34; +CYCL;71;711;Charlo, N. B.;;Canada;4;47-59N;066-20W;;;38;38;P +CYCO;71;938;Coppermine, N. W. T.;;Canada;4;67-49N;115-08W;67-50N;115-07W;22;22;P +CYCP;71;883;Blue River, B. C.;;Canada;4;52-08N;119-18W;;;679;683;P +CYCQ;--;---;Chetwynd Airport;;Canada;4;55-42N;121-38W;;;609;; +CYCS;--;---;Chesterfield Inlet;;Canada;4;63-20N;090-43W;;;11;; +CYCT;71;873;Coronation Marine Aviation Reporting Station ;;Canada;4;52-04N;111-27W;;;791;; +CYCX;71;701;Gagetown Can-Mil ;;Canada;4;45-50N;066-26W;45-50N;066-26W;51;51; +CYCY;71;090;Clyde, N. W. T.;;Canada;4;70-29N;068-31W;70-27N;068-33W;25;26;P +CYDA;71;966;Dawson, Y. T.;;Canada;4;64-03N;139-08W;;;370;370;P +CYDB;--;---;Burwash Airport;;Canada;4;61-22N;139-02W;;;807;; +CYDC;71;886;Princeton Airport ;;Canada;4;49-28N;120-31W;;;700;; +CYDF;71;809;Deer Lake, Nfld.;;Canada;4;49-13N;057-24W;;;17;22;P +CYDM;--;---;Ross River Airport;;Canada;4;61-58N;132-26W;;;705;; +CYDN;71;855;Dauphin, Man.;;Canada;4;51-06N;100-03W;51-06N;100-03W;305;305;P +CYDP;71;902;Nain, Nfld;;Canada;4;56-33N;061-41W;;;6;7;P +CYDQ;--;---;Dawson Creek Airport ;;Canada;4;55-45N;120-11W;;;655;; +CYED;71;121;Edmonton Namao Alta.;;Canada;4;53-40N;113-28W;53-40N;113-28W;688;688;P +CYEG;71;123;Edmonton International, Alta.;;Canada;4;53-18N;113-35W;53-19N;113-35W;715;723;P +CYEK;--;---;Arviat Airport;;Canada;4;61-06N;094-04W;;;10;; +CYEL;--;---;Elliot Lake Supplementary Aviation Weather Reporting Station ;;Canada;4;46-21N;082-34W;;;329;; +CYEN;71;862;Estevan, Sask.;;Canada;4;49-13N;102-58W;;;572;581;P +CYET;71;881;Edson, Alta.;;Canada;4;53-35N;116-28W;;;921;927;P +CYEU;--;---;Eureka Man ;;Canada;4;80-00N;085-49W;;;78;; +CYEV;71;957;Inuvik, N. W. T.;;Canada;4;68-18N;133-29W;68-19N;133-32W;59;68;P +CYFB;71;909;Iqaluit, N. W. T.;;Canada;4;63-45N;068-33W;63-45N;068-33W;34;34;P +CYFC;71;700;Fredericton, N. B.;;Canada;4;45-52N;066-32W;;;17;20;P +CYFO;--;---;Flin Flon Airport;;Canada;4;54-41N;101-41W;;;304;; +CYFR;--;---;Fort Resolution;;Canada;4;61-11N;113-41W;;;164;; +CYFS;71;946;Fort Simpson, N. W. T.;;Canada;4;61-45N;121-14W;;;168;169;P +CYFT;--;---;Makkovik Airport;;Canada;4;55-05N;059-11W;;;71;; +CYGE;--;---;Golden Airport;;Canada;4;51-18N;116-59W;;;785;; +CYGH;--;---;Fort Good Hope Airport;;Canada;4;66-16N;128-37W;;;60;; +CYGK;71;620;Kingston, Ont.;;Canada;4;44-13N;076-36W;;;93;93;P +CYGL;71;827;La Grande Riviere, Que;;Canada;4;53-38N;077-42W;;;195;195;P +CYGM;71;856;Gimli Industrial, Man;;Canada;4;50-37N;097-02W;;;230;232;P +CYGP;71;188;Gaspe, Que.;;Canada;4;48-46N;064-29W;;;33;33;P +CYGQ;71;834;Geraldton, Ont.;;Canada;4;49-47N;086-56W;49-42N;086-57W;349;349;P +CYGR;71;709;Iles De La Madeleineque.;;Canada;4;47-25N;061-47W;;;10;10;P +CYGT;--;---;Igloolik Airport;;Canada;4;69-22N;081-49W;;;51;; +CYGV;71;313;Havre St Pierre ;;Canada;4;50-17N;063-37W;;;33;; +CYGW;71;905;Kuujjuarapik, Que.;;Canada;4;55-17N;077-46W;;;21;10;P +CYGX;71;912;Gillam, Man.;;Canada;4;56-21N;094-42W;;;145;145;P +CYHA;71;904;Quaqtaq Airport;;Canada;4;61-03N;069-38W;;;30;; +CYHB;71;868;Hudson Bay, Sask.;;Canada;4;52-49N;102-19W;;;357;358;P +CYHD;--;---;Dryden Airport;;Canada;4;49-50N;092-45W;;;413;; +CYHE;71;114;Hope, B. C.;;Canada;4;49-22N;121-29W;;;39;39;P +CYHH;--;---;Nemiscau Airport Supplementary Aviation Weather Reporting Station ;;Canada;4;51-42N;076-07W;;;244;; +CYHI;--;---;Holman Island Airport;;Canada;4;70-46N;117-48W;;;36;; +CYHK;--;---;Gjoa Haven Airport;;Canada;4;68-38N;095-51W;;;46;; +CYHM;71;263;Hamilton Airport ;;Canada;4;43-10N;079-56W;;;237;; +CYHU;71;371;Saint Hubert Airport ;;Canada;4;45-31N;073-25W;;;27;; +CYHY;71;935;Hay River, N. W. T.;;Canada;4;60-50N;115-47W;;;164;166;P +CYHZ;71;395;Halifax International Airport ;;Canada;4;44-53N;063-30W;;;145;; +CYID;--;---;Digby Airport Aviation Weather Reporting Station ;;Canada;4;44-33N;065-47W;;;152;; +CYIK;--;---;Ivujivik Airport Supplementary Aviation Weather Reporting Station ;;Canada;4;62-25N;077-57W;;;42;; +CYIO;71;095;Pond Inlet, N. W. T.;;Canada;4;72-42N;077-58W;;;59;55;P +CYIV;71;145;Island Lake, Man.;;Canada;4;53-51N;094-39W;53-52N;094-40W;237;237;P +CYJF;--;---;Fort Liard Airport;;Canada;4;60-14N;123-29W;;;215;; +CYJT;71;815;Stephenville, Nfld.;;Canada;4;48-32N;058-33W;48-32N;058-33W;8;26;P +CYKA;71;887;Kamloops, B. C.;;Canada;4;50-42N;120-27W;;;345;346;P +CYKD;--;---;Aklavik Airport;;Canada;4;68-13N;135-00W;;;7;; +CYKF;71;368;Waterloo Well ;;Canada;4;43-28N;080-23W;;;317;; +CYKG;--;---;Kangiqsujuaq Supplementary Aviation Weather Reporting Station ;;Canada;4;61-35N;071-56W;;;151;; +CYKJ;71;488;Key Lake;;Canada;4;57-15N;105-37W;;;509;; +CYKL;71;828;Schefferville, Que.;;Canada;4;54-48N;066-48W;54-48N;066-49W;521;518;P +CYKO;--;---;Akulivik Airport;;Canada;4;60-49N;078-09W;;;20;; +CYKQ;--;---;Waskaganish Airport;;Canada;4;51-29N;078-45W;;;23;; +CYKY;71;129;Kindersley, Sask.;;Canada;4;51-31N;109-10W;51-31N;109-11W;694;694;P +CYKZ;--;---;Toronto Buttonville;;Canada;4;43-52N;079-22W;;;198;; +CYLA;--;---;Aupaluk, Que.;;Canada;4;59-17-48N;069-35-59;;;35;; +CYLC;--;---;Kimmirut A Nwt;;Canada;4;62-51N;069-53W;;;53;; +CYLD;--;---;Chapleau, Ont.;;Canada;4;47-49N;083-21W;;;447;; +CYLJ;71;125;Meadow Lake, Sask.;;Canada;4;54-08N;108-31W;;;480;480;P +CYLK;--;---;Lutsel KE, N. W. T.;;Canada;4;62-25N;110-40W;;;179;; +CYLL;71;871;Lloydminister, Alta.;;Canada;4;53-19N;110-04W;;;665;669;P +CYLT;--;---;Alert Airport;;Canada;4;82-31N;062-17W;;;31;; +CYLU;--;---;Kangiksualujjuaq A;;Canada;4;58-43N;065-59W;;;60;; +CYLW;71;203;Kelowna Airport;;Canada;4;49-58N;119-23W;49-58N;119-23W;430;430; +CYMA;71;965;Mayo Airport;;Canada;4;63-37N;135-52W;;;504;; +CYMD;71;072;Mould Bay, N. W. T.;;Canada;4;76-14N;119-20W;76-15N;119-21W;15;12;P +CYMH;--;---;Mary's Harbour ;;Canada;4;52-18N;055-51W;;;11;; +CYMJ;71;864;Moose Jaw, Sask.;;Canada;4;50-20N;105-33W;;;577;577;P +CYML;--;---;Charlevoix Airport;;Canada;4;47-36N;070-14W;;;298;; +CYMM;71;932;Fort Mcmurray, Alta.;;Canada;4;56-39N;111-13W;56-39N;111-13W;369;369;P +CYMO;71;836;Moosonee, Ont.;;Canada;4;51-16N;080-39W;51-16N;080-39W;10;10;P +CYMT;71;822;Chibougamau-Chapais, Que;;Canada;4;49-46N;074-32W;;;388;387;P +CYMU;--;---;Umiujaq;;Canada;4;56-32N;076-31W;;;71;; +CYMX;--;---;Montreal / Mirabel;;Canada;4;45-41N;074-02W;;;82;; +CYNA;71;813;Natashquan, Que.;;Canada;4;50-11N;061-49W;;;7;11;P +CYNC;--;---;Aeroport de Wemindji, Que.;;Canada;4;53-00-39N;078-49-49W;;;15;; +CYND;--;---;Gatineau Airport;;Canada;4;45-31N;075-34W;;;64;; +CYNE;71;141;Norway House, Man.;;Canada;4;53-58N;097-50W;;;223;223;P +CYNM;71;821;Matagami, Que.;;Canada;4;49-46N;077-49W;;;281;281;P +CYOA;--;---;Ekati, N. W. T.;;Canada;4;64-42N;110-37W;;;469;; +CYOC;--;---;Old Crow Airport;;Canada;4;67-34N;139-49W;;;251;; +CYOD;71;120;Cold Lake, Alta.;;Canada;4;54-25N;110-17W;54-25N;110-17W;541;541;P +CYOJ;71;066;High Level, Alta;;Canada;4;58-37N;117-10W;;;338;338;P +CYOW;71;628;Ottawa Int'L. Ont.;;Canada;4;45-19N;075-40W;45-19N;075-40W;116;114;P +CYOY;71;716;Valcartier Airport;;Canada;4;46-54N;071-30W;46-54N;071-29W;168;178; +CYPA;71;869;Prince Albert, Sask.;;Canada;4;53-13N;105-41W;53-13N;105-41W;428;428;P +CYPC;--;---;Paulatuk Airport;;Canada;4;69-21N;124-02W;;;6;; +CYPD;--;---;Port Hawkesbury;;Canada;4;45-40N;061-23W;;;114;; +CYPE;71;068;Peace River, Alta.;;Canada;4;56-14N;117-26W;;;571;571;P +CYPG;71;851;Portage Southport A;;Canada;4;49-54N;098-16W;;098-16W;269;259; +CYPH;--;---;Inukjuak Airport Supplementary Aviation Weather Reporting Station ;;Canada;4;58-28N;078-05W;;;25;; +CYPL;--;---;Pickle Lake Man ;;Canada;4;51-27N;090-12W;;;386;; +CYPN;--;---;Port Menier Man ;;Canada;4;49-50N;064-17W;;;51;; +CYPQ;71;629;Peterborough Airport ;;Canada;4;44-14N;078-22W;;;191;; +CYPR;71;898;Prince Rupert, B. C.;;Canada;4;54-18N;130-26W;;;34;34;P +CYPW;71;208;Powell River Airport ;;Canada;4;49-50N;124-30W;;;130;; +CYPX;--;---;Povungnituq;;Canada;4;60-03N;077-17W;;;23;; +CYPY;71;933;Fort Chipewyan, Alta.;;Canada;4;58-46N;111-07W;;;232;232;P +CYPZ;71;952;Burns Lake ;;Canada;4;54-23N;125-57W;;;713;; +CYQA;71;630;Muskoka, Ont.;;Canada;4;44-58N;079-18W;;;280;282;P +CYQB;71;714;Quebec, Que;;Canada;4;46-48N;071-23W;46-48N;071-23W;70;74;P +CYQD;71;867;The Pas, Man.;;Canada;4;53-58N;101-06W;53-58N;101-06W;271;271;P +CYQF;71;878;Red Deer, Alta.;;Canada;4;52-11N;113-54W;52-11N;113-54W;905;905;P +CYQG;71;538;Windsor, Ont.;;Canada;4;42-16N;082-58W;;;190;190;P +CYQH;71;953;Watson Lake, Y. T.;;Canada;4;60-07N;128-49W;60-07N;128-49W;690;690;P +CYQI;71;603;Yarmouth, N. S.;;Canada;4;43-50N;066-05W;43-52N;066-06W;43;43;P +CYQK;71;850;Kenora, Ont.;;Canada;4;49-47N;094-22W;;;407;410;P +CYQL;71;874;Lethbridge, Alta.;;Canada;4;49-38N;112-48W;49-38N;112-48W;929;929;P +CYQM;71;705;Moncton, N. B.;;Canada;4;46-07N;064-41W;;;71;71;P +CYQQ;71;893;Comox, B. C.;;Canada;4;49-43N;124-54W;49-43N;124-54W;24;24;P +CYQR;71;863;Regina, Sask.;;Canada;4;50-26N;104-40W;50-26N;104-40W;577;577;P +CYQT;71;749;Thunder Bay, Ont.;;Canada;4;48-22N;089-19W;;;199;199;P +CYQU;71;940;Grande Prairie, Alta.;;Canada;4;55-11N;118-53W;;;666;669;P +CYQV;71;138;Yorkton, Sask.;;Canada;4;51-16N;102-28W;;;498;498;P +CYQW;71;876;North Battleford, Sask.;;Canada;4;52-46N;108-15W;;;548;548;P +CYQX;71;803;Gander Int. Airport, Nfld.;;Canada;4;48-57N;054-34W;48-57N;054-34W;151;151;P +CYQY;71;707;Sydney, N. S.;;Canada;4;46-10N;060-03W;46-10N;060-03W;56;62;P +CYQZ;71;103;Quesnel Airport;;Canada;4;53-02N;122-31W;;;545;; +CYRB;71;924;Resolute, N. W. T.;;Canada;4;74-43N;094-59W;74-42N;094-58W;67;67;P +CYRJ;71;728;Roberval, Que.;;Canada;4;48-31N;072-16W;;;179;179;P +CYRL;71;854;Red Lake, Ont.;;Canada;4;51-04N;093-48W;;;375;383;P +CYRM;71;928;Rocky Mountain House, Alta;;Canada;4;52-26N;114-55W;52-23N;114-55W;988;988;P +CYRT;71;083;Rankin Inlet, N. W. T.;;Canada;4;62-49N;092-07W;;;31;31;P +CYRV;71;882;Revelstoke, B. C.;;Canada;4;50-58N;118-11W;;;443;443;P +CYSA;--;---;Sable Island Airport ;;Canada;4;43-56N;060-00W;;;4;; +CYSB;71;730;Sudbury, Ont.;;Canada;4;46-37N;080-48W;;;348;348;P +CYSC;71;610;Sherbrooke, Que.;;Canada;4;45-24N;071-53W;;;170;;P +CYSD;71;128;Suffield Airport;;Canada;4;50-16N;111-11W;;;770;; +CYSF;71;132;Stony Rapids Airport;;Canada;4;59-15N;105-50W;;;250;; +CYSJ;71;609;Saint John, N. B.;;Canada;4;45-20N;065-53W;;;103;109;P +CYSK;--;---;Sanikiluaq Airport;;Canada;4;56-32N;079-15W;;;32;; +CYSL;71;703;Saint Leonard Airport ;;Canada;4;47-09N;067-50W;;;241;; +CYSM;71;934;Fort Smith, N. W. T.;;Canada;4;60-01N;111-57W;60-02N;111-56W;203;205;P +CYSN;--;---;Saint Catharines Airport;;Canada;4;43-12N;079-10W;;;98;; +CYSR;--;---;Nanisivik Airport ;;Canada;4;72-59N;084-38W;;;649;; +CYSU;71;702;Summerside Can-Mil ;;Canada;4;46-26N;063-50W;46-26N;063-50W;24;24; +CYSY;--;---;Sachs Harbour Airport;;Canada;4;72-00N;125-17W;;;86;; +CYTE;71;910;Cape Dorset, N. W. T.;;Canada;4;64-13N;076-32W;;;51;50;P +CYTH;71;079;Thompson Weather Office, Man;;Canada;4;55-48N;097-51W;55-48N;097-52W;204;222;P +CYTJ;--;---;Terrace Bay Supplementary Aviation Weather Reporting Station ;;Canada;4;48-49N;087-06W;;;287;; +CYTL;71;848;Big Trout Lake;;Canada;4;53-50N;089-52W;53-50N;089-52W;224;224; +CYTN;--;---;Trenton Municipal A, N. S.;;Canada;4;45-36-41N;062-37-19W;;;97;; +CYTQ;--;---;Tasiujaq A;;Canada;4;58-40N;069-57W;;;31;; +CYTR;71;621;Trenton, Ont.;;Canada;4;44-07N;077-32W;44-07N;077-32W;85;86;P +CYTS;71;739;Timmins, Ont.;;Canada;4;48-34N;081-22W;;;295;295;P +CYTZ;71;265;Toronto Island Airport Automated Reporting Station;;Canada;4;43-38N;079-24W;;;77;; +CYUA;71;968;Shingle Point, Y. T.;;Canada;4;68-57N;137-13W;;;56;38;P +CYUB;71;954;Tuktoyaktuk ;;Canada;4;69-27N;133-01W;69-27N;133-01W;5;5; +CYUI;71;939;Cape Young Airport;;Canada;4;68-56N;116-55W;;;16;; +CYUJ;71;937;Lady Franklin Point, N. W. T.;;Canada;4;68-30N;113-13W;;;21;16;P +CYUK;71;929;Byron Bay Airport;;Canada;4;68-45N;109-04W;;;92;; +CYUL;71;627;Montreal / Dorval International, Que;;Canada;4;45-28N;073-45W;45-28N;073-45W;31;36;P +CYUQ;71;071;Jenny Lind Island Airport;;Canada;4;68-39N;101-44W;;;18;; +CYUS;71;911;Shepherd Bay, N. W. T.;;Canada;4;68-49N;093-26W;;;51;42;P +CYUT;--;---;Repulse Bay Airport;;Canada;4;66-32N;086-15W;;;24;; +CYUV;--;---;Longstaff Blf Airport;;Canada;4;68-56N;075-17W;;;14;; +CYUX;71;081;Hall Beach, N. W. T.;;Canada;4;68-47N;081-15W;68-46N;081-13W;8;8;P +CYUY;--;---;Rouyn Airport;;Canada;4;48-12N;078-50W;;;301;; +CYVC;71;922;La Ronge, Sask;;Canada;4;55-09N;105-16W;;;375;379;P +CYVM;--;---;Broughton Island Airport;;Canada;4;67-33N;064-02W;;;6;; +CYVO;71;725;Val D'Or, Que.;;Canada;4;48-04N;077-47W;;;337;337;P +CYVP;71;906;Kuujjuaq, Que.;;Canada;4;58-06N;068-25W;58-06N;068-25W;37;37;P +CYVQ;71;043;Norman Wells, N. W. T.;;Canada;4;65-17N;126-48W;65-17N;126-45W;67;74;P +CYVR;71;892;Vancouver International Air-Port, B. C.;;Canada;4;49-11N;123-10W;49-11N;123-10W;3;2;P +CYVT;--;---;Buffalo Narrows Man;;Canada;4;55-50N;108-27W;;;434;; +CYVV;71;633;Wiarton, Ont.;;Canada;4;44-45N;081-06W;;;222;222;P +CYWA;71;625;Petawawa, Ont.;;Canada;4;45-57N;077-19W;45-57N;077-19W;130;130;P +CYWG;71;852;Winnipeg Int. Airportman.;;Canada;4;49-54N;097-14W;49-54N;097-14W;239;239;P +CYWH;--;---;Victoria Harbour;;Canada;4;48-25N;123-20W;;;5;; +CYWJ;--;---;Fort Franklin Airport;;Canada;4;65-12N;123-26W;;;176;; +CYWK;71;825;Wabush Lake, Nfld.;;Canada;4;52-56N;066-52W;;;551;551;P +CYWL;71;104;Williams Lake, B. C.;;Canada;4;52-11N;122-03W;;;940;940;P +CYWO;--;---;Lupin Airport Supplementary Aviation Weather Reporting Station ;;Canada;4;65-46N;111-15W;;;494;; +CYWV;--;---;Wainwright Airport;;Canada;4;52-48N;110-53W;;;662;; +CYWY;--;---;Wrigley Airport;;Canada;4;63-13N;123-26W;;;150;; +CYXC;71;880;Cranbrook, B. C.;;Canada;4;49-37N;115-47W;;;939;939;P +CYXD;71;879;Edmonton Municipal Alta.;;Canada;4;53-34N;113-31W;53-34N;113-31W;671;671;P +CYXE;71;866;Saskatoon, Sask.;;Canada;4;52-10N;106-41W;52-10N;106-41W;501;504;P +CYXH;71;872;Medicine Hat, Alta.;;Canada;4;50-01N;110-43W;;;717;717;P +CYXJ;71;943;Fort St John, B. C.;;Canada;4;56-14N;120-44W;;;695;695;P +CYXL;71;842;Sioux Lookout, Ont.;;Canada;4;50-07N;091-54W;;;389;390;P +CYXN;--;---;Whale Cove Airport;;Canada;4;62-14N;092-36W;;;20;; +CYXP;--;---;Pangnirtung Airport;;Canada;4;66-09N;065-43W;;;23;; +CYXQ;--;---;Beaver Creek Airport;;Canada;4;62-25N;140-52W;;;649;; +CYXR;71;735;Earlton, Ont.;;Canada;4;47-42N;079-51W;;;243;243;P +CYXS;71;896;Prince George, B. C.;;Canada;4;53-53N;122-41W;53-53N;122-40W;691;691;P +CYXT;71;951;Terrace, B. C.;;Canada;4;54-28N;128-35W;;;217;217;P +CYXU;71;623;London, Ont.;;Canada;4;43-02N;081-09W;;;278;278;P +CYXX;71;108;Abbotsford, B. C.;;Canada;4;49-02N;122-22W;;;54;58;P +CYXY;71;964;Whitehorse, Y. T.;;Canada;4;60-43N;135-04W;60-43N;135-04W;703;703;P +CYXZ;71;738;Wawa, Ont.;;Canada;4;47-58N;084-47W;;;287;287;P +CYYB;71;731;North Bay, Ont.;;Canada;4;46-21N;079-26W;46-22N;079-25W;358;371;P +CYYC;71;877;Calgary International, Alta.;;Canada;4;51-07N;114-01W;51-07N;114-01W;1077;1084;P +CYYD;71;950;Smithers, B. C.;;Canada;4;54-49N;127-11W;;;523;523;P +CYYE;71;945;Fort Nelson, B. C.;;Canada;4;58-50N;122-35W;58-50N;122-36W;382;382;P +CYYF;71;889;Penticton, B. C.;;Canada;4;49-28N;119-36W;;;344;344;P +CYYG;71;706;Charlottetown, P. E. I.;;Canada;4;46-17N;063-08W;;;48;54;P +CYYH;--;---;Spence Bay Airport ;;Canada;4;69-33N;093-35W;;;28;; +CYYJ;71;799;Victoria Int. Airport, B. C.;;Canada;4;48-39N;123-26W;48-39N;123-26W;20;19;P +CYYL;71;078;Lynn Lake, Man.;;Canada;4;56-52N;101-05W;56-52N;101-05W;357;357;P +CYYN;71;870;Swift Current, Sask.;;Canada;4;50-17N;107-41W;;;818;818;P +CYYQ;71;913;Churchill, Man.;;Canada;4;58-44N;094-04W;58-44N;094-05W;28;29;P +CYYR;71;816;Goose, Nfld.;;Canada;4;53-19N;060-25W;53-18N;060-22W;46;49;P +CYYT;71;801;St. John's, Nfld;;Canada;4;47-37N;052-44W;47-40N;052-45W;134;140;P +CYYU;71;831;Kapuskasing, Ont.;;Canada;4;49-25N;082-28W;;;227;227;P +CYYW;71;841;Armstrong, Ont.;;Canada;4;50-18N;089-02W;;;351;351;P +CYYY;71;718;Mont Joli, Que.;;Canada;4;48-36N;068-13W;;;48;52;P +CYYZ;71;624;Toronto Pearson Int'L. Ont.;;Canada;4;43-40N;079-38W;43-41N;079-38W;173;173;P +CYZE;71;733;Gore Bay, Ont.;;Canada;4;45-53N;082-34W;;;193;193;P +CYZF;71;936;Yellowknife, N. W. T.;;Canada;4;62-28N;114-27W;;;205;206;P +CYZG;--;---;Salliut Airport Supplementary Aviation Weather Reporting Station ;;Canada;4;62-11N;075-40W;;;226;; +CYZH;71;069;Slave Lake, Alta;;Canada;4;55-18N;114-47W;55-18N;114-47W;581;581;P +CYZP;71;101;Sandspit, B. C.;;Canada;4;53-15N;131-49W;;;6;6;P +CYZR;71;634;Sarnia Airport ;;Canada;4;43-00N;082-19W;;;181;; +CYZS;71;915;Coral Harbour, N. W. T.;;Canada;4;64-12N;083-22W;64-12N;083-22W;64;64;P +CYZT;71;109;Port Hardy, B. C.;;Canada;4;50-41N;127-22W;50-41N;127-22W;22;22;P +CYZU;71;930;Whitecourt, Alta.;;Canada;4;54-09N;115-47W;;;783;782;P +CYZV;71;811;Sept-Iles, Que.;;Canada;4;50-13N;066-16W;50-13N;066-15W;55;55;P +CYZW;71;045;Teslin, Y. T.;;Canada;4;60-10N;132-44W;;;711;705;P +CYZX;71;397;Greenwood, N. S.;;Canada;4;44-59N;064-55W;;;28;28;P +CYZY;71;944;Mackenzie, B. C.;;Canada;4;55-18N;123-08W;;;695;690;P +CZAG;--;---;La Grande Iv Remote Environment Automatic Data Acquisition Concept;;Canada;4;53-45N;073-41W;;;307;; +CZBF;--;---;Bathurst Airport Aviation Weather Reporting Station ;;Canada;4;47-38N;065-45W;;;59;; +CZCP;--;---;Cape Parry, N. W. T.;;Canada;4;70-06N;124-43W;;;87;; +CZDI;71;180;Churchill Falls;;Canada;4;53-34N;064-06W;;;440;; +CZEM;--;---;Eastmain River Airport;;Canada;4;52-14N;078-31W;;;7;; +CZFA;--;---;Faro Airport;;Canada;4;62-12N;133-22W;;;717;; +CZFM;--;---;Fort Mcpherson Airport;;Canada;4;67-24N;134-51W;;;43;; +CZFN;--;---;Fort Norman Airport;;Canada;4;64-55N;125-34W;;;98;; +CZNB;--;---;North Bay Remote Environment Automatic Data Acquisition Concept ;;Canada;4;46-22N;079-25W;;;364;; +CZOC;71;044;Old Crow Automatic Weather Reporting System ;;Canada;4;67-34N;139-50W;;;251;; +CZPC;--;---;Pincher Creek Airport;;Canada;4;49-31N;113-59W;;;1190;; +CZPK;71;984;Paulatuk Automated Reporting Station ;;Canada;4;69-21N;124-03W;;;6;; +CZST;71;955;Stewart Airport;;Canada;4;55-56N;129-59W;;;7;; +CZUB;71;985;Tuktoyaktuk Automated Reporting Station ;;Canada;4;69-26N;133-02W;;;6;; +CZUE;71;948;Cape Parry, N. W. T.;;Canada;4;70-10N;124-42W;;;17;17;P +CZUM;71;182;Churchill Falls, Nfld.;;Canada;4;53-33N;064-06W;;;440;440;P +CZVL;--;---;Edmonton / Villeneuve;;Canada;4;53-40N;113-52W;;;686;; +CZWN;--;---;Wainwright Automatic Weather Reporting System ;;Canada;4;52-49N;111-05W;;;684;; +DAAD;60;515;Bou-Saada;;Algeria;1;35-20N;004-12E;;;461;461;P +DAAE;60;402;Bejaia;;Algeria;1;36-43N;005-04E;36-43N;005-04E;2;2;P +DAAF;--;---;Aoulef ;;Algeria;1;26-58N;001-05E;;;309;; +DAAG;60;390;Dar-El-Beida;;Algeria;1;36-43N;003-15E;36-43N;003-15E;25;25;P +DAAJ;60;670;Djanet;;Algeria;1;24-33N;009-28E;24-33N;009-28E;1054;1054;P +DAAP;60;640;Illizi;;Algeria;1;26-30N;008-25E;26-30N;008-25E;558;558;P +DAAS;60;445;Setif;;Algeria;1;36-11N;005-25E;36-11N;005-25E;1038;1081;P +DAAT;--;---;Tamanrasset / Aguenna;;Algeria;1;22-49N;005-28E;;;1377;; +DAAV;60;351;Jijel Achouat;;Algeria;1;36-53N;005-49E;;;2;10;P +DAAY;60;549;Mecheria;;Algeria;1;34-56N;000-26W;34-56N;000-26W;1149;1149;P +DABB;60;360;Annaba;;Algeria;1;36-50N;007-49E;36-50N;007-49E;4;4;P +DABC;60;419;Constantine;;Algeria;1;36-17N;006-37E;36-17N;006-37E;694;694;P +DABP;60;355;Skikda;;Algeria;1;36-56N;006-57E;36-56N;006-57E;7;7;P +DABS;60;475;Tebessa;;Algeria;1;35-29N;008-08E;35-29N;008-08E;813;813;P +DABT;60;468;Batna;;Algeria;1;35-33N;006-11E;;;1052;1052;P +DAFH;--;---;Tilrempt/Hassi R'mel;;Algeria;1;32-55-48N;003-18-44E;;;774;; +DAFI;60;535;Djelfa;;Algeria;1;34-41N;003-15E;34-41N;003-15E;1144;1144;P +DAOB;60;511;Tiaret;;Algeria;1;35-15N;001-26E;;;1127;1127;P +DAOF;60;656;Tindouf;;Algeria;1;27-40N;008-08W;27-40N;008-08W;431;431;P +DAOI;60;425;Chlef;;Algeria;1;36-13N;001-20E;36-13N;001-20E;143;143;P +DAOL;--;---;Oran/Tafaraoui;;Algeria;1;35-32-33N;000-31-56W;;;112;; +DAON;60;531;Tlemcen Zenata ;;Algeria;1;35-01N;001-28W;;;247;247;P +DAOO;60;490;Oran / Es Senia;;Algeria;1;35-38N;000-36W;35-38N;000-36W;90;90;P +DAOR;60;571;Bechar;;Algeria;1;31-37N;002-14W;31-37N;002-14W;773;773;P +DAOV;60;507;Mascara-Ghriss;;Algeria;1;35-12E;000-08W;;;514;; +DATG;--;---;In Guezzam;;Algeria;1;19-34N;005-45E;;;399;; +DATM;--;---;Bordj Mokhtar;;Algeria;1;21-22-30N;000-55-26E;;;396;; +DAUA;60;620;Adrar;;Algeria;1;27-53N;000-17W;27-53N;000-17W;263;263;P +DAUB;60;525;Biskra;;Algeria;1;34-48N;005-44E;34-48N;005-44E;87;87;P +DAUE;60;590;El Golea;;Algeria;1;30-34N;002-52E;30-34N;002-52E;397;397;P +DAUG;60;566;Ghardaia;;Algeria;1;32-23N;003-49E;32-23N;003-49E;450;450;P +DAUH;60;581;Hassi-Messaoud;;Algeria;1;31-40N;006-09E;;;142;142;P +DAUI;--;---;In Salah North;;Algeria;1;27-15N;002-31E;;;269;; +DAUK;60;555;Touggourt;;Algeria;1;33-07N;006-08E;33-07N;006-08E;85;85;P +DAUL;60;545;Laghouat;;Algeria;1;33-46N;002-56E;33-46N;002-56E;765;765;P +DAUO;60;559;El Oued;;Algeria;1;33-30N;006-07E;33-30N;006-47E;63;63;P +DAUT;60;607;Timimoun;;Algeria;1;29-15N;000-17E;29-15N;000-17E;312;312;P +DAUU;60;580;Ouargla;;Algeria;1;31-55N;005-24E;31-55N;005-24E;141;141;P +DAUZ;60;611;In Amenas;;Algeria;1;28-03N;009-38E;28-03N;009-38E;562;562;P +DBBB;65;344;Cotonou;;Benin;1;06-21N;002-23E;06-21N;002-23E;5;9;P +DBBC;65;338;Bohicon;;Benin;1;07-10N;002-04E;;;166;167;P +DBBK;65;306;Kandi;;Benin;1;11-08N;002-56E;11-08N;002-56E;290;292;P +DBBN;65;319;Natitingou;;Benin;1;10-19N;001-23E;;;460;461;P +DBBP;65;330;Parakou;;Benin;1;09-21N;002-37E;09-21N;002-37E;392;393;P +DBBS;65;335;Save;;Benin;1;08-02N;002-28E;;;199;200;P +DFCC;65;502;Ouahigouya;;Burkina Faso;1;13-34N;002-25W;;;337;336; +DFCO;65;516;Boromo;;Burkina Faso;1;11-45N;002-56W;;;270;271; +DFCP;65;518;Po;;Burkina Faso;1;11-09N;001-09W;;;320;322; +DFEE;65;501;Dori;;Burkina Faso;1;14-02N;000-02W;14-02N;000-02W;276;277; +DFEF;65;507;Fada N'Gourma;;Burkina Faso;1;12-02N;000-22E;;;308;309; +DFFD;65;503;Ouagadougou;;Burkina Faso;1;12-21N;001-31W;12-21N;001-31W;316;306;P +DFOD;65;505;Dedougou;;Burkina Faso;1;12-28N;003-29W;;;300;300; +DFOG;65;522;Gaoua;;Burkina Faso;1;10-20N;003-11W;;;333;335; +DFOO;65;510;Bobo-Dioulasso;;Burkina Faso;1;11-10N;004-19W;11-10N;004-19W;460;460;P +DGAA;65;472;Accra;;Ghana;1;05-36N;000-10W;05-36N;000-10W;68;69;P +DGAD;65;475;Ada;;Ghana;1;05-47N;000-38E;;;5;7;P +DGAH;65;453;Ho;;Ghana;1;06-36N;000-28E;;;158;158;P +DGAK;65;460;Akuse;;Ghana;1;06-06N;000-07E;;;17;19;P +DGAS;65;469;Saltpond;;Ghana;1;05-12N;001-04W;;;44;47;P +DGAT;65;473;Tema;;Ghana;1;05-37N;00-00;;;14;18; +DGKA;65;457;Akim Oda;;Ghana;1;05-56N;000-59W;;;139;140;P +DGKK;65;459;Koforidua;;Ghana;1;06-05N;000-15W;;;166;167;P +DGLB;65;416;Bole;;Ghana;1;09-02N;002-29W;09-02N;002-29W;299;301;P +DGLE;65;418;Tamale;;Ghana;1;09-30N;000-51W;09-30N;000-51W;168;173;P +DGLN;65;401;Navrongo;;Ghana;1;10-54N;001-06W;;;201;203;P +DGLW;65;404;Wa;;Ghana;1;10-03N;002-30W;;;323;323;P +DGLY;65;420;Yendi;;Ghana;1;09-27N;000-01W;;;195;197;P +DGSB;65;445;Sefwi Bekwai;;Ghana;1;06-12N;002-20W;;;171;172;P +DGSI;65;442;Kumasi;;Ghana;1;06-43N;001-36W;06-43N;001-36W;287;293;P +DGSN;65;439;Sunyani;;Ghana;1;07-20N;002-20W;;;309;312;P +DGSW;65;432;Wenchi;;Ghana;1;07-45N;002-06W;;;339;340;P +DGTK;65;467;Takoradi;;Ghana;1;04-53N;001-46W;04-53N;001-46W;5;9;P +DGTX;65;465;Axim;;Ghana;1;04-52N;002-14W;;;38;40;P +DIAD;65;585;Adiake;;Cote d'Ivoire;1;05-18N;003-18W;;;33;39;P +DIAP;65;578;Abidjan;;Cote d'Ivoire;1;05-15N;003-56W;05-15N;003-56W;7;8;P +DIBK;65;555;Bouake;;Cote d'Ivoire;1;07-44N;005-04W;07-44N;005-04W;376;376;P +DIBU;65;545;Bondoukou;;Cote d'Ivoire;1;08-03N;002-47W;;;369;370;P +DIDK;65;562;Dimbokro;;Cote d'Ivoire;1;06-39N;004-42W;;;92;92;P +DIDL;65;560;Daloa;;Cote d'Ivoire;1;06-52N;006-28W;;;276;277;P +DIGA;65;557;Gagnoa;;Cote d'Ivoire;1;06-08N;005-57W;;;205;210;P +DIKO;65;536;Korhogo;;Cote d'Ivoire;1;09-25N;005-37W;09-25N;005-37W;381;381;P +DIMN;65;548;Man;;Cote d'Ivoire;1;07-23N;007-31W;07-23N;007-31W;339;340;P +DIOD;65;528;Odienne;;Cote d'Ivoire;1;09-30N;007-34W;09-30N;007-34W;434;421;P +DISP;65;594;San Pedro;;Cote d'Ivoire;1;04-45N;006-39W;;;30;30;P +DISS;65;599;Sassandra;;Cote d'Ivoire;1;04-57N;006-05W;;;62;66;P +DITB;65;592;Tabou;;Cote d'Ivoire;1;04-25N;007-22W;04-25N;007-22W;21;21;P +DIYO;65;563;Yamoussoukro;;Cote d'Ivoire;1;06-54N;005-21W;;;196;213;P +DNBI;65;112;Bida;;Nigeria;1;09-06N;006-01E;;;137;143;P +DNCA;65;264;Calabar;;Nigeria;1;04-58N;008-21E;;;63;63;P +DNEN;65;257;Enugu;;Nigeria;1;06-28N;007-33E;;;137;; +DNGU;65;015;Gusau;;Nigeria;1;12-10N;006-42E;;;463;469;P +DNIB;65;208;Ibadan;;Nigeria;1;07-26N;003-54E;07-26N;003-54E;234;228;P +DNIL;65;101;Ilorin;;Nigeria;1;08-29N;004-35E;;;308;305;P +DNJO;65;134;Jos;;Nigeria;1;09-52N;008-54E;;;1295;1285;P +DNKA;65;019;Kaduna;;Nigeria;1;10-36N;007-27E;;;645;642;P +DNKN;65;046;Kano;;Nigeria;1;12-03N;008-32E;12-03N;008-32E;476;481;P +DNMA;65;082;Maiduguri;;Nigeria;1;11-51N;013-05E;;;354;; +DNMK;65;271;Makurdi;;Nigeria;1;07-41N;008-37E;07-41N;008-37E;113;97;P +DNMM;65;201;Lagos / Ikeja;;Nigeria;1;06-35N;003-20E;06-35N;003-20E;40;38;P +DNOS;65;215;Oshogbo;;Nigeria;1;07-47N;004-29E;;;305;304;P +DNPO;65;250;Port Harcourt;;Nigeria;1;04-51N;007-01E;04-51N;007-01E;18;18;P +DNSO;65;010;Sokoto;;Nigeria;1;13-01N;005-15E;;;351;302;P +DNYO;65;167;Yola;;Nigeria;1;09-14N;012-28E;09-14N;012-28E;191;174;P +DNZA;65;030;Zaria;;Nigeria;1;11-08N;007-41E;;;664;664;P +DRRB;61;075;Birni-N'Konni;;Niger;1;13-48N;005-15E;13-48N;005-15E;272;273; +DRRG;61;099;Gaya;;Niger;1;11-53N;003-27E;;;202;203; +DRRI;61;017;Bilma;;Niger;1;18-41N;012-55E;18-41N;012-55E;355;357; +DRRL;61;036;Tillabery;;Niger;1;14-12N;001-27E;;;209;210; +DRRM;61;080;Maradi;;Niger;1;13-28N;007-05E;13-28N;007-05E;372;373; +DRRN;61;052;Niamey-Aero;;Niger;1;13-29N;002-10E;13-29N;002-10E;223;227; +DRRT;61;043;Tahoua;;Niger;1;14-54N;005-15E;;;386;391; +DRZA;61;024;Agadez;;Niger;1;16-58N;007-59E;16-58N;007-59E;501;502; +DRZF;61;085;Diffa;;Niger;1;13-25N;012-47E;;;303;305; +DRZG;61;045;Goure;;Niger;1;13-59N;010-18E;;;464;460; +DRZM;61;096;Maine-Soroa;;Niger;1;13-14N;011-59E;;;338;337; +DRZR;61;090;Zinder;;Niger;1;13-47N;008-59E;13-47N;008-59E;452;453; +DTKA;60;710;Tabarka;;Tunisia;1;36-57N;008-45E;36-57N;008-45E;20;21; +DTMB;--;---;Habib Bourguiba ;;Tunisia;1;35-46N;010-45E;;;2;; +DTTA;60;715;Tunis-Carthage;;Tunisia;1;36-50N;010-14E;36-50N;010-14E;3;4;P +DTTB;60;714;Bizerte;;Tunisia;1;37-15N;009-48E;37-14N;009-49E;5;3;P +DTTD;60;775;Remada;;Tunisia;1;32-19N;010-24E;32-19N;010-24E;300;301;P +DTTF;60;745;Gafsa;;Tunisia;1;34-25N;008-49E;34-25N;008-49E;313;314;P +DTTG;60;765;Gabes;;Tunisia;1;33-53N;010-06E;33-53N;010-06E;4;5; +DTTJ;60;769;Djerba Mellita;;Tunisia;1;33-52N;010-46E;33-52N;010-46E;3;4;P +DTTK;60;735;Kairouan;;Tunisia;1;35-40N;010-06E;35-40N;010-06E;60;68;P +DTTL;60;720;Kelibia;;Tunisia;1;36-51N;011-05E;37-04N;011-02E;29;30;P +DTTM;60;740;Monastir-Skanes;;Tunisia;1;35-40N;010-45E;35-45N;010-45E;2;3;P +DTTN;60;725;Jendouba;;Tunisia;1;36-29N;008-48E;36-29N;008-48E;143;144;P +DTTR;60;780;El Borma;;Tunisia;1;31-41N;009-10E;31-41N;009-12E;258;259;P +DTTX;60;750;Sfax El-Maou;;Tunisia;1;34-43N;010-41E;34-43N;010-41E;21;23;P +DTTZ;60;760;Tozeur;;Tunisia;1;33-55N;008-06E;33-55N;008-10E;87;93;P +DXAK;65;376;Atakpame;;Togo;1;07-35N;001-07E;;;400;402;P +DXMG;65;352;Mango;;Togo;1;10-22N;000-28E;;;145;146;P +DXNG;65;355;Niamtougou;;Togo;1;09-46N;001-06E;;;342;343;P +DXSK;65;361;Sokode;;Togo;1;08-59N;001-09E;08-59N;001-09E;386;387;P +DXTA;65;380;Tabligbo;;Togo;1;06-35N;001-30E;;;44;44;P +DXXX;65;387;Lome;;Togo;1;06-10N;001-15E;06-10N;001-15E;20;25;P +EBAW;06;450;Antwerpen / Deurne;;Belgium;6;51-12N;004-28E;;;12;14;P +EBBE;06;458;Beauvechain;;Belgium;6;50-45N;004-46E;;;105;127;P +EBBL;06;479;Kleine Brogel;;Belgium;6;51-10N;005-28E;51-10N;005-28E;55;64;P +EBBR;06;451;Bruxelles National;;Belgium;6;50-54N;004-32E;50-54N;004-28E;55;58;P +EBBT;06;452;Brasschaat;;Belgium;6;51-20N;004-30E;;;22;23;P +EBBX;06;467;Bertrix Bel-Afb ;;Belgium;6;49-54N;005-13E;;;461;; +EBCI;06;449;Charleroi / Gosselies;;Belgium;6;50-28N;004-27E;;;187;192;P +EBCV;06;432;Chievres;;Belgium;6;50-34N;003-50E;;;60;63;P +EBDT;06;465;Schaffen;;Belgium;6;51-00N;005-04E;;;30;54; +EBFN;06;400;Koksijde;;Belgium;6;51-05N;002-39E;;;4;9;P +EBFS;06;456;Florennes;;Belgium;6;50-14N;004-39E;;;279;299;P +EBGT;06;431;Gent / Industrie-Zone;;Belgium;6;51-11N;003-49E;;;10;13;P +EBLB;06;496;Elsenborn;;Belgium;6;50-28N;006-11E;50-28N;006-11E;564;570;P +EBLG;06;478;Bierset;;Belgium;6;50-39N;005-27E;;;186;178;P +EBMB;06;448;Melsbroek Bel-Afb ;;Belgium;6;50-54N;004-30E;;;55;; +EBMT;06;428;Munte;;Belgium;6;50-56N;003-44E;;;55;60;P +EBOS;06;407;Oostende Airport ;;Belgium;6;51-12N;002-52E;;;4;5;P +EBSP;06;490;Spa / La Sauveniere;;Belgium;6;50-29N;005-55E;;;470;482;P +EBST;06;470;Sint-Truiden;;Belgium;6;50-48N;005-12E;;;74;75;P +EBSU;06;476;St-Hubert;;Belgium;6;50-02N;005-24E;50-02N;005-24E;563;557;P +EBTN;06;463;Goetsenhoven;;Belgium;6;50-47N;004-57E;;;71;81;P +EBWE;06;462;Weelde Military ;;Belgium;6;51-25N;005-00E;;;60;; +EBZW;06;481;Genk;;Belgium;6;50-56N;005-30E;;;61;63;P +EDAC;--;---;Altenburg Nobitz;;Germany;;50-58N;012-30E;;;195;; +EDAH;--;---;Heringsdorf;;Germany;6;53-53N;014-09E;;;28;; +EDBM;--;---;Magdeburg, Sachsen-Anhalt;;Germany;6;52-04-35N;011-37-25E;;;82;; +EDDB;10;385;Berlin-Schoenefeld;;Germany;6;52-23N;013-31E;52-23N;013-31E;47;50;P +EDDC;10;488;Dresden-Klotzsche;;Germany;6;51-08N;013-45E;;;230;232;P +EDDE;10;554;Erfurt-Bindersleben;;Germany;6;50-59N;010-58E;;;315;322;P +EDDF;10;637;Frankfurt / M-Flughafen;;Germany;6;50-03N;008-36E;50-03N;008-35E;111;113;P +EDDG;10;315;Muenster / Osnabrueck;;Germany;6;52-08N;007-42E;;;48;53;P +EDDH;10;147;Hamburg-Fuhlsbuettel;;Germany;6;53-38N;010-00E;;;16;15;P +EDDI;10;384;Berlin-Tempelhof;;Germany;6;52-28N;013-24E;52-29N;013-25E;50;49;P +EDDK;10;513;Koeln / Bonn;;Germany;6;50-52N;007-10E;50-52N;007-08E;91;100;P +EDDL;10;400;Duesseldorf;;Germany;6;51-18N;006-46E;;;45;41;P +EDDM;10;866;Munchen;;Germany;6;48-21N;011-47E;48-08N;011-43E;453;; +EDDN;10;763;Nuernberg;;Germany;6;49-30N;011-03E;49-30N;011-05E;318;318;P +EDDP;10;469;Leipzig-Schkeuditz;;Germany;6;51-25N;012-14E;;;144;149;P +EDDR;10;708;Saarbruecken / Ensheim;;Germany;6;49-13N;007-07E;49-13N;007-07E;322;320;P +EDDS;10;738;Stuttgart-Echterdingen;;Germany;6;48-41N;009-13E;48-41N;009-13E;396;391;P +EDDT;10;382;Berlin-Tegel;;Germany;6;52-34N;013-19E;;;37;37; +EDDV;10;338;Hannover;;Germany;6;52-28N;009-41E;52-28N;009-42E;56;59;P +EDDW;10;224;Bremen;;Germany;6;53-03N;008-48E;;;3;5;P +EDFH;10;616;Hahn;;Germany;6;49-57N;007-16E;;;491;498; +EDFM;10;729;Baden Wurttemberg, Neuostheim;;Germany;6;49-28-21N;008-30-56E;;;100;; +EDGS;--;---;Hessen;;Germany;6;50-42-28N;008-04-59E;;;602;; +EDHI;10;149;Hamburg-Finkenwerder;;Germany;6;53-32N;009-50E;;;5;13; +EDHK;--;---;Kiel / Holtenau Civilian;;Germany;;54-23N;010-10E;;;31;; +EDHL;10;156;Luebeck-Blankensee;;Germany;6;53-49N;010-42E;;;14;15; +EDLN;--;---;Monchengladbach;;Germany;6;51-13-49N;006-30-16E;;;38;; +EDLP;10;426;Paderborn / Lippstadt;;Germany;6;51-37N;008-37E;;;213;; +EDLV;--;---;Niederrhein;;Germany;6;51-36-09N;006-08-32E;;;32;; +EDLW;10;416;Dortmund / Wickede;;Germany;6;51-31N;007-37E;;;127;; +EDMA;10;852;Augsburg;;Germany;6;48-26N;010-56E;48-23N;010-51E;461;463;P +EDMO;--;---;Oberpfaffenhofen;;Germany;6;48-05N;011-17E;;;600;; +EDNY;10;935;Friedrichshafen;;Germany;6;47-40N;009-31E;;;416;424; +EDOP;10;745;Mecklenburg-Vorpommern, Parchim;;Germany;6;53-25-37N;011-47-01E;;;52;; +EDQD;10;677;Bayreuth;;Germany;6;49-59N;011-38E;;;488;498; +EDQM;10;685;Hof;;Germany;6;50-19N;011-53E;;;567;568;P +EDRZ;--;---;Zweibrucken, Rheinland-Pfalz;;Germany;6;49-12-34N;007-24-04E;;;344;; +EDSB;10;613;Karlsruhe, Baden Wurttemberg;;Germany;6;48-46-43N;008-04-47E;;;124;; +EDTD;10;912;Donaueschingen / Villingen;;Germany;6;47-58N;008-31E;;;680;; +EDTL;--;---;Lahr, CAN-AFB;;Germany;6;48-22-09N;007-49-40E;;;156;; +EDTZ;10;929;Konstanz;;Germany;6;47-41N;009-11E;;;443;447;P +EDVE;10;348;Braunschweig;;Germany;6;52-18N;010-27E;;;81;88;P +EDVK;10;436;Kassel / Calden;;Germany;6;51-24N;009-23E;;;277;283; +EDWD;--;---;Lemwerder;;Germany;6;53-09N;008-37E;;;30;; +EDXW;10;018;Westerland / Sylt;;Germany;6;54-55N;008-21E;;;16;20; +EDZE;10;410;Essen;;Germany;6;51-24N;006-58E;51-24N;006-58E;152;161; +EEKA;26;116;Kardla;;Estonia;6;58-59N;022-49E;;;5;; +EEKE;--;---;Kuressaare;;Estonia;6;58-13-48N;022-30-34E;;;4;; +EEPU;--;---;Parnu;;Estonia;6;58-25-09N;024-28-22E;;;14;; +EETU;--;---;Tartu/Ulenurme;;Estonia;6;58-18N;026-44E;;;59;; +EFET;--;---;Enontekio;;Finland;6;68-21-52N;023-25-39E;;;308;; +EFHA;02;945;Halli;;Finland;6;61-51N;024-48E;;;143;145; +EFHF;02;975;Helsinki-Malmi;;Finland;6;60-15N;025-03E;;;17;28; +EFHK;02;974;Helsinki-Vantaa;;Finland;6;60-19N;024-58E;60-19N;024-58E;51;56;P +EFHL;02;874;Hailuoto;;Finland;6;65-02N;024-48E;;;6;6; +EFHT;02;924;Ahtari;;Finland;6;62-32N;024-13E;;;157;161; +EFIL;--;---;Ilmajoki;;Finland;6;62-42N;022-50E;;;92;; +EFIV;02;807;Ivalo;;Finland;6;68-37N;027-25E;;;147;148;P +EFJO;02;929;Joensuu;;Finland;6;62-40N;029-38E;;;119;117;P +EFJY;02;935;Jyvaskyla;;Finland;6;62-24N;025-41E;62-24N;025-40E;141;145;P +EFKA;02;913;Kauhava;;Finland;6;63-06N;023-02E;;;42;44; +EFKE;02;864;Kemi;;Finland;6;65-47N;024-35E;;;15;; +EFKI;02;897;Kajaani;;Finland;6;64-17N;027-41E;;;143;136;P +EFKK;02;903;Kruunupyy;;Finland;6;63-43N;023-09E;;;25;; +EFKS;02;869;Kuusamo;;Finland;6;65-58N;029-11E;;;262;263;P +EFKT;--;---;Kittila;;Finland;6;67-42N;024-51E;;;643;; +EFKU;02;917;Kuopio;;Finland;6;63-01N;027-48E;63-01N;027-48E;98;102;P +EFLP;02;958;Lappeenranta;;Finland;6;61-02-45N;028-08-55E;;;106;; +EFMA;02;970;Mariehamn / Aland Island;;Finland;6;60-07N;019-54E;;;6;; +EFMI;02;947;Mikkeli;;Finland;6;61-44N;027-18E;;;138;138; +EFOU;02;875;Oulu;;Finland;6;64-56N;025-22E;;;12;15;P +EFPE;02;844;Pello;;Finland;6;66-48N;024-00E;;;84;84; +EFPO;02;952;Pori;;Finland;6;61-28N;021-48E;;;13;17;P +EFPU;02;867;Pudasjarvi;;Finland;6;65-22N;027-01E;;;114;117; +EFRO;02;845;Rovaniemi;;Finland;6;66-34N;025-50E;;;197;201; +EFSA;02;948;Savonlinna;;Finland;6;61-57N;028-57E;;;95;95; +EFSI;--;---;Seinajoki-Ilmajok;;Finland;6;62-41-37N;022-49-55E;;;91;; +EFSO;02;836;Sodankyla;;Finland;6;67-22N;026-39E;67-22N;026-39E;179;179;P +EFSU;02;879;Suomussalmi;;Finland;6;64-54N;029-01E;;;223;224; +EFTP;02;944;Tampere / Pirkkala;;Finland;6;61-25N;023-35E;;;112;112;P +EFTU;02;972;Turku;;Finland;6;60-31N;022-16E;60-31N;022-16E;49;59;P +EFUT;02;966;Utti;;Finland;6;60-54N;026-56E;;;100;100; +EFVA;02;911;Vaasa;;Finland;6;63-03N;021-46E;;;4;; +EFVI;02;915;Viitasaari;;Finland;6;63-05N;025-52E;;;132;132; +EFVR;--;---;Varkaus;;Finland;6;62-10N;027-52E;;;87;; +EGAA;03;917;Belfast / Aldergrove Airport;;United Kingdom;6;54-39N;006-13W;;;81;0;P +EGAC;03;924;Belfast / Harbour;;United Kingdom;6;54-36N;005-53W;;;5;0; +EGAE;--;---;Eglinton / Londonderr;;United Kingdom;6;55-03N;007-09W;;;9;; +EGBB;03;534;Birmingham / Airport;;United Kingdom;6;52-27N;001-44W;;;99;0;P +EGBE;--;---;Coventry Airport ;;United Kingdom;6;52-22N;001-29W;;;82;; +EGBJ;--;---;Staverton Private ;;United Kingdom;6;51-54N;002-10W;;;29;; +EGCC;03;334;Manchester Airport;;United Kingdom;6;53-21N;002-17W;;;69;0;P +EGDB;03;827;Plymouth;;United Kingdom;6;50-21N;004-07W;;;50;0;P +EGDC;03;707;Chivenor;;United Kingdom;6;51-05N;004-09W;;;8;0; +EGDG;03;817;Saint Mawgan;;United Kingdom;6;50-26N;005-00W;;;119;0;P +EGDK;--;---;Kemble Royal Air Force Base ;;United Kingdom;6;51-40N;002-03W;;;133;; +EGDL;03;740;Lyneham;;United Kingdom;6;51-30N;001-59W;;;145;0;P +EGDM;03;746;Boscombe Down;;United Kingdom;6;51-10N;001-45W;;;124;0;P +EGDP;03;858;Portland / Rnas;;United Kingdom;6;50-34N;002-27W;;;3;0; +EGDR;03;809;Culdrose;;United Kingdom;6;50-05N;005-15W;;;78;0;P +EGDX;--;---;St Athan Royal Air Force Base;;United Kingdom;6;51-24N;003-26W;;;50;; +EGDY;03;853;Yeovilton;;United Kingdom;6;51-00N;002-38W;;;23;0;P +EGEC;--;---;Campbeltown;;United Kingdom;6;55-26-14N;005-41-11W;;;13;; +EGFF;03;715;Cardiff-Wales Airport;;United Kingdom;6;51-24N;003-21W;51-24N;003-21W;67;0;P +EGFH;--;---;Swansea;;United Kingdom;6;51-36N;004-04W;;;90;; +EGGD;--;---;Bristol / Lulsgate ;;United Kingdom;6;51-23N;002-43W;;;189;; +EGGP;--;---;Liverpool Airport ;;United Kingdom;6;53-20N;002-51W;;;26;; +EGGW;--;---;Luton Airport ;;United Kingdom;6;51-52N;000-22W;;;160;; +EGHD;--;---;Plymouth / Roborough;;United Kingdom;6;50-25N;004-07W;;;25;; +EGHE;03;803;Scilly, Saint Mary'S;;United Kingdom;6;49-55N;006-18W;;;31;0; +EGHH;03;862;Bournemouth Airport;;United Kingdom;6;50-47N;001-50W;;;11;0;P +EGHI;03;865;Southampton / Weather Centre;;United Kingdom;6;50-54N;001-24W;;;9;0; +EGJA;--;---;Alderney / Channel Island;;United Kingdom;6;49-43N;002-12W;;;71;; +EGJB;03;894;Guernsey Airport;;United Kingdom;6;49-26N;002-36W;;;102;0;P +EGJJ;03;895;Jersey Airport;;United Kingdom;6;49-13N;002-12W;;;84;0;P +EGKA;03;876;Shoreham Airport;;United Kingdom;6;50-50N;000-17W;;;2;0; +EGKB;--;---;Biggin Hill ;;United Kingdom;6;51-19N;000-02E;;;183;; +EGKK;03;776;London / Gatwick Airport;;United Kingdom;6;51-09N;000-11W;;;62;0;P +EGLC;--;---;London City Airport;;United Kingdom;6;51-30N;000-30W;;;5;; +EGLF;03;768;Farnborough;;United Kingdom;6;51-17N;000-46W;;;65;0; +EGLL;03;772;London / Heathrow Airport;;United Kingdom;6;51-29N;000-27W;;;24;0;P +EGMC;--;---;Southend-On-Sea ;;United Kingdom;6;51-34N;000-42E;;;15;; +EGMD;--;---;Lydd Airport ;;United Kingdom;6;50-57N;000-56E;;;3;; +EGMH;--;---;Manston, South East;;United Kingdom;6;51-20-31N;001-20-46E;;;55;; +EGNC;03;222;Carlisle;;United Kingdom;6;54-56N;002-57W;;;26;; +EGNH;03;318;Blackpool Airport;;United Kingdom;6;53-46N;003-02W;;;10;0;P +EGNJ;--;---;Humberside;;United Kingdom;6;53-35N;000-21W;;;31;; +EGNL;03;214;Walney Island;;United Kingdom;6;54-07N;003-15W;;;15;0; +EGNM;--;---;Leeds And Bradford;;United Kingdom;6;53-52N;001-39W;;;208;; +EGNR;03;321;Hawarden;;United Kingdom;6;53-10N;002-59W;;;10;0; +EGNS;03;204;Isle Of Man / Ronaldsway Airport;;United Kingdom;6;54-05N;004-38W;;;17;0;P +EGNT;--;---;Newcastle ;;United Kingdom;6;55-02N;001-42W;;;81;; +EGNV;--;---;Tees-Side;;United Kingdom;6;54-31N;001-25W;;;37;; +EGNX;--;---;East Midlands;;United Kingdom;6;52-50N;001-20W;;;94;; +EGOD;--;---;Llanbedr;;United Kingdom;6;52-49N;004-08W;;;9;; +EGOM;03;165;Spadeadam;;United Kingdom;6;55-03N;002-33W;;;325;; +EGOP;03;605;Pembrey Sands;;United Kingdom;6;51-43N;004-22W;;;3;; +EGOS;03;414;Shawbury;;United Kingdom;6;52-48N;002-40W;;;76;0;P +EGOV;03;302;Valley;;United Kingdom;6;53-15N;004-32W;;;1;0;P +EGOW;--;---;Woodvale;;United Kingdom;6;53-34-54N;003-03-20W;;;11;; +EGOY;03;132;West Freugh;;United Kingdom;6;54-51N;004-57W;;;11;0; +EGPA;03;017;Kirkwall Airport;;United Kingdom;6;58-57N;002-54W;;;21;0;P +EGPB;03;003;Sumburgh Cape ;;United Kingdom;6;59-53N;001-18W;;;5;; +EGPC;03;075;Wick;;United Kingdom;6;58-27N;003-05W;;;39;0;P +EGPD;03;091;Aberdeen / Dyce;;United Kingdom;6;57-12N;002-13W;57-12N;002-13W;65;0;P +EGPE;03;059;Inverness / Dalcross;;United Kingdom;6;57-32N;004-03W;;;9;0; +EGPF;03;140;Glasgow Airport;;United Kingdom;6;55-52N;004-26W;;;8;0;P +EGPH;03;160;Edinburgh Airport;;United Kingdom;6;55-57N;003-21W;;;41;0;P +EGPI;--;---;Islay;;United Kingdom;6;55-40-55N;006-15-24W;;;16;; +EGPK;03;135;Prestwick Airport;;United Kingdom;6;55-30N;004-35W;;;20;0;P +EGPL;03;022;Benbecula;;United Kingdom;6;57-28N;007-22W;;;6;0;P +EGPM;--;---;Scatsa / Shetland Island;;United Kingdom;6;60-26N;001-18W;;;22;; +EGPN;--;---;Dundee / Riverside;;United Kingdom;6;56-27N;003-01W;;;4;; +EGPO;03;026;Stornoway;;United Kingdom;6;58-13N;006-19W;58-13N;006-19W;9;13;P +EGPT;--;---;Perth / Scone ;;United Kingdom;6;56-27N;003-22W;;;121;; +EGPU;03;100;Tiree;;United Kingdom;6;56-30N;006-53W;;;12;0;P +EGPW;--;---;Unst Island;;United Kingdom;6;60-44N;000-49W;;;285;; +EGQA;03;062;Tain Range;;United Kingdom;6;57-49N;003-58W;;;4;0; +EGQJ;03;111;Machrihanish;;United Kingdom;6;55-26N;005-42W;;;13;0; +EGQK;03;066;Kinloss;;United Kingdom;6;57-39N;003-34W;57-39N;003-34W;7;0;P +EGQL;03;171;Leuchars;;United Kingdom;6;56-23N;002-52W;;;12;0;P +EGQM;03;240;Boulmer;;United Kingdom;6;55-25N;001-36W;55-25N;001-36W;23;0;P +EGQS;03;068;Lossiemouth;;United Kingdom;6;57-43N;003-19W;;;13;;P +EGRB;03;779;London Weather Centre;;United Kingdom;6;51-31N;000-07W;;;5;0; +EGRR;03;763;Bracknell / Beaufort Park;;United Kingdom;6;51-23N;000-47W;;;74;0; +EGSC;--;---;Cambridge;;United Kingdom;6;52-12N;000-11E;;;15;; +EGSH;03;492;Norwich Weather Centre;;United Kingdom;6;52-38N;001-18E;;;14;0; +EGSS;03;683;Stansted Airport;;United Kingdom;6;51-53N;000-14E;;;106;0;P +EGSY;--;---;Yorkshire and Humberside, Sheffield City;;United Kingdom;6;53-23-39N;001-23-18W;;;70;; +EGTC;--;---;Cranfield;;United Kingdom;6;52-04N;000-37W;;;111;; +EGTE;03;839;Exeter Airport;;United Kingdom;6;50-44N;003-25W;;;30;; +EGTG;--;---;Filton Private ;;United Kingdom;6;51-31N;002-35W;;;69;; +EGTH;--;---;Hatfeild Private ;;United Kingdom;6;51-46N;000-15W;;;77;; +EGUA;--;---;Upper Heyford Royal Air Force Base ;;United Kingdom;6;51-56N;001-15W;;;134;; +EGUB;03;658;Benson;;United Kingdom;6;51-37N;001-05W;;;63;0;P +EGUC;03;502;Aberporth;;United Kingdom;6;52-08N;004-34W;52-08N;004-34W;133;134;P +EGUF;03;766;Farnborough Military ;;United Kingdom;6;51-17N;000-46W;;;72;; +EGUL;03;583;Lakenheath Royal Air Force Base;;United Kingdom;6;52-25N;000-34E;;;10;; +EGUM;03;797;Manston;;United Kingdom;6;51-21N;001-21E;;;55;0;P +EGUN;03;577;Mildenhall Royal Air Force Base;;United Kingdom;6;52-22N;000-29E;;;10;; +EGUO;--;---;Colerne;;United Kingdom;6;51-26-21N;002-17-11W;;;181;; +EGUP;--;---;Sculthorpe Af Met ;;United Kingdom;6;52-51N;000-46E;;;65;; +EGUW;03;590;Wattisham;;United Kingdom;6;52-07N;000-58E;;;87;0;P +EGUY;03;566;Wyton Royal Air Force Base;;United Kingdom;6;52-21N;000-07W;;;41;; +EGVA;03;644;Fairford Royal Air Force Base;;United Kingdom;6;51-41N;001-47W;;;87;; +EGVG;--;---;Woodbridge Royal Air Force Base ;;United Kingdom;6;52-05N;001-24E;;;29;; +EGVI;--;---;Greenham Common Royal Air Force Base;;United Kingdom;6;51-23N;001-17W;;;122;; +EGVJ;--;---;Bentwaters Royal Air Force Base ;;United Kingdom;6;52-08N;001-26E;;;26;; +EGVN;03;649;Brize Norton;;United Kingdom;6;51-45N;001-35W;51-45N;001-35W;88;0;P +EGVO;03;761;Odiham;;United Kingdom;6;51-14N;000-57W;;;123;0; +EGVP;03;749;Middle Wallop;;United Kingdom;6;51-09N;001-34W;;;91;0; +EGWC;--;---;Cosford Royal Air Force Base;;United Kingdom;6;52-38N;002-18W;;;83;; +EGWU;03;672;Northolt;;United Kingdom;6;51-33N;000-25W;;;38;0; +EGWZ;03;562;Alconbury Royal Air Force Base;;United Kingdom;6;52-22N;000-13W;;;49;; +EGXC;03;391;Coningsby Royal Air Force Base;;United Kingdom;6;53-05N;000-10W;;;7;; +EGXD;03;261;Disforth;;United Kingdom;6;54-08N;001-25W;;;36;0; +EGXE;03;257;Leeming;;United Kingdom;6;54-18N;001-32W;54-18N;001-32W;40;40; +EGXF;--;---;Cowden;;United Kingdom;6;53-51N;006-06W;;;15;; +EGXG;03;355;Church Fenton;;United Kingdom;6;53-50N;001-12W;;;9;0; +EGXH;03;586;Honington Royal Air Force Base;;United Kingdom;6;52-20N;000-46E;52-20N;000-46E;54;54; +EGXJ;03;453;Cottesmore;;United Kingdom;6;52-44N;000-39W;;;138;; +EGXN;--;---;Newton;;United Kingdom;6;52-58N;000-59W;;;55;; +EGXP;--;---;Scampton;;United Kingdom;6;53-18-27N;000-33-03W;;;62;; +EGXT;03;462;Wittering;;United Kingdom;6;52-37N;000-28W;;;84;0; +EGXU;03;266;Linton-On-Ouse;;United Kingdom;6;54-03N;001-15W;;;16;0; +EGXV;03;384;Leconfield;;United Kingdom;6;53-52N;000-26W;;;6;0; +EGXW;03;377;Waddington;;United Kingdom;6;53-10N;000-31W;53-10N;000-31W;68;0;P +EGXZ;--;---;Topcliffe Royal Air Force Base ;;United Kingdom;6;54-12N;001-23W;;;28;; +EGYC;03;495;Coltishall;;United Kingdom;6;52-26N;001-21E;;;20;0;P +EGYD;03;379;Cranwell;;United Kingdom;6;53-02N;000-30W;;;67;0; +EGYE;--;---;Barkston Heath Royal Air Force Base ;;United Kingdom;6;52-58N;000-34W;;;112;; +EGYH;03;469;Holbeach;;United Kingdom;6;52-52N;000-09E;;;3;0; +EGYM;03;482;Marham;;United Kingdom;6;52-39N;000-34E;;;23;0;P +EGYP;88;889;Mount Pleasant Airport;;South Georgia and the Islands;3;51-49S;058-27W;51-49S;058-27W;74;73; +EGYW;03;392;Wainfleet;;United Kingdom;6;53-05N;000-16E;;;3;0; +EHAM;06;240;Amsterdam Airport Schiphol;;Netherlands;6;52-18N;004-46E;;;-4;-2;P +EHBK;06;380;Maastricht Airport Zuid Limburg;;Netherlands;6;50-55N;005-47E;;;114;116; +EHDB;06;260;De Bilt;;Netherlands;6;52-06N;005-11E;52-06N;005-11E;2;15;P +EHDL;06;275;Deelen;;Netherlands;6;52-04N;005-53E;;;48;52; +EHEH;06;370;Eindhoven;;Netherlands;6;51-27N;005-25E;;;23;28; +EHGG;06;280;Groningen Airport Eelde;;Netherlands;6;53-08N;006-35E;;;4;4; +EHGR;06;350;Gilze-Rijen;;Netherlands;6;51-34N;004-56E;;;15;24; +EHKD;06;235;De Kooy;;Netherlands;6;52-55N;004-47E;;;0;14;P +EHLE;06;269;Lelystad;;Netherlands;6;52-27N;005-31E;;;0;; +EHLW;06;270;Leeuwarden;;Netherlands;6;53-13N;005-46E;;;1;11;P +EHRD;06;344;Rotterdam Airport Zestienhoven;;Netherlands;6;51-57N;004-27E;;;-5;-4; +EHSB;06;265;Soesterberg;;Netherlands;6;52-08N;005-17E;;;20;25; +EHTW;06;290;Twenthe;;Netherlands;6;52-16N;006-54E;52-16N;006-54E;35;57;P +EHVB;06;210;Valkenburg;;Netherlands;6;52-11N;004-25E;52-11N;004-25E;0;2; +EHVK;06;375;Volkel;;Netherlands;6;51-39N;005-42E;;;22;21;P +EHVL;06;242;Vlieland;;Netherlands;6;53-15N;004-55E;53-15N;004-55E;11;12; +EHWO;06;340;Woensdrecht;;Netherlands;6;51-27N;004-20E;51-27N;004-20E;20;17; +EICK;03;955;Cork Airport;;Ireland;6;51-51N;008-29W;;;153;162;P +EIDW;03;969;Dublin Airport;;Ireland;6;53-26N;006-15W;;;68;85;P +EIKN;--;---;Connaught;;Ireland;6;53-54-37N;008-49-05W;;;203;; +EIME;03;967;Casement Aerodrome;;Ireland;6;53-18N;006-26W;;;97;93;P +EINN;03;962;Shannon Airport;;Ireland;6;52-42N;008-55W;;;14;20;P +EKAH;06;070;Tirstrup;;Denmark;6;56-18N;010-37E;;;23;25;P +EKAT;06;078;Anholt Island Automated Reporting Station ;;Denmark;6;56-42N;011-33E;;;8;; +EKAV;06;150;Avno Danish Air Force Base ;;Denmark;6;55-05N;011-47E;;;4;; +EKBI;06;104;Billund Lufthavn;;Denmark;6;55-44N;009-10E;;;75;79;P +EKCH;06;180;Koebenhavn / Kastrup;;Denmark;6;55-37N;012-39E;55-38N;012-40E;5;5;P +EKEB;06;080;Esbjerg;;Denmark;6;55-32N;008-34E;;;30;29; +EKHO;06;054;Lindtorp Airport;;Denmark;6;56-24N;008-27E;;;15;; +EKHS;06;048;Hadsund;;Denmark;6;56-43N;010-07E;;;2;2; +EKKA;06;060;Karup;;Denmark;6;56-18N;009-07E;;;52;53;P +EKMB;06;143;Maribo Lufthavn;;Denmark;6;54-42N;011-27E;;;5;5; +EKOD;06;120;Odense / Beldringe;;Denmark;6;55-29N;010-20E;;;17;17;P +EKRK;06;170;Koebenhavn / Roskilde;;Denmark;6;55-35N;012-08E;;;44;44; +EKRN;06;190;Roenne;;Denmark;6;55-04N;014-45E;;;16;16; +EKSB;06;118;Soenderborg Lufthavn;;Denmark;6;54-58N;009-47E;;;7;14; +EKSN;06;034;Sindal Flyveplads;;Denmark;6;57-30N;010-13E;;;28;28; +EKSP;06;110;Skrydstrup;;Denmark;6;55-14N;009-16E;;;43;47;P +EKST;06;124;Sydfyns Flyveplads;;Denmark;6;55-01N;010-34E;;;6;; +EKSV;06;062;Skive Lufthavn;;Denmark;6;56-33N;009-10E;;;23;21; +EKTS;06;024;Thisted Lufthavn;;Denmark;6;57-04N;008-43E;;;7;7; +EKVA;06;100;Vandel;;Denmark;6;55-42N;009-12E;;;73;76; +EKVD;06;108;Vamdrup;;Denmark;6;55-26N;009-20E;;;44;45; +EKVG;06;010;Soervaag / Vagar;;Denmark;6;62-04N;007-17W;;;85;92; +EKVJ;06;066;Stauning Lufthavn;;Denmark;6;56-00N;008-21E;;;5;5; +EKVL;06;160;Vaerloese;;Denmark;6;55-46N;012-20E;;;18;31; +EKYT;06;030;Aalborg;;Denmark;6;57-06N;009-51E;57-06N;009-52E;3;13;P +ELLX;06;590;Luxembourg / Luxembourg;;Luxembourg;6;49-37N;006-13E;49-37N;006-13E;376;379;P +ENAL;01;210;Alesund / Vigra;;Norway;6;62-34N;006-07E;;;2;22; +ENAN;01;010;Andoya;;Norway;6;69-18N;016-09E;69-18N;016-09E;1;14;P +ENAS;01;004;Ny-Alesund Ii;;Norway;6;78-55N;011-56E;78-55N;011-56E;8;8; +ENAT;01;049;Alta Lufthavn;;Norway;6;69-59N;023-22E;;;0;3;P +ENBJ;01;028;Bjornoya;;Norway;6;74-31N;019-01E;74-31N;019-01E;16;16;P +ENBL;--;---;Forde / Bringeland;;Norway;6;61-27N;005-52E;;;150;; +ENBM;01;336;Voss-Bo;;Norway;6;60-39N;006-30E;;;125;122; +ENBN;01;112;Bronnoysund / Bronnoy;;Norway;6;65-28N;012-13E;;;0;9; +ENBO;01;152;Bodo Vi;;Norway;6;67-16N;014-22E;67-15N;014-24E;1;13;P +ENBR;01;311;Bergen / Flesland;;Norway;6;60-17N;005-14E;;;5;50;P +ENBS;--;---;Batsfjord;;Norway;6;70-38N;029-44E;;;10;; +ENBV;01;083;Berlevag;;Norway;6;70-52N;029-02E;;;1;13; +ENCN;01;452;Kristiansand / Kjevik;;Norway;6;58-12N;008-05E;;;1;17;P +ENDI;--;---;Dagali;;Norway;6;60-25N;008-31E;;;798;; +ENDR;--;---;Draugen;;Norway;6;64-21-20N;007-47-30E;;;0;; +ENDU;01;023;Bardufoss;;Norway;6;69-04N;018-32E;;;7;79;P +ENEK;--;---;Ekofisk Oil Platform;;Norway;6;56-33N;003-15E;;;3;; +ENEV;01;183;Evenes;;Norway;6;68-31N;016-41E;;;26;26; +ENFB;01;488;Oslo / Fornebu;;Norway;6;59-54N;010-38E;;;1;17;P +ENFG;01;368;Fagernes Leirin;;Norway;6;61-00N;009-18E;;;822;; +ENFL;01;310;Floro;;Norway;6;61-35N;005-02E;;;0;9; +ENFR;--;---;Frigg;;Norway;6;59-56N;002-00E;;;;; +ENGC;--;---;Gullfax Platform ;;Norway;6;61-02N;002-02E;;;10;; +ENGM;01;384;Oslo / Gardermoen;;Norway;6;60-12N;011-05E;60-12N;011-06E;20;204;P +ENHD;01;408;Haugesund / Karmoy;;Norway;6;59-21N;005-13E;;;2;24; +ENHE;--;---;Heidrun;;Norway;6;65-19-30N;002-19-36E;;;0;; +ENHF;01;052;Hammerfest;;Norway;6;70-40N;023-40E;;;8;81; +ENHK;--;---;Hasvik;;Norway;6;70-29N;022-09E;;;10;; +ENHO;01;062;Hopen;;Norway;6;76-30N;025-04E;;;6;10;P +ENHV;01;068;Honningsvag / Valan;;Norway;6;71-01N;025-59E;;;1;14; +ENJA;01;001;Jan Mayen;;Norway;6;70-56N;008-40W;70-56N;008-40W;10;9;P +ENKA;01;047;Kautokeino;;Norway;6;69-00N;023-02E;;;305;308; +ENKB;01;223;Kristiansund / Kvernberget;;Norway;6;63-07N;007-50E;;;6;62; +ENKR;01;089;Kirkenes Lufthavn;;Norway;6;69-44N;029-54E;;;9;91;P +ENLI;01;428;Lista Flyplass;;Norway;6;58-06N;006-38E;;;1;10; +ENLK;01;141;Leknes;;Norway;6;68-09N;013-37E;;;2;26; +ENMH;01;074;Mehamn;;Norway;6;71-02N;027-50E;;;1;13; +ENML;01;217;Molde / Aro;;Norway;6;62-45N;007-16E;;;0;3; +ENMS;01;122;Mosjoen Kjaerstad;;Norway;6;65-48N;013-08E;;;70;; +ENNA;01;059;Banak;;Norway;6;70-04N;024-59E;;;0;8;P +ENNK;01;194;Narvik Iii;;Norway;6;68-28N;017-30E;;;17;23; +ENNM;01;290;Namsos Lufthavn;;Norway;6;64-28N;011-35E;;;0;2; +ENNO;--;---;Notodden;;Norway;6;59-34N;009-13E;;;19;; +ENOA;--;---;Oseberg ;;Norway;6;59-19N;010-27E;;;15;; +ENOL;01;241;Orland Iii;;Norway;6;63-42N;009-36E;63-42N;009-36E;0;7;P +ENOV;01;209;Orsta-Volda / Hovden;;Norway;6;62-11N;006-04E;;;7;74; +ENRA;01;151;Mo I Rana / Rossvoll;;Norway;6;66-22N;014-18E;;;7;70; +ENRM;01;282;Rorvik / Ryum;;Norway;6;64-50N;011-09E;;;4;; +ENRO;01;289;Roros Lufthavn;;Norway;6;62-35N;011-21E;;;62;626; +ENRS;01;107;Rost Flyplass;;Norway;6;67-31N;012-06E;;;4;; +ENRY;01;494;Rygge;;Norway;6;59-23N;010-47E;;;5;53;P +ENSB;01;008;Svalbard Lufthavn;;Norway;6;78-15N;015-28E;;;2;29;P +ENSD;01;320;Sandane / Anda;;Norway;6;61-50N;006-07E;;;6;60; +ENSG;01;347;Sogndal / Haukasen;;Norway;6;61-09N;007-08E;;;49;497; +ENSH;01;161;Svolvaer / Helle;;Norway;6;68-15N;014-40E;;;0;9; +ENSK;01;162;Storkmarknes / Skagen;;Norway;6;68-35N;015-01E;;;0;3; +ENSN;01;475;Skien-Geiteryggen;;Norway;6;59-11N;009-34E;;;1;14; +ENSO;--;---;Stord / Soerstokken;;Norway;6;59-48N;005-21E;;;49;; +ENSR;01;046;Sorkjosen;;Norway;6;69-47N;020-58E;;;0;6; +ENSS;01;097;Svartnes;;Norway;6;70-21N;031-03E;;;12;; +ENST;01;116;Sandnessjoen / Stokka;;Norway;6;65-58N;012-28E;;;1;17; +ENTC;01;025;Tromso / Langnes;;Norway;6;69-41N;018-55E;;;1;10;P +ENTO;01;483;Torp;;Norway;6;59-12N;010-16E;;;8;88; +ENVA;01;271;Trondheim / Vaernes;;Norway;6;63-28N;010-56E;;;1;17;P +ENVD;01;088;Vadso;;Norway;6;70-04N;029-51E;;;3;39; +ENZV;01;415;Stavanger / Sola;;Norway;6;58-53N;005-38E;58-52N;005-40E;0;9;P +EPGD;12;150;Gdansk-Rebiechowo;;Poland;6;54-23N;018-28E;54-23N;018-28E;135;138;P +EPKK;12;566;Krakow;;Poland;6;50-05N;019-48E;50-05N;019-48E;237;237;P +EPKO;12;105;Koszalin;;Poland;6;54-12N;016-09E;54-12N;016-11E;32;34; +EPKT;12;560;Katowice;;Poland;6;50-14N;019-02E;;;284;284;P +EPPO;12;330;Poznan;;Poland;6;52-25N;016-50E;52-25N;016-50E;86;92;P +EPRZ;12;580;Rzeszow-Jasionka;;Poland;6;50-06N;022-03E;50-06N;022-03E;200;202;P +EPSC;12;205;Szczecin;;Poland;6;53-24N;014-37E;53-24N;014-37E;1;3;P +EPSK;--;---;Slupsk ;;Poland;6;54-28N;017-01E;;;25;; +EPWA;12;375;Warszawa-Okecie;;Poland;6;52-10N;020-58E;52-11N;020-59E;106;107;P +EPWR;12;424;Wroclaw Ii;;Poland;6;51-06N;016-53E;;;120;121;P +EPZG;12;400;Zielona Gora;;Poland;6;51-56N;015-32E;;;192;192;P +ESCF;02;562;Linkoping / Malmen;;Sweden;6;58-24N;015-31E;;;93;117;P +ESCL;02;376;Soderhamn;;Sweden;6;61-16N;017-06E;;;26;36;P +ESCM;02;458;Uppsala;;Sweden;6;59-53N;017-36E;;;21;41;P +ESDA;02;630;Ljungbyhed, Ljungbyhed, SWE-AFB;;Sweden;6;56-05-07N;013-12-26E;;;52;52;P +ESDB;02;607;Angelholm;;Sweden;6;56-18N;012-51E;;;20;47;P +ESDF;02;664;Ronneby;;Sweden;6;56-16N;015-17E;;;58;74;P +ESGG;02;526;Goteborg / Landvetter;;Sweden;6;57-40N;012-18E;;;169;; +ESGJ;02;550;Jonkoping Flygplats;;Sweden;6;57-46N;014-05E;;;226;232;P +ESGP;02;512;Goteborg / Save;;Sweden;6;57-47N;011-53E;;;20;53;P +ESGR;02;535;Skovde Flygplats;;Sweden;6;58-27N;013-58E;;;98;105; +ESGT;--;---;Trollhattan Private ;;Sweden;6;58-19N;012-21E;;;41;; +ESIB;02;520;Satenas;;Sweden;6;58-26N;012-42E;;;54;74;P +ESKM;--;---;Siljan / Mora;;Sweden;6;60-58N;014-31E;;;193;; +ESKN;--;---;Skavasta / Stockholm;;Sweden;6;58-47N;016-55E;;;43;; +ESMK;02;651;Kristianstad / Everod;;Sweden;6;55-55N;014-05E;;;23;; +ESMQ;02;672;Kalmar;;Sweden;6;56-44N;016-18E;;;16;; +ESMS;02;636;Malmo / Sturup;;Sweden;6;55-33N;013-22E;;;106;; +ESMT;02;604;Halmstad Swedish Air Force Base ;;Sweden;6;56-41N;012-50E;;;30;; +ESMV;02;556;Hagshult;;Sweden;6;57-18N;014-08E;;;169;172;P +ESMX;02;641;Vaxjo;;Sweden;6;56-51N;014-50E;;;199;200; +ESNG;02;049;Gallivare;;Sweden;6;67-09N;020-39E;;;359;360; +ESNJ;02;142;Jokkmokk;;Sweden;6;66-38N;019-39E;;;263;264;P +ESNK;02;259;Kramfors Flygplats;;Sweden;6;63-03N;017-46E;;;10;19;P +ESNL;--;---;Lycksele;;Sweden;6;64-32-51N;018-43-03E;;;211;; +ESNN;02;366;Sundsvall-Harnosand Flygplats;;Sweden;6;62-32N;017-27E;62-32N;017-27E;4;10;P +ESNO;02;267;Ornskoldsvik Airport;;Sweden;6;63-24N;018-58E;;;103;; +ESNQ;02;044;Kiruna Airport;;Sweden;6;67-49N;020-20E;;;452;; +ESNS;02;293;Skelleftea Airport;;Sweden;6;64-38N;021-05E;;;49;; +ESNU;02;286;Umea Flygplats;;Sweden;6;63-48N;020-17E;;;7;14;P +ESNY;--;---;Soderhamn;;Sweden;6;61-15-41N;017-05-57E;;;27;; +ESOE;--;---;Orebro Private ;;Sweden;6;59-14N;015-03E;;;57;; +ESOK;--;---;Karlstad ;;Sweden;6;59-26-41N;013-20-15E;;;107;; +ESOW;02;446;Vasteras / Hasslo;;Sweden;6;59-35N;016-38E;;;6;31;P +ESPA;02;186;Lulea / Kallax;;Sweden;6;65-33N;022-08E;65-33N;022-08E;17;34;P +ESPC;02;226;Ostersund / Froson;;Sweden;6;63-11N;014-30E;63-11N;014-30E;376;370;P +ESPD;02;128;Gunnarn;;Sweden;6;64-58N;017-42E;;;280;283;P +ESPE;02;154;Vidsel;;Sweden;6;65-52N;020-08E;;;180;182; +ESSA;02;460;Stockholm / Arlanda;;Sweden;6;59-39N;017-57E;;;38;61;P +ESSB;02;464;Stockholm / Bromma;;Sweden;6;59-21N;017-57E;59-21N;017-57E;14;14; +ESSD;02;435;Borlange;;Sweden;6;60-26N;015-31E;;;145;0; +ESSF;02;565;Hultsfred Swedish Air Force Base ;;Sweden;6;57-31N;015-50E;;;112;; +ESSK;02;443;Gavle / Sandviken Air Force Base;;Sweden;6;60-36N;016-57E;;;79;; +ESSL;--;---;Linkoping / Saab;;Sweden;6;58-24N;015-41E;;;52;; +ESSP;02;571;Norrkoping;;Sweden;6;58-35N;016-09E;;;34;0; +ESSQ;02;418;Karlstad Flygplats;;Sweden;6;59-22N;013-28E;;;46;55;P +ESSV;02;590;Visby Flygplats;;Sweden;6;57-40N;018-21E;;;51;47;P +ESTL;--;---;Ljungbyhed;;Sweden;6;56-04N;013-12E;;;43;; +ETAD;10;607;Spangdahlem;;Germany;6;49-59N;006-42E;;;365;356; +ETAR;10;614;Ramstein;;Germany;6;49-26N;007-36E;;;238;237; +ETAS;10;712;Sembach United States Air Force Operated Base In Foreign Country ;;Germany;6;49-30N;007-52E;;;321;; +ETBA;10;503;Aachen / Merzbruck;;Germany;6;50-49N;006-11E;50-49N;006-11E;191;190; +ETCE;--;---;Mebstetten / Albstadt;;Germany;6;50-07N;009-07E;;;475;; +ETEB;10;755;Ansbach / Katterbach;;Germany;6;49-19N;010-38E;49-19N;010-38E;467;476; +ETEH;10;627;Bad Kreuznach;;Germany;6;49-51N;007-53E;;;103;105; +ETEU;10;653;Giebelstadt;;Germany;6;49-39N;009-58E;49-39N;009-58E;298;298; +ETGB;10;238;Bergen;;Germany;6;52-49N;009-56E;52-49N;009-56E;70;69; +ETGG;10;033;Gluecksburg / Meierwik;;Germany;6;54-50N;009-30E;;;27;33; +ETGI;10;618;Idar-Oberstein;;Germany;6;49-42N;007-20E;49-42N;007-20E;376;377; +ETGK;10;771;Kuemmersruck;;Germany;6;49-26N;011-54E;49-26N;011-54E;419;418; +ETGW;10;272;Wittstock;;Germany;6;53-12N;012-31E;53-12N;012-31E;72;74; +ETGY;10;404;Kalkar;;Germany;6;51-44N;006-16E;;;31;43; +ETGZ;10;827;Messstetten;;Germany;6;48-11N;009-00E;;;920;930; +ETHA;10;954;Altenstadt;;Germany;6;47-50N;010-52E;47-50N;010-52E;739;757; +ETHB;10;335;Bueckeburg;;Germany;6;52-17N;009-05E;;;70;78; +ETHC;10;343;Celle;;Germany;6;52-36N;010-01E;;;39;52; +ETHE;10;306;Rheine-Bentlage;;Germany;6;52-18N;007-23E;;;40;49; +ETHF;10;439;Fritzlar;;Germany;6;51-07N;009-17E;;;172;181; +ETHI;10;142;Itzehoe;;Germany;6;54-00N;009-35E;;;25;26; +ETHL;10;837;Laupheim;;Germany;6;48-13N;009-55E;;;538;550; +ETHM;10;514;Mendig;;Germany;6;50-22N;007-19E;;;182;190; +ETHN;10;743;Niederstetten;;Germany;6;49-24N;009-58E;;;468;473; +ETHR;10;765;Roth;;Germany;6;49-13N;011-06E;49-13N;011-06E;388;395; +ETHS;10;246;Fassberg;;Germany;6;52-55N;010-11E;;;75;88; +ETHT;10;492;Cottbus Flugplatz ;;Germany;6;51-46N;014-18E;;;67;68; +ETIC;10;687;Grafenwoehr;;Germany;6;49-42N;011-57E;49-06N;011-08E;415;415; +ETID;10;642;Hanau;;Germany;6;50-10N;008-58E;50-10N;008-57E;112;114; +ETIE;10;734;Heidelberg;;Germany;6;49-24N;008-39E;;;110;109; +ETIH;10;775;Hohenfels;;Germany;6;49-13N;011-50E;;;442;442; +ETIK;10;752;Illesheim;;Germany;6;49-28N;010-23E;;;325;347; +ETIN;10;669;Kitzingen Usa \ Af ;;Germany;6;49-45N;010-12E;49-45N;010-12E;210;210; +ETME;10;034;Eggebek;;Germany;6;54-38N;009-21E;;;20;22; +ETMK;10;046;Kiel-Holtenau;;Germany;6;54-23N;010-09E;54-23N;010-09E;31;31; +ETMN;10;136;Nordholz;;Germany;6;53-46N;008-40E;;;23;31; +ETND;10;321;Diepholz;;Germany;6;52-35N;008-21E;;;39;43; +ETNG;10;500;Geilenkirchen;;Germany;6;50-58N;006-03E;;;90;98; +ETNH;10;038;Hohn;;Germany;6;54-19N;009-32E;;;12;17; +ETNJ;10;122;Jever;;Germany;6;53-32N;007-53E;;;7;21; +ETNL;10;172;Laage;;Germany;6;53-55N;012-17E;;;40;46; +ETNN;10;502;Noervenich;;Germany;6;50-50N;006-40E;;;118;135; +ETNP;10;314;Hopsten;;Germany;6;52-20N;007-32E;;;39;43; +ETNR;10;493;Preschen;;Germany;6;51-40N;014-38E;;;100;; +ETNS;10;037;Schleswig-Jagel;;Germany;6;54-28N;009-31E;;;22;25; +ETNT;10;126;Wittmundhaven;;Germany;6;53-33N;007-40E;;;8;12; +ETNU;10;281;Trollenhagen;;Germany;6;53-36N;013-19E;;;71;70; +ETNW;10;334;Wunstorf;;Germany;6;52-27N;009-26E;;;57;70; +ETOR;10;728;Coleman Mannheim ;;Germany;6;49-34N;008-28E;;;96;95; +ETOU;10;633;Wiesbaden;;Germany;6;50-03N;008-20E;;;140;; +ETSA;10;857;Landsberg;;Germany;6;48-04N;010-54E;;;623;628; +ETSB;10;613;Buechel;;Germany;6;50-10N;007-04E;;;478;486; +ETSE;10;869;Erding;;Germany;6;48-19N;011-57E;;;462;467; +ETSF;10;858;Fuerstenfeldbruck;;Germany;6;48-12N;011-16E;;;519;535; +ETSH;10;476;Holzdorf;;Germany;6;51-46N;013-11E;;;79;83; +ETSI;10;860;Ingolstadt;;Germany;6;48-43N;011-32E;;;367;370; +ETSL;10;856;Lechfeld;;Germany;6;48-11N;010-52E;;;555;562; +ETSM;10;947;Memmingen;;Germany;6;47-59N;010-14E;;;634;644; +ETSN;10;853;Neuburg / Donau;;Germany;6;48-43N;011-13E;;;380;387; +ETSP;10;626;Pferdsfeld;;Germany;6;49-51N;007-36E;;;396;403; +ETUL;10;405;Laarbruch;;Germany;6;51-36N;006-09E;;;32;31; +ETUN;10;308;Nordhorn;;Germany;6;52-27N;007-10E;;;26;26; +ETUO;10;320;Guetersloh;;Germany;6;51-55N;008-18E;;;72;72; +ETUR;10;401;Brueggen;;Germany;6;51-12N;006-08E;;;73;76; +ETWM;--;---;Meppen-Mil;;Germany;6;52-43-24N;007-19-35E;;;21;; +EVLA;--;---;Liepaja International Airport;;Latvia;6;56-31N;021-05E;;;5;; +EVRA;--;---;Riga International Airport;;Latvia;6;56-55N;023-58E;;;10;; +EYKA;--;---;Kaunas;;Lithuania;6;54-54N;023-55-12E;;;77;; +EYPA;--;---;Palanga Intl.;;Lithuania;6;55-55-12N;021-03E;;;10;; +EYSA;--;---;Siauliai Intl./Mil.;;Lithuania;6;55-53-38N;023-23-42E;;;135;; +EYVI;26;730;Vilnius;;Lithuania;6;54-38N;025-06E;;;162;156;P +FAAB;68;406;Alexander Bay;;South Africa;1;28-34S;016-32E;28-34S;016-32E;21;0;P +FAAN;68;546;Aliwal North;;South Africa;1;30-43S;026-43E;;;1348;1300;P +FABL;68;442;Bloemfontein J. B. M. Hertzog ;;South Africa;1;29-06S;026-18E;29-06S;026-18E;1354;1400;P +FABM;68;461;Bethlehem Airport;;South Africa;1;28-15S;028-20E;28-15S;028-20E;1686;1700;P +FABY;68;728;Beaufort West;;South Africa;1;32-21S;022-35E;32-21S;022-35E;842;900;P +FACL;68;380;Carolina;;South Africa;1;26-04S;030-07E;;;1693;1700; +FACT;68;816;Cape Town D. F. Malan ;;South Africa;1;33-59S;018-36E;33-58S;018-36E;42;0;P +FACV;68;618;Calvinia;;South Africa;1;31-28S;019-46E;;;975;1000;P +FADA;68;536;De Aar;;South Africa;1;30-39S;024-01E;;;1247;; +FADN;68;588;Durban Louis Botha ;;South Africa;1;29-58S;030-57E;29-58S;030-57E;14;0;P +FADY;68;538;De Aar;;South Africa;1;30-38S;023-55E;;;384;; +FAEL;68;858;East London;;South Africa;1;33-02S;027-50E;33-02S;027-50E;125;0;P +FAEO;--;---;Ermelo;;South Africa;1;26-30S;029-59E;;;1737;; +FAER;68;156;Ellisras;;South Africa;1;23-43-35S;027-41-18E;;;851;; +FAFF;68;362;Frankfort;;South Africa;1;27-16S;028-30E;;;1499;1500;P +FAFR;68;624;Fraserburg;;South Africa;1;31-55S;021-31E;;;1264;1300;P +FAGB;68;116;Gobabis;;Namibia;1;22-28S;018-58E;;;1440;1400;P +FAGE;68;906;Gough Island;;South Africa;1;40-21S;009-53W;40-21S;009-53W;54;0;P +FAGG;68;828;George Airport;;South Africa;1;34-00S;022-23E;33-58S;022-25E;193;0;P +FAGM;--;---;Johannesburg / Rand;;South Africa;1;26-15S;028-00E;;;1668;; +FAGR;68;736;Graaff Reinet;;South Africa;1;32-15S;024-32E;;;752;800;P +FAGY;--;---;Greytown;;South Africa;1;29-07S;030-34E;;;1100;; +FAHS;68;290;Hoedspruit;;South Africa;1;24-22S;031-02E;;;513;500;P +FAIR;68;263;Pretoria Irene ;;South Africa;1;25-55S;028-13E;25-55S;028-13E;1523;1500; +FAJS;68;368;Johannesburg, Johannesburg International Airport;;South Africa;1;26-08S;028-14E;26-08S;028-14E;1694;1700;P +FAKD;68;347;Klerksdorp;;South Africa;1;26-52S;026-43E;;;1355;; +FAKM;68;438;Kimberley;;South Africa;1;28-48S;024-46E;28-48S;024-46E;1198;1200;P +FALA;--;---;Lanseria Civ / Mil ;;South Africa;1;25-56S;027-56E;;;1377;; +FALT;--;---;Lichtenburg;;South Africa;1;26-11S;026-11E;;;1486;; +FALW;68;714;Langebaanweg;;South Africa;1;32-58S;018-10E;;;31;0;P +FALY;68;476;Ladysmith;;South Africa;1;28-34S;029-46E;28-34S;029-46E;1078;1100;P +FAMB;68;638;Middelburg;;South Africa;1;31-29S;025-02E;;;1270;1300;P +FAME;68;994;Marion Island;;South Africa;1;46-53S;037-52E;46-53S;037-52E;22;0;P +FAMG;--;---;Margate;;South Africa;1;30-51S;030-21E;;;151;; +FAMM;68;242;Mmabatho Airport;;South Africa;1;25-47S;025-32E;25-47S;025-32E;1281;1300;P +FAMO;68;928;Mossel Bay Cape Saint Blaize ;;South Africa;1;34-11S;022-09E;;;59;0;P +FANC;--;---;Newcastle;;South Africa;1;27-47S;029-59E;;;1251;; +FANS;68;288;Nelspruit;;South Africa;1;25-26S;030-59E;;;671;700;P +FAOB;--;---;Overberg;;South Africa;1;34-36S;020-17E;;;75;; +FAOH;68;826;Oudtshoorn;;South Africa;1;33-34S;022-13E;;;359;0;P +FAPB;68;174;Pietersburg;;South Africa;1;23-52S;029-27E;23-52S;029-27E;1228;1200;P +FAPE;68;842;Port Elizabeth;;South Africa;1;33-59S;025-36E;33-59S;025-36E;61;0;P +FAPG;--;---;Plettenberg Bay;;South Africa;1;34-05-17S;023-19-46E;;;139;; +FAPH;68;190;Phalaborwa;;South Africa;1;23-56S;031-09E;;;427;400;P +FAPI;--;---;Pietersburg Civil ;;South Africa;1;23-54S;029-28E;;;1327;; +FAPJ;68;674;Port St Johns;;South Africa;1;31-38S;029-33E;;;47;0;P +FAPM;--;---;Pietermaritzburg;;South Africa;1;29-39S;030-24E;;;739;; +FAPR;68;262;Pretoria;;South Africa;1;25-44S;028-11E;25-44S;028-11E;1330;1300;P +FAPS;--;---;Potchefstroom;;South Africa;1;26-40-16S;027-04-55E;;;1378;; +FAQT;68;648;Queenstown;;South Africa;1;31-54S;026-52E;;;1094;1100;P +FARB;68;498;Richard Bay;;South Africa;1;28-48S;032-06E;;;47;0;P +FARG;--;---;Rustenburg;;South Africa;1;25-38-39S;027-16-16E;;;1128;; +FASB;68;512;Springbok;;South Africa;1;29-40S;017-52E;29-40S;017-52E;1006;1000;P +FASI;--;---;Springs;;South Africa;1;26-14-54S;028-23-51E;;;1628;; +FASR;--;---;Standerton;;South Africa;1;26-56S;029-13E;;;1581;; +FASS;--;---;Sishen;;South Africa;1;27-38-59S;023-00E;;;1173;; +FATC;68;902;Tristan Da Cunha;;South Africa;1;37-03S;012-19W;;;23;0; +FATZ;--;---;Tzaneen ;;South Africa;1;23-49S;030-20E;;;583;; +FAUL;--;---;Ulundi;;South Africa;1;28-19-06S;031-25-04E;;;525;; +FAUP;68;424;Upington;;South Africa;1;28-24S;021-16E;28-24S;021-16E;839;800;P +FAUT;68;668;Umtata;;South Africa;1;31-32S;028-40E;;;742;700;P +FAVB;68;338;Vryburg;;South Africa;1;26-57S;024-38E;;;1234;1200;P +FAVG;--;---;Durban/Virginia;;South Africa;1;29-46-14S;031-03-37E;;;6;; +FAVR;68;614;Vredendal;;South Africa;1;31-40S;018-30E;;;34;0;P +FAVV;--;---;Vereeniging;;South Africa;1;26-34-29S;027-57-45E;;;1483;; +FAVY;--;---;Vryheid;;South Africa;1;27-47S;030-48E;;;1158;; +FAWB;--;---;Wonderboom / Pretoria;;South Africa;1;25-39S;028-13E;;;1248;; +FAWI;--;---;Witbank;;South Africa;1;25-49-51S;029-11-32E;;;1553;; +FAWK;68;264;Waterkloof Lmb;;South Africa;1;25-50S;028-13E;;;1498;1500;P +FAWM;68;346;Welkom;;South Africa;1;28-00S;026-40E;;;1338;1300;P +FBFT;68;054;Francistown;;Botswana;1;21-13S;027-30E;21-10S;027-29E;1001;1000;P +FBGZ;68;024;Ghanzi;;Botswana;1;21-42S;021-39E;21-42S;021-39E;1131;1100;P +FBJW;68;234;Jwaneng;;Botswana;1;24-36S;024-40E;;;1189;1200; +FBKE;68;029;Kasane;;Botswana;1;17-49S;025-09E;;;968;1000; +FBLT;68;040;Letlhakane;;Botswana;1;21-25S;025-36E;;;986;985; +FBMN;68;032;Maun;;Botswana;1;19-59S;023-25E;19-59S;023-25E;945;900;P +FBSK;68;240;Seretse Khama International Airport;;Botswana;1;24-13S;025-55E;24-13S;025-55E;1005;1005; +FBSN;68;038;Sua-Pan;;Botswana;1;20-28S;025-59E;20-28S;025-59E;903;904; +FBSP;--;---;Selebi Phikwe;;Botswana;1;22-03-19S;027-49-13E;;;892;; +FBSW;68;026;Shakawe;;Botswana;1;18-22S;021-51E;;;1032;1000;P +FBTE;68;226;Tshane;;Botswana;1;24-01S;021-53E;;;1118;1100;P +FBTS;68;328;Tsabong;;Botswana;1;26-03S;022-27E;26-03S;022-27E;960;1000;P +FCBB;64;450;Brazzaville / Maya-Maya;;Congo, Republic of the;1;04-15S;015-15E;04-15S;015-15E;319;316;P +FCBD;64;453;Djambala;;Congo, Republic of the;1;02-32S;014-46E;02-32S;014-46E;791;790;P +FCBM;64;402;Mouyondzi;;Congo, Republic of the;1;03-59S;013-55E;;;509;512;P +FCBO;64;452;M'Pouya;;Congo, Republic of the;1;02-37S;016-13E;;;311;312;P +FCBS;64;405;Sibiti;;Congo, Republic of the;1;03-41S;013-21E;;;530;531;P +FCOG;64;454;Gamboma;;Congo, Republic of the;1;01-52S;015-52E;;;476;377;P +FCOI;64;459;Impfondo;;Congo, Republic of the;1;01-37N;018-04E;01-37N;018-04E;335;326;P +FCOM;64;456;Makoua;;Congo, Republic of the;1;00-01S;015-35E;00-01S;015-35E;394;379;P +FCOS;64;460;Souanke;;Congo, Republic of the;1;02-04N;014-08E;;;549;550;P +FCOU;64;458;Ouesso;;Congo, Republic of the;1;01-37N;016-03E;01-37N;016-03E;352;352;P +FCPA;64;403;Makabana;;Congo, Republic of the;1;03-29S;012-37E;;;160;161;P +FCPL;64;401;Loubomo;;Congo, Republic of the;1;04-12S;012-42E;04-13S;012-40E;329;330;P +FCPP;64;400;Pointe-Noire;;Congo, Republic of the;1;04-49S;011-54E;04-49S;011-54E;17;17;P +FDMS;68;396;Manzini / Matsapa Airport;;Swaziland;1;26-32S;031-18E;;;641;; +FEFA;64;662;Alindao;;Central African Republic;1;05-03N;021-12E;;;447;449;P +FEFB;64;659;Obo;;Central African Republic;1;05-24N;026-30E;;;650;651;P +FEFF;64;650;Bangui;;Central African Republic;1;04-24N;018-31E;04-24N;018-31E;365;366;P +FEFG;64;656;Bangassou;;Central African Republic;1;04-44N;022-50E;04-44N;022-50E;499;500;P +FEFI;64;658;Birao;;Central African Republic;1;10-17N;022-47E;;;463;464;P +FEFL;64;605;Bossembele;;Central African Republic;1;05-16N;017-38E;;;673;674;P +FEFM;64;660;Bambari;;Central African Republic;1;05-51N;020-39E;;;474;475;P +FEFN;64;654;N'Dele;;Central African Republic;1;08-24N;020-39E;08-24N;020-39E;510;511;P +FEFO;64;601;Bouar;;Central African Republic;1;05-58N;015-38E;05-58N;015-38E;1019;1020;P +FEFR;64;655;Bria;;Central African Republic;1;06-32N;021-59E;;;583;584;P +FEFS;64;610;Bossangoa;;Central African Republic;1;06-29N;017-26E;06-29N;017-26E;464;465;P +FEFT;64;600;Berberati;;Central African Republic;1;04-15N;015-48E;04-13N;015-47E;582;583;P +FEFY;64;661;Yalinga;;Central African Republic;1;06-30N;023-16E;;;601;602;P +FGSL;64;810;Malabo/Fernando Poo;;Equatorial Guinea;1;03-45N;008-46E;;;56;; +FHAW;61;902;Wide Awake Field Ascension Island ;;Saint Helena;1;07-58S;014-24W;07-58S;014-24W;86;79;P +FIMP;61;990;Plaisance Mauritius ;;Mauritius;1;20-26S;057-40E;;;55;57;P +FIMR;61;988;Rodrigues;;Mauritius;1;19-41S;063-25E;19-41S;063-25E;58;59;P +FJDG;61;967;Diego Garcia;;British Indian Ocean Territory;1;07-18S;072-24E;07-18S;072-24E;1;3;P +FKAB;64;880;Banyo;;Cameroon;1;06-47N;011-49E;;;1110;; +FKAF;64;920;Bafia;;Cameroon;1;04-44N;011-15E;;;500;500;P +FKAG;64;960;Abong-Mbang;;Cameroon;1;03-58N;013-12E;;;693;; +FKAL;64;961;Lomie;;Cameroon;1;03-09N;013-37E;;;624;; +FKAM;64;882;Meiganga;;Cameroon;1;06-32N;014-22E;;;1027;1027;P +FKAN;64;911;Nkongsamba;;Cameroon;1;04-57N;009-56E;04-57N;009-56E;816;821;P +FKAO;64;901;Betare-Oya;;Cameroon;1;05-36N;014-04E;;;815;804; +FKAY;64;900;Yoko;;Cameroon;1;05-33N;012-22E;05-33N;012-22E;1027;1031;P +FKKA;64;851;Maroua-Salak;;Cameroon;1;10-27N;014-15E;;;423;422;P +FKKB;64;971;Kribi;;Cameroon;1;02-57N;009-54E;;;10;16;P +FKKC;64;912;Tiko;;Cameroon;1;04-05N;009-22E;;;52;; +FKKD;64;910;Douala Obs.;;Cameroon;1;04-00N;009-44E;04-01N;009-42E;10;9;P +FKKF;64;890;Mamfe;;Cameroon;1;05-43N;009-17E;;;126;; +FKKI;64;931;Batouri;;Cameroon;1;04-28N;014-22E;04-28N;014-22E;656;656;P +FKKM;64;893;Koundja;;Cameroon;1;05-39N;010-45E;05-39N;010-45E;1208;1210;P +FKKN;64;870;Ngaoundere;;Cameroon;1;07-21N;013-34E;07-21N;013-34E;1114;1104;P +FKKR;64;860;Garoua;;Cameroon;1;09-20N;013-23E;09-20N;013-23E;242;244;P +FKKV;64;892;Bamenda ;;Cameroon;1;06-03N;010-07E;;;1239;; +FKKY;--;---;Younde Ii;;Cameroon;1;03-50N;011-32E;;;751;; +FKYS;64;950;Yaounde;;Cameroon;1;03-50N;011-31E;03-50N;011-31E;751;760;P +FLBA;67;413;Mbala;;Zambia;1;08-51S;031-20E;;;1673;; +FLCH;67;753;Choma;;Zambia;1;16-50S;027-04E;;;1213;1278;P +FLCP;67;581;Chipata;;Zambia;1;13-33S;032-35E;13-33S;032-35E;1028;1032;P +FLIK;67;481;Isoka;;Zambia;1;10-07S;032-38E;;;1360;; +FLKB;67;403;Kawambwa;;Zambia;1;09-48S;029-05E;;;1323;1324;P +FLKO;67;641;Kaoma;;Zambia;1;14-48S;024-48E;;;1213;1213;P +FLKS;67;475;Kasama;;Zambia;1;10-13S;031-08E;10-13S;031-08E;1382;1384;P +FLKW;67;663;Kabwe;;Zambia;1;14-27S;028-28E;14-27S;028-28E;1206;1207;P +FLLC;67;666;Lusaka City Airport;;Zambia;1;14-27S;028-28E;15-25S;028-19E;1280;1280; +FLLD;67;583;Lundazi;;Zambia;1;12-17S;033-12E;;;1143;; +FLLI;67;743;Livingstone;;Zambia;1;17-49S;025-49E;17-49S;025-49E;985;986;P +FLLS;67;665;Lusaka Internationalairport;;Zambia;1;15-19S;028-27E;15-19S;028-27E;1152;1154;P +FLMA;67;461;Mansa;;Zambia;1;11-06S;028-51E;;;1382;1384;P +FLMF;--;---;Mfuwe;;Zambia;1;13-15-32S;031-56-12E;;;573;; +FLMG;67;633;Mongu;;Zambia;1;15-15S;023-09E;15-15S;023-09E;1052;1053;P +FLMP;67;477;Mpika;;Zambia;1;11-54S;031-26E;;;1400;1402;P +FLMW;67;441;Mwinilunga;;Zambia;1;11-45S;024-26E;11-45S;024-26E;1361;1363;P +FLND;67;561;Ndola;;Zambia;1;13-00S;028-39E;13-00S;028-39E;1269;1270;P +FLPA;67;541;Kasempa;;Zambia;1;13-32S;025-51E;;;1234;1234;P +FLPE;67;673;Petauke;;Zambia;1;14-15S;031-17E;;;1035;1036;P +FLPO;67;543;Kabompo;;Zambia;1;13-36S;024-12E;;;1075;; +FLSE;67;571;Serenje;;Zambia;1;13-14S;030-13E;;;1384;; +FLSN;67;731;Senanga;;Zambia;1;16-06S;023-16E;;;1027;; +FLSS;67;741;Sesheke;;Zambia;1;17-28S;024-18E;;;949;951;P +FLSW;67;551;Solwezi;;Zambia;1;12-11S;026-23E;;;1386;; +FLZB;67;531;Zambezi;;Zambia;1;13-32S;023-07E;;;1077;1078;P +FMCH;67;002;Hahaya International Airport;;Comoros;1;11-32S;043-16E;11-32S;043-16E;29;29; +FMCV;67;004;Ouani Anjouan ;;Comoros;1;12-07S;044-26E;12-07S;044-26E;19;12;P +FMCZ;67;005;Dzaoudzi / Pamanzi Mayotte ;;Comoros;1;12-48S;045-17E;12-48S;045-17E;8;7;P +FMEE;61;980;Saint-Denis / Gillot;;Reunion;1;20-53S;055-31E;20-53S;055-31E;21;25;P +FMEP;61;984;Saint-Pierre;;Reunion;1;21-20S;055-29E;21-20S;055-29E;52;53;P +FMME;67;107;Antsirabe;;Madagascar;1;19-49S;047-04E;19-49S;047-04E;1523;1532; +FMMH;67;113;Mahanoro;;Madagascar;1;19-50S;048-48E;19-50S;048-48E;5;5;P +FMMI;67;083;Antananarivo / Ivato;;Madagascar;1;18-48S;047-29E;18-48S;047-29E;1279;1276;P +FMMO;67;073;Maintirano;;Madagascar;1;18-03S;044-02E;18-03S;044-02E;23;23;P +FMMS;67;072;Sainte-Marie Aerodrome;;Madagascar;1;17-05S;049-49E;17-05S;049-49E;2;3;P +FMMT;67;095;Tamatave;;Madagascar;1;18-07S;049-24E;18-07S;049-24E;5;6;P +FMMV;67;117;Morondava;;Madagascar;1;20-17S;044-19E;20-17S;044-19E;7;8;P +FMNA;67;009;Diego-Suarez;;Madagascar;1;12-21S;049-18E;12-21S;049-18E;114;105;P +FMND;67;022;Andapa;;Madagascar;1;14-39S;049-37E;;;473;474; +FMNH;67;025;Antalaha;;Madagascar;1;14-53S;050-15E;15-00S;050-20E;87;88;P +FMNL;67;019;Analalava;;Madagascar;1;14-38S;047-46E;14-38S;047-46E;105;57;P +FMNM;67;027;Majunga;;Madagascar;1;15-40S;046-21E;14-53S;050-15E;26;18;P +FMNN;67;012;Fascene Nossi-Be ;;Madagascar;1;13-19S;048-19E;13-19S;048-19E;10;9;P +FMNQ;67;037;Besalampy;;Madagascar;1;16-45S;044-29E;16-45S;044-29E;38;36; +FMNS;67;023;Sambava;;Madagascar;1;14-17S;050-10E;14-17S;050-10E;5;5; +FMNV;67;017;Vohemar;;Madagascar;1;13-22S;050-00E;13-22S;050-00E;6;5; +FMSD;67;197;Fort-Dauphin;;Madagascar;1;25-02S;046-57E;25-02S;046-57E;8;9;P +FMSF;67;137;Fianarantsoa;;Madagascar;1;21-27S;047-06E;21-27S;047-06E;1115;1109;P +FMSG;67;157;Farafangana;;Madagascar;1;22-48S;047-50E;22-48S;047-50E;8;6;P +FMSM;67;143;Mananjary;;Madagascar;1;21-12S;048-22E;21-12S;048-22E;5;6;P +FMSO;67;152;Ranohira;;Madagascar;1;22-33S;045-24E;22-33S;045-24E;824;824;P +FMSR;67;131;Morombe;;Madagascar;1;21-45S;043-22E;21-45S;043-22E;5;4; +FMST;67;161;Tulear;;Madagascar;1;23-23S;043-44E;23-23S;043-44E;8;8;P +FNBG;66;310;Monbaca Benguela ;;Angola;1;12-35S;013-25E;;;33;4;P +FNCA;66;104;Cabinda;;Angola;1;05-33S;012-11E;;;25;20;P +FNHU;66;318;Huambo Nova Lisboa ;;Angola;1;12-48S;015-45E;12-48S;015-45E;1710;1701;P +FNKU;66;325;Bie Silva Porto ;;Angola;1;12-23S;016-57E;;;1701;1699;P +FNLU;66;160;Luanda;;Angola;1;08-51S;013-14E;08-51S;013-14E;74;70;P +FOGM;64;550;Mouila;;Gabon;1;01-52S;011-01E;;;88;89;P +FOGR;64;551;Lambarene;;Gabon;1;00-43S;010-14E;;;27;26;P +FOOB;64;510;Bitam;;Gabon;1;02-05N;011-29E;02-05N;011-29E;600;599;P +FOOC;64;504;Cocobeach;;Gabon;1;01-00N;009-36E;;;12;13;P +FOOD;64;565;Moanda;;Gabon;1;01-32S;013-16E;01-32S;013-16E;572;573;P +FOOE;64;545;Mekambo;;Gabon;1;01-01N;013-56E;;;499;501;P +FOOG;64;501;Port-Gentil;;Gabon;1;00-42S;008-45E;00-42S;008-45E;3;4;P +FOOK;64;556;Makokou;;Gabon;1;00-34N;012-52E;;;509;515;P +FOOL;64;500;Libreville;;Gabon;1;00-27N;009-25E;00-27N;009-25E;12;15;P +FOOM;64;552;Mitzic;;Gabon;1;00-47N;011-32E;;;583;583;P +FOON;--;---;Franceville / Mvengue;;Gabon;1;01-39S;013-26E;;;441;; +FOOR;64;560;Lastoursville;;Gabon;1;00-50S;012-43E;;;483;485;P +FOOT;64;507;Tchibanga;;Gabon;1;02-51S;011-01E;;;83;79;P +FOOY;64;503;Mayumba;;Gabon;1;03-25S;010-39E;;;31;34;P +FPPR;61;934;Principe;;Sao Tome and Principe;1;01-39N;007-25E;;;3;5;P +FPST;61;931;S. Tome;;Sao Tome and Principe;1;00-23N;006-43E;00-23N;006-43E;8;13;P +FQBR;67;297;Beira;;Mozambique;1;19-48S;034-54E;19-48S;034-54E;8;16; +FQCB;67;231;Cuamba;;Mozambique;1;14-49S;036-32E;;;606;607; +FQCH;67;295;Chimoio;;Mozambique;1;19-07S;033-28E;;;731;732; +FQIN;67;323;Inhambane;;Mozambique;1;23-52S;035-23E;23-52S;035-23E;14;15; +FQLC;67;217;Lichinga;;Mozambique;1;13-18S;035-14E;13-17S;035-15E;1364;1365; +FQLU;67;241;Lumbo;;Mozambique;1;15-02S;040-40E;15-02S;040-40E;10;11; +FQMA;67;341;Maputo / Mavalane;;Mozambique;1;25-55S;032-34E;25-55S;032-34E;39;44; +FQMP;67;205;Mocimboa Da Praia;;Mozambique;1;11-21S;040-22E;;;27;29; +FQNP;67;237;Nampula;;Mozambique;1;15-06S;039-17E;15-06S;039-17E;438;441; +FQPB;67;215;Pemba;;Mozambique;1;12-59S;040-32E;12-58S;040-30E;101;50; +FQQL;67;283;Quelimane;;Mozambique;1;17-53S;036-53E;17-53S;036-53E;6;16; +FQTE;67;261;Tete;;Mozambique;1;16-11S;033-35E;16-11S;033-35E;149;150; +FQTT;--;---;Tete / Chingozi;;Mozambique;1;16-06S;033-38E;;;160;; +FQVL;67;315;Vilanculos;;Mozambique;1;22-00S;035-19E;;;20;21; +FQXA;67;335;Xai Xai;;Mozambique;1;25-03S;033-38E;;;4;5; +FSIA;63;980;Seychelles Inter-National Airport;;Seychelles;1;04-40S;055-31E;04-40S;055-31E;3;3;P +FSSS;63;985;Seychelles International Airport Rawinsonde Station ;;Seychelles;1;04-41S;055-32E;04-41S;055-32E;4;4; +FTTA;64;750;Sarh;;Chad;1;09-09N;018-23E;09-09N;018-23E;365;365;P +FTTC;64;756;Abeche;;Chad;1;13-51N;020-51E;13-51N;020-51E;545;549;P +FTTD;64;706;Moundou;;Chad;1;08-37N;016-04E;;;428;422;P +FTTJ;64;700;Ndjamena;;Chad;1;12-08N;015-02E;12-08N;015-02E;295;295;P +FTTK;64;708;Bokoro;;Chad;1;12-23N;017-03E;;;300;301;P +FTTL;64;702;Bol-Berim;;Chad;1;13-26N;014-44E;;;291;292;P +FTTN;64;754;Am-Timan;;Chad;1;11-02N;020-17E;;;433;436;P +FTTP;64;709;Pala;;Chad;1;09-22N;014-55E;;;467;455;P +FTTY;64;753;Faya;;Chad;1;18-00N;019-10E;18-00N;019-10E;235;234;P +FVBB;67;991;Beitbridge;;Zimbabwe;1;22-13S;030-00E;22-13S;030-00E;456;457;P +FVBI;67;755;Binga;;Zimbabwe;1;17-37S;027-20E;;;620;617; +FVBU;67;965;Bulawayo Airport;;Zimbabwe;1;20-01S;028-37E;20-01S;028-37E;1326;1326;P +FVCH;67;983;Chipinge;;Zimbabwe;1;20-12S;032-37E;;;1131;1132;P +FVCZ;67;977;Buffalo Range;;Zimbabwe;1;21-01S;031-35E;21-01S;031-35E;429;430;P +FVFA;67;843;Victoria Falls;;Zimbabwe;1;18-06S;025-51E;18-06S;025-51E;1061;1062;P +FVGO;67;861;Gokwe;;Zimbabwe;1;18-13S;028-56E;18-13S;028-56E;1282;1282;P +FVHA;67;775;Harare Kutsaga ;;Zimbabwe;1;17-55S;031-08E;17-56S;031-06E;1479;1480;P +FVKA;67;765;Karoi;;Zimbabwe;1;16-50S;029-37E;16-50S;029-37E;1343;1344;P +FVKB;67;761;Kariba;;Zimbabwe;1;16-31S;028-53E;16-31S;028-53E;518;518; +FVMT;67;781;Mutoko;;Zimbabwe;1;17-25S;032-13E;17-25S;032-13E;1244;1244; +FVMV;67;975;Masvingo;;Zimbabwe;1;20-04S;030-52E;20-04S;030-52E;1094;1095;P +FVRU;67;881;Rusape;;Zimbabwe;1;18-32S;032-08E;18-32S;032-09E;1430;1430;P +FVTL;67;867;Gweru;;Zimbabwe;1;19-27S;029-51E;19-27S;029-51E;1428;1429;P +FVWN;67;853;Hwange National Park;;Zimbabwe;1;18-38S;027-00E;18-38S;026-51E;1079;1077;P +FWCL;67;693;Chileka;;Malawi;1;15-41S;034-58E;15-41S;034-58E;766;767;P +FWCT;67;421;Chitipa;;Malawi;1;09-42S;033-16E;;;1278;1278;P +FWDZ;67;689;Dedza;;Malawi;1;14-19S;034-16E;;;1630;1632; +FWKA;67;423;Karonga;;Malawi;1;09-57S;033-53E;09-57S;033-54E;529;529;P +FWKI;67;586;Lilongwe International Airport;;Malawi;1;13-47S;033-46E;13-47S;033-47E;1229;1229;P +FWKK;67;591;Nkhota Kota;;Malawi;1;12-55S;034-16E;;;500;500; +FWMG;67;695;Mangochi;;Malawi;1;14-26S;035-15E;;;485;485;P +FWMY;67;690;Monkey Bay;;Malawi;1;14-05S;034-55E;;;474;474; +FWMZ;67;485;Mzimba;;Malawi;1;11-53S;033-37E;11-53S;033-37E;1349;1351;P +FWSM;67;597;Salima;;Malawi;1;13-45S;034-35E;13-45S;034-35E;513;513;P +FWUU;67;489;Mzuzu;;Malawi;1;11-27S;034-01E;11-27S;034-01E;1251;1253;P +FXMM;--;---;Maseru / Moshoeshoe;;Lesotho;1;29-27S;027-33E;;;1631;; +FXMU;68;454;Maseru-Mia;;Lesotho;1;29-27S;027-33E;;;1631;1628;P +FYGF;68;014;Grootfontein;;Namibia;1;19-36S;018-07E;19-36S;018-07E;1411;1400;P +FYKM;--;---;Katima Mulilo;;Namibia;1;17-38-04S;024-10-36E;;;985;; +FYKT;68;312;Keetmanshoop;;Namibia;1;26-32S;018-07E;26-32S;018-07E;1067;1100;P +FYLZ;--;---;Luderitz / Diaz Point;;Namibia;1;26-41S;015-15E;;;130;; +FYOA;--;---;Ondangwa;;Namibia;1;17-52-42S;015-57-09E;;;1096;; +FYRK;--;---;Rooikop Saaf / Civ ;;Namibia;1;22-59S;014-39E;;;88;; +FYRU;68;018;Rundu;;Namibia;1;17-55S;019-46E;;;1083;1100;P +FYWB;--;---;Walvis Bay;;Namibia;1;22-58-59S;014-39E;;;46;; +FYWH;68;112;J. G. Strijdom;;Namibia;1;22-29S;017-28E;22-29S;017-28E;1715;1700;P +FYWW;--;---;Windhoek, Town MET;;Namibia;1;22-34S;017-06E;;;1725;; +FZAA;64;210;Kinshasa / N'Djili;;Congo, Democratic Republic of the;1;04-23S;015-26E;04-23S;015-26E;309;312;P +FZAG;64;201;Moanda;;Congo, Democratic Republic of the;1;06-00S;012-25E;;;27;27;P +FZAM;64;207;Matadi;;Congo, Democratic Republic of the;1;05-48S;013-26E;05-48S;013-26E;355;340;P +FZAN;64;206;Inga;;Congo, Democratic Republic of the;1;05-31S;013-35E;;;277;277;P +FZBA;64;115;Inongo;;Congo, Democratic Republic of the;1;01-58S;018-16E;01-58S;018-16E;300;300;P +FZBO;64;108;Bandundu;;Congo, Democratic Republic of the;1;03-18S;017-21E;;;324;324;P +FZCA;64;222;Kikwit;;Congo, Democratic Republic of the;1;05-02S;018-48E;05-02S;018-48E;518;449;P +FZCS;64;217;Kenge;;Congo, Democratic Republic of the;1;04-55S;017-04E;;;563;563;P +FZEA;64;005;Mbandaka;;Congo, Democratic Republic of the;1;00-03N;018-16E;00-03N;018-16E;345;317;P +FZFK;64;006;Gemena;;Congo, Democratic Republic of the;1;03-17N;019-47E;;;475;446;P +FZGN;64;126;Boende;;Congo, Democratic Republic of the;1;00-13S;020-51E;00-13S;020-51E;351;351;P +FZIA;64;040;Kisangani;;Congo, Democratic Republic of the;1;00-31N;025-11E;00-31N;025-11E;415;396;P +FZMB;64;072;Butembo;;Congo, Democratic Republic of the;1;00-08N;029-16E;;;1840;1840;P +FZNA;64;184;Goma;;Congo, Democratic Republic of the;1;01-41S;029-14E;;;1552;1552;P +FZNC;64;157;Rutshuru;;Congo, Democratic Republic of the;1;01-11S;029-27E;;;1275;1275;P +FZOA;64;155;Kindu;;Congo, Democratic Republic of the;1;02-57S;025-55E;02-57S;025-55E;497;497;P +FZQA;64;360;Lubumbashi-Luano;;Congo, Democratic Republic of the;1;11-40S;027-29E;;;1276;1298;P +FZQM;64;328;Kolwezi;;Congo, Democratic Republic of the;1;10-43S;025-27E;;;1405;1526;P +FZRA;64;282;Manono;;Congo, Democratic Republic of the;1;07-17S;027-26E;07-17S;027-26E;614;633;P +FZRF;64;285;Kalemie;;Congo, Democratic Republic of the;1;05-53S;029-11E;05-52S;029-11E;790;818;P +FZRQ;64;276;Kongolo;;Congo, Democratic Republic of the;1;05-21S;027-00E;;;561;561; +FZSA;64;315;Kamina / Base;;Congo, Democratic Republic of the;1;08-38S;025-15E;08-38S;025-15E;1088;1106;P +FZUA;64;235;Kananga;;Congo, Democratic Republic of the;1;05-53S;022-25E;;;654;657;P +FZUK;64;228;Tshikapa;;Congo, Democratic Republic of the;1;06-25S;020-51E;;;521;481;P +FZVA;64;146;Lodja;;Congo, Democratic Republic of the;1;03-29S;023-28E;;;479;500;P +FZVI;64;246;Lusambo;;Congo, Democratic Republic of the;1;04-58S;023-26E;;;424;424;P +FZVS;64;224;Ilebo;;Congo, Democratic Republic of the;1;04-20S;020-35E;;;465;420;P +FZWA;64;247;Mbuji-Mayi;;Congo, Democratic Republic of the;1;06-10S;023-37E;;;633;677;P +GABG;61;296;Bougouni;;Mali;1;11-25N;007-30W;11-25N;007-30W;350;351;P +GABS;61;291;Bamako / Senou;;Mali;1;12-32N;007-57W;12-32N;007-57W;380;381;P +GAGO;61;226;Gao;;Mali;1;16-16N;000-03W;16-16N;000-03W;265;260;P +GAHB;61;240;Hombori;;Mali;1;15-20N;001-41W;;;287;288;P +GAKA;61;285;Kenieba;;Mali;1;12-51N;011-14W;;;132;132;P +GAKL;61;214;Kidal;;Mali;1;18-26N;001-21E;18-26N;001-21E;458;459;P +GAKO;61;293;Koutiala;;Mali;1;12-23N;005-28W;;;365;367;P +GAKT;61;270;Kita;;Mali;1;13-04N;009-28W;;;333;334;P +GAKY;61;257;Kayes;;Mali;1;14-26N;011-26W;14-26N;011-26W;47;47;P +GAMB;61;265;Mopti;;Mali;1;14-31N;004-06W;14-31N;004-06W;276;272;P +GAMK;61;250;Menaka;;Mali;1;15-52N;002-13E;;;278;278;P +GANK;61;233;Nara;;Mali;1;15-10N;007-17W;15-10N;007-17W;271;265;P +GANR;61;230;Nioro Du Sahel;;Mali;1;15-14N;009-21W;;;235;237;P +GASG;61;272;Segou;;Mali;1;13-24N;006-09W;13-26N;006-17W;288;289;P +GASK;61;297;Sikasso;;Mali;1;11-21N;005-41W;11-21N;005-41W;374;375;P +GASN;61;277;San;;Mali;1;13-20N;004-50W;;;283;284;P +GATB;61;223;Tombouctou;;Mali;1;16-43N;003-00W;16-43N;003-00W;263;264;P +GATS;61;202;Tessalit;;Mali;1;20-12N;000-59E;20-12N;000-59E;494;491;P +GBYD;61;701;Banjul / Yundum;;Gambia, The;1;13-21N;016-48W;13-21N;016-48W;36;36;P +GCFV;60;035;Fuerteventura / Aeropuerto;;Spain;1;28-27N;013-52W;;;22;30; +GCHI;60;001;Hierro / Aeropuerto;;Spain;1;27-49N;017-53W;;;32;32; +GCLA;60;005;La Palma / Aeropuerto;;Spain;1;28-37N;017-45W;;;29;31;P +GCLP;60;030;Las Palmas De Gran Canaria / Gando;;Spain;1;27-56N;015-23W;27-56N;015-23W;23;47;P +GCRR;60;040;Lanzarote / Aeropuerto;;Spain;1;28-57N;013-36W;;;14;21;P +GCTS;60;025;Tenerife Sur;;Spain;1;28-03N;016-34W;;;64;77; +GCXO;60;015;Tenerife / Los Rodeos;;Spain;1;28-28N;016-19W;;;632;617;P +GEML;60;338;Melilla;;Spain;1;35-17N;002-57W;;;47;55;P +GFLL;61;856;Lungi;;Sierra Leone;1;08-37N;013-12W;08-37N;013-12W;25;27;P +GGBF;61;781;Bafata;;Guinea-Bissau;1;12-10N;014-40W;;;42;43; +GGOV;61;766;Bissau Aeroport ;;Guinea-Bissau;1;11-53N;015-39W;11-53N;015-39W;39;36; +GLRB;65;660;Grand Bassa, Roberts Field;;Liberia;1;06-15N;010-21W;;;18;; +GMAA;60;250;Agadir;;Morocco;1;30-23N;009-34W;30-23N;009-34W;27;23;P +GMAD;60;252;Agadir Al Massira;;Morocco;1;30-20N;009-24W;30-20N;009-25W;74;74; +GMAT;60;285;Tan-Tan;;Morocco;1;28-27N;011-09W;;;229;200;P +GMFF;60;141;Fes-Sais;;Morocco;1;33-56N;004-59W;33-56N;004-59W;579;579;P +GMFI;60;160;Ifrane;;Morocco;1;33-30N;005-10W;33-30N;005-10W;1664;1665;P +GMFK;60;210;Errachidia;;Morocco;1;31-56N;004-24W;31-58N;004-25W;1034;1042;P +GMFM;60;150;Meknes;;Morocco;1;33-53N;005-32W;33-53N;005-32W;576;549;P +GMFN;60;340;Nador;;Morocco;1;35-09N;002-55W;35-09N;002-55W;3;16;P +GMFO;60;115;Oujda;;Morocco;1;34-47N;001-56W;34-47N;001-57W;468;470;P +GMFZ;60;127;Taza;;Morocco;1;34-13N;004-00W;34-13N;004-00W;509;510;P +GMMC;60;155;Casablanca;;Morocco;1;33-34N;007-40W;33-34N;007-40W;62;62;P +GMME;60;135;Rabat-Sale;;Morocco;1;34-03N;006-46W;34-03N;006-46W;84;75;P +GMMF;60;060;Sidi Ifni;;Morocco;1;29-22N;010-11W;29-22N;010-11W;58;66;P +GMMI;60;220;Essaouira;;Morocco;1;31-31N;009-47W;31-31N;009-47W;15;8;P +GMML;--;---;Laayoune/Hassan Isl;;Morocco;1;27-10N;013-12-59W;;;6;; +GMMN;60;156;Nouasseur;;Morocco;1;33-22N;007-35W;;;200;206;P +GMMS;60;185;Safi;;Morocco;1;32-17N;009-14W;32-17N;009-14W;52;45;P +GMMW;--;---;Nador/Arwi;;Morocco;1;34-59-20N;003-01-42W;;;175;; +GMMX;60;230;Marrakech;;Morocco;1;31-37N;008-02W;31-37N;008-02W;468;466;P +GMMY;60;120;Kenitra;;Morocco;1;34-18N;006-36W;;;5;14;P +GMMZ;60;265;Ouarzazate;;Morocco;1;30-56N;006-54W;30-56N;006-54W;1139;1140;P +GMTA;60;107;Al Hoceima;;Morocco;1;35-11N;003-51W;35-11N;003-51W;27;14;P +GMTN;60;318;Tetuan / Sania Ramel;;Morocco;1;35-35N;005-20W;;;10;10;P +GMTT;60;101;Tanger Aerodrome ;;Morocco;1;35-44N;005-54W;35-44N;005-54W;19;21;P +GOGG;61;695;Ziguinchor;;Senegal;1;12-33N;016-16W;12-33N;016-16W;26;23;P +GOGK;61;698;Kolda;;Senegal;1;12-53N;014-58W;;;10;10;P +GOGS;61;697;Cap-Skirring;;Senegal;1;12-24N;016-45W;;;16;13; +GOOD;61;666;Diourbel;;Senegal;1;14-39N;016-14W;;;7;9;P +GOOG;61;627;Linguere;;Senegal;1;15-23N;015-07W;;;20;21;P +GOOK;61;679;Kaolack;;Senegal;1;14-08N;016-04W;;;6;7;P +GOOY;61;641;Dakar / Yoff;;Senegal;1;14-44N;017-30W;14-44N;017-30W;27;24;P +GOSM;61;630;Matam;;Senegal;1;15-39N;013-15W;;;15;17;P +GOSP;61;612;Podor;;Senegal;1;16-39N;014-58W;;;6;7;P +GOSS;61;600;Saint-Louis;;Senegal;1;16-03N;016-27W;16-03N;016-27W;4;4;P +GOTK;61;699;Kedougou;;Senegal;1;12-34N;012-13W;;;178;167;P +GOTT;61;687;Tambacounda;;Senegal;1;13-46N;013-41W;13-46N;013-41W;49;50;P +GQNA;61;499;Aioun El Atrouss;;Mauritania;1;16-42N;009-36W;16-42N;009-36W;223;223;P +GQNB;61;461;Boutilimit;;Mauritania;1;17-32N;014-41W;;;77;75;P +GQND;61;450;Tidjikja;;Mauritania;1;18-34N;011-26W;;;396;402;P +GQNF;61;498;Kiffa;;Mauritania;1;16-38N;011-24W;16-38N;011-24W;115;115;P +GQNI;61;497;Nema;;Mauritania;1;16-36N;007-16W;16-36N;007-16W;269;269;P +GQNJ;61;437;Akjoujt;;Mauritania;1;19-45N;014-22W;;;123;120;P +GQNK;61;492;Kaedi;;Mauritania;1;16-09N;013-31W;;;18;18; +GQNN;61;442;Nouakchott;;Mauritania;1;18-06N;015-57W;18-06N;015-57W;2;3;P +GQNR;61;489;Rosso;;Mauritania;1;16-30N;015-49W;;;5;6;P +GQPA;61;421;Atar;;Mauritania;1;20-31N;013-04W;20-31N;013-04W;226;224;P +GQPP;61;415;Nouadhibou;;Mauritania;1;20-56N;017-02W;20-56N;017-02W;5;3;P +GQPT;61;401;Bir Moghrein;;Mauritania;1;25-14N;011-37W;25-14N;011-37W;364;360;P +GSVO;60;096;Villa Cisneros;;Western Sahara;1;23-42N;015-52W;23-42N;015-56W;10;10;P +GUCY;61;832;Conakry / Gbessia;;Guinea;1;09-34N;013-37W;09-34N;013-38W;26;26; +GUFH;61;833;Faranah / Badala;;Guinea;1;10-02N;010-45W;;;458;459; +GUID;61;818;Kindia;;Guinea;1;10-03N;012-52W;;;458;459; +GUKU;61;834;Kissidougou;;Guinea;1;09-11N;010-06W;;;525;525; +GULB;61;809;Labe;;Guinea;1;11-19N;012-18W;11-19N;012-18W;1025;1026; +GUMA;61;847;Macenta;;Guinea;1;08-32N;009-28W;;;543;544; +GUNZ;61;849;N'Zerekore;;Guinea;1;07-44N;008-50W;;;470;470; +GUOK;61;816;Boke;;Guinea;1;10-56N;014-19W;;;69;69; +GUSI;61;811;Siguiri;;Guinea;1;11-26N;009-10W;;;362;366; +GUXD;61;829;Kankan;;Guinea;1;10-23N;009-18W;10-23N;009-18W;377;384; +GVAC;08;594;Sal;;Cape Verde;1;16-44N;022-57W;16-44N;022-57W;54;55;P +HAAB;63;450;Addis Ababa;;Ethiopia;1;08-59N;038-48E;08-59N;038-48E;2355;2324;P +HAAG;--;---;Agordat ;;Ethiopia;1;15-33N;037-53E;;;626;; +HAAM;63;500;Arba Minch;;Ethiopia;1;06-04N;037-40E;;;1219;; +HAAW;--;---;Awash ;;Ethiopia;1;08-59N;040-10E;;;1052;; +HAAX;--;---;Axum;;Ethiopia;1;14-07N;038-43E;;;2134;; +HABC;--;---;Baco / Bako ;;Ethiopia;1;05-50N;036-37E;;;1311;; +HABD;63;332;Bahar Dar;;Ethiopia;1;11-36N;037-24E;;;1820;1805;P +HADC;63;333;Combolcha;;Ethiopia;1;11-05N;039-43E;;;1864;1916;P +HADM;63;334;Debremarcos;;Ethiopia;1;10-21N;037-43E;;;2476;2440;P +HADR;63;471;Dire Dawa;;Ethiopia;1;09-36N;041-52E;;;1146;1146;P +HAGH;--;---;Ghinnir / Ginir ;;Ethiopia;1;07-09N;040-43E;;;1844;; +HAGN;63;331;Gondar;;Ethiopia;1;12-32N;037-26E;;;1985;1966;P +HAGO;63;478;Gode;;Ethiopia;1;05-06N;044-35E;05-06N;044-35E;320;320;P +HAGR;63;403;Gore;;Ethiopia;1;08-10N;035-33E;;;1974;1974;P +HAHM;63;451;Harar Meda;;Ethiopia;1;08-44N;039-00E;08-44N;039-00E;1876;1876;P +HAJJ;63;473;Jiggiga;;Ethiopia;1;09-20N;042-43E;;;1644;1644;P +HAJM;63;402;Jimma;;Ethiopia;1;07-40N;036-50E;;;1676;1577;P +HAKD;--;---;Kabre Dare Military ;;Ethiopia;1;06-45N;044-17E;;;550;; +HALA;63;460;Awassa;;Ethiopia;1;07-04N;038-30E;;;1652;1652;P +HAMK;63;330;Makale;;Ethiopia;1;13-30N;039-29E;;;2212;2212;P +HAML;--;---;Masslo / Meslo ;;Ethiopia;1;06-22N;039-50E;;;2274;; +HAMS;63;023;Massawa;;Ethiopia;1;15-37N;039-27E;;;10;10;P +HANG;63;533;Neghelli;;Ethiopia;1;05-17N;039-45E;05-17N;039-45E;1455;1455;P +HASB;63;043;Assab;;Ethiopia;1;13-04N;042-43E;;;14;14;P +HASO;--;---;Assosa / Asosa ;;Ethiopia;1;10-02N;034-32E;;;1733;; +HATS;--;---;Tessenei / Teseney ;;Ethiopia;1;15-07N;036-41E;;;615;; +HBBA;64;390;Bujumbura;;Burundi;1;03-19S;029-19E;03-19S;029-19E;782;783;P +HCMH;63;170;Hargeisa;;Somalia;1;09-30N;044-05E;;;1326;; +HCMI;63;160;Berbera;;Somalia;1;10-25N;045-01E;;;9;; +HCMM;63;260;Mogadiscio;;Somalia;1;02-02N;045-21E;02-02N;045-21E;9;9;P +HCMN;63;240;Belet Uen;;Somalia;1;04-42N;045-13E;;;173;173;P +HCMV;63;175;Burao;;Somalia;1;09-30N;045-34E;;;1032;; +HDAM;--;---;Djibouti \ Ambouli;;Djibouti;1;11-33N;043-10E;;;49;; +HEAR;62;337;El Arish;;Egypt;1;31-05N;033-49E;31-05N;033-50E;31;32; +HEAT;62;393;Asyut;;Egypt;1;27-03N;031-01E;27-11N;031-06E;226;70;P +HEAX;62;318;Alexandria / Nouzha;;Egypt;1;31-12N;029-57E;31-12N;029-57E;-2;7;P +HEBA;--;---;Alexandria Borg El Arab;;Egypt;1;31-31N;030-10E;;;54;; +HECA;62;366;Cairo Airport;;Egypt;1;30-08N;031-24E;;;64;74;P +HEGN;62;463;Hurguada;;Egypt;1;27-09N;033-43E;27-09N;033-43E;16;14; +HELX;62;405;Luxor;;Egypt;1;25-40N;032-42E;25-40N;032-42E;93;99;P +HEMM;62;306;Mersa Matruh;;Egypt;1;31-20N;027-13E;31-20N;027-13E;25;30; +HEPS;62;333;Port Said;;Egypt;1;31-16N;032-18E;31-16N;032-14E;6;6; +HESH;--;---;Sharm El Sheikhintl;;Egypt;1;27-58N;034-23E;;;50;; +HESN;62;414;Asswan;;Egypt;1;23-58N;032-47E;23-58N;032-47E;200;194;P +HETB;--;---;Taba;;Egypt;1;29-35-57N;034-46-36E;;;749;; +HETR;62;459;El Tor;;Egypt;1;28-14N;032-37E;28-14N;033-37E;21;14;P +HFFF;63;125;Djibouti;;Djibouti;1;11-33N;043-09E;11-33N;043-09E;13;19;P +HHAS;63;021;Asmara;;Ethiopia;1;15-17N;038-55E;15-17N;038-55E;2356;2325;P +HKEL;63;686;Eldoret;;Kenya;1;00-32N;035-17E;00-32N;035-17E;2120;2133;P +HKEM;63;720;Embu;;Kenya;1;00-30S;037-27E;00-30S;037-27E;1493;1493;P +HKGA;63;723;Garissa;;Kenya;1;00-28S;039-38E;00-28S;039-38E;138;147;P +HKIS;--;---;Isiolo ;;Kenya;1;00-21N;037-35E;;;1067;; +HKJK;--;---;Nairobi/Jomo Kenyatta Airport TWR/APP/NOF/Civil Airlines;;Kenya;1;01-19S;036-55E;;;1624;1624;P +HKKG;63;687;Kakamega;;Kenya;1;00-17N;034-47E;;;1530;; +HKKI;63;708;Kisumu;;Kenya;1;00-06S;034-45E;00-06S;034-45E;1157;1146;P +HKKR;63;710;Kericho;;Kenya;1;00-22S;035-21E;00-22S;035-21E;2184;2184;P +HKKS;63;709;Kisii;;Kenya;1;00-40S;034-47E;;;1493;; +HKKT;63;661;Kitale;;Kenya;1;01-01N;035-00E;01-01N;035-00E;1890;1875;P +HKLO;63;612;Lodwar;;Kenya;1;03-07N;035-37E;03-07N;035-37E;506;515;P +HKLU;63;772;Lamu;;Kenya;1;02-16S;040-50E;;;6;;P +HKMA;63;624;Mandera;;Kenya;1;03-56N;041-52E;03-56N;041-52E;230;231;P +HKMB;63;641;Marsabit;;Kenya;1;02-18N;037-54E;02-18N;037-54E;1219;1345;P +HKME;63;695;Meru;;Kenya;1;00-05N;037-39E;00-05N;037-39E;1554;1554;P +HKML;63;799;Malindi;;Kenya;1;03-14S;040-06E;03-14S;040-06E;20;23;P +HKMO;63;820;Mombasa;;Kenya;1;04-02S;039-37E;04-02S;039-37E;57;55;P +HKMU;63;766;Makindu;;Kenya;1;02-17S;037-50E;02-17S;037-50E;1000;1000;P +HKMY;63;619;Moyale;;Kenya;1;03-32N;039-03E;03-32N;039-03E;1097;1097;P +HKNA;63;740;Nairobi ACC/FIC/RCC/MET/COM/;;Kenya;1;01-19S;036-56E;;;1624;; +HKNC;63;741;Nairobi / Dagoretti;;Kenya;1;01-18S;036-45E;01-18S;036-45E;1798;1798;P +HKNI;63;717;Nyeri;;Kenya;1;00-30S;036-58E;00-30S;036-58E;1759;1759;P +HKNK;63;714;Nakuru;;Kenya;1;00-16S;036-06E;00-16S;036-04E;1901;1901;P +HKNO;63;737;Narok;;Kenya;1;01-08S;035-50E;01-06S;035-50E;1890;1890;P +HKNW;63;742;Nairobi / Wilson;;Kenya;1;01-19S;036-49E;;;1683;1679;P +HKNY;--;---;Nanyuki ;;Kenya;1;00-04S;037-02E;;;1905;; +HKVO;63;793;Voi;;Kenya;1;03-24S;038-34E;03-24S;038-34E;579;579;P +HKWJ;63;671;Wajir;;Kenya;1;01-45N;040-04E;01-45N;040-04E;244;244;P +HLGT;62;212;Ghat;;Libya;1;25-08N;010-09E;25-08N;010-08E;699;693;P +HLKF;62;271;Kufra;;Libya;1;24-13N;023-18E;24-13N;023-18E;417;436;P +HLLB;62;053;Benina;;Libya;1;32-06N;020-16E;32-05N;020-16E;131;132;P +HLLS;62;124;Sebha;;Libya;1;27-01N;014-27E;27-01N;014-26E;435;432;P +HLLT;62;010;Tripoli Inter-National Airport;;Libya;1;32-40N;013-09E;32-41N;013-10E;80;82;P +HLTD;62;103;Ghadames;;Libya;1;30-08N;009-30E;30-08N;009-30E;346;347;P +HRYG;64;381;Gisenyi;;Rwanda;1;01-40S;029-15E;;;1556;1554;P +HRYR;64;387;Kigali;;Rwanda;1;01-58S;030-07E;01-58S;030-07E;1491;1497;P +HSAT;62;680;Atbara;;Sudan;1;17-42N;033-58E;17-42N;033-58E;347;345;P +HSDN;62;650;Dongola;;Sudan;1;19-10N;030-29E;19-10N;030-29E;226;226;P +HSDZ;62;805;Damazine;;Sudan;1;11-47N;034-23E;11-47N;034-23E;474;470;P +HSFS;62;760;El Fasher;;Sudan;1;13-37N;025-20E;13-37N;025-20E;733;730;P +HSGF;62;752;Gedaref;;Sudan;1;14-02N;035-24E;14-02N;035-24E;599;599;P +HSGN;62;770;Geneina;;Sudan;1;13-29N;022-27E;13-29N;022-27E;805;805;P +HSKA;62;730;Kassala;;Sudan;1;15-28N;036-24E;15-28N;036-24E;500;500;P +HSKI;62;772;Kosti;;Sudan;1;13-10N;032-40E;13-10N;032-40E;381;381;P +HSLI;62;810;Kadugli;;Sudan;1;11-00N;029-43E;;;499;499;P +HSNL;62;790;Nyala;;Sudan;1;12-03N;024-53E;;;67;674;P +HSNR;62;762;Sennar;;Sudan;1;13-33N;033-37E;;;418;418;P +HSOB;62;771;El Obeid;;Sudan;1;13-10N;030-14E;13-10N;030-14E;574;574;P +HSPN;--;---;Port Sudan International;;Sudan;1;19-26N;037-14E;;;138;; +HSRN;62;801;Renk;;Sudan;1;11-45N;032-47E;;;282;282; +HSSJ;62;941;Juba;;Sudan;1;04-52N;031-36E;04-52N;031-36E;460;457;P +HSSM;62;840;Malakal;;Sudan;1;09-33N;031-39E;09-33N;031-39E;387;388;P +HSSP;62;641;Port Sudan;;Sudan;1;19-35N;037-13E;19-35N;037-13E;3;2;P +HSSS;62;721;Khartoum;;Sudan;1;15-36N;032-33E;15-36N;032-33E;382;380;P +HSSW;62;600;Wadi Halfa;;Sudan;1;21-49N;031-29E;21-48N;031-31E;183;183;P +HTAR;63;789;Arusha;;Tanzania;1;03-20S;036-37E;03-20S;036-37E;1387;1387;P +HTBU;63;729;Bukoba;;Tanzania;1;01-20S;031-49E;01-20S;031-49E;1137;1137;P +HTDA;63;894;Dar Es Salaam Airport;;Tanzania;1;06-52S;039-12E;06-52S;039-12E;55;55;P +HTDO;63;862;Dodoma;;Tanzania;1;06-10S;035-46E;06-10S;035-46E;1119;1120;P +HTIR;63;887;Iringa;;Tanzania;1;07-40S;035-45E;07-40S;035-45E;1426;1428;P +HTKA;63;801;Kigoma;;Tanzania;1;04-53S;029-38E;04-53S;029-38E;882;885;P +HTKI;--;---;Kilwa Masoko ;;Tanzania;1;08-56S;039-31E;;;18;; +HTKJ;63;791;Kilimanjaro Airport;;Tanzania;1;03-25S;037-04E;03-25S;037-04E;891;896;P +HTMB;63;932;Mbeya;;Tanzania;1;08-56S;033-28E;08-56S;033-28E;1704;1707;P +HTMG;63;866;Morogoro;;Tanzania;1;06-50S;037-39E;06-50S;037-39E;526;526;P +HTMO;63;818;Mombo;;Tanzania;1;04-53S;038-17E;04-55S;038-14E;511;411; +HTMS;63;790;Moshi;;Tanzania;1;03-21S;037-20E;;;854;831;P +HTMT;63;971;Mtwara;;Tanzania;1;10-16S;040-11E;10-16S;040-11E;113;113;P +HTMU;63;733;Musoma;;Tanzania;1;01-30S;033-48E;;;1147;1147;P +HTMW;63;756;Mwanza;;Tanzania;1;02-28S;032-55E;02-28S;032-55E;1139;1140;P +HTNA;63;969;Nachingwea;;Tanzania;1;10-21S;038-45E;;;463;465; +HTPE;63;845;Pemba / Karume Airport;;Tanzania;1;05-15S;039-49E;;;25;; +HTSE;63;816;Same;;Tanzania;1;04-05S;037-43E;04-05S;037-43E;872;872;P +HTSO;63;962;Songea;;Tanzania;1;10-41S;035-35E;10-41S;035-35E;1067;1067;P +HTSY;--;---;Shinyanga;;Tanzania;1;03-30S;033-00E;;;1100;; +HTTB;63;832;Tabora Airport;;Tanzania;1;05-05S;032-50E;05-05S;032-50E;1181;1190;P +HTTG;63;844;Tanga;;Tanzania;1;05-05S;039-04E;05-05S;039-04E;39;35;P +HTZA;63;870;Zanzibar / Kisauni;;Tanzania;1;06-13S;039-13E;;;15;15;P +HUAR;63;602;Arua;;Uganda;1;03-03N;030-55E;03-03N;030-55E;1204;1211;P +HUEN;63;705;Entebbe Airport;;Uganda;1;00-03N;032-27E;00-03N;032-27E;1155;1155;P +HUFP;--;---;Fort Portal ;;Uganda;1;00-40N;030-17E;;;1533;; +HUGU;63;630;Gulu;;Uganda;1;02-45N;032-20E;02-45N;032-20E;1104;1105;P +HUJI;63;682;Jinja;;Uganda;1;00-27N;033-11E;;;1175;1173;P +HUKB;63;726;Kabale;;Uganda;1;01-15S;029-59E;01-15S;029-59E;1867;1869;P +HUKS;63;674;Kasese;;Uganda;1;00-11N;030-06E;00-11N;030-06E;959;961;P +HULI;--;---;Lira;;Uganda;1;02-15N;032-54E;;;1091;; +HUMA;63;702;Mbarara;;Uganda;1;00-37S;030-39E;00-37S;030-39E;1412;1413;P +HUMI;63;654;Masindi;;Uganda;1;01-41N;031-43E;01-41N;031-43E;1146;1147;P +HUMO;--;---;Moroto ;;Uganda;1;02-32N;034-39E;;;1280;; +HUSO;63;658;Soroti;;Uganda;1;01-43N;033-37E;01-43N;033-37E;1132;1123;P +HUTO;63;684;Tororo;;Uganda;1;00-41N;034-10E;00-41N;034-10E;1170;1171;P +K01R;74;755;Claiborne Range, Airways Facilities Sector ;LA;United States;4;31-08N;092-34W;31-11N;092-38W;67;67; +K01T;--;---;High Island;LA;United States;4;28-08N;094-24W;;;30;; +K03Y;--;---;Hallock;MN;United States;4;48-47N;096-57W;;;250;; +K04V;--;---;Saguache, Saguache Municipal Airport;CO;United States;4;38-05-50N;106-10-07W;;;2385;; +K05F;--;---;Gatesville, City-County Airport;TX;United States;4;31-25-16N;097-47-49W;;;276;; +K07G;--;---;Charlotte, Fitch H Beach Airport;MI;United States;4;42-34-28N;084-48-41W;;;271;; +K07S;--;---;Deer Park, Deer Park Airport;WA;United States;4;47-58-27N;117-25-42W;47-57-44N;117-26-06W;672;668; +K0B9;--;---;Goat Island Remote Automatic Meteorological Observing System ;ME;United States;4;43-20N;070-24W;;;12;; +K0E4;--;---;Payson;AZ;United States;4;34-14N;111-20W;;;1498;; +K0L3;--;---;Zuma Beach;CA;United States;4;34-01N;118-49W;;;6;; +K0V1;--;---;Custer, Custer County Airport;SD;United States;4;43-43-59N;103-36-41W;43-44-00N;103-36-50W;1711;1725; +K0W8;--;---;Chincoteague;VA;United States;4;37-56N;075-23W;;;2;; +K0Y2;--;---;Sturgeon Bay;WI;United States;4;44-47N;087-19W;;;176;; +K11J;--;---;Blakely, Early County Airport;GA;United States;4;31-23-49N;084-53-42W;;;65;; +K11R;--;---;Brenham, Brenham Municipal Airport;TX;United States;4;30-13-08N;096-22-27W;;;94;; +K12B;--;---;New Castles Coast Guard Light Station;NH;United States;4;43-07N;070-29W;;;1;; +K12C;--;---;Rochelle, Rochelle Municipal-Koritz Field Airport;IL;United States;4;41-53-35N;089-04-42W;;;238;; +K12N;--;---;Andover, Aeroflex-Andover Airport;NJ;United States;4;41-00-32N;074-44-12W;41-00-29N;074-44-22W;177;177; +K13A;--;---;Nogales Automatic Meteorological Observing System;AZ;United States;4;31-25N;110-51W;;;1198;; +K13G;--;---;Niagara Coast Guard Station;NY;United States;4;43-16N;079-04W;;;82;; +K14B;--;---;Great Duck Island Coast Guard Light Station;ME;United States;4;44-09N;068-15W;;;1;; +K14C;--;---;Frankfort Coast Guard Station;MI;United States;4;44-38N;086-15W;;;174;; +K15B;--;---;Halfway Rock Coast Guard Light Station;ME;United States;4;43-39N;070-02W;;;1;; +K15C;--;---;Milwaukee Coast Guard Light Station;WI;United States;4;43-01N;087-57W;;;179;; +K16B;--;---;Heron Neck Coast Guard Light Station;ME;United States;4;44-02N;068-52W;;;1;; +K16C;--;---;Kenosha Coast Guard Station;WI;United States;4;42-35N;087-45W;;;223;; +K17C;--;---;Ludington Coast Guard Station;MI;United States;4;43-57N;086-28W;;;182;; +K17W;--;---;Wadena, Wadena Municipal Airport;MN;United States;4;46-26-48N;095-12-42W;;;418;; +K17Y;--;---;Mc Gregor, Isedor Iverson Airport;MN;United States;4;46-37-07N;093-18-35W;;;374;; +K18B;--;---;Monhegan / Manana Island;ME;United States;4;43-46N;069-20W;;;1;; +K18C;--;---;Michigan City Coast Guard Station;IN;United States;4;41-43N;086-55W;;;177;; +K18N;--;---;New London Ledge Coast Guard Station;CT;United States;4;41-18N;072-05W;;;8;; +K19C;--;---;Muskegon Coast Guard Station;MI;United States;4;43-14N;086-20W;;;182;; +K19D;--;---;Mora Municipal Automatic Weather Observing / Reporting System ;MN;United States;4;45-53N;093-16W;;;309;; +K19G;--;---;Buffalo Coast Guard Station;NY;United States;4;42-53N;078-53W;;;180;; +K19R;--;---;Ship Shoal Platform;LA;United States;4;28-41N;091-13W;;;18;; +K1A5;--;---;Franklin, Macon County Airport;NC;United States;4;35-13N;083-25W;;;616;; +K1B7;--;---;Boothville Heliport;LA;United States;4;29-21N;89-26W;;;1;; +K1F0;--;---;Ardmore, Ardmore Downtown Executive Airport;OK;United States;4;34-08-49N;097-07-21W;;;257;; +K1F9;--;---;Bridgeport, Bridgeport Municipal Airport;TX;United States;4;33-10-31N;097-49-42W;;;260;; +K1G2;--;---;Granite Falls, Granite Falls Municipal Airport/Lenzen-Roe Memorial Field;MN;United States;4;44-45-11N;095-33-21W;;;319;; +K1G7;--;---;Mississippi Canyon;LA;United States;4;28-47N;089-03W;;;18;; +K1H2;--;---;Effingham, Effingham County Memorial Airport;IL;United States;4;39-04-14N;088-32-00W;;;179;; +K1J1;--;---;Saint Simon Island Coast Guard Station;GA;United States;4;31-08N;081-22W;;;1;; +K1J2;--;---;Tybee Coast Guard Station;GA;United States;4;32-01N;080-51W;;;2;; +K1J3;--;---;Ponce De Leon Inlet;FL;United States;4;29-04N;080-55W;;;3;; +K1J4;--;---;Cape San Blas Coast Guard Station;FL;United States;4;29-41N;085-22W;;;2;; +K1J5;--;---;Santa Rosa Coast Guard Station;FL;United States;4;30-19N;087-15W;;;2;; +K1K5;72;460;Elkhart / Elkhart-Morton County Airport;KS;United States;4;37-00N;101-53W;;;1102;1102;P +K1L2;--;---;Santa Monica Pier;CA;United States;4;34-00N;118-30W;;;2;; +K1O5;--;---;Montague;CA;United States;4;41-44N;122-33W;;;770;; +K1P1;--;---;Plymouth, Plymouth Municipal Airport;NH;United States;4;43-46-45N;071-45-13W;;;154;; +K1V1;--;---;Rifle Aviation Weather Reporting Station ;CO;United States;4;39-32N;107-48W;;;1622;; +K1V4;72;614;Saint Johnsbury;VT;United States;4;44-25-10N;072-01-10W;44-25-10N;072-01-10W;212;210; +K1W9;--;---;Wrightsville Beach;NC;United States;4;34-11N;077-49W;;;3;; +K20B;--;---;Rockland Coast Guard Station;ME;United States;4;44-06N;069-06W;;;1;; +K20C;--;---;Saint Joseph Coast Guard Station;MI;United States;4;42-07N;086-29W;;;176;; +K20G;--;---;Ashtabula Coast Guard Station;OH;United States;4;41-55N;080-48W;;;178;; +K20J;--;---;West Jonesport Coast Guard Station;ME;United States;4;44-32N;067-37W;;;5;; +K20V;--;---;Kremmling, Mc Elroy Airfield;CO;United States;4;40-03-13N;106-22-08W;;;2259;; +K215;--;---;Rantoul, Frank Elliott Field Airport;IL;United States;4;40-17-03N;088-08-03W;;;225;; +K21C;--;---;Sheboygan Coast Guard Station;WI;United States;4;43-45N;087-42W;;;1;; +K21G;--;---;Marblehead Coast Guard Station;OH;United States;4;41-33N;082-44W;;;196;; +K23B;--;---;Seguin Island Coast Guard Light Station;ME;United States;4;43-40N;069-46W;;;1;; +K23G;--;---;Cleveland Harbor Coast Guard Station;OH;United States;4;41-30N;081-43W;;;181;; +K24B;--;---;West Quoddy Head Coast Guard Light Station;ME;United States;4;44-48N;066-57W;;;1;; +K24G;--;---;Toledo Coast Guard Station;OH;United States;4;41-42N;083-27W;;;180;; +K25B;--;---;Portsmouth Harbor;NH;United States;4;43-04N;070-43W;;;1;; +K25G;--;---;Erie Coast Guard Station;PA;United States;4;42-07N;080-05W;;;175;; +K25R;--;---;Edinburg, Edinburg International Airport;TX;United States;4;26-26-31N;098-07-46W;;;24;; +K26B;--;---;Isle Of Shoals Coast Guard Station;NH;United States;4;42-58N;070-37W;;;1;; +K26G;--;---;Rochester Coast Guard Light Station;NY;United States;4;43-15N;077-36W;;;82;; +K27A;--;---;Elberton, Elbert County Airport-Patz Field;GA;United States;4;34-05-42N;082-48-57W;;;184;; +K27B;--;---;Cape Neddick Coast Guard Light Station;ME;United States;4;43-10N;070-36W;;;12;; +K27G;--;---;Lorain Coast Guard Station;OH;United States;4;41-28N;082-11W;;;176;; +K27U;--;---;Salmon;ID;United States;4;45-11N;113-54W;;;1210;; +K27Y;--;---;Grand Marais Coast Guard Station;MI;United States;4;46-40N;085-59W;;;183;; +K28G;--;---;Oswego Coast Guard Station;NY;United States;4;43-28N;076-31W;;;78;; +K28K;--;---;Grncyn Blk52 Supplementary Aviation Weather Reporting Station ;LA;United States;4;27-53N;091-30W;;;1;; +K28T;--;---;Sabine Pass;TX;United States;4;29-42N;093-57W;;;5;; +K28Y;--;---;North Manitou Shoal;MI;United States;4;45-01N;085-57W;;;177;; +K29B;--;---;Boston / Hull Coast Guard Light Station;MA;United States;4;42-19N;070-53W;;;0;; +K29G;--;---;Ravenna / Portage County;OH;United States;4;41-13N;081-15W;;;365;; +K29Y;--;---;Devils Island Light Station;WI;United States;4;47-05N;090-44W;;;192;; +K2B8;--;---;Portland Head Coast Guard Light Station;ME;United States;4;43-37N;070-12W;;;23;; +K2C2;72;269;White Sands;NM;United States;4;32-23N;106-29W;32-24N;106-22W;1244;1244; +K2DP;74;695;Dare County Gunnery Range;NC;United States;4;35-40N;075-54W;35-41N;075-54W;3;3; +K2F8;--;---;Bastrop, Morehouse Memorial Airport;LA;United States;4;32-45-21N;091-52-50W;;;51;; +K2G6;--;---;Meadville, Port Meadville Airport;PA;United States;4;41-37-33N;080-12-44W;41-37-33N;080-12-39W;426;428; +K2GL;--;---;Galliano, Galliano Heliport;LA;United States;4;29-24-48N;090-17-56W;;;2;; +K2H1;--;---;Huntington B. Oil;CA;United States;4;33-34N;118-08W;;;36;; +K2I4;--;---;Columbus / Bolton Field;OH;United States;4;39-54N;083-08W;;;280;; +K2I5;--;---;Rantoul, Rantoul Natl Aviation Cntr-Frank Elliott Fld Airp.;IL;United States;4;40-17-37N;088-08-33W;;;225;; +K2L6;--;---;Marina Del Rey;CA;United States;4;33-58N;118-26W;;;8;; +K2L7;--;---;Solana Beach;CA;United States;4;32-59N;117-16W;;;5;; +K2P3;--;---;Paynesville, Paynesville Municipal Airport;MN;United States;4;45-22-20N;094-44-47W;;;360;; +K2PJ;74;792;Poinsett Range, Sumpter;SC;United States;4;33-51N;080-29W;33-51N;080-29W;68;68; +K2R8;--;---;Port Aransas, Mustang Beach Airport;TX;United States;4;27-48-41N;097-05-20W;;;2;; +K2S9;--;---;Willapa Harbor;WA;United States;4;46-42N;123-49W;;;5;; +K2U7;--;---;Stanley, Stanley Airport;ID;United States;4;44-12-30N;114-56-04W;;;1952;1980; +K2V9;--;---;Gunnison Aviation Weather Reporting Station ;CO;United States;4;38-36N;106-55W;;;2380;; +K2WX;--;---;Buffalo;SD;United States;4;45-36-16N;103-32-47W;45-36-16N;103-32-48W;915;915; +K30B;--;---;Sandwich Coast Guard Station;MA;United States;4;41-47N;070-30W;;;1;; +K30G;--;---;Saginaw River Coast Guard Station;MI;United States;4;43-38N;083-51W;;;177;; +K30N;--;---;Faulkner Island Coast Guard Light Station;CT;United States;4;41-13N;072-40W;;;15;; +K30Y;--;---;Duluth Harbor Coast Guard Station;MN;United States;4;46-46N;092-05W;;;186;; +K31B;--;---;Chatham Coast Guard Station;MA;United States;4;41-40N;069-57W;;;1;; +K31F;--;---;Seminole, Gaines County Airport;TX;United States;4;32-40-31N;102-39-09W;;;1010;; +K31G;--;---;Belle Isle Coast Guard Station;MI;United States;4;42-20N;082-58W;;;177;; +K31Y;--;---;Eagle Harbor Coast Guard Light Station;MI;United States;4;47-28N;088-10W;;;186;; +K32N;--;---;Little Gulf Island Light Station;CT;United States;4;41-12N;072-06W;;;6;; +K32Y;--;---;Portage Coast Guard Station;MI;United States;4;47-14N;088-38W;;;190;; +K33B;--;---;Buzzards Bay Coast Guard Light Station;MA;United States;4;41-23N;071-02W;;;1;; +K33G;--;---;Port Huron Coast Guard Station;MI;United States;4;43-00N;082-25W;;;177;; +K34B;--;---;Gloucester Coast Guard Station;MA;United States;4;42-35N;070-40W;;;1;; +K34N;--;---;Eatons Neck Coast Guard Station;NY;United States;4;40-57N;073-24W;;;1;; +K34Y;--;---;Marquette Coast Guard Light Station;MI;United States;4;46-33N;087-23W;;;203;; +K35B;--;---;Merrimac River Coast Guard Station;MA;United States;4;42-49N;070-52W;;;1;; +K36B;--;---;Race Point Coast Guard Station;MA;United States;4;42-03N;070-11W;;;1;; +K36U;--;---;Heber, Heber City Municipal-Russ McDonald Field Airport;UT;United States;4;40-28-55N;111-25-44W;;;1718;; +K36Y;--;---;Point Betsie / Frankfort;MI;United States;4;44-37N;086-12W;;;183;; +K37B;--;---;Scituate Coast Guard Station;MA;United States;4;42-12N;070-43W;;;1;; +K37W;--;---;Erwin, Harnett County Airport;NC;United States;4;35-22-43N;078-44-01W;;;60;; +K38Y;--;---;Saint Ignace;MI;United States;4;45-51N;084-43W;;;176;; +K39Y;--;---;Tawas Point Coast Guard Station;MI;United States;4;44-15N;083-26W;;;178;; +K3A1;--;---;Cullman, Folsom Field Airport;AL;United States;4;34-16-07N;086-51-30W;;;294;; +K3A6;--;---;Newhall;CA;United States;4;34-22N;118-34W;;;427;; +K3B1;--;---;Greenville, Greenville Municipal Airport;ME;United States;4;45-27-47N;069-33-06W;45-27-44N;069-35-43W;427;;P +K3B2;--;---;Marshfield Airport;MA;United States;4;42-06N;070-41W;;;3;; +K3B6;--;---;Eugene Island 330;LA;United States;4;28-05N;92-42W;;;0;; +K3D4;--;---;Frankfort, Frankfort Dow Memorial Field Airport;MI;United States;4;44-37-30N;086-12-02W;;;193;; +K3DU;--;---;Drummond;MT;United States;4;46-40N;113-09W;;;1202;; +K3HE;--;---;Howell;MI;United States;4;42-38N;083-59W;;;293;; +K3HT;--;---;Harlowton;MT;United States;4;46-26N;109-50W;;;1268;; +K3KM;--;---;Wichita, Colonel James Jabara Airport;KS;United States;4;37-44-59N;097-13-08W;;;434;; +K3L3;--;---;Newport Beach;CA;United States;4;33-36N;117-53W;;;3;; +K3LC;--;---;Lincoln, Logan County Airport;IL;United States;4;40-09-31N;089-20-06W;;;182;; +K3LF;--;---;Litchfield, Litchfield Municipal Airport;IL;United States;4;39-09-44N;089-40-28W;;;210;; +K3O6;--;---;Treasure Island;CA;United States;4;37-48N;122-22W;;;8;; +K3OI;--;---;Lamoni;IA;United States;4;40-37N;093-57W;;;342;; +K3R1;--;---;Bay City, Bay City Municipal Airport;TX;United States;4;28-58N;095-51W;;;14;; +K3RN;74;365;Graying Air Force Range;MI;United States;4;44-50N;084-33W;44-50N;084-33W;387;387; +K3S2;--;---;Aurora State;OR;United States;4;45-15N;122-46W;;;60;; +K3SE;--;---;Spencer;IA;United States;4;43-10N;095-09W;;;404;408;P +K3T1;--;---;Mineola/Quitman, Wood County Airport;TX;United States;4;32-44-31N;095-29-47W;;;132;; +K3T5;--;---;La Grange, Fayette Regional Air Center Airport;TX;United States;4;29-54-29N;096-57-00W;;;99;; +K3TH;--;---;Thompson Falls;MT;United States;4;47-36N;115-22W;;;725;; +K3V8;--;---;Venice Heliport;LA;United States;4;29-07N;089-12W;;;80;; +K3W4;--;---;Swansboro / Bogue;NC;United States;4;34-39N;077-06W;;;2;; +K40B;--;---;Clayton Lake;ME;United States;4;46-37N;069-32W;;;314;; +K40G;--;---;Grand Canyon, Valle Airport;AZ;United States;4;35-39-03N;112-08-46W;;;1829;; +K40J;--;---;Perry-Foley, Perry-Foley Airport;FL;United States;4;30-04-19N;083-34-25W;30-04-41N;083-34-48W;13;13; +K40N;--;---;Chester County Airport;PA;United States;4;39-59N;075-52W;;;201;; +K40Y;--;---;Thunder Bay Island;MI;United States;4;45-04N;083-33W;;;178;; +K41G;--;---;Bath;MI;United States;4;42-51N;084-29W;;;261;; +K41I;--;---;Eugene Island;LA;United States;4;28-28N;091-47W;;;30;; +K43F;--;---;Litchfield Municipal;MN;United States;4;45-06N;094-30W;;;347;; +K43S;--;---;West Point Coast Guard Light Station;WA;United States;4;47-40N;122-26W;;;4;; +K44N;--;---;Millbrook / Sky Acres;NY;United States;4;41-42N;073-44W;;;213;; +K44W;74;696;Diamond Shoals Coast Guard Station;NC;United States;4;35-09N;075-18W;;;1;; +K44Y;--;---;Sault Ste. Marie Coast Guard Station;MI;United States;4;46-30N;084-20W;;;176;; +K45B;--;---;Brant Point Coast Guard Station;MA;United States;4;41-17N;070-05W;;;8;; +K45J;--;---;Rockingham, Rockingham-Hamlet Airport;NC;United States;4;34-53-27N;079-45-32W;;;109;; +K45N;--;---;Bay Shore / Fire Island;NY;United States;4;40-38N;073-16W;;;5;; +K45W;--;---;Oracoke Coast Guard Station;NC;United States;4;35-07N;075-59W;;;2;; +K47A;--;---;Canton, Cherokee County Airport;GA;United States;4;34-18-38N;084-25-26W;;;372;; +K48N;--;---;Montauk Point Coast Guard Light Station;NY;United States;4;41-04N;071-56W;;;1;; +K49N;--;---;East Moriches Coast Guard Station;NY;United States;4;40-47N;072-45W;;;1;; +K49Y;--;---;Preston, Fillmore County Airport;MN;United States;4;43-40-36N;092-10-47W;;;389;; +K4A9;--;---;Fort Payne, Isbell Field Airport;AL;United States;4;34-28-25N;085-43-17W;;;267;; +K4BK;--;---;Brookings;OR;United States;4;42-03N;124-17W;;;24;; +K4BL;--;---;Blanding ;UT;United States;4;37-37N;109-28W;;;1840;; +K4BQ;--;---;Broadus ;MT;United States;4;45-26N;105-24W;;;922;; +K4CB;74;618;Cuddleback Gunnery Range;CA;United States;4;35-16N;117-26W;35-16N;117-26W;864;864; +K4CR;--;---;Corona / Lincoln;NM;United States;4;34-06N;105-41W;;;1981;; +K4DG;72;568;Douglas;WY;United States;4;42-45N;105-23W;;;1477;; +K4F4;--;---;Gilmer, Fox Stephens Field - Gilmer Municipal Airport;TX;United States;4;32-41-56N;094-56-56W;;;127;; +K4HV;--;---;Hanksville ;UT;United States;4;38-22N;110-43W;;;1314;; +K4L7;--;---;Hermosa Beach Pier;CA;United States;4;33-52N;118-24W;;;8;; +K4LW;--;---;Lakeview;OR;United States;4;42-13N;120-21W;;;1455;; +K4MR;74;638;Melrose Gunnery Range;NM;United States;4;34-18N;103-48W;34-18N;103-48W;1326;1326; +K4MY;--;---;Moriarty;NM;United States;4;34-59N;106-03W;;;1890;; +K4OM;--;---;Omak;WA;United States;4;48-25N;119-32W;;;374;382;P +K4SL;--;---;Torreon;NM;United States;4;35-48N;107-11W;;;2106;; +K4SU;74;619;Superior Valley Gunnery Range;CA;United States;4;36-20N;117-06W;36-20N;117-06W;962;962; +K4SV;--;---;Strevell;ID;United States;4;42-01N;113-15W;;;1612;; +K4T6;--;---;Midlothian/Waxahachie, Mid-Way Regional Airport;TX;United States;4;32-27-21N;096-54-44W;;;217;; +K4V5;--;---;Durango Aviation Weather Reporting Station;CO;United States;4;37-17N;107-52W;;;2012;; +K50N;--;---;Rockaway Coast Guard Station;NY;United States;4;40-34N;073-53W;;;3;; +K50Q;72;495;Farallon Island;CA;United States;4;37-42N;123-00W;;;12;; +K51N;--;---;Short Beach Coast Guard Station;NY;United States;4;40-35N;073-33W;;;1;; +K51Q;--;---;San Francisco Pbs ;CA;United States;4;37-45N;122-42W;;;5;; +K52N;--;---;Wildwood;NJ;United States;4;39-00N;074-49W;;;2;; +K52Q;--;---;Davis Point Aviation Weather Reporting Station ;CA;United States;4;38-03N;122-16W;;;18;; +K53D;--;---;Glenwood;MN;United States;4;45-39N;095-23W;;;423;; +K53Q;--;---;Pillar Pt / El Granda;CA;United States;4;37-30N;122-30W;;;40;; +K53S;--;---;Point Wilson Coast Guard Light Station;WA;United States;4;48-07N;122-45W;;;1;; +K54N;--;---;Manasquan Inl Coast Guard Station;NJ;United States;4;40-06N;074-01W;;;1;; +K54Q;--;---;Castroville / Moss;CA;United States;4;36-48N;121-48W;;;5;; +K55D;--;---;Grayling, Grayling AAF Airport;MI;United States;4;44-40-49N;084-43-44W;;;353;; +K55N;--;---;Atlantic City Coast Guard Station;NJ;United States;4;39-23N;074-25W;;;4;; +K56N;--;---;Sandy Hook Coast Guard Station;NJ;United States;4;40-28N;074-01W;;;5;; +K5G9;--;---;Lambertville, Toledo Suburban Airport;MI;United States;4;41-44-09N;083-39-19W;;;204;; +K5I3;--;---;Pikeville Remote Automatic Meteorological Observing System ;KY;United States;4;37-29N;082-31W;;;446;; +K5J0;--;---;John Day, John Day State Airport;OR;United States;4;44-24-15N;118-57-45W;;;1127;; +K5L8;--;---;Long Beach ;CA;United States;4;33-46N;118-10W;;;3;; +K5R0;--;---;East Addition B323;TX;United States;4;28-13N;093-45W;;;26;; +K5R5;--;---;Wharton, Wharton Regional Airport;TX;United States;4;29-15-15N;096-09-15W;;;31;; +K5T5;--;---;Hillsboro, Hillsboro Municipal Airport;TX;United States;4;32-05-00N;097-05-50W;;;209;; +K5T6;--;---;Santa Teresa, Dona Ana County Airport at Santa Teresa;NM;United States;4;31-52-51N;106-42-17W;;;1253;; +K61N;--;---;Indian River Coast Guard Station;DE;United States;4;38-37N;075-04W;;;1;; +K61W;--;---;Annapolis Coast Guard Station;MD;United States;4;38-55N;076-28W;;;8;; +K62G;--;---;Wilmette Marines;IL;United States;4;42-04N;087-41W;;;183;; +K62H;--;---;Giddings, Giddings-Lee County Airport;TX;United States;4;30-10-09N;096-58-48W;;;148;; +K62W;--;---;Cape Henry Coast Guard Light Station;VA;United States;4;36-56N;076-00W;;;1;; +K63G;--;---;Chicago / Calumet Coast Guard Station;IL;United States;4;41-43N;087-32W;;;180;; +K63W;--;---;Milford Haven Coast Guard Station;VA;United States;4;37-29N;076-19W;;;1;; +K64W;--;---;Parramore Beach;VA;United States;4;37-32N;075-37W;;;1;; +K65W;--;---;Thomas Point Coast Guard Station;MD;United States;4;38-54N;076-26W;;;1;; +K66W;--;---;Cove Point Coast Guard Light Station;MD;United States;4;38-23N;076-23W;;;1;; +K67B;--;---;Castle Hill Coast Guard Station;RI;United States;4;41-27N;071-21W;;;15;; +K67W;--;---;Stillpond Coast Guard Station;MD;United States;4;39-20N;076-06W;;;8;; +K69R;--;---;Rocksprings, Edwards County Airport;TX;United States;4;29-56-48N;100-10-25W;;;723;; +K6A3;--;---;Andrews, Andrews-Murphy Airport;NC;United States;4;35-11-40N;083-51-53W;;;518;; +K6L9;--;---;Huntington Beach;CA;United States;4;33-39N;118-00W;;;35;; +K6R6;--;---;Dryden, Terrel County Airport;TX;United States;4;30-02-53N;102-12-47W;;;707;701; +K6R9;--;---;Llano, Llano Municipal Airport;TX;United States;4;30-47-01N;098-39-43W;;;336;; +K6V3;--;---;Richlands, Tazewell County Airport;VA;United States;4;37-03-49N;081-47-53W;;;808;; +K75S;--;---;Burlington / Mt Vern;WA;United States;4;48-28N;122-25W;;;43;; +K76S;--;---;Oak Harbor Airpark;WA;United States;4;48-15N;122-40W;;;58;; +K77M;--;---;Malta;ID;United States;4;42-19N;113-20W;;;1375;; +K77W;--;---;Cape Lookout Coast Guard Station;NC;United States;4;34-36N;076-32W;;;4;; +K78W;--;---;South Port / Oak Island Coast Guard Station;NC;United States;4;33-53N;078-01W;;;1;; +K79J;--;---;Andalusia, Andalusia-Opp Municipal Airport;AL;United States;4;31-18-00N;086-23-00W;;;94;94; +K79W;--;---;Oregon Inlet Coast Guard Station;NC;United States;4;35-46N;075-31W;;;1;; +K7A9;--;---;Plains / Peterson Field;GA;United States;4;32-05N;084-22W;;;160;; +K7B5;--;---;West Cameron 560A;LA;United States;4;28-17N;93-11W;;;0;; +K7D2;--;---;Troy, Oakland/Troy Airport;MI;United States;4;42-32-35N;083-10-40W;;;222;; +K7F6;--;---;Clarksville, Clarksville-Red River County Airport;TX;United States;4;33-35-35N;095-03-48W;;;134;; +K7F9;--;---;Comanche, Comanche County-City Airport;TX;United States;4;31-55N;098-36-01W;;;423;; +K7R1;--;---;Venice, Venice Heliport;LA;United States;4;29-15-46N;089-21-48W;29-15-45N;089-21-46W;0;3; +K7R2;--;---;Leeville;LA;United States;4;29-13N;090-14W;;;2;; +K7R3;--;---;Amelia / Lake Palourd;LA;United States;4;29-42N;091-06W;;;2;; +K7R4;--;---;Intracoastal City;LA;United States;4;29-47N;092-08W;;;5;; +K7R5;--;---;Cameron Heliport;LA;United States;4;29-47N;093-18W;;;1;; +K7R8;--;---;South Marsh Island;LA;United States;4;28-18N;091-59W;;;1;; +K82S;--;---;Cape Disappointment;WA;United States;4;46-17N;124-03W;;;55;; +K83S;--;---;Coos Bay Coast Guard Station;OR;United States;4;43-21N;124-20W;;;23;; +K84J;--;---;Folly Beach Long Range Navigation;SC;United States;4;32-41N;079-53W;;;3;; +K84Q;--;---;Blunts Reef Coast Guard Station;CA;United States;4;40-26N;124-30W;;;8;; +K84S;--;---;Grays Harbor Coast Guard Station;WA;United States;4;46-55N;124-06W;;;6;; +K85J;--;---;Georgetown Coast Guard Light Station;SC;United States;4;33-13N;079-11W;;;8;; +K85Q;--;---;Santa Cruz Harbor;CA;United States;4;36-58N;122-00W;;;1;; +K85S;--;---;Siuslaw River Coast Guard Station;OR;United States;4;44-00N;124-07W;;;12;; +K86J;--;---;Sullivans Island Coast Guard Station;SC;United States;4;32-46N;079-51W;;;3;; +K86Q;--;---;St George Reef Coast Guard Light Station;CA;United States;4;41-50N;124-24W;;;45;; +K86S;--;---;Smith Island Coast Guard Light Station;WA;United States;4;48-19N;122-51W;;;1;; +K87Q;72;390;Point Piedras Blanca;CA;United States;4;35-39-56N;121-17-05W;;;17;27;P +K87S;--;---;Quillayute River Coast Guard Light Station;WA;United States;4;47-54N;124-38W;;;1;; +K88Q;--;---;Samoa / Humboldt Bay;CA;United States;4;40-46N;124-14W;;;2;; +K88S;--;---;Tillamook Bay Coast Guard Station;OR;United States;4;45-34N;123-55W;;;15;; +K89Q;--;---;Point Arena Coast Guard Light Station;CA;United States;4;38-57N;123-44W;;;18;; +K8B9;--;---;Egg Rock Light Station;ME;United States;4;44-21N;068-08W;;;12;; +K8D3;--;---;Sisseton, Sisseton Municipal Airport;SD;United States;4;45-40-08N;096-59-29W;45-40-04N;096-59-52W;354;354; +K8F7;--;---;Decatur, Decatur Municipal Airport;TX;United States;4;33-15-16N;097-34-50W;;;319;; +K8R0;--;---;Pascagoula Coast Guard Station;MS;United States;4;30-22N;088-34W;;;8;; +K8R1;--;---;Mobile Point Coast Guard Station;AL;United States;4;30-14N;088-02W;;;1;; +K8R3;--;---;Southwest Pass Coast Guard Station;LA;United States;4;28-55N;089-26W;;;1;; +K8R5;--;---;Grand Isle Coast Guard Station;LA;United States;4;29-16N;089-57W;;;2;; +K8R6;--;---;Calcasieu Coast Guard Station;LA;United States;4;29-47N;093-21W;;;1;; +K8R7;--;---;Sabine Pass Coast Guard Station;TX;United States;4;29-44N;093-52W;;;1;; +K8R8;--;---;Freeport Coast Guard Station;TX;United States;4;28-57N;095-18W;;;2;; +K8S0;--;---;Browning, Starr-Browning Airstrip;MT;United States;4;48-36-04N;113-06-53W;;;1419;; +K8Y2;--;---;Buffalo, Buffalo Municipal Airport;MN;United States;4;45-09-32N;093-50-35W;;;295;; +K8Y8;--;---;Crane Lake Automatic Weather Observing / Reporting System;MN;United States;4;46-16N;092-34W;;;350;; +K90S;--;---;Umpqua River Coast Guard Station;OR;United States;4;43-41N;124-10W;;;41;; +K91Q;--;---;Point Blunt Coast Guard Light Station;CA;United States;4;37-51N;122-25W;;;73;; +K91S;--;---;Alki Point Coast Guard Light Station;WA;United States;4;47-31N;122-25W;;;1;; +K92Q;--;---;Bodega Bay Coast Guard Light Station;CA;United States;4;38-19N;123-03W;;;3;; +K92S;--;---;Cape Blanco Coast Guard Station;OR;United States;4;42-50N;124-34W;;;57;; +K93Q;--;---;Pigeon Point Coast Guard Light Station;CA;United States;4;37-11N;122-24W;;;1;; +K93S;--;---;Cape Flattery Coast Guard Light Station;WA;United States;4;48-23N;124-44W;;;26;; +K94B;--;---;Wood Island Light Station;ME;United States;4;43-27N;070-19W;;;9;; +K94Q;--;---;Point Bonita Coast Guard Light Station;CA;United States;4;37-48N;122-31W;;;1;; +K95B;--;---;Cape Vincent Marine Aviation Reporting Station;NY;United States;4;44-07N;076-20W;;;75;; +K95Q;--;---;Point Pinos Coast Guard Light Station;CA;United States;4;36-38N;121-56W;;;6;; +K95S;--;---;Yaquina Bay Coast Guard Station;OR;United States;4;44-37N;124-03W;;;1;; +K96B;--;---;Owl's Head Light Station;ME;United States;4;44-05N;069-02W;;;15;; +K96Q;--;---;Trinidad Head Coast Guard Light Station;CA;United States;4;41-03N;124-09W;;;58;; +K96S;--;---;New Dungeness Coast Guard Station;WA;United States;4;48-10N;123-06W;;;12;; +K97Q;--;---;Point Reyes Coast Guard Station;CA;United States;4;38-00N;123-01W;;;87;; +K97S;--;---;Point No Point Coast Guard Station;WA;United States;4;47-55N;122-32W;;;1;; +K98Q;--;---;Rio Vista Coast Guard Light Station;CA;United States;4;38-09N;121-42W;;;1;; +K99M;--;---;Moorhead, Moorhead Municipal Airport;MN;United States;4;46-50-21N;096-39-47W;;;280;; +K99Q;--;---;Port Chicago;CA;United States;4;38-02N;122-02W;;;12;; +K99S;--;---;Point Robinson Coast Guard Light Station;WA;United States;4;47-23N;122-22W;;;0;; +K9B2;72;612;Newport;VT;United States;4;44-56N;072-12W;;;233;233; +K9B5;--;---;Bear Island Coast Guard Station;ME;United States;4;44-17N;068-16W;;;12;; +K9BB;--;---;Wells;NV;United States;4;41-07N;114-58W;;;1722;; +K9F2;--;---;Fourchon Supplementary Aviation Weather Reporting Station;LA;United States;4;29-06N;090-12W;;;2;; +K9L0;--;---;Dana Point;CA;United States;4;33-27N;117-41W;;;15;; +K9R0;--;---;Galveston Coast Guard Station;TX;United States;4;29-20N;094-46W;;;1;; +K9R1;--;---;Port Aransas Coast Guard Station;TX;United States;4;27-50N;097-04W;;;1;; +K9V9;72;653;Chamberlain, Chamberlain Municipal Airport;SD;United States;4;43-46-00N;099-19-06W;43-46-00N;099-19-06W;516;519; +K9W7;--;---;Currituck, Currituck County Airport;NC;United States;4;36-23-56N;076-00-58W;;;5;; +KA21;--;---;Portage Glacier, Portage Visitor Center;AK;United States;4;60-47-03N;148-50-46W;60-47-59N;148-50-20W;31;28; +KAAA;--;---;Lincoln, Logan County Airport;IL;United States;4;40-09-31N;089-20-06W;;;182;; +KAAF;72;220;Apalachicola, Apalachicola;FL;United States;4;29-43-37N;085-01-29W;29-43-20N;085-01-32W;6;5;P +KAAO;--;---;Wichita, Colonel James Jabara Airport;KS;United States;4;37-44-59N;097-13-08W;37-44-52N;097-13-28W;432;434; +KAAT;--;---;Alturas;CA;United States;4;41-29-29N;120-33-52W;41-28-59N;120-33-51W;1333;1331; +KABE;72;517;Allentown, Lehigh Valley International Airport;PA;United States;4;40-39-03N;075-26-57W;40-39-12N;075-25-59W;120;114; +KABI;72;266;Abilene, Abilene Regional Airport;TX;United States;4;32-24-37N;099-40-54W;32-24-45N;099-40-52W;545;548;P +KABQ;72;365;Albuquerque, Albuquerque International Airport;NM;United States;4;35-02-30N;106-36-53W;35-02-13N;106-37-18W;1631;1618;P +KABR;72;659;Aberdeen, Aberdeen Regional Airport;SD;United States;4;45-26-36N;098-24-47W;45-27-25N;098-25-36W;396;400;P +KABX;--;---;Albuquerque Nexrad;NM;United States;4;35-09N;106-49W;;;1814;; +KABY;72;216;Albany, Southwest Georgia Regional Airport;GA;United States;4;31-32-08N;084-11-40W;31-32-12N;084-14-3W;60;58; +KACB;--;---;Bellaire, Antrim County Airport;MI;United States;4;44-59-18N;085-11-54W;;;190;; +KACK;--;---;Nantucket, Nantucket Memorial Airport;MA;United States;4;41-15-14N;070-03-35W;41-15-26N;070-03-49W;14;16; +KACQ;--;---;Waseca, Waseca Municipal Airport;MN;United States;4;44-04-24N;093-33-11W;;;343;; +KACT;72;256;Waco, Waco Regional Airport;TX;United States;4;31-37-02N;097-13-40W;31-36-33N;097-13-18W;157;151;P +KACV;--;---;Arcata / Eureka, Arcata Airport;CA;United States;4;40-58-41N;124-06-31W;40-58-14N;124-06-25W;66;67; +KACY;72;407;Atlantic City, Atlantic City International Airport;NJ;United States;4;39-27-53N;074-35-12W;39-26-58N;074-34-02W;23;35;P +KADC;--;---;Wadena, Wadena Municipal Airport;MN;United States;4;46-27-01N;095-12-39W;;;417;; +KADG;--;---;Adrian, Lenawee County Airport;MI;United States;4;41-52-04N;084-04-46W;41-52-24N;084-04-28W;244;241; +KADH;--;---;Ada, Ada Municipal Airport;OK;United States;4;34-48-16N;096-40-17W;;;310;; +KADM;--;---;Ardmore Municipal;OK;United States;4;34-18N;097-01W;;;232;; +KADQ;--;---;Kodiak, Kodiak Airport;AK;United States;4;57-45-04N;152-29-08W;57-44-52N;152-29-29W;22;33; +KADS;--;---;Dallas / Addison Airport;TX;United States;4;32-58N;096-50W;;;196;; +KADU;--;---;Audubon, Audubon County Airport;IA;United States;4;41-42-04N;094-55-13W;;;392;; +KADW;74;594;Camp Springs / Andrews Air Force Base;MD;United States;4;38-49N;076-51W;;;86;88;P +KAEG;--;---;Albuquerque, Double Eagle II Airport;NM;United States;4;35-08-42N;106-47-42W;;;1779;; +KAEL;--;---;Albert Lea Automatic Weather Observing / Reporting System ;MN;United States;4;43-41N;093-22W;;;383;; +KAEX;74;754;Alexandria, Alexandria International Airport;LA;United States;4;31-20-05N;092-33-31W;31-19-26N;092-32-37W;27;27; +KAFF;74;531;Air Force Academy;CO;United States;4;38-58N;104-49W;38-58N;104-49W;2003;1999; +KAFJ;--;---;Washington Automatic Weather Observing / Reporting System ;PA;United States;4;40-08N;080-17W;;;361;; +KAFK;--;---;Nebraska City, Nebraska City Municipal Airport;NE;United States;4;40-36N;095-51W;;;354;; +KAFN;--;---;Jaffrey, Jaffrey Municipal-Silver Ranch Airport;NH;United States;4;42-48-21N;072-00-02W;42-48-23N;072-00-10W;317;313; +KAFW;--;---;Fort Worth, Fort Worth Alliance Airport;TX;United States;4;32-58-24N;097-19-05W;32-59-17N;097-18-39W;220;233; +KAGC;--;---;Pittsburgh, Allegheny County Airport;PA;United States;4;40-21-17N;079-55-18W;40-20-44N;079-55-37W;382;389; +KAGR;74;796;Avon Park Gunnery Range;FL;United States;4;27-39N;081-20W;27-39N;081-20W;20;20; +KAGS;72;218;Augusta, Bush Field;GA;United States;4;33-21-52N;081-57-48W;33-22-18N;081-58-27W;44;44;P +KAHN;72;311;Athens, Athens Airport;GA;United States;4;33-57-03N;083-19-41W;33-57-05N;083-19-25W;246;244;P +KAIA;--;---;Alliance, Alliance Municipal Airport;NE;United States;4;42-03-26N;102-48-00W;42-03-51N;102-48-57W;1197;1196; +KAID;--;---;Anderson Municipal;IN;United States;4;40-07N;085-37W;;;280;; +KAIG;--;---;Antigo - Lang Automatic Weather Observing / Reporting System ;WI;United States;4;45-09N;087-09W;;;;; +KAIO;--;---;Atlantic;IA;United States;4;41-24N;095-03W;;;360;; +KAIT;--;---;Aitkin NDB Automatic Weather Observing / Reporting System ;MN;United States;4;46-33N;093-41W;;;367;; +KAIZ;--;---;Kaiser Memorial Automatic Weather Observing / Reporting System ;MO;United States;4;38-06N;092-33W;;;265;; +KAJG;--;---;Mount Carmel, Mount Carmel Municipal Airport;IL;United States;4;38-36-23N;087-43-36W;;;131;; +KAKH;--;---;Gastonia, Gastonia Municipal Airport;NC;United States;4;35-11-48N;081-09-21W;35-12-01N;081-09-12W;243;243; +KAKO;--;---;Akron, Akron-Washington County Airport;CO;United States;4;40-10-28N;103-12-52W;40-10-15N;103-12-31W;1431;1421; +KAKQ;--;---;Wakefield, Wakefield Municipal Airport;VA;United States;4;36-58-53N;077-00-04W;36-58-48N;077-00-08W;34;33; +KAKR;--;---;Akron, Akron Fulton International Airport;OH;United States;4;41-02-15N;081-27-51W;41-02-17N;081-27-26W;325;363; +KAKW;--;---;Klawock, Klawock Airport;AK;United States;4;55-34-34N;133-04-34W;55-34-49N;133-04-08W;15;18; +KALB;72;518;Albany, Albany County Airport;NY;United States;4;42-44-48N;073-47-56W;42-44-43N;073-48-31W;86;92;P +KALI;--;---;Alice, Alice International Airport;TX;United States;4;27-44-28N;098-01-37W;27-44-31N;098-01-59W;54;53; +KALM;--;---;Alamogordo-White;NM;United States;4;32-50N;105-59W;;;1279;; +KALN;--;---;Alton/St. Louis, St. Louis Regional Airport;IL;United States;4;38-54N;090-03W;;;166;; +KALO;72;548;Waterloo, Waterloo Municipal Airport;IA;United States;4;42-33-16N;092-24-04W;42-33-00N;092-23-52W;266;264; +KALS;72;462;Alamosa, San Luis Valley Regional Airport;CO;United States;4;37-26-20N;105-51-41W;37-26-36N;105-51-52W;2297;2299;P +KALW;--;---;Walla Walla, Walla Walla Regional Airport;WA;United States;4;46-05-42N;118-17-03W;46-05-35N;118-16-55W;367;363; +KALX;--;---;Alexander City, Thomas C Russell Field Airport;AL;United States;4;32-54-53N;085-57-46W;;;209;; +KAMA;72;363;Amarillo, Amarillo International Airport;TX;United States;4;35-13-12N;101-43-02W;35-13-58N;101-42-28W;1099;1093;P +KAMG;--;---;Alma, Bacon County Airport;GA;United States;4;31-32-10N;082-30-24W;31-32-27N;082-30-30W;61;59; +KAMN;--;---;Alma, Gratiot Community Airport;MI;United States;4;43-19-19N;084-41-16W;;;229;; +KAMW;--;---;Ames, Ames Municipal Airport;IA;United States;4;41-59-26N;093-37-08W;41-59-57N;093-37-22W;288;279; +KAMX;--;---;Miami Nexrad;FL;United States;4;25-37N;080-25W;;;34;; +KANB;--;---;Anniston, Anniston Metropolitan Airport;AL;United States;4;33-35-26N;085-50-51W;33-35-25N;085-51-04W;186;183; +KAND;--;---;Anderson, Anderson County Airport;SC;United States;4;34-29-52N;082-42-35W;34-30-04N;082-42-54W;238;239; +KANE;--;---;Minneapolis / Blaine;MN;United States;4;45-09N;093-13W;;;278;; +KANJ;72;734;Sault Ste. Marie;MI;United States;4;46-28-46N;084-21-26W;46-28-45N;084-21-24W;210;219;P +KANN;--;---;Annette, Annette Island Airport;AK;United States;4;55-01-49N;131-34-34W;55-01-44N;131-34-38W;36;34; +KANW;--;---;Ainsworth Municipal;NE;United States;4;42-35N;100-00W;;;789;; +KAOH;--;---;Lima, Lima Allen County Airport;OH;United States;4;40-42-29N;084-01-17W;40-42-17N;084-01-36W;297;296; +KAOO;--;---;Altoona, Altoona-Blair County Airport;PA;United States;4;40-18-00N;078-19-01W;40-17-37N;078-19-20W;458;455; +KAPA;--;---;Denver, Centennial Airport;CO;United States;4;39-33-50N;104-50-54W;39-34-30N;104-50-42W;1793;1775; +KAPC;--;---;Napa, Napa County Airport;CA;United States;4;38-12-27N;122-16-46W;38-12-28N;122-16-41W;10;13; +KAPF;--;---;Naples, Naples Municipal Airport;FL;United States;4;26-09N;081-46W;;;2;; +KAPG;--;---;Phillips Army Air Field / Aberdeen;MD;United States;4;39-28N;076-10W;;;18;; +KAPN;72;639;Alpena, Alpena County Regional Airport;MI;United States;4;45-04-18N;083-33-52W;45-04-12N;083-33-59W;210;210; +KAPV;--;---;Apple Valley;CA;United States;4;34-35N;117-11W;;;932;; +KAQO;--;---;Llano, Llano Municipal Airport;TX;United States;4;30-47-01N;098-39-43W;;;336;; +KAQP;--;---;Appleton, Appleton Municipal Airport;MN;United States;4;45-13-39N;096-00-15W;;;310;; +KAQQ;72;220;Apalachicola, Apalachicola;FL;United States;4;29-43-37N;085-01-29W;29-43-20N;085-01-32W;6;5;P +KAQR;--;---;Atoka, Atoka Municipal Airport;FL;United States;4;34-23-54N;096-08-53W;;;180;; +KAQW;--;---;North Adams, Harriman-And-West Airport;MA;United States;4;42-41-50N;073-10-13W;42-41-50N;073-09-51W;199;201; +KARA;--;---;New Iberia, Acadiana Regional Airport;LA;United States;4;30-01-44N;091-53-04W;30-01-47N;091-52-35W;7;18; +KARB;--;---;Ann Arbor, Ann Arbor Municipal Airport;MI;United States;4;42-13-26N;083-44-24W;42-13-31N;083-44-47W;255;251; +KARG;--;---;Walnut Ridge Automatic Weather Observing / Reporting System ;AR;United States;4;36-08N;090-55W;;;83;; +KARL;--;---;Arlington;WY;United States;4;41-42N;106-13W;;;2179;; +KARR;--;---;Aurora, Aurora Municipal Airport;IL;United States;4;41-46-12N;088-28-53W;41-46-05N;088-27-57W;215;215; +KART;--;---;Watertown, Watertown International Airport;NY;United States;4;43-59-31N;076-01-18W;43-59-38N;076-01-25W;99;100; +KARV;--;---;Minocqua / Woodruff;WI;United States;4;45-56N;089-44W;;;496;; +KASD;--;---;Slidell, Slidell Airport;LA;United States;4;30-20-35N;089-49-19W;30-20-25N;089-49-20W;9;8; +KASE;--;---;Aspen, Aspen-Pitkin County Airport;CO;United States;4;39-13-44N;106-52-10W;39-13-33N;106-52-04W;2382;2354; +KASG;--;---;Springdale Municipal;AR;United States;4;36-11N;094-07W;;;412;; +KASH;--;---;Nashua / Boire Field;NH;United States;4;42-47N;071-31W;;;61;; +KASJ;--;---;Ahoskie, Tri-County Airport;NC;United States;4;36-17-51N;077-10-15W;;;21;; +KAST;72;791;Astoria, Astoria Regional Airport;OR;United States;4;46-09-25N;123-52-57W;46-09-22N;123-52-51W;3;3; +KASW;--;---;Warsaw, Warsaw Municipal Airport;IN;United States;4;41-16-28N;085-50-24W;;;259;; +KASX;--;---;Ashland, Kennedy Memorial Airport;WI;United States;4;46-32-59N;090-55-06W;46-33-09N;090-54-57W;251;251; +KATL;72;219;Atlanta, Hartsfield Atlanta International Airport;GA;United States;4;33-37-47N;084-26-32W;33-38-24N;084-25-17W;312;296;P +KATS;--;---;Artesia, Artesia Municipal Airport;NM;United States;4;32-51-09N;104-28-03W;;;1079;; +KATT;72;254;Austin City, Austin Camp Mabry;TX;United States;4;30-19N;097-46W;;;200;;P +KATW;--;---;Appleton / Outagamie;WI;United States;4;44-15N;088-31W;;;280;; +KATX;--;---;Seattle NEXRAD;WA;United States;4;48-12N;122-30W;;;185;; +KATY;--;---;Watertown, Watertown Municipal Airport;SD;United States;4;44-54-17N;097-08-58W;44-55-17N;097-09-38W;532;532; +KAUB;--;---;Auburn University Automatic Meteorological Observing System;AL;United States;4;32-36N;085-30W;;;198;; +KAUD;--;---;Audubon Park;LA;United States;4;29-56N;090-08W;;;2;; +KAUG;--;---;Augusta, Augusta State Airport;ME;United States;4;44-19-14N;069-47-50W;44-19-03N;069-47-39W;107;109; +KAUH;--;---;Aurora, Aurora Municipal Airport;NE;United States;4;40-53-38N;097-59-40W;;;550;; +KAUM;--;---;Austin Municipal;MN;United States;4;43-40N;092-56W;;;375;; +KAUN;--;---;Auburn, Auburn Municipal Airport;CA;United States;4;38-57N;121-04W;;;467;; +KAUO;--;---;Auburn-Opelika Airport;AL;United States;4;32-37N;085-26W;;;236;; +KAUS;--;---;Austin, Austin-Bergstrom International Airport;TX;United States;4;30-11-40N;097-40-12W;30-11-57N;097-40-13W;165;172; +KAUW;--;---;Wausau, Wausau Downtown Airport;WI;United States;4;44-55-43N;089-37-36W;44-55-46N;089-37-39W;366;362; +KAVC;--;---;South Hill, Mecklenburg-Brunswick Regional Airport;VA;United States;4;36-41-19N;078-03-15W;;;135;; +KAVK;--;---;Alva, Alva Regional Airport;OK;United States;4;36-46-23N;098-40-12W;;;449;; +KAVL;72;315;Asheville, Asheville Regional Airport;NC;United States;4;35-25-55N;082-32-15W;35-26-04N;082-32-14W;660;670; +KAVP;72;513;Wilkes-Barre - Scranton, Wilkes-Barre / Scranton International Airport;PA;United States;4;41-20-20N;075-43-36W;41-20-10N;075-43-50W;293;291; +KAVX;72;292;Avalon, Catalina Airport;CA;United States;4;33-24-18N;118-24-57W;33-24-12N;118-24-48W;488;482; +KAWG;--;---;Washington;IA;United States;4;41-17N;091-40W;;;230;; +KAWH;--;---;Wildhorse Reservation / Elko;NV;United States;4;41-40N;115-47W;;;1902;; +KAWI;--;---;Wainwright, Wainwright Airport;AK;United States;4;70-38-19N;160-00-24W;70-38-19N;160-00-24W;9;8; +KAWM;--;---;West Memphis, West Memphis Municipal Airport;AR;United States;4;35-08N;090-14W;;;65;; +KAWO;--;---;Arlington Municipal;WA;United States;4;48-10N;122-10W;;;42;; +KAXA;--;---;Algona;IA;United States;4;43-05N;094-16W;;;372;; +KAXN;--;---;Alexandria, Chandler Field;MN;United States;4;45-52-07N;095-23-39W;45-51-55N;095-23-23W;434;433; +KAXO;--;---;Grand Isle Supplementary Aviation Weather Reporting Station;LA;United States;4;29-15N;089-58W;;;2;; +KAYE;--;---;Fort Devens / Ayer;MA;United States;4;42-34N;071-36W;;;82;; +KAYS;72;213;Waycross / Ware County, Ga;GA;United States;4;31-15N;082-24W;31-15N;082-24W;46;46;P +KAZC;--;---;Colorado City, Colorado City Municipal Airport;AZ;United States;4;36-57N;113-00W;;;1486;; +KAZO;--;---;Kalamazoo, Kalamazoo / Battle Creek International Airport;MI;United States;4;42-13-45N;085-32-47W;42-14-22N;085-33-22W;266;272; +KB23;--;---;Battle Mountain;NV;United States;4;40-36N;116-52W;;;1381;; +KBAB;--;---;Marysville, Beale Air Force Base;CA;United States;4;39-08N;121-26W;;;34;; +KBAD;--;---;Barksdale Air Force Base;LA;United States;4;32-30N;093-40W;;;51;; +KBAF;--;---;Westfield, Barnes Municipal Airport;MA;United States;4;42-09-35N;072-42-46W;42-09-25N;072-43-06W;82;83; +KBAK;--;---;Columbus / Bakalar ;IN;United States;4;39-16N;085-54W;;;200;; +KBAX;--;---;Bad Axe, Huron County Memorial Airport;MI;United States;4;43-46-51N;082-59-08W;;;233;; +KBAZ;--;---;New Braunfels, New Braunfels Municipal Airport;TX;United States;4;29-42-31N;098-02-43W;29-42-20N;098-02-08W;197;195; +KBBB;--;---;Benson Municipal;MN;United States;4;45-19N;095-39W;;;317;; +KBBW;--;---;Broken Bow, Broken Bow Municipal Airport;NE;United States;4;41-26N;099-39W;;;776;; +KBCB;--;---;Virginia Tech Airport;VA;United States;4;37-13N;080-25W;;;650;; +KBCE;--;---;Bryce Canyon, Bryce Canyon Airport;UT;United States;4;37-42-23N;112-08-44W;37-42-05N;112-09-16W;2312;2312; +KBCG;--;---;Butte La Rose;LA;United States;4;30-07N;091-33W;;;10;; +KBCT;--;---;Boca Raton, Boca Raton Airport;FL;United States;4;26-22-43N;080-06-28W;;;4;; +KBDE;--;---;Baudette, Baudette International Airport;MN;United States;4;48-43-36N;094-36-44W;48-43-17N;094-36-10W;330;329; +KBDF;--;---;Bradford / Rinkenberg;IL;United States;4;41-14N;089-37W;;;247;; +KBDL;72;508;Windsor Locks, Bradley International Airport;CT;United States;4;41-56-17N;072-40-57W;41-55-59N;072-41-12W;53;60; +KBDR;72;504;Bridgeport, Sikorsky Memorial Airport;CT;United States;4;41-09-30N;073-07-44W;41-09-50N;073-07-40W;3;7; +KBED;74;490;Bedford, Hanscom Field;MA;United States;4;42-28-06N;071-17-40W;42-27-57N;071-17-22W;40;50; +KBEH;--;---;Benton Harbor, Southwest Michigan Regional Airport;MI;United States;4;42-07-43N;086-25-42W;42-07-32N;086-25-44W;196;191; +KBET;--;---;Bethel, Bethel Airport;AK;United States;4;60-47-09N;161-49-35W;60-47-03N;161-50-08W;39;39; +KBFD;--;---;Bradford, Bradford Regional Airport;PA;United States;4;41-47-55N;078-38-09W;41-47-57N;078-38-24W;653;647; +KBFF;72;566;Scottsbluff, Heilig Field;NE;United States;4;41-52-01N;103-35-09W;41-52-12N;103-35-36W;1208;1203; +KBFI;--;---;Seattle, Seattle Boeing Field;WA;United States;4;47-32-45N;122-18-49W;47-31-45N;122-18-11W;5;4; +KBFL;72;384;Bakersfield, Meadows Field Airport;CA;United States;4;35-26-01N;119-03-24W;35-26-02N;119-03-06W;155;151; +KBFM;--;---;Mobile, Mobile Downtown Airport;AL;United States;4;30-36-50N;088-03-48W;30-37-37N;088-04-05W;7;20; +KBFU;--;---;Belle Fourche;WY;United States;4;43-56N;105-27W;;;1422;; +KBFW;--;---;Silver Bay;MN;United States;4;47-12N;091-24W;;;331;; +KBGD;--;---;Borger, Hutchinson County Airport;TX;United States;4;35-41-42N;101-23-42W;35-41-43N;101-23-40W;931;927; +KBGE;--;---;Bainbridge, Decatur County Industrial Air Park Airport;GA;United States;4;30-58N;084-38W;;;43;; +KBGM;72;515;Binghamton, Binghamton Regional Airport;NY;United States;4;42-12-28N;075-58-53W;42-12-32N;075-58-58W;496;492;P +KBGR;--;---;Bangor, Bangor International Airport;ME;United States;4;44-47-50N;068-49-07W;44-48-43N;068-49-31W;58;57; +KBHB;--;---;Bar Harbor Automatic Weather Observing / Reporting System;ME;United States;4;44-27N;068-22W;;;26;; +KBHK;--;---;Baker, Baker Municipal Airport;MT;United States;4;46-20-52N;104-15-27W;46-21-22N;104-16-12W;905;902; +KBHM;72;228;Birmingham, Birmingham International Airport;AL;United States;4;33-33-56N;086-44-42W;33-33-48N;086-44-42W;196;197;P +KBHX;--;---;Eureka NEXRAD;CA;United States;4;40-30N;124-18W;;;767;; +KBID;--;---;Block Island, Block Island State Airport;RI;United States;4;41-10N;071-34W;;;33;; +KBIE;--;---;Beatrice Municipal;NE;United States;4;40-18N;096-45W;;;403;; +KBIF;--;---;Biggs Army Air Field / Ft. Bliss;TX;United States;4;31-51N;106-23W;;;1204;; +KBIG;--;---;Delta Junction / Ft. Greely, Allen Army Air Field;AK;United States;4;63-59-37N;145-41-33W;63-59-20N;145-43-05W;389;387; +KBIH;72;480;Bishop, Bishop Airport;CA;United States;4;37-22-16N;118-21-29W;37-22-15N;118-21-59W;1256;1253; +KBIL;72;677;Billings, Billings Logan International Airport;MT;United States;4;45-48-25N;108-32-32W;45-48-15N;108-32-09W;1112;1091;P +KBIS;72;764;Bismarck, Bismarck Municipal Airport;ND;United States;4;46-46-57N;100-45-26W;46-46-20N;100-45-26W;511;503;P +KBIT;--;---;Bittercreek;WY;United States;4;41-39N;108-35W;;;2160;; +KBIV;--;---;Holland, Tulip City Airport;MI;United States;4;42-44-46N;086-05-48W;42-44-38N;086-06-56W;209;208; +KBIX;--;---;Keesler Air Force Base / Biloxi;MS;United States;4;30-25N;088-55W;;;10;; +KBJC;--;---;Broomfield / Jeffco;CO;United States;4;39-55N;105-07W;;;1724;; +KBJI;72;755;Bemidji;MN;United States;4;47-30N;094-56W;;;423;420;P +KBJJ;--;---;Wooster, Wayne County Airport;OH;United States;4;40-52-23N;081-53-12W;40-52-27N;081-52-54W;346;343; +KBKE;--;---;Baker City, Baker City Municipal Airport;OR;United States;4;44-50-14N;117-48-33W;45-50-27N;117-48-25W;1028;1024; +KBKF;--;---;Aurora, Buckley Air Force Base Airport;CO;United States;4;39-42-36N;104-45-29W;;;1726;; +KBKL;--;---;Cleveland, Burke Lakefront Airport;OH;United States;4;41-31-32N;081-40-08W;41-30-44N;081-41-21W;178;184; +KBKS;--;---;Falfurrias, Brooks County Airport;TX;United States;4;27-12-24N;098-07-16W;;;34;; +KBKT;--;---;Ft. Pickett / Blackstone;VA;United States;4;37-05N;077-57W;;;130;; +KBKV;--;---;Brooksville, Hernando County Airport;FL;United States;4;28-28-25N;082-27-16W;28-28-23N;082-27-09W;23;20; +KBKW;72;412;Beckley, Raleigh County Memorial Airport;WV;United States;4;37-47-42N;081-07-29W;37-47-00N;081-07-16W;763;764; +KBKX;--;---;Brookings Automatic Weather Observing / Reporting System;SD;United States;4;44-18N;096-49W;;;502;; +KBLF;--;---;Bluefield, Mercer County Airport;WV;United States;4;37-17-45N;081-12-28W;37-17-32N;081-12-33W;871;873; +KBLH;--;---;Blythe, Blythe Airport;CA;United States;4;33-37-09N;114-43-01W;33-36-48N;114-42-48W;121;119; +KBLI;--;---;Bellingham, Bellingham International Airport;WA;United States;4;48-47-58N;122-32-21W;48-47-56N;122-32-05W;48;50; +KBLM;--;---;Belmar-Farmingdale;NJ;United States;4;40-11N;074-08W;;;48;; +KBLU;--;---;Emigrant Gap, Blue Canyon Nyack Airport;CA;United States;4;39-16-34N;120-42-29W;39-16-32N;120-42-29W;1610;1609; +KBLV;--;---;Belleville, Scott AFB/MidAmerica Airport;IL;United States;4;38-33N;089-51W;;;140;; +KBLX;--;---;Billing Yell Nexrad;MT;United States;4;45-51-14N;108-36-22W;;;1116;; +KBMG;--;---;Bloomington, Monroe County Airport;IN;United States;4;39-08-35N;086-37-00W;39-08-51N;086-36-44W;257;257; +KBMI;--;---;Bloomington / Normal;IL;United States;4;40-29N;088-55W;;;267;; +KBML;72;616;Berlin, Berlin Municipal Airport;NH;United States;4;44-34-34N;071-10-43W;44-34-41N;071-10-49W;353;345; +KBMQ;--;---;Burnet, Burnet Municipal Craddock Field;TX;United States;4;30-44-26N;098-14-07W;30-44-27N;098-14-10W;392;389; +KBMX;--;---;Birmingham Nexrad;AL;United States;4;33-10N;086-45W;;;231;; +KBNA;72;327;Nashville, Nashville International Airport;TN;United States;4;36-07-08N;086-41-21W;36-06-59N;086-40-31W;182;210;P +KBNO;72;683;Burns, Burns Municipal Airport;OR;United States;4;43-35-42N;118-57-23W;43-35-12N;118-57-12W;1263;1264;P +KBNW;--;---;Boone Municipal;IA;United States;4;42-03N;093-51W;;;354;; +KBNY;--;---;Burney;CA;United States;4;40-53N;121-40W;;;957;; +KBOI;72;681;Boise, Boise Air Terminal;ID;United States;4;43-34-00N;116-14-26W;43-34-03N;116-12-40W;871;875;P +KBOS;72;509;Boston, Logan International Airport;MA;United States;4;42-21-38N;071-00-38W;42-21-51N;071-01-09W;6;54;P +KBOW;--;---;Bartow Municipal;FL;United States;4;27-57N;081-47W;;;39;; +KBOX;--;---;Boston Nexrad;MA;United States;4;41-57N;071-08W;;;71;; +KBPG;--;---;Big Spring, Big Spring McMahon-Wrinkle Airport;TX;United States;4;32-12N;101-31W;;;784;; +KBPI;72;671;Big Piney, Big Piney-Marbleton Airport;WY;United States;4;42-34-44N;110-06-11W;42-34-41N;110-06-14W;2126;2117; +KBPK;--;---;Mountain Home, Baxter County Regional Airport;AR;United States;4;36-22-14N;092-28-19W;36-22-17N;092-27-42W;282;280; +KBPP;--;---;Bowman, Bowman Municipal Airport;ND;United States;4;46-11-13N;103-25-41W;;;902;; +KBPT;72;241;Beaumont / Port Arthur, Southeast Texas Regional Airport;TX;United States;4;29-57-03N;094-01-15W;29-57-27N;094-01-21W;5;5; +KBQK;--;---;Brunswick / Glynco;GA;United States;4;31-15N;081-28W;;;8;; +KBRD;--;---;Brainerd, Brainerd-Crow Wing County Regional Airport;MN;United States;4;46-24-17N;094-07-51W;46-23-33N;094-08-24W;373;372; +KBRL;--;---;Burlington, Burlington Regional Airport;IA;United States;4;40-46-22N;091-07-31W;40-46-55N;091-07-11W;212;211; +KBRO;72;250;Brownsville, Brownsville / South Padre Island International Airport;TX;United States;4;25-54-51N;097-25-23W;25-54-22N;097-25-54W;7;5;P +KBRX;--;---;Bordeaux;WY;United States;4;41-56N;104-57W;;;1422 +KBTL;--;---;Battle Creek, Kellogg Airport;MI;United States;4;42-18-45N;085-14-27W;42-18-49N;085-14-19W;290;290; +KBTM;--;---;Butte, Bert Mooney Airport;MT;United States;4;45-57-17N;112-29-51W;45-57-15N;112-30-05W;1690;1688; +KBTP;--;---;Butler County Automatic Weather Observing / Reporting System;PA;United States;4;40-47N;079-57W;;;380;; +KBTR;--;---;Baton Rouge, Baton Rouge Metropolitan, Ryan Field;LA;United States;4;30-32-14N;091-08-49W;30-31-50N;091-08-36W;21;21; +KBTT;--;---;Bettles, Bettles Airport;AK;United States;4;66-54-58N;151-30-32W;66-54-58N;151-30-33W;196;197; +KBTV;72;617;Burlington, Burlington International Airport;VT;United States;4;44-28-05N;073-09-01W;44-28-08N;073-09-18W;101;105;P +KBUF;72;528;Buffalo, Greater Buffalo International Airport;NY;United States;4;42-56-27N;078-44-09W;42-56-21N;078-43-10W;220;225;P +KBUO;--;---;Beaumont;CA;United States;4;33-56N;116-58W;;;692;; +KBUR;72;288;Burbank, Burbank-Glendale-Pasadena Airport;CA;United States;4;34-11-59N;118-21-53W;34-11-58N;118-21-11W;236;217; +KBUU;--;---;Burlington, Burlington Municipal Airport;WI;United States;4;42-41-26N;088-18-17W;;;237;; +KBUY;--;---;Burlington, Burlington Alamance Regional Airport;NC;United States;4;36-02-52N;079-28-26W;36-03-00N;079-28-46W;188;180; +KBVE;72;232;Boothville;LA;United States;4;29-20N;089-24W;29-20N;089-24W;0;1; +KBVI;--;---;Beaver Falls Airport;PA;United States;4;40-46N;080-24W;;;382;; +KBVN;--;---;Albion, Albion Municipal Airport;NE;United States;4;41-43-43N;098-03-21W;;;551;; +KBVO;--;---;Bartlesville, Bartlesville Municipal Airport;OK;United States;4;36-46-06N;096-01-34W;36-45-32N;096-00-26W;217;210; +KBVR;--;---;Beaver Rim;WY;United States;4;42-35N;108-17W;;;2072;; +KBVS;--;---;Burlington/Mount Vernon, Skagit Regional Airport;WA;United States;4;48-28-15N;122-25-15W;;;44;; +KBVX;--;---;Batesville Automatic Weather Observing / Reporting System;AR;United States;4;35-44N;091-39W;;;141;; +KBVY;--;---;Beverly, Beverly Municipal Airport;MA;United States;4;42-35-01N;070-54-59W;42-35-07N;070-54-46W;33;28; +KBWD;--;---;Brownwood, Brownwood Regional Airport;TX;United States;4;31-48N;098-57W;;;422;; +KBWG;--;---;Bowling Green, Bowling Green-Warren County Regional Airport;KY;United States;4;36-57-52N;086-25-10W;36-57-45N;086-25-35W;167;161; +KBWI;72;406;Baltimore, Baltimore-Washington International Airport;MD;United States;4;39-10-00N;076-41-00W;39-10-44N;076-40-11W;44;59; +KBXA;--;---;Bogalusa, George R Carr Memorial Air Field;LA;United States;4;30-48-49N;089-51-53W;;;36;; +KBYG;--;---;Buffalo, Buffalo Johnson County Airport;WY;United States;4;44-22-53N;106-43-08W;44-22-43N;106-42-55W;1514;1497; +KBYH;--;---;Eaker Air Force Base;AR;United States;4;35-58N;089-57W;;;78;; +KBYI;--;---;Burley, Burley Municipal Airport;ID;United States;4;42-32-33N;113-46-17W;42-32-20N;113-46-06W;1265;1264; +KBYS;74;611;Fort Irwin/Barstow, Bicycle Lake Army Airfield;CA;United States;4;35-17N;116-37W;35-17N;116-37W;716;716; +KBYY;--;---;Bay City, Bay City Municipal Airport;TX;United States;4;28-58-23N;095-51-48W;;;14;; +KBZN;--;---;Bozeman, Gallatin Field;MT;United States;4;45-47-17N;111-09-39W;45-46-35N;111-09-15W;1364;1361; +KC09;--;---;Morris, Morris Municipal-James R Washburn Field Airport;IL;United States;4;41-25-31N;088-25-07W;;;178;; +KC19;--;---;Holland / Tulip City;MI;United States;4;42-45N;086-06W;;;210;; +KC52;--;---;Burlington, Burlington Municipal Airport;WI;United States;4;42-41-26N;088-18-17W;;;237;; +KC58;--;---;Two Rivers Coast Guard Station;WI;United States;4;44-08N;087-33W;;;176;; +KC73;--;---;Dixon / Walgreen Field;IL;United States;4;41-50N;089-27W;;;240;; +KC75;--;---;Lacon, Marshall County Airport;IL;United States;4;41-01-09N;089-23-11W;;;173;; +KC96;--;---;Winter Park Resort ;CO;United States;4;39-53N;105-46W;;;2771;; +KCAD;--;---;Cadillac / Wexford County;MI;United States;4;44-17N;085-25W;;;398;; +KCAE;72;310;Columbia, Columbia Metropolitan Airport;SC;United States;4;33-56-31N;081-07-05W;33-56-43N;081-07-22W;71;73;P +KCAG;72;570;Craig, Craig-Moffat Airport;CO;United States;4;40-29-36N;107-31-25W;40-29-34N;107-31-16W;1888;1887;P +KCAK;72;521;Akron, Akron-Canton Regional Airport;OH;United States;4;40-55-05N;081-26-33W;40-54-43N;081-26-18W;374;377; +KCAO;72;360;Clayton, Clayton Municipal Airpark;NM;United States;4;36-26-54N;103-09-11W;36-26-46N;103-09-18W;1513;1514;P +KCAR;72;712;Caribou, Caribou Municipal Airport;ME;United States;4;46-52-02N;068-00-48W;46-52-06N;068-00-48W;191;191;P +KCAV;--;---;Clarion;IA;United States;4;42-45N;093-46W;;;354;; +KCBF;--;---;Council Bluffs;IA;United States;4;41-16N;095-46W;;;382;; +KCBG;--;---;Cambridge Municipal;MN;United States;4;45-34N;093-16W;;;287;; +KCBM;--;---;Columbus Air Force Base;MS;United States;4;33-39N;088-27W;;;67;; +KCCO;--;---;Newnan, Newnan Coweta County Airport;GA;United States;4;33-18-44N;084-46-13W;;;296;; +KCCR;--;---;Concord, Buchanan Field;CA;United States;4;37-59-30N;122-03-07W;37-59-09N;122-03-16W;7;11; +KCCU;--;---;Copper Mountain, Red Cliff Pass;CO;United States;4;39-28-02N;106-09-01W;;;3680;; +KCCX;--;---;State College Nexrad;PA;United States;4;40-55N;078-00W;;;758;; +KCCY;--;---;Charles City;IA;United States;4;43-04N;092-37W;;;343;; +KCDC;--;---;Cedar City, Cedar City Municipal Airport;UT;United States;4;37-42-24N;113-05-48W;37-42-00N;113-05-30W;1715;1714; +KCDD;--;---;Crane Lake, Scotts Seaplane Base;MN;United States;4;48-15-59N;92-29-01W;;;341;; +KCDH;--;---;Camden / Harrell Field;AR;United States;4;33-37N;092-46W;;;40;; +KCDJ;--;---;Chillicothe, Chillicothe Agri-Science Center;MO;United States;4;39-49N;093-35W;;;234;; +KCDR;--;---;Chadron, Chadron Municipal Airport;NE;United States;4;42-50-15N;103-05-43W;42-49-44N;103-05-50W;1005;1010; +KCDS;--;---;Childress, Childress Municipal Airport;TX;United States;4;34-25-39N;100-17-00W;34-25-39N;100-16-58W;595;594; +KCDV;--;---;Cordova, Smith Airport;AK;United States;4;60-29-20N;145-27-04W;60-29-38N;145-28-02W;12;18; +KCDW;--;---;Caldwell, Essex County Airport;NJ;United States;4;40-52-35N;074-16-59W;40-52-33N;074-16-40W;52;64; +KCEC;--;---;Crescent City, Jack McNamara Field Airport;CA;United States;4;41-46-49N;124-14-12W;;;17;; +KCEF;74;491;Chicopee Falls / Westover Air Force Base;MA;United States;4;42-12N;072-32W;;;75;75; +KCEU;--;---;Clemson, Clemson-Oconee County Airport;SC;United States;4;34-40-20N;082-52-53W;34-40-19N;082-52-49W;272;268; +KCEW;--;---;Crestview, Sikes Airport;FL;United States;4;30-46-20N;086-31-12W;;;65;55; +KCEZ;--;---;Cortez, Cortez-Montezuma County Airport;CO;United States;4;37-18-23N;108-37-32W;37-18-14N;108-37-43W;1803;1797; +KCFE;--;---;Buffalo, Buffalo Municipal Airport;MN;United States;4;45-09-32N;093-50-35W;;;295;; +KCFV;--;---;Coffeyville, Coffeyville Municipal Airport;KS;United States;4;37-05-28N;095-33-59W;37-05-52N;095-34-32W;229;225; +KCGF;--;---;Cleveland / Cuyahoga;OH;United States;4;41-34N;081-29W;;;268;; +KCGI;--;---;Cape Girardeau, Cape Girardeau Regional Airport;MO;United States;4;37-13-32N;089-34-42W;37-13-38N;089-33-53W;104;102; +KCGX;--;---;Chicago / Meigs;IL;United States;4;41-52N;087-36W;;;181;; +KCGZ;--;---;Casa Grande, Casa Grande Municipal Airport;AZ;United States;4;32-57N;111-46W;;;446;; +KCHA;72;324;Chattanooga, Lovell Field;TN;United States;4;35-02-00N;085-12-00W;35-01-31N;085-12-06W;207;210;P +KCHD;--;---;Chandler, Chandler Municipal Airport;AZ;United States;4;33-16-09N;111-48-40W;;;379;; +KCHH;74;494;Chatham;MA;United States;4;41-40N;069-58W;41-40N;069-58W;14;16; +KCHI;--;---;Chicago Weather Service Forecast Office;IL;United States;4;42-00N;087-53W;;;181;; +KCHK;--;---;Chickasha, Chickasha Municipal Airport;OK;United States;4;35-05-46N;097-57-58W;;;351;; +KCHO;--;---;Charlottesville, Charlottesville-Albemarle Airport;VA;United States;4;38-08-18N;078-27-21W;38-08-19N;078-27-00W;195;192; +KCHS;72;208;Charleston, Charleston Air Force Base;SC;United States;4;32-53-56N;080-02-26W;32-53-40N;080-01-40W;14;13;P +KCIC;--;---;Chico Municipal ;CA;United States;4;39-48N;121-51W;;;73;; +KCID;72;545;Cedar Rapids, Cedar Rapids Municipal Airport;IA;United States;4;41-52-58N;091-43-26W;41-53-20N;091-42-23W;263;264; +KCIN;--;---;Carroll;IA;United States;4;42-03N;094-47W;;;375;; +KCIR;--;---;Cairo, Cairo Regional Airport,IL;United States;4;37-03-52N;089-13-10W;;;98;; +KCIU;--;---;Chippewa International Automatic Weather Observing / Reporting System;MI;United States;4;46-15N;084-28W;;;244;; +KCJR;--;---;Culpeper, Culpeper County Airport;VA;United States;4;38-31-36N;077-51-32W;;;95;; +KCKB;--;---;Clarksburg, Clarksburg Benedum Airport;WV;United States;4;39-18-00N;080-13-29W;39-18-00N;080-13-45W;366;360; +KCKC;--;---;Grand Marais, Grand Marais/Cook County Airport;MN;United States;4;47-50-18N;090-22-59W;;;548;; +KCKL;72;229;Centreville;AL;United States;4;32-54N;087-15W;32-54N;087-15W;140;140;P +KCKN;--;---;Crookston Municipal Field;MN;United States;4;47-51N;096-37W;;;273;; +KCKV;--;---;Clarksville, Outlaw Field Airport;TN;United States;4;36-37-19N;087-24-54W;36-37-18N;087-25-07W;168;165; +KCLE;72;524;Cleveland, Cleveland-Hopkins International Airport;OH;United States;4;41-24-18N;081-51-10W;41-24-41N;081-51-36W;241;236;P +KCLI;--;---;Clintonville, Clintonville Municipal Airport;WI;United States;4;44-36-50N;088-43-53W;;;251;; +KCLL;--;---;College Station, Easterwood Field;TX;United States;4;30-34-56N;096-21-42W;30-35-30N;096-21-30W;97;96; +KCLM;--;---;Port Angeles, William R. Fairchild International Airport;WA;United States;4;48-07-20N;123-30-19W;48-07-01N;123-29-32W;87;85; +KCLT;72;314;Charlotte, Charlotte / Douglas International Airport;NC;United States;4;35-12-48N;080-56-55W;35-13-25N;080-56-46W;228;220;P +KCMA;--;---;Camarillo, Camarillo Airport;CA;United States;4;34-13N;119-05W;;;23;; +KCMH;72;428;Columbus, Port Columbus International Airport;OH;United States;4;39-59-42N;082-52-35W;40-00-24N;082-53-15W;248;247;P +KCMI;--;---;Champaign / Urbana, University Of Illinois-Willard Airport;IL;United States;4;40-01-56N;088-16-24W;40-02-24N;088-16-15W;229;228; +KCMS;--;---;Cemetery Separa;WY;United States;4;41-32N;109-28W;;;1949;; +KCMX;72;744;Hancock, Houghton County Memorial Airport;MI;United States;4;47-10-06N;088-29-20W;47-10-15N;088-29-46W;334;326; +KCMY;--;---;Sparta, Sparta / Fort McCoy Airport;WI;United States;4;43-57-30N;090-44-16W;;;255;; +KCNC;--;---;Chariton;IA;United States;4;41-02N;093-22W;;;320;; +KCNK;72;458;Concordia, Blosser Municipal Airport;KS;United States;4;39-33-05N;097-39-02W;39-33-00N;097-39-15W;453;447;P +KCNM;--;---;Carlsbad, Cavern City Air Terminal Airport;NM;United States;4;32-20-15N;104-15-48W;32-20-33N;104-15-07W;1004;985; +KCNO;--;---;Chino, Chino Airport;CA;United States;4;33-58-32N;117-37-25W;33-58-45N;117-38-19W;198;207; +KCNU;--;---;Chanute, Chanute Martin Johnson Airport;KS;United States;4;37-40-13N;095-29-03W;37-41-09N;095-29-14W;305;297; +KCNY;--;---;Moab, Canyonlands Field;UT;United States;4;38-45-36N;109-44-41W;38-45-41N;109-44-22W;1388;1390; +KCOD;72;670;Cody;WY;United States;4;44-31N;109-01W;;;1551;1553;P +KCOE;--;---;Coeur D'Alene Automatic Weather Observing / Reporting System;ID;United States;4;47-46N;116-49W;;;707;; +KCOF;74;795;Cocoa / Patrick Air Force Base;FL;United States;4;28-14N;080-36W;;;3;3; +KCON;72;605;Concord, Concord Municipal Airport;NH;United States;4;43-11-43N;071-30-04W;43-12-22N;071-30-36W;105;103; +KCOQ;--;---;Cloquet Automatic Weather Observing / Reporting System;MN;United States;4;46-42N;092-30W;;;390;; +KCOS;72;466;Colorado Springs, City Of Colorado Springs Municipal Airport;CO;United States;4;38-48-57N;104-42-39W;38-48-31N;104-43-14W;1881;1856; +KCOT;--;---;Cotulla, Cotulla-La Salle County Airport;TX;United States;4;28-27-30N;099-13-13W;28-27-13N;099-13-05W;145;140; +KCOU;72;445;Columbia, Columbia Regional Airport;MO;United States;4;38-49-01N;092-13-06W;38-49-06N;092-13-14W;271;271;P +KCPC;--;---;Whiteville, Columbus County Municipal Airport;NC;United States;4;34-16-22N;078-42-54W;;;30;; +KCPK;--;---;Chesapeake, Chesapeake Municipal Airport;VA;United States;4;36-39-56N;076-19-14W;;;6;; +KCPR;72;569;Casper, Natrona County International Airport;WY;United States;4;42-53-51N;106-28-23W;42-53-50N;106-27-50W;1630;1621;P +KCPS;--;---;Cahokia / St. Louis, St. Louis Downtown Airport;IL;United States;4;38-34-15N;090-09-22W;38-34-13N;090-09-41W;126;126; +KCPT;--;---;Cleburne, Cleburne Municipal Airport,TX;United States;4;32-21-13N;097-26-01W;;;260;; +KCPW;--;---;Pagosa Springs, Wolf Creek Pass;CO;United States;4;37-27-05N;106-48-01W;;;3584;; +KCQB;--;---;Chandler, Chandler Municipal Airport;OK;United States;4;35-43-26N;096-49-13W;;;300;;; +KCQC;--;---;Clines Corners;NM;United States;4;35-00N;105-40W;;;2160;; +KCQM;--;---;Cook, Cook Municipal Airport;MN;United States;4;47-49-19N;092-41-22W;;;405;; +KCQN;--;---;Chattanooga / Daisy;TN;United States;4;35-10N;085-09W;;;225;; +KCQT;--;---;Los Angeles / USC Campus Downtown;CA;United States;4;34-01N;118-17W;;;56;; +KCQV;--;---;Colville Municipal;WA;United States;4;48-33N;117-53W;;;572;; +KCQX;--;---;Chatham, Chatham Municipal Airport;MA;United States;4;41-41-15N;069-59-36W;41-41-17N;069-59-32W;20;19; +KCRE;--;---;North Myrtle Beach, Grand Strand Airport;SC;United States;4;33-48-42N;078-43-26W;33-48-07N;078-34-4W;10;10; +KCRG;--;---;Jacksonville, Craig Municipal Airport;FL;United States;4;30-20-10N;081-30-53W;30-20-11N;081-30-53W;12;13; +KCRP;72;251;Corpus Christi, Corpus Christi International Airport;TX;United States;4;27-46-23N;097-30-46W;27-46-26N;097-29-59W;13;16;P +KCRQ;--;---;Carlsbad, McClellan-Palomar Airport;CA;United States;4;33-07-48N;117-16-33W;33-07-38N;117-16-32W;100;99; +KCRS;--;---;Corsicana, Campbell Field-Corsicana Municipal Airport;TX;United States;4;32-01-52N;096-23-56W;32-01-42N;096-23-46W;136;133; +KCRV;--;---;Nederland Mountain, Corona Pass;CO;United States;4;40-03-01N;105-35-02W;;;3538;; +KCRW;72;414;Charleston, Yeager Airport;WV;United States;4;38-22-46N;081-35-29W;38-21-44N;081-35-24W;299;309;P +KCSG;--;---;Columbus, Columbus Metropolitan Airport;GA;United States;4;32-30-58N;084-56-32W;32-31-18N;084-56-39W;121;135; +KCSL;--;---;Camp San Luis Airport ;CA;United States;4;35-20N;120-44W;;;76;; +KCSM;--;---;Clinton, Clinton-Sherman Airport;OK;United States;4;35-21-24N;099-12-13W;35-21-05N;099-11-50W;585;588; +KCSQ;--;---;Creston;IA;United States;4;41-01N;094-22W;;;394;; +KCSV;--;---;Crossville, Crossville Memorial-Whitson Field Airport;TN;United States;4;35-57-05N;085-05-06W;35-57-14N;085-04-59W;573;570; +KCTB;--;---;Cut Bank, Cut Bank Municipal Airport;MT;United States;4;48-36-30N;112-22-34W;;;1175;; +KCTD;--;---;Continental Div;WY;United States;4;41-43N;107-47W;;;2146;; +KCTO;--;---;Calverton / Grumman;NY;United States;4;40-55N;072-47W;;;23;; +KCTY;72;212;Cross City, Cross City Airport;FL;United States;4;29-33-00N;083-06-19W;29-37-49N;083-06-31W;12;12;P +KCTZ;--;---;Clinton, Sampson County Airport;NC;United States;4;34-58-32N;078-21-53W;;;45;; +KCUB;--;---;Columbia, Columbia Owens Downtown Airport;SC;United States;4;33-58-15N;080-59-40W;33-58-22N;080-59-39W;64;56; +KCUL;--;---;Carmi, Carmi Municipal Airport;IL;United States;4;38-05-22N;088-07-23W;;;118;; +KCUT;--;---;Custer, Custer County Airport;SD;United States;4;43-43-59N;103-37-03W;43-44-00N;103-36-50W;1707;1725; +KCVG;72;421;Covington / Cincinnati, Cincinnati / Northern Kentucky International Airport;KY;United States;4;39-02-35N;084-40-18W;39-03-17N;084-39-40W;273;269;P +KCVN;--;---;Clovis Municipal Automatic Weather Observing / Reporting System;NM;United States;4;34-26N;103-05W;;;1284;; +KCVO;--;---;Corvallis Municipal Automatic Weather Observing / Reporting System;OR;United States;4;44-30N;123-17W;;;75;; +KCVS;--;---;Cannon Air Force Base / Clovis;NM;United States;4;34-23N;103-19W;;;1309;; +KCVX;--;---;Charlevoix, Charlevoix Municipal Airport;MI;United States;4;45-18-17N;085-16-29W;;;204;; +KCWA;--;---;Mosinee / Central Wisconsin;WI;United States;4;44-47N;089-40W;;;389;; +KCWF;--;---;Chenault Airpark;LA;United States;4;30-13N;093-09W;;;4;; +KCWI;--;---;Clinton Municipal Automatic Weather Observing / Reporting System;IA;United States;4;41-50N;090-20W;;;216;; +KCWL;--;---;Calexico, Calexico International Airport;CA;United States;4;32-40-10N;115-30-48W;;;1;; +KCXO;--;---;Conroe, Montgomery County Airport;TX;United States;4;30-21-24N;095-24-50W;30-21-11N;095-25-30W;74;75; +KCXY;--;---;Harrisburg, Capital City Airport;PA;United States;4;40-13-02N;076-51-05W;40-13-13N;076-51-14W;106;106; +KCYS;72;564;Cheyenne, Cheyenne Airport;WY;United States;4;41-09-28N;104-48-25W;41-09-11N;104-48-33W;1876;1865;P +KCZD;--;---;Cozad Municipal;NE;United States;4;40-52N;100-00W;;;762;; +KCZK;--;---;Cascade Locks State;OR;United States;4;45-40N;121-53W;;;46;; +KCZZ;--;---;Campo;CA;United States;4;32-37-34N;116-28-06W;;;807;807; +KD07;--;---;Faith;SD;United States;4;45-01-55N;102-01-09W;;;787;784; +KD19;--;---;Luverne, Quentin Aanenson Field Airport;MN;United States;4;43-37-16N;096-12-56W;;;436;; +KD45;72;756;Warroad;MN;United States;4;48-56N;095-21W;;;328;328; +KD87;--;---;Harbor Springs, Harbor Springs Airport;MI;United States;4;45-25-32N;084-54-48W;;;209;; +KD97;--;---;South St. Paul Municipal;MN;United States;4;44-51N;093-09W;;;250;; +KDAA;--;---;Fort Belvoir;VA;United States;4;38-43N;077-11W;;;21;; +KDAB;--;---;Daytona Beach, Daytona Beach Regional Airport;FL;United States;4;29-10-38N;081-03-36W;29-10-56N;081-02-53W;10;9; +KDAG;--;---;Daggett, Barstow-Daggett Airport;CA;United States;4;34-51-13N;116-47-12W;34-51-10N;116-47-30W;587;587; +KDAL;--;---;Dallas, Dallas Love Field;TX;United States;4;32-51-09N;096-51-20W;32-50-42N;096-51-00W;148;158; +KDAN;--;---;Danville, Danville Regional Airport;VA;United States;4;36-34-22N;079-20-10W;36-34-32N;079-20-24W;174;175; +KDAW;--;---;Rochester, Skyhaven Airport;NH;United States;4;43-16-41N;070-55-20W;43-16-56N;070-55-47W;98;100; +KDAX;--;---;Sacramento Nexrad;CA;United States;4;38-30N;121-41W;;;44;; +KDAY;72;429;Dayton, Cox Dayton International Airport;OH;United States;4;39-54-22N;084-13-07W;39-54-16N;084-12-20W;307;305;P +KDBQ;72;547;Dubuque, Dubuque Regional Airport;IA;United States;4;42-23-52N;090-42-13W;42-24-20N;090-42-20W;328;326;P +KDCA;72;405;Washington DC, Reagan National Airport;VA;United States;4;38-50-54N;077-02-03W;38-50-56N;077-02-29W;4;18;P +KDCU;--;---;Decatur, Pryor Field;AL;United States;4;34-39-29N;086-56-36W;34-39-01N;086-56-52W;180;176; +KDDC;72;451;Dodge City, Dodge City Regional Airport;KS;United States;4;37-46-22N;099-58-11W;37-45-45N;099-58-08W;790;789;P +KDDH;--;---;Bennington, Bennington Morse State Airport;VT;United States;4;42-53-24N;073-14-47W;42-53-24N;073-14-54W;252;244; +KDEC;--;---;Decatur, Decatur Airport;IL;United States;4;39-50-04N;088-51-56W;39-50-05N;088-52-37W;208;207; +KDEE;--;---;Deering, Deering Airport;AK;United States;4;66-04-14N;162-45-30W;66-04-13N;162-45-30W;4;4; +KDEH;--;---;Decorah;IA;United States;4;43-17N;091-44W;;;353;; +KDEN;72;565;Denver, Denver International Airport;CO;United States;4;39-49-58N;104-39-27W;39-51-45N;104-40-25W;1655;1640; +KDEQ;--;---;De Queen, J Lynn Helms Sevier County Airport;AR;United States;4;34-02-49N;094-23-58W;34-02-44N;094-23-58W;108;106; +KDET;--;---;Detroit, Detroit City Airport;MI;United States;4;42-24-33N;083-00-36W;42-24-35N;083-00-18W;191;190; +KDEW;--;---;Deer Park, Deer Park Airport;WA;United States;4;47-58-27N;117-25-42W;47-57-44N;117-26-06W;672;668; +KDFI;--;---;Defiance, Defiance Memorial Airport;OH;United States;4;41-20-11N;084-25-46W;41-20-04N;084-25-40W;215;219; +KDFW;72;259;Dallas / Fort Worth, Dallas / Fort Worth International Airport;TX;United States;4;32-53-49N;097-01-19W;32-53-07N;097-01-18W;183;174;P +KDGW;72;568;Douglas, Converse County Airport;WY;United States;4;42-47-39N;105-22-55W;42-47-47N;105-23-06W;1502;1499; +KDHN;--;---;Dothan, Dothan Regional Airport;AL;United States;4;31-19-17N;085-26-59W;31-18-54N;085-26-51W;122;113; +KDHS;--;---;Dead Horse;WY;United States;4;44-13N;106-06W;;;1241;; +KDHT;--;---;Dalhart, Dalhart Municipal Airport;TX;United States;4;36-01-24N;102-32-50W;36-01-16N;102-32-52W;1216;1217; +KDIK;--;---;Dickinson, Dickinson Municipal Airport;ND;United States;4;46-47-50N;102-48-07W;46-48-11N;102-47-59W;790;788; +KDIX;--;---;Philadelphia NEXRAD;PA;United States;4;39-57N;074-25W;;;70;; +KDKB;--;---;De Kalb, De Kalb Taylor Municipal Airport;IL;United States;4;41-55-55N;088-42-30W;;;279;; +KDKK;--;---;Dunkirk, Chautauqua County / Dunkirk Airport;NY;United States;4;42-29-35N;079-16-33W;42-29-37N;079-16-45W;211;202; +KDKX;--;---;Knoxville Downtown;TN;United States;4;35-58N;083-52W;;;254;; +KDLF;--;---;Laughlin, Laughlin Air Force Base Auxiliary Airfield;TX;United States;4;29-07-00N;100-28-00W;;;294;294; +KDLH;72;745;Duluth, Duluth International Airport;MN;United States;4;46-50-34N;092-13-34W;46-50-22N;092-11-24W;435;435;P +KDLL;--;---;Baraboo, Baraboo Wisconsin Dells Airport;WI;United States;4;43-31-19N;089-46-15W;;;298;; +KDLN;--;---;Dillon, Dillon Airport;MT;United States;4;45-15-27N;112-33-16W;45-15-10N;112-33-10W;1597;1591; +KDLS;--;---;The Dalles, Columbia Gorge Regional / The Dalles Municipal Airport;OR;United States;4;45-37-07N;121-10-02W;45-37-06N;121-10-17W;75;71; +KDMA;--;---;Davis-Monthan Air Force Base;AZ;United States;4;32-10N;110-53W;;;824;; +KDMH;--;---;Baltimore, Inner Harbor;MD;United States;4;39-17N;076-37W;;;6;; +KDMN;--;---;Deming, Deming Municipal Airport;NM;United States;4;32-15-44N;107-43-14W;32-15-19N;107-43-21W;1315;1311; +KDMO;--;---;Sedalia, Sedalia Memorial Airport;MO;United States;4;38-42-44N;093-10-28W;38-42-15N;093-11-00W;277;274; +KDMX;--;---;Des Moines Nexrad;IA;United States;4;41-44N;093-43W;;;322;; +KDNL;--;---;Augusta, Daniel Field;GA;United States;4;33-28-01N;082-02-19W;33-27-56N;082-02-07W;128;130; +KDNN;--;---;Dalton, Dalton Municipal Airport;GA;United States;4;34-43-18N;084-52-09W;;;216;; +KDNR;72;469;Denver / Stapleton International, Co.;CO;United States;4;39-47N;104-52W;39-45N;104-52W;1626;1626;P +KDNS;--;---;Denison;IA;United States;4;41-59N;095-23W;;;388;; +KDNV;--;---;Danville, Vermilion County Airport;IL;United States;4;40-11-58N;087-35-44W;;;212;; +KDOV;--;---;Dover Air Force Base;DE;United States;4;39-08N;075-28W;;;9;; +KDPA;--;---;Chicago / West Chicago, Dupage Airport;IL;United States;4;41-53-47N;088-15-04W;41-54-24N;088-15-20W;231;230; +KDPG;74;003;Dugway Proving Grounds;UT;United States;4;40-10N;112-56W;40-11N;112-56W;1326;1325; +KDPL;--;---;Kenansville, Duplin County Airport;NC;United States;4;35-00-00N;077-58-54W;;;42;; +KDQH;--;---;Douglas, Douglas Municipal Airport;GA;United States;4;31-28-36N;082-51-37W;;;78;; +KDRA;72;387;Mercury, Desert Rock Airport;NV;United States;4;36-37-14N;116-01-40W;36-37-27N;116-01-06W;1007;1006;P +KDRC;--;---;Deer Creek;WY;United States;4;42-50N;105-52W;;;1543;; +KDRI;--;---;De Ridder, Beauregard Parish Airport;LA;United States;4;30-49-54N;093-20-23W;;;63;; +KDRO;--;---;Durango, Durango-La Plata County Airport;CO;United States;4;37-08-35N;107-45-35W;37-09-34N;107-45-00W;2038;2035; +KDRT;72;261;Del Rio, Del Rio International Airport;TX;United States;4;29-22-29N;100-55-25W;29-22-28N;100-55-06W;304;313;P +KDSM;72;546;Des Moines, Des Moines International Airport;IA;United States;4;41-32-16N;093-39-58W;41-32-20N;093-39-25W;291;295;P +KDSV;--;---;Dansville, Dansville Municipal Airport;NY;United States;4;42-34-10N;077-42-52W;42-34-03N;077-42-51W;201;198; +KDTL;--;---;Detroit Lakes Automatic Weather Observing / Reporting System;MN;United States;4;46-50N;095-53W;;;426;; +KDTN;--;---;Shreveport, Shreveport Downtown Airport;LA;United States;4;32-32-33N;093-44-41W;32-32-23N;093-44-55W;54;53; +KDTO;--;---;Denton, Denton Municipal Airport;TX;United States;4;33-12-22N;097-11-56W;33-12-04N;097-11-39W;195;196; +KDTS;--;---;Destin, Destin-Ft. Walton Beach Airport;FL;United States;4;30-23-36N;086-28-03W;30-23-48N;086-28-17W;6;5; +KDTW;72;537;Detroit, Detroit Metropolitan Wayne County Airport;MI;United States;4;42-13-53N;083-19-51W;42-12-51N;083-21-13W;194;195;P +KDTX;--;---;Detroit NEXRAD;MI;United States;4;42-42N;083-27W;;;361;; +KDUA;--;---;Durant, Eaker Field Airport;OK;United States;4;33-56-32N;096-23-40W;;;213;; +KDUC;--;---;Duncan, Halliburton Field Airport;OK;United States;4;34-28-15N;097-57-36W;;;339;; +KDUG;--;---;Douglas Bisbee, Bisbee Douglas International Airport;AZ;United States;4;31-28-09N;109-36-13W;;;1266;; +KDUH;--;---;Lambertville, Toledo Suburban Airport;MI;United States;4;41-44-09N;083-39-19W;;;204;; +KDUJ;--;---;Du Bois, Du Bois-Jefferson County Airport;PA;United States;4;41-11N;078-54W;;;555;; +KDUX;--;---;Dumas, Moore County Airport;TX;United States;4;35-51-28N;102-00-47W;;;1129;; +KDVL;--;---;Devils Lake Automatic Weather Observing / Reporting System;ND;United States;4;48-07N;098-55W;;;443;; +KDVN;--;---;Davenport, Davenport Municipal Airport;IA;United States;4;41-36-50N;090-35-29W;41-36-38N;090-35-06W;229;228; +KDVT;--;---;Phoenix, Phoenix-Deer Valley Municipal Airport;AZ;United States;4;33-41-25N;112-03-56W;33-41-08N;112-04-53W;450;443; +KDWH;--;---;Houston, Hooks Memorial Airport;TX;United States;4;30-04-03N;095-33-22W;30-04-00N;095-33-21W;46;46; +KDXR;--;---;Danbury, Danbury Municipal Airport;CT;United States;4;41-22-18N;073-29-04W;41-22-21N;073-29-03W;139;139; +KDXX;--;---;Madison, Madison-Lac Qui Parle County Airport;MN;United States;4;44-59-10N;096-10-40W;;;330;; +KDYL;--;---;Doylestown, Doylestown Airport;PA;United States;4;40-19-48N;075-07-21W;40-20-01N;075-07-22W;120;117; +KDYR;--;---;Dyersburg Automatic Weather Observing / Reporting System;TN;United States;4;36-00N;089-24W;;;103;; +KDYS;--;---;Abilene, Dyess Air Force Base;TX;United States;4;32-25-12N;099-51-25W;;;545;; +KDYT;--;---;Duluth, Sky Harbor Airport;MN;United States;4;46-43-19N;092-02-36W;;;186;; +KE12;--;---;East Cameron 345;LA;United States;4;28-05N;092-42W;;;0;; +KE15;--;---;Graham, Graham Municipal Airport;TX;United States;4;33-06-36N;098-33-19W;;;342;; +KE24;--;---;Whiteriver, Whiteriver Airport;AZ;United States;4;33-49N;109-59W;;;1570;; +KE28;74;733;Northrup Landing Strip;NM;United States;4;33-54N;106-24W;32-54N;106-24W;1193;1193; +KE29;--;---;Sonora, Sonora Municipal Airport;TX;United States;4;30-35-08N;100-38-54W;;;652;; +KE33;--;---;Chama;NM;United States;4;36-54N;106-35W;;;2393;; +KE38;--;---;Alpine, Alpine-Casparis Municipal Airport;TX;United States;4;30-23-03N;103-41-00W;;;1376;; +KE74;--;---;Safford Automatic Meteorological Observing System;AZ;United States;4;32-49N;109-41W;;;950;; +KEAA;--;---;Eagle, Eagle Airport;AK;United States;4;64-46-35N;141-09-38W;64-46-35N;141-09-38W;268;273; +KEAR;--;---;Kearney Municipal Automatic Weather Observing / Reporting System;NE;United States;4;40-44N;099-00W;;;649;; +KEAT;--;---;Wenatchee, Pangborn Memorial Airport;WA;United States;4;47-23-56N;120-12-25W;47-24-06N;120-12-21W;381;377; +KEAU;--;---;Eau Claire, Chippewa Valley Regional Airport;WI;United States;4;44-51-55N;091-29-06W;;;277;; +KEAX;--;---;Pleasant NEXRAD;MO;United States;4;38-49N;094-16W;;;335;; +KEBG;--;---;Edinburg, Edinburg International Airport;TX;United States;4;26-26-31N;098-07-46W;;;24;; +KEBS;--;---;Webster City;IA;United States;4;42-26N;093-52W;;;342;; +KECG;--;---;Elizabeth City, Elizabeth City Coast Guard Air Station;NC;United States;4;36-15-47N;076-10-58W;36-15-50N;076-10-30W;3;11; +KECU;--;---;Rocksprings, Edwards County Airport;TX;United States;4;29-56-48N;100-10-25W;;;723;; +KEDE;--;---;Edenton, Northeastern Regional Airport;NC;United States;4;36-01-40N;076-34-02W;;;6;; +KEDW;72;381;Edwards Air Force Base;CA;United States;4;34-55N;117-54W;34-54N;117-55W;702;705; +KEED;--;---;Needles, Needles Airport;CA;United States;4;34-45-58N;114-37-24W;;;300;; +KEEN;--;---;Keene / Dillant Automatic Weather Observing / Reporting System;NH;United States;4;42-54N;072-16W;;;149;; +KEEO;--;---;Meeker, Meeker Airport;CO;United States;4;40-02-32N;107-53-23W;40-02-25N;107-53-30W;1948;1930; +KEET;--;---;Alabaster, Shelby County Airport;AL;United States;4;33-10-42N;086-46-54W;33-10-35N;086-46-51W;178;173; +KEEW;--;---;Neenah;WI;United States;4;44-13N;088-33W;;;275;; +KEFC;--;---;Belle Fourche, Belle Fourche Municipal Airport;SD;United States;4;44-44N;103-52W;;;972;; +KEFD;--;---;Houston / Ellington;TX;United States;4;29-36N;095-10W;;;10;; +KEFT;--;---;Monroe, Monroe Municipal Airport;WI;United States;4;42-36-54N;089-35-27W;;;331;; +KEGE;--;---;Eagle County Regional;CO;United States;4;39-39N;106-55W;;;1993;; +KEGI;--;---;Duke Field / Eglin Auxiliary;FL;United States;4;30-39N;086-31W;;;59;; +KEGV;--;---;Eagle River, Eagle River Union Airport;WI;United States;4;45-55-54N;089-16-09W;;;501;; +KEHA;--;---;Elkhart Automatic Weather Observing / Reporting System;KS;United States;4;37-00N;101-54W;;;1099;; +KEHO;--;---;Shelby, Shelby Municipal Airport;NC;United States;4;35-15N;081-36W;;;258;; +KEHR;--;---;Henderson City;KY;United States;4;37-49N;087-41W;;;117;; +KEKA;72;594;Eureka;CA;United States;4;40-48N;124-10W;;;13;18;P +KEKM;--;---;Elkhart Municipal;IN;United States;4;41-43N;086-00W;;;237;; +KEKN;72;417;Elkins, Elkins-Randolph County-Jennings Randolph Field;WV;United States;4;38-53-07N;079-51-10W;38-53-01N;079-51-17W;605;603; +KEKO;--;---;Elko, Elko Regional Airport;NV;United States;4;40-49-30N;115-47-30W;;;1568;1547; +KELD;--;---;El Dorado, South Arkansas Regional at Goodwin Field Airport;AR;United States;4;33-13-15N;092-48-48W;33-13-00N;092-48-37W;84;81; +KELM;--;---;Elmira, Elmira / Corning Regional Airport;NY;United States;4;42-09-23N;076-54-10W;42-09-45N;076-53-44W;291;302; +KELN;--;---;Ellensburg, Ellensburg Bowers Field;WA;United States;4;47-02-01N;120-31-45W;47-01-45N;120-32-11W;536;519; +KELO;--;---;Ely Municipal Automatic Weather Observing / Reporting System;MN;United States;4;47-49N;091-50W;;;443;; +KELP;72;270;El Paso, El Paso International Airport;TX;United States;4;31-48-40N;106-22-33W;31-47-50N;106-23-28W;1206;1197;P +KELY;72;486;Ely, Ely Airport;NV;United States;4;39-17-42N;114-50-43W;39-17-35N;114-50-32W;1907;1906;P +KELZ;--;---;Wellsville, Wellsville Municipal Airport;NY;United States;4;42-06-27N;077-59-04W;42-06-39N;077-59-28W;647;646; +KEMP;--;---;Emporia, Emporia Municipal Airport;KS;United States;4;38-19-44N;096-11-38W;39-19-45N;096-11-29W;367;367; +KEMT;--;---;El Monte;CA;United States;4;34-05N;118-02W;;;90;; +KEMV;--;---;Emporia, Emporia-Greensville Regional Airport;VA;United States;4;36-41-13N;077-28-58W;;;39;; +KEND;--;---;Vance Air Force Base / Enid;OK;United States;4;36-20N;097-55W;;;398;; +KENL;--;---;Centralia, Centralia Municipal Airport;IL;United States;4;38-30-53N;089-05-32W;;;163;; +KENN;--;---;Nenana, Nenana Municipal Airport;AK;United States;4;64-32-52N;149-05-02W;64-32-52N;149-05-02W;110;109; +KENV;72;581;Wendover / Air Force Auxillary Field;UT;United States;4;40-44N;114-02W;40-44N;114-02W;1291;1292;P +KENW;--;---;Kenosha, Kenosha Regional Airport;WI;United States;4;42-35-42N;087-56-17W;42-35-40N;087-55-39W;226;219; +KENX;--;---;Albany NEXRAD;NY;United States;4;42-36N;074-04W;;;581;; +KEOK;--;---;Keokuk Municipal;IA;United States;4;40-28N;091-26W;;;205;; +KEPH;--;---;Ephrata, Ephrata Municipal Airport;WA;United States;4;47-18-27N;119-30-57W;47-18-37N;119-31-18W;389;383; +KEPO;72;608;Eastport;ME;United States;4;44-55N;067-00W;;;24;23; +KEPZ;72;364;Santa Teresa;NM;United States;4;31-52N;106-42W;31-52N;106-42W;1252;1252;P +KEQY;--;---;Monroe, Monroe Airport;NC;United States;4;35-01-01N;080-37-14W;35-01-20N;080-37-09W;207;212; +KERI;72;526;Erie, Erie International Airport;PA;United States;4;42-04-48N;080-10-57W;42-04-59N;080-11-00W;223;222; +KERV;--;---;Kerrville, Kerrville Municipal Airport/Louis Schreiner Field;TX;United States;4;29-58N;099-05W;;;493;; +KERY;--;---;Newberry, Luce County Airport;MI;United States;4;46-18-40N;085-27-26W;;;265;; +KESC;72;648;Escanaba;MI;United States;4;45-45N;087-02W;;;180;187; +KESF;--;---;Alexandria, Alexandria Esler Regional Airport;LA;United States;4;31-23-42N;092-17-25W;31-23-29N;092-17-41W;34;28; +KESN;--;---;Easton / Newman Field;MD;United States;4;38-48N;076-04W;;;22;; +KEST;--;---;Estherville, Estherville Municipal Airport;IA;United States;4;43-24-04N;094-44-50W;43-24-13N;094-44-48W;401;401; +KESX;--;---;Las Vegas Nexrad;NV;United States;4;35-43N;114-54W;;;1509;; +KETB;--;---;West Bend, West Bend Municipal Airport;WI;United States;4;43-25-20N;088-07-41W;;;270;; +KETH;--;---;Wheaton NDB Automatic Weather Observing / Reporting System;MN;United States;4;45-42N;096-30W;;;313;; +KEUG;72;693;Eugene, Mahlon Sweet Field;OR;United States;4;44-08-00N;123-12-52W;44-07-15N;123-12-40W;111;114;P +KEUL;--;---;Caldwell Automatic Weather Observing / Reporting System;ID;United States;4;43-38N;116-38W;;;740;; +KEVM;--;---;Eveleth Municipal Automatic Weather Observing / Reporting System;MN;United States;4;47-24N;092-30W;;;421;; +KEVV;72;432;Evansville, Evansville Regional Airport;IN;United States;4;38-02-35N;087-31-13W;38-01-53N;087-32-16W;127;117;P +KEVW;--;---;Evanston, Evanston-Uninta County Burns Field;WY;United States;4;41-16-23N;111-01-50W;41-16-23N;111-01-44W;2183;2177; +KEWB;--;---;New Bedford, New Bedford Regional Airport;MA;United States;4;41-40-31N;070-57-25W;41-41-04N;070-57-07W;24;23; +KEWK;--;---;Newton Automatic Weather Observing / Reporting System;KS;United States;4;38-03N;097-17W;;;467;; +KEWN;--;---;New Bern, Craven County Regional Airport;NC;United States;4;35-04-03N;077-02-50W;35-04-36N;077-02-37W;5;3; +KEWR;72;502;Newark, Newark International Airport;NJ;United States;4;40-40-57N;074-10-10W;40-42-22N;074-09-36W;5;7; +KEWX;--;---;San Antonio Nexrad;TX;United States;4;29-42N;098-02W;;;223;; +KEXX;--;---;Lexington, Davidson County Airport;NC;United States;4;35-46-52N;080-18-14W;;;223;; +KEYE;--;---;Indianapolis, Eagle Creek Airpark;IN;United States;4;39-49-30N;086-17-45W;39-49-34N;086-17-42W;250;248; +KEYF;--;---;Elizabethtown, Curtis L Brown Jr. Field Airport;NC;United States;4;34-36N;078-35W;;;40;; +KEYW;72;201;Key West, Key West International Airport;FL;United States;4;24-33-13N;081-45-13W;24-33-11N;081-45-24W;1;5;P +KEZF;--;---;Fredericksburg, Shannon Airport;VA;United States;4;38-16N;077-27W;;;26;; +KEZM;--;---;Eastman, Heart of Georgia Regional Airport;GA;United States;4;32-12-51N;083-07-40W;;;93;; +KF05;--;---;Vernon, Wilbarger County Airport;TX;United States;4;34-13-32N;099-17-01W;;;386;; +KF10;74;645;Henryetta Municipal;OK;United States;4;35-24N;096-01W;35-24N;096-01W;259;259; +KF18;--;---;Cleburne, Cleburne Municipal Airport;TX;United States;4;32-21-13N;097-26-01W;;;260;; +KF30;74;646;Sulphur Municipal;OK;United States;4;34-31N;096-59W;34-31N;096-59W;320;320; +KF39;--;---;Sherman-Denison;TX;United States;4;33-43N;096-40W;;;228;; +KF55;--;---;Granbury, Granbury Municipal Airport;TX;United States;4;32-26-39N;097-49-01W;;;237;; +KFAF;--;---;Fort Eustis / Felker;VA;United States;4;37-08N;076-37W;;;4;; +KFAM;--;---;Farmington Airport;MO;United States;4;37-46N;090-26W;;;288;; +KFAR;72;753;Fargo, Hector International Airport;ND;United States;4;46-55-31N;096-48-40W;46-54-29N;096-48-31W;274;277;P +KFAT;72;389;Fresno, Fresno Air Terminal;CA;United States;4;36-46-48N;119-43-10W;36-47-13N;119-43-01W;101;104;P +KFAY;--;---;Fayetteville, Fayetteville Regional Airport;NC;United States;4;34-59-22N;078-52-48W;34-59-29N;078-53-08W;57;55; +KFBG;74;693;Fort Bragg / Simmons Army Airfield;NC;United States;4;35-08N;078-56W;35-08N;078-56W;74;74; +KFBL;--;---;Faribault Municipal Automatic Weather Observing / Reporting System;MN;United States;4;44-20N;093-19W;;;322;; +KFCA;72;779;Kalispell, Glacier Park International Airport;MT;United States;4;48-18-15N;114-15-49W;48-18-33N;114-15-01W;906;908;P +KFCH;--;---;Fresno-Chandler;CA;United States;4;36-44N;119-49W;;;85;; +KFCL;--;---;Fort Collins Supplementary Aviation Weather Reporting Station ;CO;United States;4;40-35N;105-05W;;;1525;; +KFCM;--;---;Minneapolis, Flying Cloud Airport;MN;United States;4;44-49-56N;093-28-13W;44-49-18N;093-27-29W;287;280; +KFCS;72;468;Fort Carson;CO;United States;4;38-42N;104-46W;38-42N;104-46W;1789;1789; +KFCX;--;---;Roanoke NEXRAD;VA;United States;4;37-01N;080-16W;;;904;; +KFDK;--;---;Frederick, Frederick Municipal Airport;MD;United States;4;39-25-03N;077-22-28W;;;92;; +KFDR;--;---;Frederick, Frederick Municipal Airport;OK;United States;4;34-20-40N;098-58-59W;34-21-25N;098-59-12W;382;377; +KFDY;--;---;Findlay, Findlay Airport;OH;United States;4;41-00-49N;083-40-07W;;;248;; +KFEP;--;---;Freeport, Albertus Airport;IL;United States;4;42-14-47N;089-34-56W;;;262;; +KFET;--;---;Fremont Municipal Airport;NE;United States;4;41-27N;096-31W;;;379;; +KFFA;--;---;Kill Devil Hills, First Flight Airport;NC;United States;4;36-01N;075-40W;;;4;; +KFFC;--;---;Atlanta, Peachtree City-Falcon Field;GA;United States;4;33-21-19N;084-34-01W;33-21-29N;084-34-07W;246;248; +KFFL;--;---;Fair Field;IA;United States;4;41-03N;091-59W;;;244;; +KFFM;--;---;Fergus Falls Automatic Weather Observing / Reporting System;MN;United States;4;46-17N;096-09W;;;616;; +KFFO;74;570;Dayton / Wright-Patterson Air Force Base;OH;United States;4;39-50N;084-03W;39-50N;084-03W;251;251;P +KFFT;--;---;Frankfort, Capital City Airport;KY;United States;4;38-11-05N;084-54-12W;38-10-50N;084-54-12W;245;236; +KFFZ;--;---;Mesa / Falcon Field;AZ;United States;4;33-28N;111-44W;;;424;; +KFGN;--;---;Flag Island;MN;United States;4;49-19N;94-54W;;;329;; +KFHR;--;---;Friday Harbor, Friday Harbor Airport;WA;United States;4;48-31-13N;123-01-31W;48-31-31N;123-01-28W;33;32; +KFHU;72;273;Fort Huachuca;AZ;United States;4;31-35N;110-20W;31-35N;110-20W;1438;1428; +KFIG;--;---;Clearfield, Clearfield-Lawrence Airport;PA;United States;4;41-02-48N;078-24-42W;41-02-51N;078-24-51W;462;462; +KFIR;--;---;First Divide;WY;United States;4;41-18N;110-46W;;;2294;; +KFIT;--;---;Fitchburg, Fitchburg Municipal Airport;MA;United States;4;42-33-07N;071-45-21W;42-33-15N;071-45-14W;106;103; +KFKA;--;---;Preston, Fillmore County Airport;MN;United States;4;43-40-36N;092-10-47W;;;389;; +KFKL;--;---;Franklin Automatic Weather Observing / Reporting System;PA;United States;4;41-23N;079-52W;;;469;; +KFKN;--;---;Franklin / J B Rose;VA;United States;4;36-42N;076-54W;;;12;; +KFKS;--;---;Frankfort, Frankfort Dow Memorial Field Airport;MI;United States;4;44-37-30N;086-12-02W;;;193;; +KFLD;--;---;Fond Du Lac, Fond Du Lac County Airport;WI;United States;4;43-46-12N;088-29-11W;43-46-05N;088-29-19W;246;240; +KFLG;--;---;Flagstaff, Flagstaff Pulliam Airport;AZ;United States;4;35-08-25N;111-40-20W;35-08-31N;111-40-15W;2137;2134; +KFLL;--;---;Fort Lauderdale, Fort Lauderdale / Hollywood International Airport;FL;United States;4;26-04-05N;080-09-09W;26-04-13N;080-09-21W;3;30; +KFLO;--;---;Florence, Florence Regional Airport;SC;United States;4;34-11-16N;079-43-51W;34-11-36N;079-43-45W;45;44; +KFLP;--;---;Flippin Automatic Weather Observing / Reporting System;AR;United States;4;36-18N;092-28W;;;350;; +KFLV;--;---;Fort Leavenworth;KS;United States;4;39-22N;094-55W;;;235;; +KFME;--;---;Fort Meade / Tipton;MD;United States;4;39-05N;076-46W;;;46;; +KFMH;72;506;Otis Air National Guard Base;MA;United States;4;41-39N;070-31W;;;40;; +KFMN;--;---;Farmington, Four Corners Regional Airport;NM;United States;4;36-44-37N;108-13-45W;36-44-21N;108-13-38W;1677;1685; +KFMY;--;---;Fort Myers, Page Field;FL;United States;4;26-35-03N;081-51-45W;26-35-27N;081-51-25W;5;4; +KFNB;--;---;Falls City, Brenner Field Airport;NE;United States;4;40-04-44N;095-35-31W;;;300;; +KFNL;--;---;Fort Collins Automatic Weather Observing / Reporting System;CO;United States;4;40-27N;105-01W;;;1529;; +KFNT;72;637;Flint, Bishop International Airport;MI;United States;4;42-58-00N;083-44-58W;42-58-27N;083-44-52W;238;233;P +KFOA;--;---;Flora, Flora Municipal Airport;IL;United States;4;38-39-54N;088-27-11W;;;144;; +KFOD;72;549;Fort Dodge;IA;United States;4;42-33N;094-11W;;;354;355; +KFOE;--;---;Topeka, Forbes Field;KS;United States;4;38-56-29N;095-39-02W;38-56-53N;095-40-35W;329;320; +KFOK;--;---;Westhampton Beach, The Gabreski Airport;NY;United States;4;40-51-03N;072-37-14W;40-50-23N;072-38-29W;20;33; +KFOQ;--;---;Freeport Supplementary Aviation Weather Reporting Station ;TX;United States;4;29-00N;095-19W;;;2;; +KFOZ;--;---;Bigfork, Bigfork Municipal Airport;MN;United States;4;47-46-58N;093-39-01W;;;411;; +KFPK;--;---;Charlotte, Fitch H Beach Airport;MI;United States;4;42-34-28N;084-48-41W;;;271;; +KFPR;--;---;Fort Pierce, St. Lucie County International Airport;FL;United States;4;27-29-53N;080-22-36W;27-29-35N;080-22-24W;8;13; +KFQD;--;---;Rutherfordton, Rutherford County-Marchman Field Airport;NC;United States;4;35-25-42N;081-56-06W;;;329;; +KFRG;--;---;Farmingdale, Republic Airport;NY;United States;4;40-44-03N;073-25-01W;40-43-39N;073-25-07W;24;21; +KFRI;72;455;Fort Riley;KS;United States;4;39-06N;096-46W;39-03N;096-46W;325;320; +KFRM;--;---;Fairmont Municipal Automatic Weather Observing / Reporting System;MN;United States;4;43-39N;094-25W;;;354;; +KFSD;72;651;Sioux Falls, Foss Field;SD;United States;4;43-34-37N;096-45-13W;43-35-14N;096-44-03W;435;434;P +KFSE;--;---;Fosston, Fosston Municipal Airport;MN;United States;4;47-35-34N;095-46-24W;;;389;; +KFSI;72;355;Fort Sill;OK;United States;4;34-36N;098-24W;34-39N;098-24W;362;360; +KFSM;72;344;Fort Smith, Fort Smith Regional Airport;AR;United States;4;35-20-01N;094-21-54W;35-20-16N;094-22-12W;142;140;P +KFST;--;---;Fort Stockton, Fort Stockton-Pecos County Airport;TX;United States;4;30-54-43N;102-55-00W;30-54-33N;102-54-45W;917;918; +KFSW;--;---;Fort Madison;IA;United States;4;40-40N;091-20W;;;221;; +KFTG;--;---;Denver Nexrad;CO;United States;4;39-47N;104-33W;;;1709;; +KFTK;72;424;Fort Knox;KY;United States;4;37-54N;085-58W;37-54N;085-58W;230;230; +KFTW;--;---;Fort Worth, Meacham International Airport;TX;United States;4;32-49-31N;097-21-51W;32-49-35N;097-21-22W;216;214; +KFTY;--;---;Atlanta, Fulton County Airport-Brown Field;GA;United States;4;33-46-39N;084-31-28W;33-46-37N;084-31-12W;256;263; +KFUL;--;---;Fullerton, Fullerton Municipal Airport;CA;United States;4;33-52-19N;117-59-05W;33-52-15N;117-58-48W;29;35; +KFVE;--;---;Frenchville, Northern Aroostook Regional Airport;ME;United States;4;47-17-06N;068-18-26W;47-17-13N;068-18-50W;301;301; +KFVX;--;---;Farmville;VA;United States;4;37-21N;078-26W;;;125;; +KFWA;72;533;Fort Wayne, Fort Wayne International Airport;IN;United States;4;40-58-42N;085-11-43W;40-59-11N;085-11-17W;248;248;P +KFWC;--;---;Fairfield, Fairfield Municipal Airport;IL;United States;4;38-22-43N;088-24-46W;;;133;; +KFWD;72;249;Fort Worth;TX;United States;4;32-50N;097-18W;32-50N;097-18W;196;196; +KFWN;--;---;Sussex, Sussex Airport;NJ;United States;4;41-12-01N;074-37-23W;41-12-02N;074-37-29W;128;133; +KFWS;--;---;Fort Worth, Forth Worth Spinks Airport;TX;United States;4;32-34N;097-18W;;;213;; +KFXE;--;---;Fort Lauderdale, Fort Lauderdale Executive Airport;FL;United States;4;26-12-00N;080-11-00W;26-11-44N;080-10-25W;4;6; +KFYJ;--;---;West Point, Middle Peninsula Regional Airport;VA;United States;4;37-31-16N;076-45-52W;;;7;; +KFYV;--;---;Fayetteville, Drake Field;AR;United States;4;36-00-37N;094-10-04W;36-00-19N;094-10-21W;381;379; +KFZY;--;---;Fulton, Oswego County Airport;NY;United States;4;43-21-03N;076-23-17W;;;145;; +KGAD;--;---;Gadsden Municipal Automatic Weather Observing / Reporting System;AL;United States;4;33-58N;086-05W;;;173;; +KGAG;--;---;Gage, Gage Airport;OK;United States;4;36-17-48N;099-46-08W;36-17-50N;099-46-07W;677;668; +KGBD;--;---;Great Bend Automatic Weather Observing / Reporting System;KS;United States;4;38-21N;098-52W;;;575;; +KGBG;--;---;Galesburg, Galesburg Municipal Airport;IL;United States;4;40-56-17N;090-25-52W;;;233;; +KGBN;74;724;Gila Bend U. S. Army Airfield;AZ;United States;4;32-26N;112-41W;32-56N;112-42W;262;261; +KGCC;72;665;Gillette, Gillette-Campbell County Airport;WY;United States;4;44-20-22N;105-32-31W;44-20-54N;105-32-13W;1330;1320;P +KGCK;--;---;Garden City, Garden City Regional Airport;KS;United States;4;37-55-39N;100-43-28W;37-55-36N;100-43-44W;881;877; +KGCM;--;---;Claremore, Claremore Regional Airport;OK;United States;4;36-17-40N;095-28-47W;;;221;; +KGCN;--;---;Grand Canyon, Grand Canyon National Park Airport;AZ;United States;4;35-56-46N;112-09-17W;35-57-27N;112-08-39W;2014;2016; +KGDB;--;---;Granite Falls, Granite Falls Municipal Airport/Lenzen-Roe Memorial Field;MN;United States;4;44-45-11N;095-33-21W;;;319;; +KGDJ;--;---;Granbury, Granbury Municipal Airport;TX;United States;4;32-26-39N;097-49W;;;237;; +KGDP;72;262;Pine Springs, Guadalupe Mountains National Park;TX;United States;4;31-49-52N;104-48-32W;;;1661;1692;P +KGDV;--;---;Glendive Automatic Weather Observing / Reporting System;MT;United States;4;47-08N;104-48W;;;749;; +KGED;--;---;Georgetown, Sussex County Airport;DE;United States;4;38-41-24N;075-21-45W;38-41-30N;075-21-46W;15;19; +KGEG;72;785;Spokane, Spokane International Airport;WA;United States;4;47-37-17N;117-31-40W;47-37-19N;117-32-22W;723;735;P +KGEU;--;---;Glendale, Glendale Municipal Airport;AZ;United States;4;33-31-38N;112-17-43W;;;325;; +KGEV;--;---;Jefferson, Ashe County Airport;NC;United States;4;36-26N;81-25W;;;969; +KGEY;--;---;Greybull, South Big Horn County Airport;WY;United States;4;44-30-57N;108-04-33W;44-30-36N;108-04-49W;1199;1191; +KGEZ;--;---;Shelbyville, Shelbyville Municipal Airport;IN;United States;4;39-35-08N;085-48-00W;39-34-42N;085-47-59W;245;245; +KGFA;--;---;Malmstrom Air Force Base;MT;United States;4;47-30N;111-11W;;;1075;; +KGFK;--;---;Grand Forks, Grand Forks International Airport;ND;United States;4;47-56-53N;097-10-57W;47-57-02N;097-10-42W;257;190; +KGFL;--;---;Glens Falls, Floyd Bennett Memorial Airport;NY;United States;4;43-20-28N;073-36-38W;43-20-30N;073-36-20W;100;103; +KGGB;--;---;Golden Gate Bridge;CA;United States;4;37-49N;122-28W;;;81;; +KGGG;72;247;Longview, Gregg County Airport;TX;United States;4;32-23-26N;094-42-50W;32-22-48N;094-42-43W;111;107;P +KGGW;72;768;Glasgow, Glasgow International Airport;MT;United States;4;48-12-50N;106-37-17W;48-12-30N;106-37-34W;699;693;P +KGHW;--;---;Glenwood Automatic Surface Observing System ;MN;United States;4;45-39N;095-19W;;;425;; +KGIF;--;---;Winter Haven, Winter Haven's Gilbert Airport;FL;United States;4;28-03-38N;081-45-27W;28-03-34N;081-45-08W;44;43; +KGJT;72;476;Grand Junction, Walker Field;CO;United States;4;39-08-02N;108-32-19W;39-07-00N;108-32-00W;1481;1452;P +KGKJ;--;---;Meadville, Port Meadville Airport;PA;United States;4;41-37-35N;080-12-53W;;;427;; +KGKN;--;---;Gulkana, Gulkana Airport;AK;United States;4;62-09-37N;145-27-27W;62-09-30N;145-27-24W;481;480; +KGKY;--;---;Arlington, Arlington Municipal Airport;TX;United States;4;32-39-50N;097-05-45W;32-39-52N;097-05-30W;192;185; +KGLD;72;465;Goodland, Renner Field;KS;United States;4;39-22-03N;101-41-35W;39-22-12N;101-41-53W;1114;1114;P +KGLE;--;---;Gainesville, Gainesville Municipal Airport;TX;United States;4;33-39-05N;097-11-49W;;;256;; +KGLH;--;---;Greenville, Mid Delta Regional Airport;MS;United States;4;33-28-58N;090-59-08W;33-28-53N;090-59-25W;40;45; +KGLR;--;---;Gaylord, Otsego County Airport;MI;United States;4;45-00-59N;084-41-20W;45-00-59N;084-41-30W;404;407; +KGLS;72;242;Galveston, Scholes Field;TX;United States;4;29-16-13N;094-51-51W;29-16-05N;094-51-18W;2;6;P +KGLW;--;---;Glasgow, Glasgow Municipal Airport;KY;United States;4;37-01-54N;085-57-13W;;;218;; +KGMJ;--;---;Grove, Grove Municipal Airport;OK;United States;4;36-36-19N;094-44-19W;;;254;; +KGMU;--;---;Greenville, Greenville Downtown Airport;SC;United States;4;34-50-46N;082-20-46W;34-51-01N;082-21-05W;319;315; +KGNA;--;---;Grand Marais, The Bay of Grand Marais;MN;United States;4;47-50N;090-23W;;;186;; +KGNC;--;---;Seminole, Gaines County Airport;TX;United States;4;32-40-31N;102-39-09W;;;1010;; +KGNR;--;---;Greenville;ME;United States;4;45-28N;69-35W;;;427;; +KGNT;--;---;Grants, Grants-Milan Municipal Airport;NM;United States;4;35-09-55N;107-54-08W;35-09-58N;107-53-56W;1988;1987; +KGNV;--;---;Gainesville, Gainesville Regional Airport;FL;United States;4;29-41-31N;082-16-32W;29-41-34N;082-16-48W;46;45; +KGOK;--;---;Guthrie, Guthrie Municipal Airport;OK;United States;4;35-51-07N;097-24-27W;35-51-03N;097-25-07W;327;324; +KGON;--;---;Groton / New London, Groton / New London Airport;CT;United States;4;41-19-39N;072-02-58W;41-19-55N;072-02-42W;3;3; +KGOV;--;---;Grayling, Grayling Army Airfield;MI;United States;4;44-40-49N;084-43-44W;;;353;; +KGPM;--;---;Grand Prairie, Grand Prairie Municipal Airport;TX;United States;4;32-41-55N;097-02-48W;;;180;; +KGPT;--;---;Gulfport, Gulfport-Biloxi Regional Airport;MS;United States;4;30-24-43N;089-04-51W;30-24-05N;089-04-21W;8;14; +KGPZ;--;---;Grand Rapids Automatic Weather Observing / Reporting System;MN;United States;4;47-13N;093-31W;;;413;; +KGRB;72;645;Green Bay, Austin Straubel International Airport;WI;United States;4;44-28-46N;088-08-12W;44-29-47N;088-06-46W;211;205;P +KGRD;--;---;Greenwood, Greenwood County Airport;SC;United States;4;34-14-50N;082-09-17W;34-14-46N;082-09-11W;192;185; +KGRF;74;207;Fort Lewis / Gray U. S. Army Airfield;WA;United States;4;47-07N;122-33W;47-08N;122-36W;92;87; +KGRI;72;552;Grand Island, Central Nebraska Regional Airport;NE;United States;4;40-57-30N;098-18-45W;40-57-30N;098-19-05W;562;561;P +KGRK;--;---;Fort Hood / Gray U. S. Army Airfield;TX;United States;4;31-04N;097-50W;;;309;; +KGRN;--;---;Gordon Municipal;NE;United States;4;42-48N;102-10W;;;1085;; +KGRR;72;635;Grand Rapids, Gerald R. Ford International Airport;MI;United States;4;42-52-51N;085-31-22W;42-53-04N;085-31-45W;242;239;P +KGSB;--;---;Seymour-Johnson Air Force Base;NC;United States;4;35-20N;077-58W;;;33;; +KGSH;--;---;Goshen, Goshen Municipal Airport;IN;United States;4;41-31-34N;085-47-12W;41-31-24N;085-47-39W;252;252; +KGSM;--;---;Ship Shoal 207A;LA;United States;4;28-32N;090-59W;;;1;; +KGSO;72;317;Greensboro, Piedmont Triad International Airport;NC;United States;4;36-05-51N;079-56-37W;36-05-53N;079-56-38W;282;275;P +KGSP;72;312;Greer, Greenville-Spartanburg Airport;SC;United States;4;34-53-02N;082-13-15W;34-53-00N;082-13-13W;296;286;P +KGTB;74;370;Fort Drum / Wheeler-Sack U. S. Army Airfield;NY;United States;4;44-03N;075-44W;44-03N;075-44W;207;207; +KGTF;72;775;Great Falls, Great Falls International Airport;MT;United States;4;47-28-24N;111-22-56W;47-28-48N;111-21-31W;1120;1119;P +KGTR;--;---;Golden Tri Automatic Weather Observing / Reporting System;MS;United States;4;33-27N;088-35W;;;80;; +KGTU;--;---;Georgetown Automatic Weather Observing / Reporting System;TX;United States;4;30-41N;097-41W;;;240;; +KGUC;--;---;Gunnison Automatic Weather Observing / Reporting System;CO;United States;4;38-32N;106-56W;;;2339;; +KGUP;--;---;Gallup, Gallup Municipal Airport;NM;United States;4;35-30-40N;108-47-22W;35-30-54N;108-46-50W;1973;1971; +KGUS;--;---;Grissom Air Force Base / Peru;IN;United States;4;40-39N;086-09W;;;247;; +KGUY;--;---;Guymon / Guymon Municipal Airport;OK;United States;4;36-40-54N;101-30-19W;;;952;948; +KGVL;--;---;Gainesville, Gilmer Memorial Airport;GA;United States;4;34-16-19N;083-49-49W;34-16-33N;083-49-51W;388;386; +KGVT;--;---;Greenville / Majors;TX;United States;4;33-04N;096-04W;;;163;; +KGVW;--;---;Kansas City, Richards-Gebaur Airport;MO;United States;4;38-50-06N;094-33-41W;38-50-45N;094-33-21W;332;337; +KGWO;--;---;Greenwood, Greenwood-LeFlore Airport;MS;United States;4;33-29-33N;090-05-01W;33-29-45N;090-05-22W;47;44; +KGWW;--;---;Goldsboro, Goldsboro-Wayne Municipal Airport;NC;United States;4;35-27-38N;077-57-54W;;;40;; +KGXY;--;---;Greeley / Weld Automatic Weather Observing / Reporting System;CO;United States;4;40-26N;104-38W;;;1420;; +KGYB;--;---;Giddings, Giddings-Lee County Airport;TX;United States;4;30-10-09N;096-58-48W;;;148;; +KGYI;--;---;Sherman/Denison, Grayson County Airport;TX;United States;4;33-43N;096-40W;;;228;; +KGYL;--;---;Glencoe, Glencoe Municipal Airport;MN;United States;4;44-45-22N;094-04-52W;;;302;; +KGYR;--;---;Goodyear Municipal;AZ;United States;4;33-25N;112-23W;;;295;; +KGYY;--;---;Gary Regional;IN;United States;4;41-37N;087-25W;;;180;; +KGZH;--;---;Evergreen, Middleton Field;AL;United States;4;31-25-08N;087-02-53W;31-25-10N;087-02-38W;78;78; +KH08;--;---;High Island 264C;LA;United States;4;28-28N;93-44W;;;0;; +KH32;--;---;Southwest Harbor;ME;United States;4;44-16N;068-19W;;;5;; +KH39;--;---;High Island A572c;LA;United States;4;27-57N;093-59W;;;30;; +KH92;74;643;Hominy Municipal;OK;United States;4;36-26N;096-23W;36-26N;096-23W;251;252; +KHAO;--;---;Hamilton, Butler County Regional Airport;OH;United States;4;39-21-41N;084-31-15W;39-21-47N;084-31-34W;193;188; +KHAT;72;304;Cape Hatteras;NC;United States;4;35-16N;075-33W;35-16N;075-33W;2;3;P +KHBG;--;---;Hattiesburg, Bobby L Chain Municipal Airport;MS;United States;4;31-15-54N;089-15-11W;31-16-11N;089-15-14W;46;44; +KHBI;--;---;Asheboro, Asheboro Municipal Airport;NC;United States;4;35-39-14N;079-53-42W;;;205;; +KHBR;--;---;Hobart, Hobart Municipal Airport;OK;United States;4;34-59-22N;099-03-09W;34-59-19N;099-03-26W;476;473; +KHBV;--;---;Hebbronville, Jim Hogg County Airport;TX;United States;4;27-20N;098-44W;;;202;; +KHCD;--;---;Hutchinson Automatic Weather Observing / Reporting System;MN;United States;4;44-52N;094-23W;;;323;; +KHCO;--;---;Hallock, Hallock Municipal Airport;MN;United States;4;48-45-10N;096-56-35W;;;250;; +KHDC;--;---;Hammond, Hammond Municipal Airport;LA;United States;4;30-31-15N;090-25-03W;;;13;; +KHDE;--;---;Brewster Field Airport;NE;United States;4;40-27N;099-20W;;;704;; +KHDN;--;---;Hayden / Yampa Automatic Weather Observing / Reporting System;CO;United States;4;40-29N;107-13W;;;2012;; +KHDO;--;---;Hondo, Hondo Municipal Airport;TX;United States;4;29-21-34N;099-10-27W;29-21-26N;099-09-49W;283;282; +KHEF;--;---;Manassas, Manassas Regional Airport/Harry P. Davis Field;VA;United States;4;38-43N;077-31W;;;59;; +KHEI;--;---;Hettinger, Hettinger Municipal Airport;ND;United States;4;46-00-38N;102-38-59W;46-01-02N;102-39-07W;824;828; +KHEY;--;---;Hanchey AHP / Ozark;AL;United States;4;31-21N;085-40W;;;97;; +KHEZ;--;---;Natchez / Hardy Automatic Weather Observing / Reporting System;MS;United States;4;31-37N;091-18W;;;83;; +KHFD;--;---;Hartford, Hartford-Brainard Airport;CT;United States;4;41-44-06N;072-39-06W;41-44-05N;072-39-07W;5;4; +KHFF;--;---;Mackall U. S. Army Airfield;NC;United States;4;35-02N;079-30W;;;115;; +KHGR;--;---;Hagerstown, Washington County Regional Airport;MD;United States;4;39-42-21N;077-43-48W;39-42-37N;077-43-53W;214;224; +KHGX;--;---;Houston / Galviston Nexrad;TX;United States;4;29-28N;095-05W;;;35;; +KHHF;--;---;Canadian, Hemphill County Airport;TX;United States;4;35-54N;100-24W;;;730;; +KHHR;--;---;Hawthorne, Hawthorne Municipal Airport;CA;United States;4;33-55-25N;118-19-55W;33-55-24N;118-20-10W;19;18; +KHIB;--;---;Hibbing, Chisholm-Hibbing Airport;MN;United States;4;47-23-12N;092-50-20W;47-23-33N;092-50-21W;412;412; +KHIE;--;---;Whitefield, Mount Washington Regional Airport;NH;United States;4;44-21-58N;071-33-09W;44-21-57N;071-33-03W;327;318; +KHIF;--;---;Hill Air Force Base / Ogden;UT;United States;4;41-07N;111-58W;;;1459;; +KHIO;--;---;Portland, Portland-Hillsboro Airport;OR;United States;4;45-32-53N;122-57-16W;45-32-15N;122-56-57W;62;68; +KHJH;--;---;Hebron, Hebron Municipal Airport;NE;United States;4;40-09-08N;097-35-13W;;;447;; +KHJO;--;---;Hanford, Hanford Municipal Airport;CA;United States;4;36-19-07N;119-37-44W;;;74;; +KHKA;--;---;Blytheville, Blytheville Municipal Airport;AR;United States;4;35-56-20N;089-49-57W;35-56-17N;089-49-55W;78;78; +KHKS;--;---;Jackson, Hawkins Field Airport;MS;United States;4;32-20-05N;090-13-21W;32-19-58N;090-13-35W;104;108; +KHKY;--;---;Hickory, Hickory Regional Airport;NC;United States;4;35-44-32N;081-22-56W;35-44-30N;081-23-22W;362;354; +KHLC;--;---;Hill City, Hill City Municipal Airport;KS;United States;4;39-22-29N;099-49-47W;;;678;669; +KHLD;--;---;Hiland;WY;United States;4;43-06N;107-19W;;;1846;; +KHLG;--;---;Wheeling, Wheeling Ohio County Airport;WV;United States;4;40-10-13N;080-38-40W;40-10-54N;080-38-48W;364;372; +KHLN;72;772;Helena, Helena Regional Airport;MT;United States;4;46-36-20N;111-57-49W;46-36-09N;111-59-39W;1180;1187;P +KHLR;72;257;Fort Hood;TX;United States;4;31-06N;097-20W;31-06N;097-20W;283;270; +KHLX;--;---;Hillsville;VA;United States;4;36-46N;080-49W;;;834;; +KHMM;--;---;Hamilton / Ravalli County;MT;United States;4;46-15N;114-09W;;;1110;; +KHMN;74;732;Holloman Air Force Base;NM;United States;4;32-51N;106-06W;32-54N;106-06W;1248;1248; +KHMS;72;784;Hanford;WA;United States;4;46-34N;119-36W;;;223;223; +KHMZ;--;---;Bedford, Bedford County Airport;PA;United States;4;40-05-07N;078-30-44W;;;354;; +KHNB;--;---;Huntingburg;IN;United States;4;38-15N;086-57W;;;161;; +KHND;--;---;Las Vegas, Henderson Airport;NV;United States;4;35-58-35N;115-07-58W;;;749;; +KHNR;--;---;Harlan, Harlan Municipal Airport;IA;United States;4;41-35-04N;095-20-23W;;;375;; +KHNS;--;---;Haines, Haines Airport;AK;United States;4;59-14-38N;135-30-34W;59-14-36N;135-30-34W;4;5; +KHNZ;--;---;Oxford, Henderson-Oxford Airport;NC;United States;4;36-21-42N;078-31-45W;;;161; +KHOB;--;---;Hobbs / Lea County;NM;United States;4;32-41N;103-13W;;;1115;; +KHOM;--;---;Homer, Homer Airport;AK;United States;4;59-38-33N;151-29-14W;59-38-23N;151-29-02W;23;23; +KHON;72;654;Huron, Huron Regional Airport;SD;United States;4;44-23-17N;098-13-42W;44-23-09N;098-13-22W;392;390;P +KHOP;74;671;Fort Campbell U. S. Army Airfield;KY;United States;4;36-40N;087-30W;36-40N;087-30W;174;174; +KHOT;--;---;Hot Springs, Memorial Field Airport;AR;United States;4;34-28-41N;093-05-46W;34-28-57N;093-05-44W;165;162; +KHOU;--;---;Houston, Houston Hobby Airport;TX;United States;4;29-38-15N;095-16-57W;29-38-24N;095-16-38W;14;36; +KHPN;--;---;White Plains, Westchester County Airport;NY;United States;4;41-04-01N;073-42-27W;41-03-46N;073-42-41W;134;121; +KHQM;--;---;Hoquiam, Bowerman Airport;WA;United States;4;46-58-16N;123-55-12W;46-58-26N;123-55-37W;4;7; +KHQU;--;---;Thomson, Thomson-McDuffie County Airport;GA;United States;4;33-31-46N;082-30-59W;;;152;; +KHQZ;--;---;Mesquite, Mesquite Metro Airport;TX;United States;4;32-44-49N;096-31-49W;;;136;; +KHRI;--;---;Hermiston, Hermiston Municipal Airport;OR;United States;4;45-49-33N;119-15-40W;45-49-41N;119-15-44W;194;195; +KHRJ;--;---;Erwin, Harnett County Airport;NC;United States;4;35-22-43N;078-44-01W;;;60;; +KHRL;--;---;Harlingen, Rio Grande Valley International Airport;TX;United States;4;26-13-47N;097-39-19W;26-13-33N;097-39-40W;10;10; +KHRO;--;---;Harrison, Boone County Airport;AR;United States;4;36-15-42N;093-09-17W;36-15-53N;093-09-03W;416;417; +KHRT;74;777;Hurlburt Field;FL;United States;4;30-25N;086-41W;30-26N;086-41W;12;11; +KHSA;--;---;Bay St. Louis, Stennis International Airport;MS;United States;4;30-22-04N;089-27-17W;;;7;; +KHSB;--;---;Harrisburg, Harrisburg-Raleigh Airport;IL;United States;4;37-48-41N;088-32-57W;;;121;; +KHSE;--;---;Hatteras, Mitchell Field;NC;United States;4;35-13-56N;075-37-21W;35-13-55N;075-37-22W;5;3; +KHSI;--;---;Hastings, Hastings Municipal Airport;NE;United States;4;40-36-02N;098-25-33W;40-36-00N;098-25-35W;595;591; +KHSP;--;---;Hot Springs / Ingalls;VA;United States;4;37-57N;079-50W;;;1156;; +KHSS;--;---;Hot Springs Aviation Weather Reporting Station;NC;United States;4;35-54N;082-49W;;;451;; +KHST;--;---;Homestead Air Force Base;FL;United States;4;25-29N;080-23W;;;2;; +KHSV;72;323;Huntsville, Huntsville International / Jones Field;AL;United States;4;34-38-37N;086-47-08W;34-38-46N;086-46-16W;192;191;P +KHTH;--;---;Hawthorne Municipal;NV;United States;4;38-33N;118-38W;;;1285;; +KHTL;72;638;Houghton Lake, Roscommon County Airport;MI;United States;4;44-21-04N;084-40-27W;44-21-02N;084-40-39W;350;351;P +KHTO;--;---;East Hampton, East Hampton Airport;NY;United States;4;40-57-34N;072-15-07W;;;17;; +KHTS;72;425;Huntington, Tri-State Airport;WV;United States;4;38-21-54N;082-33-18W;38-22-09N;082-33-18W;252;254;P +KHUF;--;---;Terre Haute, Terre Haute International Airport - Hulman Field;IN;United States;4;39-26-30N;087-19-31W;39-27-43N;087-18-09W;178;179; +KHUL;--;---;Houlton, Houlton International Airport;ME;United States;4;46-07-23N;067-47-31W;46-07-30N;067-47-10W;149;150; +KHUM;--;---;Houma-Terrebonne;LA;United States;4;29-34N;090-40W;;;3;; +KHUT;--;---;Hutchinson, Hutchinson Municipal Airport;KS;United States;4;38-04-05N;097-51-38W;38-03-59N;097-51-38W;470;467; +KHVN;--;---;New Haven, Tweed-New Haven Airport;CT;United States;4;41-15-50N;072-53-14W;41-15-55N;072-53-05W;4;3; +KHVR;72;777;Havre, Havre City-County Airport;MT;United States;4;48-32-34N;109-45-48W;48-32-46N;109-45-42W;789;787;P +KHWD;--;---;Hayward, Hayward Air Terminal;CA;United States;4;37-39-39N;122-07-06W;37-39-46N;122-07-11W;14;21; +KHWO;--;---;Hollywood, North Perry Airport;FL;United States;4;25-59-56N;080-14-28W;26-00-00N;080-15-06W;2;2; +KHWV;--;---;Shirley, Brookhaven Airport;NY;United States;4;40-49-18N;072-52-08W;40-48-56N;072-52-03W;25;21; +KHXD;--;---;Hilton Head Automatic Weather Observing / Reporting System;SC;United States;4;32-13N;080-42W;;;6;; +KHYA;--;---;Hyannis, Barnstable Municipal-Boardman Airport;MA;United States;4;41-40-19N;070-16-11W;41-40-19N;070-16-11W;15;22; +KHYI;--;---;San Marcos, San Marcos Municipal Airport;TX;United States;4;29-53-37N;097-51-53W;;;182;; +KHYR;--;---;Hayward, Hayward Municipal Airport;WI;United States;4;46-01-14N;091-27-01W;46-01-38N;091-26-45W;370;370; +KHYS;--;---;Hays Municipal Automatic Weather Observing / Reporting System;KS;United States;4;38-51N;099-16W;;;609;; +KHYX;--;---;Saginaw, Saginaw County H.W. Browne Airport;MI;United States;4;43-26-00N;083-51-45W;;;183;; +KHZX;--;---;Mc Gregor, Isedor Iverson Airport;MN;United States;4;46-37-07N;093-18-35W;;;374;; +KHZY;--;---;Ashtabula, Ashtabula County Airport;OH;United States;4;41-46-46N;080-41-48W;41-46-48N;080-42-04W;281;276; +KI16;--;---;Pineville, Kee Field Airport;WV;United States;4;37-36-01N;081-33-33W;;;544;; +KI63;--;---;Mount Sterling, Mount Sterling Municipal Airport;IL;United States;4;39-59-15N;090-48-15W;;;223;; +KIAB;--;---;McConnell Air Force Base;KS;United States;4;37-37N;097-16W;;;418;; +KIAD;72;403;Washington DC, Washington-Dulles International Airport;VA;United States;4;38-56-05N;077-26-51W;38-57-06N;077-26-37W;95;93;P +KIAG;--;---;Niagara Falls, Niagara Falls International Airport;NY;United States;4;43-06-26N;078-56-43W;43-06-01N;078-56-37W;180;182; +KIAH;72;243;Houston, Houston Intercontinental Airport;TX;United States;4;29-59-33N;095-21-50W;29-58-25N;095-20-33W;29;36; +KIBM;--;---;Kimball, Kimball Municipal Airport/Robert E Arraj Field;NE;United States;4;41-11N;103-40W;;;1501;; +KICL;--;---;Clarinda;IA;United States;4;40-43N;095-02W;;;303;; +KICT;72;450;Wichita, Wichita Mid-Continent Airport;KS;United States;4;37-38-50N;097-25-46W;37-39-16N;097-26-35W;406;408;P +KIDA;--;---;Idaho Falls, Fanning Field;ID;United States;4;43-31-15N;112-03-58W;43-30-56N;112-03-58W;1445;1453; +KIDI;--;---;Indiana / Stewart Field;PA;United States;4;40-38N;079-06W;;;429;; +KIDV;--;---;I-25 Divide;WY;United States;4;43-56N;106-39W;;;1531;; +KIEN;--;---;Pine Ridge, Pine Ridge Airport;SD;United States;4;43-01-32N;102-31-23W;43-01-34N;102-31-23W;1015;998; +KIER;--;---;Natchitoches, Natchitoches Regional Airport;LA;United States;4;31-44-09N;093-05-57W;;;37;; +KIFP;--;---;Bullhead City, Laughlin/Bullhead International Airport;AZ;United States;4;35-09-27N;114-33-34W;;;212;; +KIGC;--;---;Charleston Air Force Base;SC;United States;4;32-54N;080-03W;;;14;; +KIGM;72;370;Kingman, Kingman Airport;AZ;United States;4;35-15-28N;113-55-59W;35-15-35N;113-56-31W;1050;1032;P +KIGQ;--;---;Chicago, Lansing Municipal Airport;IL;United States;4;41-32-24N;087-31-56W;;;188;; +KIGX;--;---;Chapel Hill, Williams Airport;NC;United States;4;35-46-00N;079-03-51W;35-56-01N;079-03-38W;155;155; +KIIB;--;---;Independence, Independence Municipal Airport;IA;United States;4;42-27N;091-56W;;;298;; +KIIY;--;---;Washington, Washington-Wilkes County Airport;GA;United States;4;33-46-47N;082-48-59W;;;197;; +KIJD;--;---;Willimantic, Windham Airport;CT;United States;4;41-44-31N;072-11-01W;41-44-21N;072-10-56W;75;75; +KIJX;--;---;Jacksonville, Jacksonville Municipal Airport;IL;United States;4;39-46-27N;090-14-19W;;;190;; +KIKA;--;---;Inyan Kara;WY;United States;4;44-18N;104-38W;;;1319;; +KIKK;--;---;Kankakee, Greater Kankakee Airport;IL;United States;4;41-04-17N;087-50-47W;;;192;; +KIKR;--;---;Kirtland, Kirtland Air Force Base Auxiliary Field;NM;United States;4;34-57-00N;106-34-00W;;;1612;1609; +KIKV;--;---;Ankeny, Ankeny Regional Airport;IA;United States;4;41-41-24N;093-33-57W;;;275;; +KILE;--;---;Killeen Municipal Automatic Weather Observing / Reporting System;TX;United States;4;31-05N;097-41W;;;258;; +KILG;--;---;Wilmington, New Castle County Airport;DE;United States;4;39-40-22N;075-36-03W;39-40-30N;075-35-54W;24;28; +KILI;--;---;Iliamna, Iliamna Airport;AK;United States;4;59-44-57N;154-54-33W;59-44-57N;154-54-33W;63;52; +KILL;--;---;Willmar / Rice Automatic Weather Observing / Reporting System;MN;United States;4;45-07N;095-05W;;;344;; +KILM;--;---;Wilmington, Wilmington International Airport;NC;United States;4;34-16-14N;077-54-09W;34-16-31N;077-54-42W;10;9; +KILN;--;---;Wilmington, Airborne Airpark Airport;OH;United States;4;39-25-42N;083-46-45W;;;328;332; +KIML;--;---;Imperial, Imperial Municipal Airport;NE;United States;4;40-31N;101-37W;;;997;; +KIMT;--;---;Iron Mountain / Kingsford, Ford Airport;MI;United States;4;45-48-51N;088-06-32W;45-48-50N;088-07-00W;360;349; +KIND;72;438;Indianapolis, Indianapolis International Airport;IN;United States;4;39-43-30N;086-16-55W;39-42-29N;086-16-47W;243;242;P +KINJ;--;---;Hillsboro, Hillsboro Municipal Airport;TX;United States;4;32-05N;097-05-50W;;;209;; +KINK;--;---;Wink, Winkler County Airport;TX;United States;4;31-46-47N;103-12-05W;31-47-01N;103-11-40W;860;855; +KINL;72;747;International Falls, Falls International Airport;MN;United States;4;48-33-43N;093-23-52W;48-33-59N;093-23-53W;361;360;P +KINS;74;614;Indian Springs Gunnery Range;NV;United States;4;36-32N;115-54W;36-32N;115-54W;952;972; +KINT;--;---;Winston Salem, Smith Reynolds Airport;NC;United States;4;36-08-00N;080-13-29W;36-08-13N;080-13-42W;295;291; +KINW;72;374;Winslow, Winslow Municipal Airport;AZ;United States;4;35-01-41N;110-43-15W;35-01-17N;110-43-02W;1505;1490; +KINX;--;---;Tulsa Nexrad;OK;United States;4;36-11N;095-34W;;;226;; +KIOW;--;---;Iowa City, Iowa City Municipal Airport;IA;United States;4;41-37-58N;091-32-35W;47-38-25N;091-32-30W;203;198; +KIPJ;--;---;Lincolnton, Lincolnton-Lincoln County Regional Airport;NC;United States;4;35-28-59N;081-09-41W;;;267;; +KIPL;--;---;Imperial, Imperial County Airport;CA;United States;4;32-50-03N;115-34-43W;32-50-08N;115-34-36W;-17;-15; +KIPT;72;514;Williamsport, Williamsport Regional Airport;PA;United States;4;41-14-30N;076-55-15W;41-14-41N;076-55-08W;161;164; +KIRK;--;---;Kirksville, Kirksville Regional Airport;MO;United States;4;40-05-50N;092-32-36W;40-05-33N;092-32-41W;294;293; +KIRS;--;---;Sturgis, Kirsch Municipal Airport;MI;United States;4;41-48-46N;085-26-21W;;;282;; +KISM;--;---;Orlando, Kissimmee Municipal Airport;FL;United States;4;28-17-23N;081-26-14W;;;25;; +KISN;72;767;Williston, Sloulin Field International Airport;ND;United States;4;48-10-26N;103-38-12W;48-10-37N;103-37-52W;604;579;P +KISO;--;---;Kinston, Kinston Regional Jetport at Stallings Field;NC;United States;4;35-20N;077-37W;;;29;; +KISP;--;---;Islip, Long Island Mac Arthur Airport;NY;United States;4;40-47-38N;073-06-06W;40-47-29N;073-06-12W;30;43; +KISQ;--;---;Manistique, Schoolcraft County Airport;MI;United States;4;45-58-29N;086-10-19W;;;209;; +KISW;--;---;Wisconsin Rapids, Alexander Field South Wood County Airport;WI;United States;4;44-21-33N;089-50-13W;44-21-42N;089-49-59W;311;307; +KITH;--;---;Ithaca / Tompkins County;NY;United States;4;42-29N;076-27W;;;335;; +KITR;--;---;Burlington, Carson County Airport;CO;United States;4;39-14-32N;102-16-58W;39-14-38N;102-17-08W;1285;1279; +KIWA;--;---;Mesa, Williams Gateway Airport;AZ;United States;4;33-19N;111-39W;;;421;; +KIWD;--;---;Ironwood Automatic Weather Observing / Reporting System;MI;United States;4;46-32N;090-08W;;;375;; +KIWI;--;---;Wiscasset, Wiscasset Airport;ME;United States;4;43-57-49N;069-42-42W;43-57-50N;069-42-40W;20;20; +KIWS;--;---;West Houston / Lakeside;TX;United States;4;29-49N;095-40W;;;34;; +KIXD;--;---;Olathe, New Century Aircenter;KS;United States;4;38-49-28N;094-53-13W;38-50-03N;094-53-25W;331;342; +KIYK;--;---;Inyokern;CA;United States;4;35-40N;117-50W;;;749;; +KIZA;--;---;Santa Ynez, Santa Ynez Airport;CA;United States;4;34-36-25N;120-04-32W;;;205;; +KIZG;--;---;Fryeburg, Eastern Slopes Regional Airport;ME;United States;4;43-59-21N;070-57-01W;43-59-18N;070-56-59W;137;135; +KJAC;--;---;Jackson Hole Automatic Weather Observing / Reporting System;WY;United States;4;43-36N;110-44W;;;1964;; +KJAN;72;235;Jackson, Jackson International Airport;MS;United States;4;32-19-11N;090-04-39W;32-19-08N;090-04-49W;105;89;P +KJAS;--;---;Jasper, Jasper County-Bell Field Airport;TX;United States;4;30-53-08N;094-02-05W;;;65;; +KJAX;72;206;Jacksonville, Jacksonville International Airport;FL;United States;4;30-29-40N;081-41-36W;30-29-38N;081-40-52W;9;7;P +KJBR;--;---;Jonesboro, Jonesboro Municipal Airport;AR;United States;4;35-50-14N;090-38-35W;35-50-10N;090-38-53W;79;79; +KJCT;74;740;Junction, Kimble County Airport;TX;United States;4;30-30-39N;099-45-59W;30-30-36N;099-45-57W;527;523;P +KJDD;--;---;Mineola/Quitman, Wood County Airport;TX;United States;4;32-44-31N;095-29-47W;;;132;; +KJDN;--;---;Jordan, Jordan Airport;MT;United States;4;47-19-33N;106-56-51W;;;811;801; +KJEF;--;---;Jefferson City, Jefferson City Memorial Airport;MO;United States;4;38-35-40N;092-09-21W;38-35-42N;092-09-15W;167;168; +KJER;--;---;Jerome, Jerome County Airport;ID;United States;4;42-43-36N;114-27-26W;;;1234;; +KJFK;74;486;New York, Kennedy International Airport;NY;United States;4;40-38-19N;073-45-44W;40-38-34N;073-46-52W;3;9; +KJGG;--;---;Williamsburg, Williamsburg-Jamestown Airport;VA;United States;4;37-14-21N;076-42-57W;;;15;; +KJHW;--;---;Jamestown Automatic Weather Observing / Reporting System;NY;United States;4;42-09N;079-16W;;;525;; +KJKJ;--;---;Moorhead, Moorhead Municipal Airport;MN;United States;4;46-50-21N;096-39-47W;;;280;; +KJKL;--;---;Jackson, Carroll Airport;KY;United States;4;37-35-29N;083-18-52W;37-35-29N;083-19-02W;421;412; +KJLN;--;---;Joplin, Joplin Regional Airport;MO;United States;4;37-09-22N;094-30-02W;37-08-50N;094-30-03W;299;299; +KJMR;--;---;Mora, Mora Municipal Airport;MN;United States;4;45-53-10N;093-16-18W;;;309;; +KJMS;--;---;Jamestown, Jamestown Municipal Airport;ND;United States;4;46-55-47N;098-40-42W;46-55-35N;098-40-35W;457;455; +KJNW;--;---;Newport;OR;United States;4;44-35N;124-04W;;;48;; +KJNX;--;---;Smithfield, Johnston County Airport;NC;United States;4;35-32-27N;078-23-25W;;;50;; +KJOT;--;---;Joliet, Joliet Regional Airport;IL;United States;4;41-31-05N;088-10-31W;;;177;; +KJQF;--;---;Concord, Concord Regional Airport;NC;United States;4;35-23-07N;080-42-35W;;;210;; +KJSO;--;---;Jacksonville, Cherokee County Airport;TX;United States;4;31-52-09N;095-13-02W;;;206;; +KJST;--;---;Johnstown, Johnstown-Cambria County Airport;PA;United States;4;40-18-58N;078-50-02W;40-19-10N;078-49-59W;696;694; +KJSV;--;---;Sallisaw, Sallisaw Municipal Airport;OK;United States;4;35-26-17N;094-48-10W;;;161;; +KJVL;--;---;Janesville / Rock County;WI;United States;4;42-37N;089-02W;;;246;; +KJWG;--;---;Watonga, Watonga Airport;OK;United States;4;35-51-53N;098-25-15W;;;472;; +KJWX;--;---;Fort Ritchie;MD;United States;4;39-44N;077-26W;;;275;; +KJWY;--;---;Midlothian/Waxahachie, Mid-Way Regional Airport;TX;United States;4;32-27-21N;096-54-44W;;;217;; +KJXI;--;---;Gilmer, Fox Stephens Field - Gilmer Municipal Airport;TX;United States;4;32-41-56N;094-56-55W;;;127;; +KJXN;--;---;Jackson, Jackson County-Reynolds Field Airport;MI;United States;4;42-15-35N;084-27-34W;;;305;; +KJYG;--;---;St. James, St. James Municipal Airport;MN;United States;4;43-59-11N;094-33-29W;;;325;; +KJYL;--;---;Sylvania, Plantation Airpark;GA;United States;4;32-38-43N;081-35-47W;;;57;; +KJYM;--;---;Hillsdale, Hillsdale Municipal Airport;MI;United States;4;41-55-17N;084-35-09W;;;360;; +KJYO;--;---;Leesburg / Godfrey;VA;United States;4;39-05N;077-34W;;;119;; +KJYR;--;---;York, York Municipal Airport;NE;United States;4;40-53-48N;097-37-22W;;;509;; +KKAL;--;---;Kaltag, Kaltag Airport;AK;United States;4;64-19-27N;158-43-59W;64-19-27N;158-43-59W;60;52; +KKLS;--;---;Kelso-Longview Automatic Weather Observing / Reporting System;WA;United States;4;46-07N;122-54W;;;5;; +KKVL;--;---;Kivalina, Kivalina Airport;AK;United States;4;67-43-52N;164-32-33W;67-43-52N;164-32-33W;3;3; +KL10;--;---;San Clemente;CA;United States;4;33-25N;117-37W;;;3;; +KL13;--;---;Point Loma / Cabrillo;CA;United States;4;32-40N;117-29W;;;111;; +KL14;--;---;Cabrillo Beach;CA;United States;4;33-43N;118-17W;;;8;; +KL21;--;---;Scripps Pier / La Jol;CA;United States;4;32-52N;117-15W;;;4;; +KL27;--;---;Santa Catalina Island;CA;United States;4;33-20N;118-20W;;;3;; +KL34;--;---;Oceanside Harbor;CA;United States;4;33-13N;117-24W;;;9;; +KL40;--;---;High Island A489b;LA;United States;4;28-12N;094-12W;;;;; +KL42;--;---;Oakdale, Allen Parish Airport;LA;United States;4;30-45-02N;092-41-19W;;;33;; +KL46;--;---;Anacapa Island;CA;United States;4;34-01N;119-22W;;;42;; +KL55;--;---;Malibu Beach;CA;United States;4;34-02N;118-41W;;;139;; +KL58;--;---;Mission Beach;CA;United States;4;32-46N;117-14W;;;2;; +KL79;--;---;Oxnard / Channel Island;CA;United States;4;34-10N;119-13W;;;2;; +KL82;--;---;Terminal Island;CA;United States;4;33-44N;118-16W;;;10;; +KL97;--;---;Point Vincente;CA;United States;4;33-44N;118-24W;;;5;; +KL98;--;---;El Capitan Beach;CA;United States;4;33-27N;120-02W;;;27;; +KLAA;--;---;Lamar, Lamar Municipal Airport;CO;United States;4;38-04-21N;102-41-12W;38-04-34N;102-41-31W;1128;1119; +KLAF;--;---;Lafayette, Purdue University Airport;IN;United States;4;40-24-45N;086-56-51W;40-24-53N;086-56-00W;184;182; +KLAL;--;---;Lakeland Regional;FL;United States;4;27-59N;082-01W;;;43;; +KLAM;--;---;Los Alamos;NM;United States;4;35-53N;106-17W;;;2179;; +KLAN;72;539;Lansing, Capital City Airport;MI;United States;4;42-46-49N;084-34-44W;42-46-27N;084-35-35W;262;264; +KLAR;--;---;Laramie, Laramie Regional Airport;WY;United States;4;41-18-43N;105-40-30W;41-19-01N;105-40-16W;2218;2216; +KLAS;72;386;Las Vegas, McCarran International Airport;NV;United States;4;36-04-44N;115-09-19W;36-04-58N;115-08-47W;663;636;P +KLAW;--;---;Lawton, Lawton Municipal Airport;OK;United States;4;34-33-27N;098-25-00W;34-34-34N;098-25-16W;338;337; +KLAX;72;295;Los Angeles, Los Angeles International Airport;CA;United States;4;33-56-17N;118-23-20W;33-56-41N;118-24-10W;38;46;P +KLBB;72;267;Lubbock, Lubbock International Airport;TX;United States;4;33-40-03N;101-49-17W;33-39-30N;101-48-52W;1000;992;P +KLBE;--;---;Latrobe / Westmorland;PA;United States;4;40-17N;079-24W;;;361;; +KLBF;72;562;North Platte, North Platte Regional Airport;NE;United States;4;41-07-19N;100-40-06W;41-07-58N;100-41-54W;846;847;P +KLBL;--;---;Liberal Municipal Automatic Weather Observing / Reporting System;KS;United States;4;37-03N;100-58W;;;879;; +KLBR;--;---;Clarksville, Clarksville/Red River County-J D Trissell Field Airport;TX;United States;4;33-35-35N;095-03-48W;;;134;; +KLBT;--;---;Lumberton, Lumberton Municipal Airport;NC;United States;4;34-36-26N;079-03-36W;34-36-50N;079-03-37W;38;37; +KLBX;--;---;Angleton / Lake Jackson, Brazoria County Airport;TX;United States;4;29-06-55N;095-27-47W;29-06-42N;095-27-35W;7;6; +KLCH;72;240;Lake Charles, Lake Charles Regional Airport;LA;United States;4;30-07-34N;093-13-24W;30-07-29N;093-12-55W;5;3;P +KLCI;--;---;Laconia Municipal Automatic Weather Observing / Reporting System;NH;United States;4;43-34N;071-25W;;;166;; +KLCK;--;---;Rickenbacker Air National Guard Base;OH;United States;4;39-49N;082-56W;;;227;; +KLDM;--;---;Ludington, Mason County Airport;MI;United States;4;43-58N;86-24W;;;197;; +KLDS;--;---;Leeds;MT;United States;4;48-33N;109-41W;;;775;; +KLEB;--;---;Lebanon, Lebanon Municipal Airport;NH;United States;4;43-37-38N;072-18-21W;43-37-41N;072-18-42W;182;171; +KLEE;--;---;Leesburg, Leesburg Regional Airport;FL;United States;4;28-49-21N;081-48-32W;28-49-44N;081-48-48W;24;23; +KLEW;--;---;Auburn-Lewiston;ME;United States;4;44-03N;070-17W;;;88;; +KLEX;72;422;Lexington, Blue Grass Airport;KY;United States;4;38-02-27N;084-36-21W;38-02-13N;084-35-54W;298;300;P +KLFI;74;598;Langley Air Force Base;VA;United States;4;37-05N;076-21W;;;3;6; +KLFK;--;---;Lufkin, Angelina County Airport;TX;United States;4;31-14-02N;094-45-00W;31-13-53N;094-45-12W;90;88; +KLFT;--;---;Lafayette, Lafayette Regional Airport;LA;United States;4;30-12-08N;091-59-35W;30-12-10N;091-59-42W;12;11; +KLGA;72;503;New York, La Guardia Airport;NY;United States;4;40-46-45N;073-52-48W;40-46-25N;073-53-08W;6;11;P +KLGB;72;297;Long Beach, Long Beach Airport;CA;United States;4;33-48-42N;118-08-47W;33-48-42N;118-08-57W;17;10; +KLGC;--;---;La Grange, Callaway Airport;GA;United States;4;33-00-32N;085-04-21W;;;211;; +KLGD;--;---;La Grande Automatic Weather Observing / Reporting System;OR;United States;4;45-17N;118-00W;;;827;; +KLGU;--;---;Logan, Logan-Cache Airport;UT;United States;4;41-46-58N;111-51-14W;41-46-58N;111-51-12W;1357;1355; +KLHB;--;---;Hearne, Hearne Municipal Airport;TX;United States;4;30-52-18N;096-37-20W;;;87;; +KLHD;--;---;Anchorage, Lake Hood Sea Plane Base;AK;United States;4;61-10-41N;149-57-49W;61-10-41N;149-57-49W;21;28; +KLHQ;--;---;Lancaster, Fairfield County Airport;OH;United States;4;39-45-26N;082-39-48W;39-45-10N;082-39-42W;264;260; +KLHU;--;---;Lake Havasu Automatic Weather Observing / Reporting System;AZ;United States;4;34-28N;111-46W;;;147;; +KLHW;72;209;Ft. Stewart;GA;United States;4;31-53N;081-34W;31-53N;081-34W;14;14; +KLHX;--;---;La Junta, La Junta Municipal Airport;CO;United States;4;38-02-58N;103-30-44W;38-02-43N;103-30-41W;1288;1277; +KLHZ;--;---;Louisburg, Franklin County Airport;NC;United States;4;36-01-24N;078-19-49W;;;113;; +KLIC;--;---;Limon, Limon Municipal Airport;CO;United States;4;39-16-24N;103-40-00W;39-16-09N;103-40-00W;1635;1630; +KLIT;--;---;Little Rock, Adams Field;AR;United States;4;34-43-36N;092-14-10W;34-43-59N;092-14-26W;79;79; +KLIX;72;233;Slidell;LA;United States;4;30-20N;089-49W;30-20N;089-49W;8;8; +KLIZ;--;---;Loring Air Force Base / Limeston;ME;United States;4;46-57N;067-53W;;;227;; +KLJF;--;---;Litchfield, Litchfield Municipal Airport;MN;United States;4;45-05-50N;094-30-26W;;;348;; +KLKU;--;---;Louisa, Louisa County / Freeman Field Airport;VA;United States;4;38-00-35N;077-58-13W;;;150;; +KLKV;--;---;Lakeview Automatic Weather Observing / Reporting System;OR;United States;4;42-10N;120-24W;;;1441;; +KLLJ;--;---;Challis, Challis Airport;ID;United States;4;44-31-22N;114-12-54W;44-31-12N;114-12-54W;1546;1536; +KLLQ;--;---;Monticello, Monticello Municipal Airport/Ellis Field;AR;United States;4;33-38-18N;091-45-04W;33-38-04N;091-45-20W;82;83; +KLMT;--;---;Klamath Falls, Klamath Falls International Airport;OR;United States;4;42-08-49N;121-43-27W;42-09-41N;121-44-32W;1247;1246; +KLNC;--;---;Lancaster, Lancaster Airport;TX;United States;4;32-34-45N;096-43-08W;;;153;; +KLND;72;576;Lander;WY;United States;4;42-48-53N;108-43-41W;42-49-00N;108-44-00W;1703;1694;P +KLNK;72;551;Lincoln, Lincoln Municipal Airport;NE;United States;4;40-49-52N;096-45-52W;40-51-01N;096-44-52W;370;364; +KLNL;--;---;Land O' Lakes, Kings Land O' Lakes Airport;WI;United States;4;46-09-14N;089-12-43W;;;520;; +KLNN;--;---;Willoughby;OH;United States;4;41-41N;081-23W;;;191;; +KLNP;--;---;Wise / Lonesome Pine;VA;United States;4;36-59N;082-32W;;;817;; +KLNR;--;---;Lone Rock, Tri-County Regional Airport;WI;United States;4;43-12-43N;090-10-53W;43-12-48N;090-11-27W;219;217; +KLNS;--;---;Lancaster, Lancaster Airport;PA;United States;4;40-07-13N;076-17-40W;40-07-28N;076-16-52W;123;125; +KLOL;--;---;Lovelock, Derby Field Airport;NV;United States;4;40-03-59N;118-33-55W;40-04-13N;118-34-09W;1190;1189; +KLOM;--;---;Philadelphia, Wings Field Airport;PA;United States;4;40-08-15N;075-15-54W;;;92;; +KLOR;--;---;Fort Rucker, Lowe Army Heliport;AL;United States;4;31-21-32N;085-44-54W;;;78;93; +KLOT;--;---;Chicago/Romeoville, Lewis University Airport;IL;United States;4;41-36-30N;088-05-39W;;;205;; +KLOU;--;---;Louisville, Bowman Field Airport;KY;United States;4;38-13-40N;085-39-49W;38-13-40N;085-39-39W;166;164; +KLOZ;--;---;London, London-Corbin Airport-Magee Field;KY;United States;4;37-05-22N;084-04-07W;37-05-15N;084-04-15W;369;362; +KLPC;--;---;Lompoc Automatic Weather Observing / Reporting System;CA;United States;4;34-40N;120-28W;;;27;; +KLPR;--;---;Lorain / Elyria, Lorain County Regional Airport;OH;United States;4;41-20-46N;082-10-46W;41-20-20N;082-10-38W;242;241; +KLRD;72;252;Laredo International Airport;TX;United States;4;27-33N;099-28W;;;155;; +KLRF;--;---;Little Rock Air Force Base;AR;United States;4;34-55N;092-09W;;;95;; +KLRJ;--;---;Le Mars, Le Mars Municipal Airport;IA;United States;4;42-46-41N;096-11-37W;;;365;; +KLRU;--;---;Las Cruces, Las Cruces International Airport;NM;United States;4;32-17-22N;106-55-19W;;;1358;; +KLRX;--;---;Elko Nexrad;NV;United States;4;40-44-20N;116-48-10W;;;2019;; +KLSD;--;---;Lexington / Creech;KY;United States;4;38-02N;084-37W;;;299;; +KLSE;72;643;La Crosse, La Crosse Municipal Airport;WI;United States;4;43-52-46N;091-15-24W;43-52-18N;091-15-09W;199;200; +KLSF;72;225;Fort Benning;GA;United States;4;32-20N;084-50W;32-20N;084-50W;71;130; +KLSV;--;---;Nellis Air Force Base;NV;United States;4;36-14N;115-02W;;;570;; +KLTS;72;352;Altus Air Force Base;OK;United States;4;34-39N;099-16W;34-39N;099-16W;420;420; +KLTX;--;---;Wilmington Nexrad;NC;United States;4;33-59N;078-26W;;;44;; +KLUD;--;---;Decatur, Decatur Municipal Airport;TX;United States;4;33-15-16N;097-34-50W;;;319;; +KLUF;--;---;Luke Air Force Base / Phoenix;AZ;United States;4;33-32N;112-23W;33-32N;112-23W;332;332; +KLUK;--;---;Cincinnati, Cincinnati Municipal Airport Lunken Field;OH;United States;4;39-06-21N;084-24-57W;39-06-26N;084-25-24W;147;155; +KLUM;--;---;Menomonie, Menomonie Municipal Airport-Score Field;WI;United States;4;44-53-32N;091-52-04W;;;273;; +KLVJ;--;---;Houston, Pearland Regional Airport;TX;United States;4;29-31-16N;095-14-31W;29-31-05N;095-14-29W;13;12; +KLVK;--;---;Livermore, Livermore Municipal Airport;CA;United States;4;37-41-34N;121-48-52W;37-41-45N;121-49-01W;121;117; +KLVM;--;---;Livingston, Mission Field Airport;MT;United States;4;45-41-58N;110-26-54W;45-41-49N;110-27-12W;1419;1418; +KLVN;--;---;Minneapolis, Airlake Airport;MN;United States;4;44-37-40N;093-13-41W;;;293;; +KLVS;--;---;Las Vegas, Las Vegas Municipal Airport;NM;United States;4;35-39-15N;105-08-33W;35-39-05N;105-08-50W;2096;2091; +KLVX;--;---;Louisville Nexrad;KY;United States;4;37-59N;085-56W;;;254;; +KLWB;--;---;Lewisburg / Greenbrier;WV;United States;4;37-52N;080-24W;;;702;; +KLWC;--;---;Lawrence, Lawrence Municipal Airport;KS;United States;4;39-00-30N;095-12-42W;39-00-18N;095-12-57W;253;253; +KLWD;--;---;Lamoni, Lamoni Municipal Airport;IA;United States;4;40-37-50N;093-54-03W;40-37-47N;093-54-01W;344;346; +KLWM;--;---;Lawrence, Lawrence Municipal Airport;MA;United States;4;42-42-47N;071-07-33W;42-42-55N;071-07-14W;45;54; +KLWS;72;783;Lewiston, Lewiston-Nez Perce County Airport;ID;United States;4;46-22-29N;117-00-52W;46-22-38N;117-00-37W;438;438; +KLWT;--;---;Lewistown, Lewistown Municipal Airport;MT;United States;4;47-02-57N;109-27-59W;;;1270;; +KLWV;--;---;Lawrenceville, Lawrenceville-Vincennes International Airport;IL;United States;4;38-45-38N;087-35-56W;38-45-40N;087-36-20W;131;131; +KLWX;--;---;Baltimore / DC Nexrad;MD;United States;4;38-59N;077-29W;;;113;; +KLXL;--;---;Little Falls Automatic Weather Observing / Reporting System;MN;United States;4;45-57N;094-21W;;;342;; +KLXN;--;---;Lexington, Jim Kelly Field Airport;NE;United States;4;40-47-28N;099-46-38W;;;736;; +KLXT;--;---;Lee's Summit, Lee's Summit Municipal Airport;MO;United States;4;38-57-35N;094-22-18W;;;306;; +KLXV;--;---;Leadville, Lake County Airport;CO;United States;4;39-13-41N;106-18-58W;;;3026;3028; +KLYH;72;410;Lynchburg, Lynchburg Regional Airport;VA;United States;4;37-19-15N;079-12-24W;37-19-45N;079-12-09W;285;295; +KLZK;72;340;North Little Rock, North Little Rock Airport;AR;United States;4;34-50N;092-15W;34-50N;092-15W;165;165;P +KLZU;--;---;Lawrenceville, Gwinnett County-Briscoe Field Airport;GA;United States;4;33-58-41N;083-57-45W;;;323;; +KM30;--;---;Metropolis, Metropolis Municipal Airport;IL;United States;4;37-11-09N;088-45-02W;;;117;; +KM39;--;---;Mena, Mena Intermountain Municipal Airport;AR;United States;4;34-32-43N;094-12-09W;34-32-54N;094-12-33W;329;; +KM82;--;---;Huntsville, Madison County Executive Airport;AL;United States;4;34-51-41N;086-33-26W;;;230;; +KMAE;--;---;Madera, Madera Municipal Airport;CA;United States;4;36-59-12N;120-06-39W;36-59-20N;120-06-28W;77;77; +KMAF;72;265;Midland, Midland International Airport;TX;United States;4;31-56-52N;102-12-31W;31-56-38N;102-11-23W;875;872;P +KMAI;--;---;Marianna, Marianna Municipal Airport;FL;United States;4;30-50-12N;085-11-01W;30-50-06N;085-10-56W;34;32; +KMAX;--;---;Medford Nexrad;OR;United States;4;42-04-51N;122-42-57W;;;2290; +KMBG;--;---;Mobridge, Mobridge Municipal Airport;SD;United States;4;45-33-00N;100-24-31W;45-32-35N;100-24-13W;522;510; +KMBL;--;---;Manistee, Manistee County-Blacker Airport;MI;United States;4;44-16N;086-15W;;;189;; +KMBS;--;---;Saginaw, MBS International Airport;MI;United States;4;43-31-58N;084-04-46W;43-31-36N;084-04-58W;204;202; +KMCB;--;---;McComb, McComb / Pike County / John E Lewis Field Airport;MS;United States;4;31-10-42N;090-28-19W;31-10-55N;090-28-16W;126;124; +KMCC;--;---;Sacramento, McClellan Airfield Airport;CA;United States;4;38-40N;121-24W;;;23;; +KMCD;--;---;Macinac Island, Mackinac Island Airport;MI;United States;4;45-51-54N;084-38-14W;;;226;; +KMCE;--;---;Merced, Merced Municipal Airport;CA;United States;4;37-16-59N;120-30-28W;37-17-20N;120-30-52W;47;47; +KMCF;74;788;Macdill Air Force Base, Fl.;FL;United States;4;27-51N;082-30W;27-51N;082-30W;4;4; +KMCG;--;---;McGrath, McGrath Airport;AK;United States;4;62-57-22N;155-36-21W;62-57-29N;155-36-00W;102;102; +KMCI;72;446;Kansas City, Kansas City International Airport;MO;United States;4;39-17-50N;094-43-50W;39-17-57N;094-43-03W;312;320;P +KMCK;--;---;McCook, McCook Municipal Airport;NE;United States;4;40-12-11N;100-35-18W;40-12-14N;100-35-38W;786;782; +KMCN;72;217;Macon, Middle Georgia Regional Airport;GA;United States;4;32-41-16N;083-39-16W;32-42-05N;083-38-53W;107;109;P +KMCO;72;205;Orlando, Orlando International Airport;FL;United States;4;28-25-02N;081-19-30W;28-25-52N;081-18-38W;29;29;P +KMCW;--;---;Mason City, Mason City Municipal Airport;IA;United States;4;43-09-28N;093-19-53W;43-09-12N;093-20-11W;370;369; +KMDD;--;---;Midland, Midland Airpark;TX;United States;4;32-02-11N;102-06-03W;;;854;; +KMDH;--;---;Carbondale / Murphysboro, Southern Illinois Airport;IL;United States;4;37-46-59N;089-14-42W;37-46-36N;089-15-09W;125;130; +KMDQ;--;---;Huntsville, Madison County Executive Airport;AL;United States;4;34-51-41N;086-33-26W;;;230;; +KMDT;--;---;Harrisburg, Harrisburg International Airport;PA;United States;4;40-11-37N;076-45-48W;40-11-50N;076-45-48W;95;95; +KMDW;72;534;Chicago, Chicago Midway Airport;IL;United States;4;41-47-03N;087-45-19W;41-46-49N;087-45-08W;188;188; +KMDZ;--;---;Medford, Taylor County Airport;WI;United States;4;45-06-04N;090-18-12W;;;448;; +KMEB;--;---;Maxton, Laurinburg-Maxton Airport;NC;United States;4;34-47-29N;079-22-05W;34-47-47N;079-22-07W;67;67; +KMEH;--;---;Meacham, Meacham;OR;United States;4;45-30-41N;118-25-29W;45-30-41N;118-25-29W;1135;1136; +KMEI;72;234;Meridian, Key Field;MS;United States;4;32-20-17N;088-44-52W;32-20-03N;088-44-25W;90;89;P +KMEM;72;334;Memphis, Memphis International Airport;TN;United States;4;35-03-40N;089-59-06W;35-03-00N;089-58-45W;101;86;P +KMER;72;481;Merced / Castle Air Force Base;CA;United States;4;37-22N;120-34W;37-23N;120-34W;57;60; +KMFD;--;---;Mansfield, Mansfield Lahm Municipal Airport;OH;United States;4;40-49-13N;082-31-04W;40-48-56N;082-30-45W;395;395; +KMFE;--;---;McAllen, Miller International Airport;TX;United States;4;26-10-47N;098-14-40W;26-10-42N;098-14-17W;32;38; +KMFI;--;---;Marshfield, Marshfield Municipal Airport;WI;United States;4;44-38-17N;090-11-15W;44-38-25N;090-11-01W;389;379; +KMFR;72;597;Medford, Rogue Valley International Airport;OR;United States;4;42-22-52N;122-52-20W;42-22-37N;122-52-50W;405;396;P +KMFV;--;---;Melfa / Accomack Airport;VA;United States;4;37-39N;075-46W;;;15;; +KMGE;72;227;Marietta / Dobbins Air Force Base;GA;United States;4;33-55N;084-31W;;;326;326;P +KMGG;--;---;Maple Lake, Maple Lake Municipal Airport;MN;United States;4;45-14-10N;093-59-08W;;;313;; +KMGJ;--;---;Montgomery, Orange County Airport;NY;United States;4;41-30-33N;074-15-54W;41-30-55N;074-15-41W;111;108; +KMGM;72;226;Montgomery, Dannelly Field;AL;United States;4;32-18-01N;086-24-22W;32-18-17N;086-23-27W;67;63;P +KMGN;--;---;Harbor Springs, Harbor Springs Airport;MI;United States;4;45-25-32N;084-54-48W;;;209;; +KMGR;--;---;Moultrie, Moultrie Municipal Airport;GA;United States;4;31-05-05N;083-48-11W;;;90;; +KMGW;--;---;Morgantown, Morgantown Municipal-Hart Field;WV;United States;4;39-38-58N;079-55-16W;39-38-35N;079-55-12W;380;378; +KMGY;--;---;Dayton, Dayton-Wright Brothers Airport;OH;United States;4;39-35-20N;084-13-29W;39-35-29N;084-13-42W;292;289; +KMHE;--;---;Mitchell, Mitchell Municipal Airport;SD;United States;4;43-46N;098-02W;;;397;; +KMHK;--;---;Manhattan, Manhattan Municipal Airport;KS;United States;4;39-08-07N;096-40-40W;39-08-03N;096-40-10W;321;317; +KMHN;--;---;Mullen / Hooker County;NE;United States;4;42-03N;101-04W;;;994;; +KMHR;--;---;Sacramento, Sacramento Mather Airport;CA;United States;4;38-33N;121-18W;;;29;; +KMHS;--;---;Mount Shasta;CA;United States;4;41-18-57N;122-18-58W;41-18-56N;122-18-57W;1077;1078; +KMHT;--;---;Manchester, Manchester Airport;NH;United States;4;42-55-45N;071-26-09W;42-56-01N;071-26-21W;71;81; +KMHV;--;---;Mojave;CA;United States;4;35-04N;118-09W;;;849;; +KMHX;72;305;Newport;NC;United States;4;34-47N;076-53W;34-47N;076-53W;11;11; +KMIA;72;202;Miami, Miami International Airport;FL;United States;4;25-47-26N;080-18-59W;25-48-12N;080-17-49W;3;8;P +KMIB;--;---;Minot Air Force Base;ND;United States;4;48-25N;101-21W;;;508;; +KMIC;--;---;Minneapolis, Crystal Airport;MN;United States;4;45-03-45N;093-21-03W;45-03-39N;093-21-20W;264;265; +KMIE;--;---;Muncie, Delaware County-Johnson Field;IN;United States;4;40-14-03N;085-23-37W;40-14-31N;085-23-47W;285;285; +KMIV;--;---;Millville, Millville Municipal Airport;NJ;United States;4;39-21-58N;075-04-42W;39-22-12N;075-04-15W;26;23; +KMIW;--;---;Marshalltown, Marshalltown Municipal Airport;IA;United States;4;42-06-38N;092-54-58W;42-06-31N;092-54-51W;296;296; +KMJQ;--;---;Jackson Municipal Automatic Weather Observing / Reporting System;MN;United States;4;43-39N;094-59W;;;441;; +KMKC;--;---;Kansas City, Kansas City Downtown Airport;MO;United States;4;39-07-15N;094-35-49W;39-07-27N;094-35-31W;231;227; +KMKE;72;640;Milwaukee, General Mitchell International Airport;WI;United States;4;42-57-18N;087-54-16W;42-56-52N;087-54-23W;220;206;P +KMKG;72;636;Muskegon, Muskegon County Airport;MI;United States;4;43-10-16N;086-14-12W;43-09-50N;086-14-19W;191;191;P +KMKJ;--;---;Marion / Wytheville;VA;United States;4;36-54N;081-21W;;;780;; +KMKK;--;---;Kaunakakai, Molokai Airport;HI;United States;5;21-09-28N;157-05-55W;21-09-29N;157-05-54W;138;141; +KMKL;--;---;Jackson, McKellar-Sipes Regional Airport;TN;United States;4;35-35-35N;088-55-00W;35-36-12N;088-55-22W;132;128; +KMKO;--;---;Muskogee, Davis Field;OK;United States;4;35-39-25N;095-21-35W;35-39-33N;095-21-14W;185;185; +KMKT;--;---;Mankato Automatic Weather Observing / Reporting System;MN;United States;4;44-13N;093-55W;;;311;; +KMKX;--;---;Milwaukee NEXRAD;WI;United States;4;42-58N;088-33W;;;312;; +KMLB;72;204;Melbourne, Melbourne International Airport;FL;United States;4;28-06-10N;080-38-45W;28-05-57N;080-38-36W;10;10; +KMLC;--;---;McAlester, McAlester Regional Airport;OK;United States;4;34-52-56N;095-46-59W;34-52-30N;095-46-59W;234;232; +KMLD;--;---;Malad City;ID;United States;4;42-10N;112-18W;;;1373;; +KMLE;--;---;Omaha, Millard Airport;NE;United States;4;41-11-45N;096-06-44W;;;320;; +KMLF;--;---;Milford, Milford Municipal Airport;UT;United States;4;38-25-21N;113-00-35W;38-25-08N;113-00-34W;1536;1534; +KMLI;72;544;Moline, Quad-City Airport;IL;United States;4;41-27-05N;090-30-53W;41-26-33N;090-30-34W;179;184; +KMLJ;--;---;Milledgeville, Baldwin County Airport;GA;United States;4;33-09-15N;083-14-26W;;;117;; +KMLP;--;---;Mullan Pass, Mullan Pass Vor;ID;United States;4;47-27-15N;115-40-11W;47-27-23N;115-38-45W;1829;1837; +KMLS;74;230;Miles City, Frank Wiley Field Airport;MT;United States;4;46-25-41N;105-53-11W;46-25-40N;105-52-29W;801;801; +KMLT;--;---;Millinocket, Millinocket Municipal Airport;ME;United States;4;45-38-52N;068-41-31W;45-38-38N;068-41-30W;124;123; +KMLU;--;---;Monroe, Monroe Regional Airport;LA;United States;4;32-30-42N;092-01-53W;32-30-36N;092-02-36W;24;29; +KMMH;--;---;Mammoth / June Lakes;CA;United States;4;37-37N;118-50W;;;2173;; +KMMK;--;---;Meriden, Meriden Markham Municipal Airport;CT;United States;4;41-30-35N;072-49-40W;41-30-48N;072-49-49W;31;31; +KMML;--;---;Marshall / Ryan Automatic Weather Observing / Reporting System;MN;United States;4;44-27N;095-49W;;;359;; +KMMO;74;460;Marseilles Island;IL;United States;4;41-22N;088-41W;;;223;225; +KMMT;--;---;McEntire Air National Guard Weather Facility Base;SC;United States;4;33-55N;080-48W;;;77;; +KMMU;--;---;Morristown Municipal;NJ;United States;4;40-48N;074-25W;;;57;; +KMMV;--;---;McMinnville, McMinnville Municipal Airport;OR;United States;4;45-11-46N;123-07-56W;45-11-58N;123-08-17W;48;48; +KMNH;--;---;Elbert Mountain, Monument Pass;CO;United States;4;39-13-00N;104-38-02W;;;2152;; +KMNI;--;---;Manning / Cooper Regional;SC;United States;4;33-35N;080-13W;;;32;; +KMNM;--;---;Menominee Automatic Weather Observing / Reporting System;MI;United States;4;45-08N;087-38W;;;191;; +KMNN;--;---;Marion, Marion Municipal Airport;OH;United States;4;40-37-00N;083-04-06W;40-36-59N;083-04-06W;303;301; +KMOB;72;223;Mobile, Mobile Regional Airport;AL;United States;4;30-41-18N;088-14-44W;30-40-58N;088-14-30W;66;67;P +KMOD;--;---;Modesto, Modesto City-County-Sham Field;CA;United States;4;37-37-27N;120-57-02W;37-37-45N;120-57-11W;29;29; +KMOP;--;---;Mount Pleasant, Mount Pleasant Municipal Airport;MI;United States;4;43-37N;84-44W;;;230;; +KMOT;--;---;Minot, Minot International Airport;ND;United States;4;48-15-34N;101-16-49W;48-16-13N;101-17-06W;523;519; +KMOX;--;---;Morris Municipal Automatic Weather Observing / Reporting System;MN;United States;4;45-34N;095-58W;;;344;; +KMPO;--;---;Mount Pocono, Pocono Mountains Municipal Airport;PA;United States;4;41-08-20N;075-23-46W;41-08-47N;075-22-31W;584;577; +KMPV;--;---;Barre / Montpelier, Knapp State Airport;VT;United States;4;44-12-17N;072-33-58W;44-12-08N;072-33-47W;355;343; +KMPZ;--;---;Mount Pleasant, Mount Pleasant Municipal Airport;IA;United States;4;40-56-48N;091-30-40W;;;224;; +KMQB;--;---;Macomb, Macomb Municipal Airport;IL;United States;4;40-31-13N;090-39-09W;;;216;; +KMQE;--;---;East Milton;MA;United States;4;42-12-44N;71-06-53W;;;192;; +KMQI;--;---;Manteo / Dare County Regional;NC;United States;4;35-55N;075-42W;;;4;; +KMQM;--;---;Monida;MT;United States;4;44-34N;112-19W;;;2068;; +KMQT;72;743;Marquette;MI;United States;4;46-32N;087-33W;46-34N;087-24W;434;434;P +KMQY;--;---;Smyrna;TN;United States;4;36-01N;086-31W;;;166;; +KMRB;--;---;Martinsburg, Eastern West Virginia Regional/Shepherd Airport;WV;United States;4;39-24-07N;077-59-04W;39-23-58N;077-58-50W;170;164; +KMRC;--;---;Columbia / Maury County;TN;United States;4;35-33N;087-11W;;;206;; +KMRF;72;264;Marfa;TX;United States;4;30-22N;104-01W;;;1478;1481;P +KMRH;--;---;Beaufort, Michael J Smith Field Airport;NC;United States;4;34-44-01N;076-39-38W;34-43-59N;076-39-16W;3;3; +KMRI;--;---;Anchorage, Merrill Field;AK;United States;4;61-13-01N;149-51-18W;61-13-04N;149-50-25W;41;40; +KMRJ;--;---;Mineral Point, Iowa County Airport;WI;United States;4;42-53-07N;090-13-55W;;;359;; +KMRN;--;---;Morganton, Morganton-Lenoir Airport;NC;United States;4;35-49-17N;081-36-39W;;;387;; +KMRX;--;---;Morristown Nexrad;TN;United States;4;36-10N;083-24W;;;437;; +KMRY;--;---;Monterey, Monterey Peninsula Airport;CA;United States;4;36-35-26N;121-50-51W;36-35-17N;121-51-12W;77;66; +KMSL;--;---;Muscle Shoals, North West Alabama Regional Airport;AL;United States;4;34-44-38N;087-35-58W;34-44-49N;087-37-03W;167;164; +KMSN;72;641;Madison, Dane County Regional-Truax Field;WI;United States;4;43-08-26N;089-20-43W;43-08-22N;089-20-46W;262;261;P +KMSO;72;773;Missoula, Missoula International Airport;MT;United States;4;46-55-15N;114-05-33W;46-55-30N;114-05-24W;975;975;P +KMSP;72;658;Minneapolis, Minneapolis-St. Paul International Airport;MN;United States;4;44-52-59N;093-13-44W;44-53-15N;093-12-25W;256;265;P +KMSS;--;---;Massena, Massena International-Richards Field;NY;United States;4;44-56-09N;074-50-44W;44-56-00N;074-50-35W;66;66; +KMSV;--;---;Monticello Automatic Weather Observing / Reporting System;NY;United States;4;41-42N;074-48W;;;428;; +KMSX;--;---;Missoula NEXRAD;MT;United States;4;47-02N;113-59W;;;2451;; +KMSY;72;231;New Orleans, New Orleans International Airport;LA;United States;4;29-59-34N;090-15-03W;29-59-11N;090-15-31W;1;5;P +KMTC;--;---;Selfridge Air National Guard Base;MI;United States;4;42-37N;082-50W;;;177;; +KMTH;--;---;Marathon, Marathon Airport;FL;United States;4;24-43-33N;081-02-52W;24-43-31N;081-02-57W;2;2; +KMTJ;--;---;Montrose, Montrose Regional Airport;CO;United States;4;38-30-18N;107-53-51W;38-29-32N;107-53-21W;1755;1750; +KMTN;--;---;Baltimore / Martin;MD;United States;4;39-20N;076-25W;;;7;; +KMTO;--;---;Mattoon / Charleston, Coles County Memorial Airport;IL;United States;4;39-28-41N;088-16-45W;39-29-01N;088-16-33W;220;214; +KMTP;--;---;Montauk, Montauk Airport;NY;United States;4;41-04-23N;071-55-24W;;;2;2; +KMTV;--;---;Martinsville;VA;United States;4;36-38N;080-01W;;;287;; +KMTW;--;---;Manitowoc Municipal Automatic Weather Observing / Reporting System;WI;United States;4;44-08N;087-41W;;;198;; +KMTX;--;---;Salt Lake Nexrad;UT;United States;4;41-26N;112-45W;;;2004;; +KMUI;--;---;Muir Army Air Field / Indiantown;PA;United States;4;40-26N;076-34W;;;149;; +KMUO;--;---;Mountain Home Air Force Base;ID;United States;4;43-03N;115-52W;;;913;; +KMUT;--;---;Muscatine;IA;United States;4;41-22N;091-09W;;;167;; +KMUX;--;---;Monterey NEXRAD;CA;United States;4;37-10N;121-54W;;;1082;; +KMVE;--;---;Montevideo Automatic Weather Observing / Reporting System;MN;United States;4;44-58N;095-43W;;;315;; +KMVL;--;---;Morrisville, Morrisville-Stowe State Airport;VT;United States;4;44-32-10N;072-36-58W;44-32-13N;072-36-57W;223;223; +KMVN;--;---;Mount Vernon Automatic Weather Observing / Reporting System;IL;United States;4;38-19N;088-52W;;;146;; +KMVY;--;---;Vineyard Haven, Marthas Vineyard Airport;MA;United States;4;41-23-32N;070-37-00W;41-23-22N;070-36-45W;20;16; +KMWA;--;---;Marion, Williamson County Regional Airport;IL;United States;4;37-45-01N;089-00-04W;;;144;; +KMWC;--;---;Milwaukee / Timmerman;WI;United States;4;43-07N;088-02W;;;227;; +KMWH;--;---;Moses Lake, Grant County Airport;WA;United States;4;47-11-35N;119-18-48W;47-11-23N;119-19-19W;361;362; +KMWK;--;---;Mount Airy, Mount Airy/Surry County Airport;NC;United States;4;36-27-35N;080-33-11W;;;380;; +KMWL;--;---;Mineral Wells, Mineral Wells Airport;TX;United States;4;32-46-54N;098-03-37W;32-47-00N;098-03-45W;297;284; +KMWM;--;---;Windom, Windom Municipal Airport;MN;United States;4;43-54-48N;095-06-34W;;;430;; +KMWN;72;613;Mount Washington;NH;United States;4;44-16N;071-18W;;;1909;1910; +KMWS;72;289;Mount Wilson;CA;United States;4;34-14N;118-04W;;;1739;; +KMWT;--;---;Mount Ida;AR;United States;4;34-33N;93-35W;;;214;; +KMXF;--;---;Maxwell Air Force Base / Montgomery;AL;United States;4;32-23N;086-22W;;;51;; +KMXO;--;---;Monticello Municipal;IA;United States;4;42-14N;091-10W;;;259;; +KMYF;--;---;San Diego, Montgomery Field;CA;United States;4;32-48-52N;117-08-11W;32-49-01N;117-08-04W;128;136; +KMYL;--;---;McCall, McCall Airport;ID;United States;4;44-53-00N;116-05-58W;44-53-50N;116-05-54W;1530;1533; +KMYP;--;---;Salida Mountain, Monarch Pass;CO;United States;4;38-29-04N;106-19-01W;;;3667 +KMYR;74;791;Myrtle Beach Air Force Base;SC;United States;4;33-41N;078-56W;33-41N;078-56W;8;8; +KMYV;--;---;Marysville, Yuba County Airport;CA;United States;4;39-05-52N;121-34-11W;39-05-50N;121-33-56W;19;21; +KMZH;--;---;Moose Lake, Moose Lake Carlton County Airport;MN;United States;4;46-25N;092-48W;;;328;; +KN00;--;---;Fulton, Oswego County Airport;NY;United States;4;43-20-59N;076-23-05W;43-21-03N;076-23-37W;144;138; +KN11;--;---;New Haven Coast Guard Station;CT;United States;4;41-16N;072-54W;;;3;; +KN28;--;---;Ambrose / Ft. Tilden;NY;United States;4;40-27N;073-49W;;;1;; +KN60;--;---;Garrison;ND;United States;4;47-38-45N;101-26-22W;;;582;582; +KN67;--;---;Philadelphia, Wings Field Airport;PA;United States;4;40-08-15N;075-15-54W;;;92;; +KN78;74;590;Barnegat Coast Guard Station;NJ;United States;4;39-46N;074-06W;;;6;; +KN80;--;---;Ocean City, Ocean City Municipal Airport;MD;United States;4;38-18-30N;075-07-26W;38-18-38N;075-07-13W;3;3; +KN84;--;---;Bronx / Execution Coast Guard Station;NY;United States;4;40-53N;073-44W;;;8;; +KN91;--;---;Cape May Coast Guard Station;NJ;United States;4;38-57N;074-53W;;;2;; +KNAE;--;---;Astor, Bombing Range Detachment Astor;FL;United States;4;29-08-35N;081-37-58W;29-08-34N;081-37-59W;28;29; +KNAK;--;---;Annapolis, United States Naval Academy;MD;United States;4;38-59-29N;076-29-00W;38-59-02N;076-29-03W;2;11; +KNBC;--;---;Beaufort, Marine Corps Air Station;SC;United States;4;32-29-37N;080-42-11W;32-28-15N;080-43-26W;11;8; +KNBE;--;---;Dallas United States Naval Air Station;TX;United States;4;32-44N;096-58W;;;150;; +KNBG;--;---;New Orleans, Naval Air Station;LA;United States;4;29-50-14N;090-01-28W;29-49-33N;090-01-32W;0;0; +KNBJ;--;---;Barin, Barin Field, Naval Air Facility;AL;United States;4;30-23-28N;087-37-57W;30-23-20N;087-38-13W;13;14; +KNBQ;--;---;Kings Bay, Naval Station;GA;United States;4;30-47-39N;081-33-25W;30-47-05N;081-34-14W;8;10; +KNBT;--;---;Piney Island, Bt-11 Bombing Range;NC;United States;4;35-01-20N;076-27-45W;34-58-00N;076-23-11W;5;3; +KNCA;--;---;Jacksonville, New River, Marine Corps Air Station;NC;United States;4;34-42-21N;077-26-27W;34-42-26N;077-26-07W;7;4; +KNDZ;--;---;Milton, Whiting Field South;FL;United States;4;30-41-50N;087-01-12W;30-42-12N;087-00-54W;54;62; +KNED;--;---;Winner, Wiley Field;SD;United States;4;43-23-22N;099-50-34W;43-23-17N;099-50-40W;619;621; +KNEL;72;409;Lakehurst Naval Air Station;NJ;United States;4;40-02N;074-19W;40-02N;074-19W;31;24; +KNEW;--;---;New Orleans, New Orleans Lakefront Airport;LA;United States;4;30-02-58N;090-01-44W;30-02-31N;090-01-32W;2;3; +KNEX;--;---;Charleston Nise;SC;United States;4;32-55N;079-59W;;;12;; +KNFE;--;---;Fentress, Naval Auxiliary Landing Field;VA;United States;4;36-42-03N;076-07-42W;36-42-20N;076-07-40W;3;4; +KNFG;--;---;Oceanside, Camp Pendleton, Marine Corps Air Station;CA;United States;4;33-18-17N;117-21-14W;33-18-25N;117-21-13W;23;23; +KNFJ;--;---;Milton, Choctaw Pensacola, Naval Auxiliary Landing Field;FL;United States;4;30-30-42N;086-57-14W;30-30-45N;086-57-19W;33;38; +KNFL;--;---;Fallon, Naval Air Station;NV;United States;4;39-25-56N;118-41-08W;39-25-16N;118-42-34W;1199;1199; +KNFW;--;---;Fort Worth, Naval Air Station;TX;United States;4;32-45-57N;097-26-00W;32-46-36N;097-25-54W;198;187; +KNGP;--;---;Corpus Christi, Naval Air Station;TX;United States;4;27-41-19N;097-17-30W;27-41-30N;097-16-54W;5;4; +KNGU;--;---;Norfolk, Naval Air Station;VA;United States;4;36-56-01N;076-17-45W;36-56-21N;076-17-34W;4;8; +KNGW;--;---;Corpus Christi, Cabiness Field, Naval Auxiliary Landing Field;TX;United States;4;27-43-21N;097-26-33W;27-43-50N;097-29-04W;9;12; +KNGZ;74;506;Alameda Naval Air Station;CA;United States;4;37-47N;122-19W;;;4;9; +KNHK;72;404;Patuxent River, Naval Air Station;MD;United States;4;38-16-43N;076-24-50W;38-17-20N;076-25-23W;12;6; +KNHZ;74;392;Brunswick, Naval Air Station;ME;United States;4;43-54-01N;069-56-06W;43-53-52N;069-56-06W;22;23; +KNID;74;612;China Lake, Naval Air Facility;CA;United States;4;35-41-11N;117-41-24W;35-41-15N;117-40-47W;696;682; +KNIP;--;---;Jacksonville, Naval Air Station;FL;United States;4;30-14-03N;081-40-29W;30-13-45N;081-40-03W;6;8; +KNIS;--;---;Cherry Point, Marine Corps Air Station;NC;United States;4;34-53-11N;076-51-47W;34-54-35N;076-53-16W;8;9; +KNJK;72;281;El Centro, Naval Air Facility;CA;United States;4;32-49-30N;115-39-38W;32-49-28N;115-40-22W;-13;-13; +KNJM;--;---;Swansboro, Bogue Field, Marine Corps Auxiliary Landing Field;NC;United States;4;34-41-34N;077-01-46W;34-41-34N;077-01-46W;6;6; +KNJW;--;---;Meridian Range, B;MS;United States;4;32-47-39N;088-49-58W;32-47-38N;088-49-58W;164;163; +KNKT;72;309;Cherry Point, Marine Corps Air Station;NC;United States;4;34-53-52N;076-52-51W;34-54-35N;076-53-16W;8;9; +KNKX;72;293;San Diego, Miramar MCAS/Mitscher Field Airport;CA;United States;4;32-52-06N;117-08-33W;32-52-28N;117-08-20W;146;146; +KNLC;74;702;Lemoore, Naval Air Station;CA;United States;4;36-18-13N;119-56-17W;36-19-40N;119-56-50W;71;72; +KNLT;--;---;Atlantic, Atlantic Field Outlying Landing Field;NC;United States;4;34-52-45N;076-20-10W;34-52-35N;076-20-50W;4;4; +KNMM;--;---;Meridian, Naval Air Station;MS;United States;4;32-32-47N;088-32-35W;32-33-27N;088-33-33W;96;86; +KNMT;--;---;McMullen, McMullen Target Site;TX;United States;4;28-14-10N;098-43-27W;28-14-10N;098-43-25W;79;85; +KNNZ;--;---;Point Sur;CA;United States;4;36-18N;121-53W;;;34;; +KNOG;--;---;Orange Grove, Naval Auxiliary Landing Field;TX;United States;4;27-53-21N;098-02-39W;27-53-58N;098-02-54W;78;91; +KNOW;74;201;Port Angeles Coast Guard Air Station;WA;United States;4;48-08N;123-24W;;;5;9; +KNPA;--;---;Pensacola, Naval Air Station;FL;United States;4;30-21-22N;087-19-24W;30-20-51N;087-19-40W;9;10; +KNQA;--;---;Millington, Millington Municipal Airport;TN;United States;4;35-21-24N;089-52-13W;;;98;; +KNQI;--;---;Kingsville, Naval Air Station;TX;United States;4;27-30-11N;097-48-42W;27-30-20N;097-48-51W;15;15; +KNQX;--;---;Key West, Naval Air Station;FL;United States;4;24-34-46N;081-41-02W;27-34-49N;081-41-18W;1;6; +KNRA;--;---;Coupeville, Outlying Landing Field;WA;United States;4;48-11-26N;122-37-50W;48-11-27N;122-37-45W;60;59; +KNRB;--;---;Mayport, Naval Air Facility;FL;United States;4;30-23-45N;081-25-21W;30-23-33N;081-25-02W;5;4; +KNRC;--;---;Crows Landing Naval Auxiliary Landing Field;CA;United States;4;37-24N;121-06W;;;50;; +KNRS;--;---;Imperial Beach, Naval Auxiliary Landing Field;CA;United States;4;32-33-47N;117-06-36W;;;7;5; +KNSE;--;---;Milton, Whiting Field North;FL;United States;4;30-44-00N;087-01-00W;30-43-04N;087-01-21W;60;60; +KNSI;72;291;San Nicholas Island;CA;United States;4;33-14-05N;119-27-10W;33-14-25N;119-27-31W;153;153; +KNTD;72;391;Point Mugu, Naval Air Warfare Center;CA;United States;4;34-07-26N;119-07-18W;34-06-46N;119-07-04W;3;2; +KNTU;--;---;Virginia Beach, Oceana, Naval Air Station;VA;United States;4;36-49-16N;076-01-42W;36-49-07N;076-02-00W;6;6; +KNUC;--;---;San Clemente, Naval Auxiliary Landing Field;CA;United States;4;33-01-16N;118-34-52W;33-01-19N;118-35-01W;55;62; +KNUI;--;---;St. Inigoes, Webster Field, Naval Electronic Systems Engineering Activity;MD;United States;4;38-08-56N;076-25-12W;38-08-30N;076-25-45W;6;6; +KNUQ;74;509;Mountain View, Moffett Field;CA;United States;4;37-24-21N;122-02-53W;37-24-32N;122-02-59W;10;19; +KNUW;--;---;Whidbey Island, Naval Air Station;WA;United States;4;48-20-57N;122-39-02W;48-20-45N;122-40-06W;14;8; +KNVT;--;---;Corpus Christi, Waldron Outlying Landing Field;TX;United States;4;27-37-52N;097-18-42W;27-37-54N;097-18-42W;7;10; +KNXP;--;---;Twenty-Nine Palms, Marine Corps Air-Ground Combat Center;CA;United States;4;34-17-40N;116-08-42W;34-17-41N;116-09-08W;626;627; +KNXX;--;---;Willow Grove, Naval Air Station;PA;United States;4;40-11-35N;075-08-40W;40-12-15N;075-08-20W;110;101; +KNYC;--;---;New York City, Central Park;NY;United States;4;40-47-00N;073-58-00W;;;47;48; +KNYG;--;---;Quantico, Marine Corps Air Facility;VA;United States;4;38-30-45N;077-17-30W;38-32-20N;077-18-25W;3;3; +KNYL;--;---;Yuma, Marine Corps Air Station;AZ;United States;4;32-37-25N;113-45-50W;32-39-34N;114-35-35W;64;63; +KNZC;--;---;Cecil, Naval Air Station;FL;United States;4;30-12-44N;081-52-13W;30-13-16N;081-52-51W;24;26; +KNZY;--;---;San Diego, North Island, Naval Air Station;CA;United States;4;32-41-27N;117-12-32W;32-47-08N;117-11-49W;7;14; +KO18;--;---;Hanford, Hanford Municipal Airport;CA;United States;4;36-19-03N;119-37-46W;36-18-52N;119-37-39W;75;74; +KO64;72;590;Fort Bragg;CA;United States;4;39-24N;123-49W;;;19;; +KO72;--;---;Point Cabrillo;CA;United States;4;39-21N;123-49W;;;20;; +KO87;--;---;Shelter Cove;CA;United States;4;40-01N;124-04W;;;21;; +KOAJ;--;---;Jacksonville Automatic Weather Observing / Reporting System;NC;United States;4;34-50N;077-37W;;;29;; +KOAK;72;493;Oakland, Metro Oakland International Airport;CA;United States;4;37-43-10N;122-14-07W;37-42-45N;122-12-48W;1;26;P +KOAX;72;558;Valley;NE;United States;4;41-19N;096-22W;41-19N;096-22W;350;350; +KOCF;--;---;Ocala Municipal Automatic Weather Observing / Reporting System;FL;United States;4;29-10N;082-13W;;;27;; +KOCH;--;---;Nacogdoches Automatic Weather Observing / Reporting System;TX;United States;4;31-35N;094-43W;;;108;; +KOCW;--;---;Washington, Warren Field Airport;NC;United States;4;35-34-14N;077-02-59W;;;12;; +KODO;--;---;Odessa, Odessa-Schlemeyer Field;TX;United States;4;31-55-17N;102-23-30W;31-55-08N;102-23-32W;914;902; +KODX;--;---;Ord, Evelyn Sharp Field Airport;NE;United States;4;41-37-27N;098-57-09W;;;631;; +KOEB;--;---;Coldwater, Branch County Memorial Airport;MI;United States;4;41-56N;085-03-09W;;;292;; +KOEO;--;---;Osceola, L O Simenstad Municipal Airport;WI;United States;4;45-18-31N;092-41-24W;;;275;; +KOFF;72;554;Omaha / Offutt Air Force Base;NE;United States;4;41-07N;095-54W;;;319;315; +KOFK;72;556;Norfolk, Stefan Memorial Airport;NE;United States;4;41-58-50N;097-26-13W;41-59-05N;097-25-48W;479;470;P +KOFP;--;---;Ashland, Hanover County Municipal Airport;VA;United States;4;37-42-29N;077-26-04W;37-42-25N;077-26-18W;62;62; +KOGA;--;---;Ogallala, Searle Field Airport;NE;United States;4;41-07-11N;101-46-08W;;;999;; +KOGB;--;---;Orangeburg, Orangeburg Municipal Airport;SC;United States;4;33-27-50N;080-51-13W;33-27-59N;080-51-18W;60;59; +KOGD;72;575;Ogden, Ogden-Hinckley Airport;UT;United States;4;41-11-37N;112-00-59W;41-11-36N;112-00-25W;1362;1353; +KOGS;--;---;Ogdensburg International;NY;United States;4;44-41N;075-28W;;;91;; +KOHX;--;---;Nashville NEXRAD;TN;United States;4;36-45N;086-34W;;;206;; +KOJC;--;---;Olathe, Johnson County Executive Airport;KS;United States;4;38-51-00N;094-44-21W;38-50-51N;094-44-14W;334;326; +KOKB;--;---;Oceanside, Oceanside Municipal Airport;CA;United States;4;33-13-05N;117-21-05W;33-13-03N;117-21-07W;9;8; +KOKC;72;353;Oklahoma City, Will Rogers World Airport;OK;United States;4;35-23-19N;097-36-01W;35-24-05N;097-36-04W;394;390;P +KOKH;--;---;Oceanside, Oceanside Municipal Airport;CA;United States;4;33-13-10N;117-20-58W;33-13-03N;117-21-07W;8;8; +KOKK;--;---;Kokomo, Kokomo Municipal Airport;IN;United States;4;40-32N;086-04W;;;253;; +KOKM;--;---;Okmulgee, Okmulgee Municipal Airport;OK;United States;4;35-40-05N;095-56-55W;;;220;; +KOKV;--;---;Winchester Regional;VA;United States;4;39-09N;078-09W;;;222;; +KOKX;--;---;N. Y. City NEXRAD;NY;United States;4;40-52N;072-52W;;;60;; +KOLD;--;---;Old Town / Dewitt Field;ME;United States;4;44-57N;068-40W;;;39;; +KOLE;--;---;Olean Municipal;NY;United States;4;42-14N;078-22W;;;651;; +KOLF;--;---;Wolf Point, Clayton Airport;MT;United States;4;48-05-40N;105-34-38W;48-05-43N;105-34-21W;605;604; +KOLM;72;792;Olympia, Olympia Airport;WA;United States;4;46-58-24N;122-54-12W;46-58-30N;122-53-46W;62;58; +KOLS;--;---;Nogales, Nogales International Airport;AZ;United States;4;31-25-15N;110-50-45W;31-25-05N;110-50-57W;1198;1184; +KOLU;--;---;Columbus Municipal Automatic Weather Observing / Reporting System;NE;United States;4;41-27N;097-20W;;;440;; +KOLV;--;---;Olive Branch, Olive Branch Airport;MS;United States;4;34-58-44N;089-47-13W;;;122;; +KOLY;--;---;Olney-Noble, Olney-Noble Airport;IL;United States;4;38-43-19N;088-10-35W;;;147;; +KOLZ;--;---;Oelwein, Oelwein Municipal Airport;IA;United States;4;42-40-51N;091-58-28W;;;328;; +KOMA;72;550;Omaha, Eppley Airfield;NE;United States;4;41-18-37N;095-53-57W;41-18-03N;095-53-55W;299;312;P +KOMH;--;---;Orange, Orange County Airport;VA;United States;4;38-14-50N;78-02-44W;;;142;; +KOMK;--;---;Omak, Omak Airport;WA;United States;4;48-27-51N;119-31-05W;48-27-40N;119-30-54W;397;395; +KONA;--;---;Winona Municipal Automatic Weather Observing / Reporting System;MN;United States;4;44-05N;091-42W;;;200;; +KONL;--;---;O'Neill / Baker Field;NE;United States;4;42-28N;098-41W;;;619;; +KONM;72;362;Socorro Municipal;NM;United States;4;34-01N;106-54W;;;1478;; +KONO;--;---;Ontario, Ontario Municipal Airport;OR;United States;4;44-01-10N;117-00-35W;44-01-24N;117-00-46W;667;667; +KONP;--;---;Newport, Newport Municipal Airport;OR;United States;4;44-34-49N;124-03-29W;;;49;; +KONT;--;---;Ontario, Ontario International Airport;CA;United States;4;34-03-12N;117-34-33W;34-03-05N;117-35-55W;287;275; +KONZ;--;---;Detroit/Grosse Ile, Grosse Ile Airport;MI;United States;4;42-05-55N;083-09-40W;;;180;; +KOPF;--;---;Miami, Opa Locka Airport;FL;United States;4;25-54-36N;080-16-59W;25-54-35N;080-16-23W;3;16; +KOPN;--;---;Thomaston, Thomaston-Upson County Airport;GA;United States;4;32-57-18N;084-15-52W;;;243;; +KOQT;--;---;Oak Ridge;TN;United States;4;36-01-22N;84-14W;;;279;; +KOQU;--;---;N. Kingston / Quonset;RI;United States;4;41-36N;071-25W;;;6;; +KORB;--;---;Orr;MN;United States;4;48-01N;092-52W;;;397;; +KORC;--;---;Orange City;IA;United States;4;42-59N;096-04W;;;431;; +KORD;72;530;Chicago, Chicago-O'Hare International Airport;IL;United States;4;41-58-47N;087-54-16W;42-00N;087-53W;203;200;P +KORE;--;---;Orange, Orange Municipal Airport;MA;United States;4;42-34-18N;072-16-39W;42-34-20N;072-16-31W;169;164; +KORF;72;308;Norfolk, Norfolk International Airport;VA;United States;4;36-54-13N;076-11-31W;36-53-28N;076-17-06W;8;14;P +KORG;--;---;Orange, Orange County Airport;TX;United States;4;30-04-09N;093-48-13W;;;4;; +KORH;--;---;Worcester, Worcester Regional Airport;MA;United States;4;42-16-14N;071-52-23W;42-16-10N;071-52-18W;307;304; +KORL;--;---;Orlando, Orlando Executive Airport;FL;United States;4;28-32-47N;081-20-09W;28-32-37N;081-19-44W;34;37; +KORS;--;---;Eastsound, Orcas Island Airport;WA;United States;4;48-42-29;122-54-37W;;;9;; +KOSA;--;---;Mount Pleasant, Mount Pleasant Regional Airport;TX;United States;4;33-05-43N;094-57-41W;;;111;; +KOSC;--;---;Oscoda, Oscoda-Wurtsmith Airport;MI;United States;4;44-27N;083-22W;;;193;; +KOSH;--;---;Oshkosh, Wittman Regional Airport;WI;United States;4;43-58-00N;088-33-29W;43-58-54N;088-33-37W;246;248; +KOSU;--;---;Columbus, Ohio State University Airport;OH;United States;4;40-04-41N;083-04-41W;40-04-30N;083-04-16W;275;280; +KOTG;--;---;Worthington Automatic Weather Observing / Reporting System;MN;United States;4;43-39N;095-35W;;;480;; +KOTH;--;---;North Bend Automatic Weather Observing / Reporting System;OR;United States;4;43-25N;124-15W;;;4;; +KOTM;--;---;Ottumwa, Ottumwa Industrial Airport;IA;United States;4;41-06-24N;092-26-53W;41-06-24N;092-26-44W;258;256; +KOUN;72;357;Norman / Max Westheimer;OK;United States;4;35-13N;097-27W;35-13N;097-27W;357;357; +KOVE;--;---;Oroville, Oroville Municipal Airport;CA;United States;4;39-29-41N;121-37-13W;39-29-42N;121-36-48W;57;58; +KOVL;--;---;Olivia, Olivia Regional Airport;MN;United States;4;44-46-43N;095-01-58W;;;328;; +KOVS;--;---;Boscobel, Boscobel Airport;WI;United States;4;43-09-22N;090-40-39W;43-08-42N;090-42-07W;205;202; +KOWA;--;---;Owatonna Automatic Weather Observing / Reporting System;MN;United States;4;44-07N;093-15W;;;350;; +KOWB;--;---;Owensboro / Daviess;KY;United States;4;37-44N;087-10W;;;124;; +KOWD;--;---;Norwood, Norwood Memorial Airport;MA;United States;4;42-11-27N;071-10-26W;42-11-10N;071-10-39W;15;19; +KOWY;--;---;Owyhee;NV;United States;4;41-57N;116-06W;;;1645;; +KOXB;--;---;Ocean City, Ocean City Municipal Airport;MD;United States;4;38-18-38N;075-07-26W;;;4;; +KOXC;--;---;Oxford Automatic Weather Observing / Reporting System;CT;United States;4;41-29N;073-08W;;;222;; +KOXR;--;---;Oxnard, Oxnard Airport;CA;United States;4;34-12-02N;119-12-11W;34-11-58N;119-12-20W;13;20; +KOXV;--;---;Knoxville;IA;United States;4;41-18N;093-07W;;;283;; +KOZR;--;---;Cairns Army Air Field / Ozark;AL;United States;4;31-17N;085-43W;;;91;; +KOZW;--;---;Howell, Livingston County Airport;MI;United States;4;42-37-46N;083-59-03W;;;293;; +KP00;--;---;Tenneco Platform;LA;United States;4;28-00N;093-00W;;;15;; +KP01;--;---;Ajo Municipal;AZ;United States;4;32-27N;112-52W;;;444;; +KP06;--;---;Bullhead City;AZ;United States;4;35-10N;114-34W;;;167;; +KP07;74;730;Sanderson;TX;United States;4;30-10N;102-25W;;;865;865;P +KP11;72;758;Devils Lake;ND;United States;4;48-06N;098-52W;;;439;443;P +KP21;--;---;Main Pass B68;LA;United States;4;29-40N;088-53W;;;1;; +KP22;--;---;Vermilion B131;LA;United States;4;29-04N;092-11W;;;1;; +KP24;72;765;Roseglen;ND;United States;4;47-45N;101-50W;;;624;624;P +KP25;--;---;Vermilion B215;LA;United States;4;28-42N;092-19W;;;1;; +KP26;--;---;Grand Isle B95;LA;United States;4;28-30N;090-07W;;;1;; +KP28;72;452;Medicine Lodge, Medicine Lodge;KS;United States;4;37-17-02N;098-33-10W;;;469;469; +KP30;--;---;West Cameron;LA;United States;4;28-20N;093-01W;;;24;; +KP35;72;540;Spickard;MO;United States;4;40-15N;093-43W;;;271;270;P +KP38;72;487;Caliente;NV;United States;4;37-36-44N;114-31-35W;37-36-44N;114-31-35W;1333;1333;P +KP39;72;750;Pequot Lake;MN;United States;4;46-36N;094-19W;;;390;390; +KP43;--;---;Ventura Harbor;CA;United States;4;34-15N;119-15W;;;7;; +KP44;--;---;Santa Barbara Harbor;CA;United States;4;34-24N;119-42W;;;8;; +KP47;--;---;Chetco River Coast Guard Station;OR;United States;4;42-09N;124-16W;;;6;; +KP58;--;---;Port Hope;MI;United States;4;44-01-19N;082-47-35W;;;179;179; +KP59;--;---;Copper Harbor;MI;United States;4;47-28-01N;087-52-30W;;;190;190; +KP60;--;---;Yellowstone Lake;WY;United States;4;44-32-40N;110-25-16W;;;2388;2388; +KP61;--;---;Grand Marais;MN;United States;4;47-44-50N;090-20-40W;;;185;185; +KP65;--;---;Lukeville;AZ;United States;4;31-53N;112-49W;;;511;; +KP67;--;---;Lidgerwood Remote Automatic Meteorological Observing System;ND;United States;4;46-06N;097-09W;;;351;; +KP68;--;---;Eureka;NV;United States;4;39-36-05N;116-00-20W;;;1812;1809; +KP69;--;---;Lowell;ID;United States;4;46-08-39N;115-35-47W;;;480;480; +KP75;--;---;Manistique;MI;United States;4;45-57-00N;086-13-47W;;;178;178; +KP88;--;---;Rome Automatic Meteorological Observing System;OR;United States;4;42-54N;117-39W;;;1162;; +KP92;--;---;Salt Point;LA;United States;4;29-33-44N;091-31-32W;;;0;0; +KPAE;--;---;Everett, Snohomish County Airport;WA;United States;4;47-55-23N;122-16-57W;47-54-25N;122-16-42W;184;180; +KPAH;72;435;Paducah, Barkley Regional Airport;KY;United States;4;37-03-23N;088-46-26W;37-04-07N;088-46-20W;125;118; +KPAM;74;775;Tyndall Air Force Base;FL;United States;4;30-04N;085-35W;30-04N;085-35W;5;13; +KPAO;--;---;Palo Alto Airport;CA;United States;4;37-28N;122-07W;;;2;; +KPAQ;--;---;Palmer, Palmer Municipal Airport;AK;United States;4;61-35-46N;149-05-30W;61-35-52N;149-05-29W;70;69; +KPAT;--;---;Pathfinder Hill;WY;United States;4;42-34N;106-51W;;;1912;; +KPBF;--;---;Pine Bluff, Grider Field Airport;AR;United States;4;34-10-30N;091-56-05W;34-10-44N;091-56-16W;63;62; +KPBG;--;---;Plattsburgh Air Force Base;NY;United States;4;44-39N;073-28W;;;72;; +KPBH;--;---;Phillips / Price County;WI;United States;4;45-42N;090-24W;;;449;; +KPBI;72;203;West Palm Beach, Palm Beach International Airport;FL;United States;4;26-41-05N;080-05-58W;26-40-40N;080-06-30W;5;6;P +KPBV;--;---;St. George Island, New St. George Airport;AK;United States;4;56-34-37N;169-39-47W;56-34-37N;169-39-47W;27;34; +KPBZ;--;---;Pittsburgh Nexrad;PA;United States;4;40-32N;080-13W;;;386;; +KPCU;--;---;Picayune / Pearl River;MS;United States;4;30-31N;089-42W;;;19;; +KPCZ;--;---;Waupaca, Waupaca Municipal Airport;WI;United States;4;44-20-01N;089-00-55W;;;252;; +KPDC;--;---;Prairie Du Chien, Prairie Du Chien Municipal Airport;WI;United States;4;43-01-19N;091-07-29W;;;201;; +KPDK;--;---;Atlanta, De Kalb-Peachtree Airport;GA;United States;4;33-52-42N;084-17-53W;33-52-30N;084-17-06W;305;302; +KPDT;72;688;Pendleton, Eastern Oregon Regional At Pendleton Airport;OR;United States;4;45-41-54N;118-50-03W;45-41-22N;118-50-18W;455;458;P +KPDX;72;698;Portland, Portland International Airport;OR;United States;4;45-35-27N;122-36-01W;45-35-50N;122-36-21W;8;7;P +KPEA;--;---;Pella, Pella Municipal Airport;IA;United States;4;41-24N;092-56W;;;270;; +KPEF;--;---;Peterson Air Force Base;CO;United States;4;38-49N;104-44W;;;1876;; +KPEO;--;---;Penn Yan, Penn Yan Airport;NY;United States;4;42-38-35N;077-02-58W;42-38-37N;077-03-32W;275;256; +KPEQ;--;---;Pecos, Pecos Municipal Airport;TX;United States;4;31-22-56N;103-30-38W;;;796;; +KPFC;--;---;Pacific City State;OR;United States;4;45-12N;123-58W;;;2;; +KPFN;--;---;Panama City, Panama City-Bay County International Airport;FL;United States;4;30-12-27N;085-41-06W;30-12-22N;085-40-54W;6;12; +KPGA;72;371;Page, Page Municipal Airport;AZ;United States;4;36-55-14N;111-26-53W;36-55-15N;111-26-53W;1314;1307;P +KPGD;--;---;Punta Gorda, Charlotte County Airport;FL;United States;4;26-55-04N;081-59-37W;26-54-57N;081-59-53W;7;7; +KPGL;--;---;Pascagoula / Jackson;MS;United States;4;30-24N;088-29W;;;3;; +KPGV;--;---;Pitt-Greenville Airport;NC;United States;4;35-38N;077-24W;;;8;; +KPHD;--;---;New Philadelphia, Harry Clever Field;OH;United States;4;40-28-19N;081-25-25W;40-28-13N;081-25-03W;272;272; +KPHF;--;---;Newport News, Newport News / Williamsburg International Airport;VA;United States;4;37-07-55N;076-29-35W;37-07-54N;076-30-04W;13;12; +KPHL;72;408;Philadelphia, Philadelphia International Airport;PA;United States;4;39-52-06N;075-13-52W;39-52-34N;075-14-37W;6;18;P +KPHN;--;---;St. Clair County International;MI;United States;4;42-55N;082-32W;;;198;; +KPHP;--;---;Philip, Philip Airport;SD;United States;4;44-03-04N;101-36-04W;44-03-08N;101-36-00W;673;672; +KPHX;72;278;Phoenix, Phoenix Sky Harbor International Airport;AZ;United States;4;33-26-03N;112-03-04W;33-26-07N;112-00-33W;345;336;P +KPIA;72;532;Peoria, Greater Peoria Regional Airport;IL;United States;4;40-40-03N;089-41-02W;40-39-59N;089-41-15W;201;205;P +KPIB;--;---;Pine Belt Regional Automatic Weather Observing / Reporting System;MS;United States;4;31-28N;089-20W;;;91;; +KPIE;--;---;St. Petersburg / Clearwater, St. Petersburg / Clearwater International Airport;FL;United States;4;27-54-44N;082-41-08W;27-54-14N;082-41-30W;3;4; +KPIH;72;578;Pocatello, Pocatello Regional Airport;ID;United States;4;42-55-13N;112-34-16W;42-54-16N;112-35-24W;1356;1359;P +KPIL;--;---;Port Isabel, Port Isabel-Cameron County Airport;TX;United States;4;26-09-33N;097-20-15W;26-09-34N;097-20-21W;5;5; +KPIN;--;---;Piney Creek;WY;United States;4;44-34N;106-49W;;;1392;; +KPIR;--;---;Pierre, Pierre Regional Airport;SD;United States;4;44-22-58N;100-17-09W;44-22-49N;100-17-32W;531;526; +KPIT;72;520;Pittsburgh, Pittsburgh International Airport;PA;United States;4;40-30-14N;080-15-59W;40-29-41N;080-11-25W;366;357;P +KPJB;--;---;Payson;AZ;United States;4;34-16N;111-21W;;;1571;; +KPJI;--;---;Point Judith Coast Guard Station;RI;United States;4;41-21N;071-28W;;;2;; +KPKB;--;---;Parkersburg, Mid-Ohio Valley Regional Airport;WV;United States;4;39-20-42N;081-26-21W;;;262;; +KPKD;--;---;Park Rapids, Park Rapids Municipal Airport;MN;United States;4;46-54-02N;095-04-04W;46-53-55N;095-03-51W;439;442; +KPKF;72;741;Park Falls;WI;United States;4;45-56N;090-27W;;;462;469;P +KPKV;--;---;Port Lavaca, Calhoun County Airport;TX;United States;4;28-39-14N;096-40-52W;;;9;; +KPLB;--;---;Plattsburgh, Clinton County Airport;NY;United States;4;44-40-56N;073-31-40W;44-41-29N;073-31-19W;113;106; +KPLN;--;---;Pellston, Pellston Regional Airport of Emmet County Airport;MI;United States;4;45-34-15N;084-47-48W;45-34-08N;084-47-10W;220;217; +KPMD;72;382;Palmdale, Palmdale Production Flight Plant;CA;United States;4;34-37-47N;118-04-53W;34-37-12N;118-04-50W;775;780; +KPMP;--;---;Pompano Beach, Pompano Beach Airpark;FL;United States;4;26-14-44N;080-06-41W;26-14-35N;080-06-51W;6;6; +KPNC;--;---;Ponca City, Ponca City Municipal Airport;OK;United States;4;36-43-50N;097-05-59W;36-43-45N;097-06-04W;307;308; +KPNE;--;---;Philadelphia, Northeast Philadelphia Airport;PA;United States;4;40-04-44N;075-00-49W;40-04-31N;075-00-35W;36;28; +KPNM;--;---;Princeton;MN;United States;4;45-33N;093-36W;;;298;; +KPNS;--;---;Pensacola, Pensacola Regional Airport;FL;United States;4;30-28-41N;087-11-13W;30-28-37N;087-11-33W;36;38; +KPNT;--;---;Pontiac, Pontiac Municipal Airport;IL;United States;4;40-55-25N;088-37-31W;;;201;; +KPOB;72;303;Pope Air Force Base;NC;United States;4;35-10N;079-02W;35-10N;079-02W;61;61; +KPOC;--;---;La Verne / Brackett;CA;United States;4;34-06N;117-47W;;;308;; +KPOE;72;239;Fort Polk;LA;United States;4;31-02N;093-02W;31-02N;093-02W;100;110; +KPOF;--;---;Poplar Bluff, Poplar Bluff Municipal Airport;MO;United States;4;36-46-14N;090-19-20W;;;100;100; +KPOU;--;---;Poughkeepsie, Dutchess County Airport;NY;United States;4;41-37-36N;073-53-03W;41-37-28N;073-52-57W;50;46; +KPPA;--;---;Pampa, Perry Lefors Field Airport;TX;United States;4;35-36-46N;100-59-46W;;;989;; +KPPF;--;---;Parsons, Tri-City Airport;KS;United States;4;37-19-40N;095-30-15W;37-20-17N;095-30-31W;274;274; +KPPQ;--;---;Pittsfield, Pittsfield Penstone Municipal Airport;IL;United States;4;39-38-20N;090-46-42W;;;216;; +KPQI;72;713;Presque Isle;ME;United States;4;46-41N;068-03W;;;163;146; +KPQL;--;---;Pascagoula, Lott International Airport;MS;United States;4;30-27-49N;088-31-55W;30-27-45N;088-31-36W;5;6; +KPQN;--;---;Pipestone Automatic Weather Observing / Reporting System;MN;United States;4;43-59N;096-19W;;;529;; +KPRB;--;---;Paso Robles, Paso Robles Municipal Airport;CA;United States;4;35-40-22N;120-37-37W;35-40-19N;120-38-13W;255;245; +KPRC;--;---;Prescott, Love Field;AZ;United States;4;34-38-57N;112-25-20W;34-38-58N;112-25-14W;1537;1524; +KPRG;--;---;Paris, Edgar County Airport;IL;United States;4;39-42-01N;087-40-11W;;;199;; +KPRX;--;---;Paris / Cox Field;TX;United States;4;33-38N;095-27W;;;167;; +KPSC;--;---;Pasco, Tri-Cities Airport;WA;United States;4;46-16-11N;119-07-00W;46-15-37N;119-06-52W;124;121; +KPSF;--;---;Pittsfield, Pittsfield Municipal Airport;MA;United States;4;42-25-38N;073-17-21W;42-25-32N;073-17-30W;364;355; +KPSK;--;---;Dublin / New River Valley;VA;United States;4;37-08N;080-41W;;;642;; +KPSM;--;---;Pease Air Force Base / Portsmouth;NH;United States;4;43-05N;070-49W;;;31;; +KPSN;--;---;Palestine, Palestine Municipal Airport;TX;United States;4;31-46-46N;095-42-22W;;;129;; +KPSP;--;---;Palm Springs, Palm Springs Regional Airport;CA;United States;4;33-49-20N;116-30-13W;33-49-35N;116-30-26W;140;135; +KPSX;--;---;Palacios, Palacios Municipal Airport;TX;United States;4;28-43-39N;096-15-03W;;;5;; +KPTB;--;---;Petersburg Automatic Weather Observing / Reporting System;VA;United States;4;37-11N;077-31W;;;59;; +KPTK;--;---;Pontiac, Oakland County International Airport;MI;United States;4;42-39-47N;083-24-36W;42-39-46N;083-25-00W;299;300; +KPTN;--;---;Patterson Memorial;LA;United States;4;29-43N;091-20W;;;3;; +KPTT;74;543;Pratt Municipal;KS;United States;4;37-42N;098-45W;37-42N;098-45W;595;595; +KPTV;--;---;Porterville Automatic Weather Observing / Reporting System;CA;United States;4;36-02N;119-04W;;;135;; +KPTW;--;---;Pottstown, Pottstown Limerick Airport;PA;United States;4;40-14-18N;075-33-26W;40-14-31N;075-33-22W;89;89; +KPUB;72;464;Pueblo, Pueblo Memorial Airport;CO;United States;4;38-17-24N;104-29-54W;38-17-03N;104-29-43W;1440;1420;P +KPUC;72;470;Price, Carbon County Airport;UT;United States;4;39-36-33N;110-45-17W;39-36-41N;110-44-55W;1805;2091;P +KPUM;--;---;Pumpkin Vine;WY;United States;4;41-03N;105-28W;;;2420;; +KPUW;--;---;Pullman / Moscow, Pullman / Moscow Regional Airport;WA;United States;4;46-44-38N;117-06-35W;46-44-37N;117-06-48W;779;773; +KPUX;--;---;Pueblo NEXRAD;CO;United States;4;38-28N;104-11W;;;1620;; +KPVC;--;---;Provincetown, Provincetown Municipal Airport;MA;United States;4;42-04N;070-13W;;;2;; +KPVD;72;507;Providence, Theodore Francis Green State Airport;RI;United States;4;41-43-26N;071-25-41W;41-43-53N;071-25-43W;16;16; +KPVJ;--;---;Pauls Valley, Pauls Valley Municipal Airport;OK;United States;4;34-42-40N;097-13-24W;;;295;; +KPVU;--;---;Provo Municipal Automatic Weather Observing / Reporting System;UT;United States;4;40-13N;111-43W;;;1369;; +KPVW;--;---;Plainview, Hale County Airport;TX;United States;4;34-10-05N;101-43-02W;;;1028;; +KPWA;--;---;Oklahoma City, Wiley Post Airport;OK;United States;4;35-32-28N;097-38-48W;35-31-52N;097-38-34W;396;397; +KPWC;--;---;Pine River, Pine River Regional Airport;MN;United States;4;46-43-30N;094-23-01W;;;395;; +KPWG;--;---;Mc Gregor Automatic Weather Observing / Reporting System;TX;United States;4;31-29N;097-19W;;;180;; +KPWK;--;---;Chicago / Wheeling, Pal-Waukee Airport;IL;United States;4;42-07-15N;087-54-17W;42-06-37N;087-54-11W;197;203; +KPWM;72;606;Portland, Portland International Jetport;ME;United States;4;43-38-32N;070-18-16W;43-38-53N;070-18-09W;22;15;P +KPWT;--;---;Bremerton National Automatic Weather Observing / Reporting System;WA;United States;4;47-30N;122-45W;;;147;; +KPYM;--;---;Plymouth, Plymouth Municipal Airport;MA;United States;4;41-54-31N;070-43-41W;41-54-34N;070-43-54W;45;43; +KPYX;--;---;Perryton, Perryton Ochiltree County Airport;TX;United States;4;36-24N;100-44W;;;890;; +KPZQ;--;---;Presque Isle / Rogers;MI;United States;4;45-24N;083-49W;;;204;; +KQCA;--;---;Granite Peak;UT;United States;4;40-10N;113-21W;;;1310;; +KQCB;--;---;Little Mountain;UT;United States;4;41-15N;112-15W;;;1326;; +KQCJ;--;---;Eagle Range;UT;United States;4;41-03N;113-05W;;;1294;; +KQIR;--;---;Al Udeid;;Qatar;2;25-07N;051-18E;;;42;; +KQUK;--;---;Camp Bondsteel;;Serbia and Montenegro;6;42-35N;021-23E;;;592;; +KRAC;--;---;Racine, Batten International Airport;WI;United States;4;42-45-31N;087-49-04W;42-45-32N;087-49-13W;205;203; +KRAD;--;---;Warroad Automatic Weather Observing / Reporting System;MN;United States;4;48-56N;095-20W;;;328;; +KRAL;--;---;Riverside, Riverside Municipal Airport;CA;United States;4;33-57-05N;117-27-02W;33-56-59N;117-26-21W;248;252; +KRAP;72;662;Rapid City, Rapid City Regional Airport;SD;United States;4;44-02-44N;103-03-14W;44-02-33N;103-03-43W;976;965;P +KRAX;--;---;Raleigh NEXRAD;NC;United States;4;35-40N;078-30W;;;141;; +KRBD;--;---;Dallas, Redbird Airport;TX;United States;4;32-40-33N;096-51-50W;32-40-51N;096-51-51W;201;203; +KRBG;--;---;Roseburg, Roseburg Regional Airport;OR;United States;4;43-14-02N;123-21-22W;43-14-10N;123-21-23W;160;154; +KRBL;72;591;Red Bluff, Red Bluff Municipal Airport;CA;United States;4;40-09-02N;122-15-08W;40-09-19N;122-14-28W;106;104;P +KRBO;--;---;Robstown, Nueces County Airport;TX;United States;4;27-46-42N;097-41-25W;;;24;; +KRCA;--;---;Ellsworth Air Force Base;SD;United States;4;44-09N;103-06W;;;999;; +KRCX;--;---;Ladysmith, Ruck County Airport;WI;United States;4;45-29-48N;091-00-01W;;;377;; +KRDD;72;592;Redding, Redding Municipal Airport;CA;United States;4;40-30-54N;122-17-48W;40-31-00N;122-17-50W;153;155; +KRDG;--;---;Reading, Reading Regional Airport;PA;United States;4;40-22-24N;075-57-34W;40-22-33N;075-57-58W;105;109; +KRDK;--;---;Red Oak;IA;United States;4;41-01N;095-16W;;;318;; +KRDM;--;---;Redmond, Roberts Field Airport;OR;United States;4;44-15-15N;121-08-59W;;;938;; +KRDR;--;---;Grand Forks Air Force Base;ND;United States;4;47-58N;097-24W;47-58N;097-24W;278;278; +KRDU;72;306;Raleigh / Durham, Raleigh-Durham International Airport;NC;United States;4;35-52-14N;078-47-11W;35-52-59N;078-47-01W;133;130;P +KRED;--;---;Red Lodge;MT;United States;4;45-11N;109-16W;;;1757;; +KREE;--;---;Reese Air Force Base / Lubbock;TX;United States;4;33-36N;102-03W;;;1017;; +KREO;--;---;Rome, Rome;OR;United States;4;42-35-26N;117-51-52W;42-35-24N;117-52-07W;1234;1235; +KRFD;72;543;Rockford, Greater Rockford Airport;IL;United States;4;42-11-34N;089-05-36W;42-11-25N;089-05-10W;224;221; +KRGK;--;---;Red Wing, Red Wing Municipal Airport;MN;United States;4;44-35-25N;092-29-10W;;;239;; +KRGX;--;---;Reno NEXRAD;NV;United States;4;39-45N;119-28W;;;2560;; +KRHI;--;---;Rhinelander, Rhinelander-Oneida County Airport;WI;United States;4;45-37-54N;089-28-56W;45-37-34N;089-27-48W;495;485; +KRHP;--;---;Andrews, Andrews-Murphy Airport;NC;United States;4;35-11-42N;083-51-49W;;;517;; +KRHV;--;---;San Jose / Reid / Hillv;CA;United States;4;37-20N;121-49W;;;41;; +KRIC;72;401;Richmond, Richmond International Airport;VA;United States;4;37-30-40N;077-19-24W;37-30-34N;077-19-55W;51;50;P +KRIE;--;---;Rice Lake Municipal;WI;United States;4;45-29N;091-43W;;;347;; +KRIL;--;---;Rifle, Garfield County Regional Airport;CO;United States;4;39-31-30N;107-43-38W;39-31-25N;107-43-30W;1690;1678; +KRIV;72;286;Riverside / March Air Force Base;CA;United States;4;33-54N;117-15W;;;469;468; +KRIW;72;672;Riverton, Riverton Regional Airport;WY;United States;4;43-03-43N;108-26-47W;43-03-43N;108-27-19W;1684;1664; +KRJO;--;---;San Marcos Automatic Weather Observing / Reporting System;TX;United States;4;29-54N;097-52W;;;182;; +KRKD;--;---;Rockland / Knox Automatic Weather Observing / Reporting System;ME;United States;4;44-04N;069-06W;;;17;; +KRKP;--;---;Rockport, Aransas County Airport;TX;United States;4;28-05-01N;097-02-47W;28-05-23N;097-02-45W;7;6; +KRKR;--;---;Poteau, Robert S Kerr Airport;OK;United States;4;35-01-18N;094-37-17W;;;138;; +KRKS;72;574;Rock Springs, Rock Springs-Sweetwater County Airport;WY;United States;4;41-35-39N;109-03-55W;;;2060;; +KRLX;--;---;Charleston;WV;United States;4;38-19N;081-43W;;;364;; +KRME;--;---;Griffiss Air Force Base / Rome;NY;United States;4;43-14N;075-24W;;;154;; +KRMG;72;320;Rome, R. B. Russell Airport;GA;United States;4;34-20-52N;085-09-40W;34-21-09N;085-09-44W;194;193; +KRMN;--;---;Stafford, Stafford Regional Airport;VA;United States;4;38-23-53N;077-27-19W;;;65;; +KRMY;--;---;Marshall, Brooks Field Airport;MI;United States;4;42-15-04N;084-57-20W;;;287;; +KRND;--;---;Randolph Air Force Base;TX;United States;4;29-32N;098-17W;;;232;; +KRNH;--;---;New Richmond, New Richmond Municipal Airport;WI;United States;4;45-08-54N;092-32-17W;;;304;; +KRNM;--;---;Ramona, Ramona Airport;CA;United States;4;33-02-15N;116-54-57W;33-02-27N;116-54-39W;424;427; +KRNO;72;488;Reno, Reno Tahoe International Airport;NV;United States;4;39-29-02N;119-46-16W;39-29-53N;119-46-24W;1345;1342;P +KRNT;--;---;Renton, Renton Municipal Airport;WA;United States;4;47-29-40N;122-12-46W;47-29-50N;122-12-43W;8;21; +KROA;72;411;Roanoke, Roanoke Regional Airport;VA;United States;4;37-19-01N;079-58-27W;37-19-32N;079-58-34W;358;362;P +KROC;72;529;Rochester, Greater Rochester International Airport;NY;United States;4;43-07-00N;077-40-36W;43-07-44N;077-40-27W;170;178; +KROG;--;---;Rogers Automatic Weather Observing / Reporting System;AR;United States;4;36-22N;094-06W;;;415;; +KROS;--;---;Rush City, Rush City Regional Airport;MN;United States;4;45-41-53N;092-57-11W;;;281;; +KROW;72;268;Roswell, Roswell Industrial Air Center Airport;NM;United States;4;33-18-29N;104-30-28W;33-18-25N;104-31-38W;1118;1112; +KROX;--;---;Roseau Municipal Automatic Weather Observing / Reporting System;MN;United States;4;48-51N;095-42W;;;323;; +KRPD;--;---;Rice Lake, Rice Lake Regional-Carl's Field Airport;WI;United States;4;45-25-05N;091-46-25W;;;337;; +KRPE;--;---;Sabine Pass;TX;United States;4;29-42N;093-57W;;;3;; +KRPH;--;---;Graham, Graham Municipal Airport;TX;United States;4;33-06-36N;098-33-19W;;;342;; +KRPJ;--;---;Rochelle, Rochelle Municipal-Koritz Field Airport;IL;United States;4;41-53-35N;089-04-42W;;;238;; +KRQB;--;---;Big Rapids, Roben-Hood Airport;MI;United States;4;43-43-21N;085-30-15W;;;302;; +KRQE;72;276;Window Rock, Window Rock Airport;AZ;United States;4;35-39N;109-04W;35-39-34N;109-03-31W;2055;2055; +KRRF;--;---;New Port Richey, Tampa Bay Executive Airport;FL;United States;4;28-11-21N;082-37-33W;28-11-19N;082-37-44W;12;12; +KRRL;--;---;Merrill, Merrill Municipal Airport;WI;United States;4;45-11N;089-42W;;;401;; +KRRT;--;---;Warroad, Warroad International-Swede Carlston Field;MN;United States;4;48-56-29N;095-20-54W;;;327;; +KRSL;--;---;Russell, Russell Municipal Airport;KS;United States;4;38-52-22N;098-48-47W;;;567;567; +KRSN;--;---;Ruston, Ruston Regional Airport;LA;United States;4;32-30-52N;092-35-18W;;;95;; +KRST;72;644;Rochester, Rochester International Airport;MN;United States;4;43-54-15N;092-29-30W;43-54-42N;092-29-30W;401;403;P +KRSV;--;---;Robinson, Robinson Municipal Airport;IL;United States;4;39-00-57N;087-38-59W;;;141;; +KRSW;--;---;Fort Myers, Southwest Florida International Airport;FL;United States;4;26-31-37N;081-45-59W;26-32-13N;081-45-32W;9;9; +KRTN;--;---;Raton, Raton Municipal \ Crews Field Airport;NM;United States;4;36-44-31N;104-39-28W;;;1935;1939; +KRTX;--;---;Portland NEXRAD;OR;United States;4;45-43N;122-58W;;;514;; +KRUE;72;342;Russellville, Russellville Regional Airport;AR;United States;4;35-15-32N;093-05-36W;35-15-35N;093-05-48W;123;115; +KRUM;72;618;Rumford;ME;United States;4;44-32N;070-32W;;;192;205; +KRUQ;--;---;Salisbury, Rowan County Airport;NC;United States;4;35-39N;080-31W;;;236;; +KRUT;--;---;Rutland, Rutland State Airport;VT;United States;4;43-32N;072-57W;;;240;; +KRVL;--;---;Reedsville / Mifflin;PA;United States;4;40-41N;077-38W;;;250;; +KRVS;--;---;Tulsa, Jones Jr. Airport;OK;United States;4;36-02-33N;095-59-22W;36-02-09N;095-59-23W;194;200; +KRWF;--;---;Redwood Falls, Redwood Falls Municipal Airport;MN;United States;4;44-32-50N;095-04-56W;44-32-35N;095-04-38W;312;311; +KRWI;--;---;Rocky Mount, Rocky Mount-Wilson Regional Airport;NC;United States;4;35-51-18N;077-53-35W;35-51-02N;077-53-54W;49;47; +KRWL;--;---;Rawlins, Rawlins Municipal Airport;WY;United States;4;41-48-20N;107-11-59W;;;2077;; +KRXE;--;---;Rexburg, Rexburg-Madison County Airport;ID;United States;4;43-49-54N;111-48-22W;43-49-55N;111-48-20W;1481;1480; +KRYV;--;---;Watertown;WI;United States;4;43-10N;088-43W;;;254;; +KRYY;--;---;Marietta, Cobb County-McCollum Field Airport;GA;United States;4;34-00-47N;084-35-55W;;;317;; +KRZN;--;---;Siren, Burnett County Airport;WI;United States;4;45-49-22N;092-22-21W;;;301;; +KRZZ;--;---;Roanoke Rapids, Halifax County Airport;NC;United States;4;36-26-22N;077-42-35W;36-26-32N;077-42-37W;77;75; +KS02;--;---;Ship Shoal B224a;LA;United States;4;28-30N;091-18W;;;32;; +KS06;--;---;Mullan Aviation Weather Reporting Station;ID;United States;4;47-28N;115-48W;;;1011;; +KS14;--;---;Spencer;ID;United States;4;44-21N;112-11W;;;1793;; +KS21;--;---;Sunriver;OR;United States;4;43-53N;121-27W;;;1266;; +KS29;--;---;Salida;CO;United States;4;38-31N;106-01W;;;2186;; +KS38;--;---;Burrows Island;WA;United States;4;48-05N;122-06W;;;18;; +KS47;--;---;Tillamook, Tillamook Airport;OR;United States;4;45-25-05N;123-48-52W;;;11;; +KS53;--;---;Destruction Island;WA;United States;4;47-40N;124-29W;;;24;; +KS58;--;---;South Timbalier;LA;United States;4;28-32N;090-35W;;;1;; +KS65;--;---;Ship Shoal 198g;LA;United States;4;28-30N;091-12W;;;2;; +KS80;--;---;Grangeville ;ID;United States;4;45-57N;116-08W;;;1009;; +KS88;--;---;Arlington Automatic Weather Observing / Reporting System;WA;United States;4;48-10N;122-09W;;;42;; +KSAC;72;483;Sacramento, Sacramento Executive Airport;CA;United States;4;38-30-25N;121-29-42W;38-30-50N;121-29-49W;6;11; +KSAD;--;---;Safford, Safford Municipal Airport;AZ;United States;4;32-51-26N;109-38-08W;32-51-01N;109-38-16W;968;962; +KSAF;--;---;Santa Fe, Santa Fe County Municipal Airport;NM;United States;4;35-36-38N;106-05-42W;35-37-03N;106-05-03W;1934;1930; +KSAN;72;290;San Diego, San Diego International-Lindbergh Field;CA;United States;4;32-44-01N;117-10-59W;32-44-11N;117-11-22W;4;12;P +KSAR;--;---;Sparta, Sparta Community-Hunter Field Airport;IL;United States;4;38-08-56N;089-41-55W;;;164;; +KSAT;72;253;San Antonio, San Antonio International Airport;TX;United States;4;29-31-58N;098-27-49W;29-31-42N;098-28-25W;246;243;P +KSAV;72;207;Savannah, Savannah International Airport;GA;United States;4;32-07-08N;081-12-08W;32-07-34N;081-11-55W;15;14;P +KSAW;--;---;Gwinn, Sawyer Airport;MI;United States;4;46-21-13N;087-23-45W;;;372;; +KSAZ;--;---;Staples, Staples Municipal Airport;MN;United States;4;46-22-51N;094-48-24W;;;392;; +KSBA;--;---;Santa Barbara, Santa Barbara Municipal Airport;CA;United States;4;34-25-34N;119-50-37W;34-25-49N;119-50-36W;3;3; +KSBD;--;---;Norton Air Force Base / San Bern;CA;United States;4;34-06N;117-14W;;;353;; +KSBM;--;---;Sheboygan, Sheboygan County Memorial Airport;WI;United States;4;43-46-35N;087-50-59W;43-45-41N;087-51-04W;228;232; +KSBN;72;535;South Bend, South Bend Regional Airport;IN;United States;4;41-42-32N;086-19-07W;41-42-31N;086-18-52W;244;237; +KSBP;--;---;San Luis Obispo, San Luis Obispo County-Mc Chesney Field;CA;United States;4;35-14-10N;120-38-10W;35-14-19N;120-38-22W;63;59; +KSBS;--;---;Steamboat Springs;CO;United States;4;40-31N;106-52W;;;2096;; +KSBY;--;---;Salisbury, Salisbury-Ocean City Wicomico County Regional Airport;MD;United States;4;38-20-26N;075-30-37W;38-20-32N;075-31-00W;16;19; +KSCC;--;---;Deadhorse, Deadhorse Airport;AK;United States;4;70-11-30N;148-28-38W;70-11-53N;148-28-03W;17;23; +KSCH;--;---;Schenectady Airport;NY;United States;4;42-51N;073-56W;;;115;; +KSCK;72;492;Stockton, Stockton Metropolitan Airport;CA;United States;4;37-53-23N;121-13-25W;37-53-51N;121-15-00W;9;10;P +KSDA;--;---;Shenandoah Municipal;IA;United States;4;40-45N;095-25W;;;296;; +KSDB;72;383;Sandberg;CA;United States;4;34-44-37N;118-43-28W;34-44-37N;118-43-27W;1378;1377; +KSDF;72;423;Louisville, Standiford Field;KY;United States;4;38-10-38N;085-43-47W;38-10-44N;085-43-50W;151;146; +KSDL;--;---;Scottsdale, Scottsdale Airport;AZ;United States;4;33-37-22N;111-54-38W;33-37-17N;111-54-34W;460;447; +KSDM;--;---;San Diego, Brown Field Municipal Airport;CA;United States;4;32-34-31N;116-59-35W;32-34-10N;116-59-04W;164;159; +KSDY;--;---;Sidney-Richland;MT;United States;4;47-42N;104-12W;;;605;; +KSEA;72;793;Seattle, Seattle-Tacoma International Airport;WA;United States;4;47-26-41N;122-18-49W;47-26-37N;122-18-07W;130;136;P +KSEE;--;---;San Diego / Gillespie;CA;United States;4;32-50N;116-58W;;;117;; +KSEG;--;---;Selinsgrove, Penn Valley Airport;PA;United States;4;40-49-09N;076-51-58W;40-48-59N;076-51-25W;137;134; +KSEM;--;---;Craig Field / Selma;AL;United States;4;32-21N;086-59W;;;51;; +KSEP;72;260;Stephenville, Clark Field Municipal Airport;TX;United States;4;32-13N;098-11W;32-13N;098-11W;403;402; +KSET;--;---;St. Charles, St. Charles County Smartt Airport;MO;United States;4;38-55-50N;090-25-57W;38-55-49N;090-26-01W;133;134; +KSEZ;--;---;Sedona Airport;AZ;United States;4;34-51N;111-47W;;;1471;; +KSFB;--;---;Orlando / Sanford Airport;FL;United States;4;28-47N;081-15W;;;17;; +KSFD;72;656;Winner, Bob Wiley Field Airport;SD;United States;4;43-23-26N;099-50-33W;;;619;; +KSFF;--;---;Spokane, Felts Field;WA;United States;4;47-41-08N;117-19-13W;47-40-51N;117-19-04W;595;609; +KSFM;--;---;Sanford Municipal Automatic Weather Observing / Reporting System;ME;United States;4;43-24N;070-43W;;;74;; +KSFO;72;494;San Francisco, San Francisco International Airport;CA;United States;4;37-37-11N;122-21-53W;37-37-01N;122-22-58W;3;26;P +KSFQ;--;---;Suffolk, Suffolk Municipal Airport;VA;United States;4;36-40-56N;076-36-07W;;;22;; +KSFY;--;---;Savanna, Tri-Township Airport;IL;United States;4;42-02-45N;090-06-28W;;;188;; +KSFZ;--;---;Pawtucket Automatic Weather Observing / Reporting System;RI;United States;4;41-55N;071-30W;;;134;; +KSGF;72;440;Springfield, Springfield Regional Airport;MO;United States;4;37-14-23N;093-23-23W;37-14-26N;093-23-28W;386;389;P +KSGH;--;---;Springfield Municipal;OH;United States;4;39-50N;083-50W;;;321;; +KSGJ;--;---;St. Augustine, St. Augustine Airport;FL;United States;4;29-57-33N;081-20-23W;;;3;; +KSGR;--;---;Houston, Sugar Land Municipal / Hull Field Airport;TX;United States;4;29-37-20N;095-39-24W;;;25;; +KSGS;--;---;South St. Paul, South St. Paul Municipal-Richard E. Fleming Field Airport;MN;United States;4;44-51-26N;093-01-58W;;;250;; +KSGT;--;---;Stuttgart Automatic Weather Observing / Reporting System;AR;United States;4;34-36N;091-34W;;;68;; +KSGU;--;---;Saint George Automatic Weather Observing / Reporting System;UT;United States;4;37-05N;113-36W;;;896;; +KSHD;--;---;Staunton / Shenandoah;VA;United States;4;38-16N;078-54W;;;366;; +KSHI;--;---;Ashtabula, Ashtabula County Airport;OH;United States;4;41-46-46N;080-41-48W;41-46-48N;080-42-04W;281;276; +KSHL;--;---;Sheldon;IA;United States;4;43-13N;095-50W;;;432;; +KSHN;--;---;Shelton, Shelton Sanderson Field;WA;United States;4;47-14-17N;123-08-27W;47-14-24N;123-08-25W;82;82; +KSHP;--;---;Sheppard Air Force Base;TX;United States;4;33-58N;098-29W;;;314;; +KSHR;72;666;Sheridan, Sheridan County Airport;WY;United States;4;44-46-10N;106-58-08W;44-46-26N;106-58-12W;1225;1202;P +KSHV;72;248;Shreveport, Shreveport Regional Airport;LA;United States;4;32-26-49N;093-49-27W;32-27-02N;093-50-01W;78;80;P +KSIB;--;---;Sibley Peak;WY;United States;4;42-27N;105-02W;;;1500;; +KSIL;--;---;Slidell Radar Site;LA;United States;4;30-15N;089-46W;;;3;; +KSIY;--;---;Montague, Siskiyou County Airport;CA;United States;4;41-46-53N;122-28-05W;;;807;; +KSJC;--;---;San Jose, San Jose International Airport;CA;United States;4;37-21-33N;121-55-27W;35-39-56N;121-17-05W;18;25; +KSJN;--;---;St. Johns, St. Johns Industrial Airpark;AZ;United States;4;34-31-06N;109-22-45W;34-31-09N;109-22-44W;1747;1745; +KSJT;72;263;San Angelo, Mathis Field;TX;United States;4;31-21-05N;100-29-38W;31-21-22N;100-30-10W;584;581;P +KSJX;--;---;Beaver Island, Beaver Island Airport;MI;United States;4;45-41-32N;085-33-59W;;;204;; +KSKA;--;---;Fairchild Air Force Base;WA;United States;4;47-37N;117-39W;;;750;; +KSKC;--;---;Waukesha;WI;United States;4;43-02N;088-14W;;;284;; +KSKF;--;---;Kelly Air Force Base;TX;United States;4;29-23N;098-35W;;;210;; +KSKX;--;---;Taos Municipal Airport Automatic Weather Observing / Reporting System;NM;United States;4;36-27N;105-40W;;;2161;; +KSLB;--;---;Storm Lake;IA;United States;4;42-36N;095-14W;;;454;; +KSLC;72;572;Salt Lake City, Salt Lake City International Airport;UT;United States;4;40-46-41N;111-58-10W;40-46-35N;111-57-31W;1288;1286;P +KSLE;72;694;Salem, McNary Field;OR;United States;4;44-54-28N;122-59-42W;44-54-33N;123-00-25W;64;59;P +KSLG;--;---;Siloam Springs Automatic Weather Observing / Reporting System;AR;United States;4;36-12N;094-29W;;;300;; +KSLH;--;---;Cheboygan, Cheboygan County Airport;MI;United States;4;45-39-13N;084-31-09W;;;195;; +KSLI;--;---;Los Alamitos U. S. Army Airfield;CA;United States;4;33-47N;118-03W;;;11;; +KSLK;--;---;Saranac Lake, Adirondack Regional Airport;NY;United States;4;44-23-35N;074-12-10W;44-22-49N;074-12-14W;507;498; +KSLN;--;---;Salina, Salina Municipal Airport;KS;United States;4;38-46-48N;097-38-39W;38-46-08N;097-38-39W;387;385; +KSLO;72;433;Salem, Salem-Leckrone Airport;IL;United States;4;38-38-34N;088-57-51W;38-39N;088-58W;175;174; +KSLR;--;---;Sulphur Springs, Sulphur Springs Municipal Airport;TX;United States;4;33-09-40N;095-37-16W;;;149;; +KSLW;--;---;Smithville / Wooster;OH;United States;4;40-53N;081-50W;;;357;; +KSME;--;---;Somerset, Somerset-Pulaski County - J.T. Wilson Field Airport;KY;United States;4;37-03-15N;084-36-54W;;;283;; +KSMF;--;---;Sacramento, Sacramento International Airport;CA;United States;4;38-42-05N;121-35-38W;38-41-30N;121-35-23W;8;6; +KSMN;--;---;Salmon, Lemhi County Airport;ID;United States;4;45-07N;113-53W;;;1233;; +KSMO;--;---;Santa Monica, Santa Monica Municipal Airport;CA;United States;4;34-00-57N;118-27-05W;34-01-10N;118-26-53W;53;57; +KSMP;--;---;Stampede Pass;WA;United States;4;47-16-36N;121-20-14W;47-16-36N;121-20-14W;1207;1208; +KSMQ;--;---;Somerville, Somerset Airport;NJ;United States;4;40-37-26N;074-40-10W;40-37-32N;074-40-08W;32;30; +KSMX;72;394;Santa Maria, Santa Maria Public Airport;CA;United States;4;34-53-58N;120-26-55W;34-53-57N;120-26-56W;78;74;P +KSNA;--;---;Santa Ana, John Wayne Airport-Orange County Airport;CA;United States;4;33-40-48N;117-51-59W;33-40-41N;117-52-08W;16;15; +KSNK;--;---;Snyder, Winston Field Airport;TX;United States;4;32-41-36N;100-57-01W;;;741;; +KSNL;--;---;Shawnee, Shawnee Municipal Airport;OK;United States;4;35-21-26N;096-56-34W;;;327;; +KSNP;--;---;St. Paul Island, St. Paul Island Airport;AK;United States;4;57-09-21N;170-13-15W;57-09-25N;170-13-01W;13;7; +KSNS;--;---;Salinas, Salinas Municipal Airport;CA;United States;4;36-39-49N;121-36-29W;36-39-37N;121-36-18W;25;30; +KSNT;--;---;Stanley, Stanley Ranger Station;ID;United States;4;44-12-31N;114-56-04W;;;1980;; +KSNY;72;561;Sidney, Sidney Municipal Airport;NE;United States;4;41-05-58N;102-59-08W;41-06-10N;102-58-56W;1314;1307;P +KSOP;--;---;Southern Pines Automatic Weather Observing / Reporting System;NC;United States;4;35-14N;079-24W;;;141;; +KSOV;--;---;Seldovia, Seldovia Airport;AK;United States;4;59-26-48N;151-42-16W;59-26-48N;151-42-16W;8;10; +KSOW;--;---;Show Low Municipal;AZ;United States;4;34-16N;110-00W;;;1954;; +KSPA;--;---;Spartanburg Memorial;SC;United States;4;34-55N;081-57W;;;246;; +KSPB;--;---;Scappoose, Scappoose Industrial Airpark;OR;United States;4;45-46-09N;122-51-44W;45-46-35N;122-51-35W;16;14; +KSPD;--;---;Springfield, Comanche National Grassland;CO;United States;4;37-17N;102-37W;;;1335;; +KSPF;--;---;Spearfish / Clyde Ice;SD;United States;4;44-29N;103-47W;;;1188;; +KSPG;--;---;St. Petersburg, Whitted Airport;FL;United States;4;27-46-04N;082-37-34W;27-46-00N;082-37-40W;2;2; +KSPI;72;439;Springfield, Capital Airport;IL;United States;4;39-50-43N;089-41-02W;39-51-04N;089-40-36W;182;181; +KSPS;72;351;Wichita Falls, Sheppard Air Force Base;TX;United States;4;33-58-43N;098-29-34W;33-58-25N;098-30-07W;309;308;P +KSPW;--;---;Spencer, Spencer Municipal Airport;IA;United States;4;43-09-56N;095-12-10W;43-10-02N;095-11-47W;408;403; +KSQI;--;---;Sterling Rockfalls;IL;United States;4;41-45N;089-40W;;;197;; +KSQL;--;---;San Carlos Airport;CA;United States;4;37-31N;122-15W;;;1;; +KSRC;--;---;Searcy, Searcy Municipal Airport;AR;United States;4;35-12-43N;091-44-14W;;;81;; +KSRF;--;---;Hamilton U. S. Army Airfield;CA;United States;4;38-04N;122-30W;;;1;; +KSRN;--;---;South Marsh 268A;LA;United States;4;29-07N;91-52W;;;0;; +KSRQ;--;---;Sarasota / Bradenton, Sarasota-Bradenton International Airport;FL;United States;4;27-24-05N;082-33-31W;27-24-09N;082-33-10W;9;18; +KSRR;--;---;Ruidoso Regional;NM;United States;4;33-28N;105-32W;;;2076;; +KSSC;74;790;Shaw Air Force Base;SC;United States;4;33-58N;080-29W;33-58N;080-29W;74;73; +KSSF;--;---;San Antonio, Stinson Municipal Airport;TX;United States;4;29-20-20N;098-28-18W;29-20-19N;098-28-04W;175;176; +KSSI;--;---;Brunswick, Malcolm McKinnon Airport;GA;United States;4;31-09-06N;081-23-29W;31-09-20N;081-23-13W;6;6; +KSSU;--;---;White Sulphur Sprng;WV;United States;4;37-46N;080-20W;;;549;; +KSTC;72;655;St. Cloud, St. Cloud Municipal Airport;MN;United States;4;45-32-41N;094-03-07W;45-33-00N;094-04-05W;312;314;P +KSTE;--;---;Stevens Point, Stevens Point Municipal Airport;WI;United States;4;44-32-42N;089-31-49W;;;338;; +KSTJ;72;449;St. Joseph, Rosecrans Memorial Airport;MO;United States;4;39-46-05N;094-54-33W;39-46-14N;094-54-10W;251;247; +KSTL;72;434;St. Louis, Lambert-St. Louis International Airport;MO;United States;4;38-45-09N;090-22-25W;38-45-06N;090-21-07W;184;171;P +KSTP;--;---;St. Paul, St. Paul Downtown Holman Field;MN;United States;4;44-55-49N;093-02-53W;44-56-31N;093-03-55W;214;219; +KSTS;--;---;Santa Rosa, Santa Rosa Sonoma County Airport;CA;United States;4;38-30-00N;122-49-00W;38-30-16N;122-48-17W;38;39; +KSTT;--;---;Charlotte Amalie, King Airport;VI;United States;4;18-20-18N;064-58-44W;18-20-26N;064-58-30W;4;15; +KSTX;--;---;Christiansted, Hamilton Airport;VI;United States;4;17-42-03N;064-48-24W;17-42-08N;064-47-56W;18;9; +KSUA;--;---;Stuart, Witham Field Airport;FL;United States;4;27-10-54N;080-13-16W;;;6;; +KSUE;--;---;Sturgeon Bay;WI;United States;4;44-51N;087-25W;;;221;; +KSUN;--;---;Hailey / Friedman Memorial;ID;United States;4;43-30N;114-18W;;;1620;; +KSUS;--;---;St. Louis, Spirit Of St. Louis Airport;MO;United States;4;38-39-26N;090-39-21W;38-39-45N;090-39-07W;141;141; +KSUT;--;---;Oak Island, Brunswick County Airport;NC;United States;4;33-55-45N;078-04-29W;;;8;; +KSUU;74;516;Fairfield / Travis Air Force Base;CA;United States;4;38-16N;121-57W;;;19;22;P +KSUW;--;---;Superior, Richard I. Bong Airport;WI;United States;4;46-41-23N;092-05-41W;;;205;; +KSUX;72;557;Sioux City, Sioux Gateway Airport;IA;United States;4;42-24-09N;096-23-04W;42-24-03N;096-22-39W;335;338;P +KSVC;72;272;Silver City / Grant;NM;United States;4;32-38N;108-09W;;;1659;; +KSVE;--;---;Susanville Municipal;CA;United States;4;40-23N;120-34W;;;1263;; +KSVH;--;---;Statesville, Statesville Municipal Airport;NC;United States;4;35-45-55N;080-57-24W;;;294;; +KSVN;--;---;Hunter U. S. Army Airfield ;GA;United States;4;32-01N;081-09W;;;13;; +KSWD;--;---;Seward, Seward Airport;AK;United States;4;60-07-37N;149-25-07W;60-07-58N;149-25-35W;6;2; +KSWF;--;---;Newburgh / Stewart;NY;United States;4;41-30N;074-06W;;;150;; +KSWO;--;---;Stillwater, Stillwater Regional Airport;OK;United States;4;36-09-44N;097-05-21W;36-09-28N;097-05-01W;300;290; +KSWW;--;---;Sweetwater, Avenger Field Airport;TX;United States;4;32-28-02N;100-27-59W;;;725;; +KSXT;--;---;Sexton Summit,;OR;United States;4;42-36-01N;123-21-51W;42-36-01N;123-21-52W;0;1170; +KSYR;72;519;Syracuse, Syracuse Hancock International Airport;NY;United States;4;43-06-33N;076-06-12W;43-06-39N;076-06-38W;128;127;P +KSZL;--;---;Whiteman Air Force Base;MO;United States;4;38-44N;093-33W;;;265;; +KSZN;--;---;Santa Cruz Island;CA;United States;4;34-01N;119-45W;;;10;; +KSZT;--;---;Sandpoint, Sandpoint Airport;ID;United States;4;48-17-58N;116-33-36W;;;648;; +KT08;--;---;Tomahawk, Tomahawk Regional Airport;WI;United States;4;45-28-08N;089-48-20W;;;453;; +KT18;--;---;Falfurrias, Brooks County Airport;TX;United States;4;27-12-24N;098-07-16W;;;34;; +KT46;--;---;South Brazos A70;TX;United States;4;28-01N;095-52W;;;23;; +KT49;--;---;Big Spring, Big Spring McMahon-Wrinkle Airport;TX;United States;4;32-12N;101-31W;;;784;; +KT53;--;---;Robstown, Nueces County Airport;TX;United States;4;27-46-42N;097-41-25W;;;24;; +KT56;--;---;Crockett, Houston County Airport;TX;United States;4;31-18-25N;095-24-13W;;;106;; +KT62;--;---;Tooele;UT;United States;4;40-19N;112-18W;;;1628;; +KT65;--;---;Weslaco, Mid Valley Airport;TX;United States;4;26-10-39N;097-58-23W;;;21;; +KT72;--;---;Hearne, Hearne Municipal Airport;TX;United States;4;30-52-18N;096-37-20W;;;87;; +KT82;--;---;Fredericksburg, Gillespie County Airport;TX;United States;4;30-14-37N;098-54-34W;;;517;; +KT97;--;---;Port Lavaca, Calhoun County Airport;TX;United States;4;28-39-14N;096-40-52W;;;9;; +KTAD;--;---;Trinidad, Perry Stokes Airport;CO;United States;4;37-16N;104-26W;;;1756;; +KTAL;--;---;Tanana, Calhoun Memorial Airport;AK;United States;4;65-10-28N;152-06-25W;65-10-29N;152-06-30W;69;72; +KTAN;--;---;Taunton, Taunton Municipal Airport;MA;United States;4;41-52-32N;071-01-16W;41-52-31N;071-01-12W;13;7; +KTAZ;--;---;Taylorville, Taylorville Municipal Airport;IL;United States;4;39-32-03N;089-19-40W;;;190;; +KTBN;--;---;Fort Leonard Wood;MO;United States;4;37-44N;092-08W;;;353;; +KTBR;--;---;Statesboro, Statesboro-Bulloch County Airport;GA;United States;4;32-28-59N;081-44-14W;;;57;; +KTBW;72;210;Tampa Bay Area;FL;United States;4;27-42N;082-24W;27-42N;082-24W;12;13;P +KTCC;--;---;Tucumcari, Tucumcari Municipal Airport;NM;United States;4;35-10-58N;103-36-11W;35-10-52N;103-36-33W;1239;1235; +KTCL;--;---;Tuscaloosa, Tuscaloosa Municipal Airport;AL;United States;4;33-12-43N;087-36-57W;33-13-26N;087-36-30W;52;49; +KTCM;74;206;Tacoma / McChord Air Force Base;WA;United States;4;47-09N;122-29W;47-09N;122-29W;98;87; +KTCS;72;271;Truth Or Consequences, Truth Or Consequences Municipal Airport;NM;United States;4;33-14-12N;107-16-05W;33-14-17N;107-16-08W;1478;1469; +KTDF;--;---;Roxboro, Person County Airport;NC;United States;4;36-17-06N;078-59-03W;;;186;; +KTDO;--;---;Toledo-Winlock Memorial;WA;United States;4;46-29N;122-48W;;;113;; +KTDZ;--;---;Toledo, Metcalf Field;OH;United States;4;41-33-47N;083-28-35W;41-33-52N;083-28-34W;189;189; +KTEB;--;---;Teterboro, Teterboro Airport;NJ;United States;4;40-51-32N;074-03-24W;40-51-09N;074-03-19W;2;7; +KTEW;--;---;Mason, Mason Jewett Field Airport;MI;United States;4;42-33-57N;084-25-24W;;;280;; +KTEX;--;---;Telluride, Telluride Regional Airport;CO;United States;4;37-57-14N;107-54-31W;;;2767;; +KTFX;--;---;Great Falls Nexrad;MT;United States;4;47-28N;111-22W;;;1151;; +KTHV;--;---;York, York Airport;PA;United States;4;39-55-10N;076-52-37W;39-55-22N;076-52-41W;146;144; +KTIF;--;---;Thedford, Thomas County Airport;NE;United States;4;41-57-43N;100-34-08W;;;892;; +KTIK;72;354;Tinker Air Force Base;OK;United States;4;35-25N;097-23W;35-25N;097-23W;394;397; +KTIP;--;---;Rantoul, Rantoul National Aviation Center Airport-Frank Elliott Field;IL;United States;4;40-17-37N;088-08-33W;;;225;; +KTIW;--;---;Tacoma, Tacoma Narrows Airport;WA;United States;4;47-16-03N;122-34-34W;47-16-09N;122-34-25W;96;96; +KTIX;--;---;Titusville;FL;United States;4;28-31N;080-48W;;;11;; +KTKA;--;---;Talkeetna, Talkeetna Airport;AK;United States;4;62-19-12N;150-05-42W;62-19-13N;150-05-38W;109;107; +KTKI;--;---;Mc Kinney, Collin County Regional Airport at Mc Kinney;TX;United States;4;33-10-40N;096-35-25W;33-10-39N;096-35-31W;178;179; +KTLH;72;214;Tallahassee, Tallahassee Regional Airport;FL;United States;4;30-23-35N;084-21-12W;30-23-46N;084-21-20W;24;16;P +KTLX;--;---;Oklahoma City Nexrad;OK;United States;4;35-20N;097-17W;;;338;; +KTMB;--;---;Miami, Kendall-Tamiami Executive Airport;FL;United States;4;25-38-31N;080-26-05W;25-38-50N;080-25-35W;3;2; +KTMH;--;---;20 Mile Hill;WY;United States;4;43-07N;106-20W;;;1743;; +KTNB;--;---;Boone, Watauga County Hospital Heliport;NC;United States;4;36-12N;081-39W;;;959;; +KTNU;--;---;Newton Municipal;IA;United States;4;41-41N;093-01W;;;290;; +KTNX;--;---;Tonopah Test Range;NV;United States;4;37-48N;116-47W;;;1691;; +KTOA;--;---;Torrance, Zamperini Field Airport;CA;United States;4;33-48N;118-20W;;;31;; +KTOB;--;---;Dodge Center, Dodge Center Airport;MN;United States;4;44-01-05N;092-49-53W;;;398;; +KTOI;--;---;Troy, Troy Municipal Airport;AL;United States;4;31-51-38N;086-00-44W;31-51-39N;088-00-28W;121;118; +KTOL;72;536;Toledo, Toledo Express Airport;OH;United States;4;41-35-19N;083-48-05W;41-35-33N;083-48-15W;208;210; +KTOP;72;456;Topeka, Philip Billard Municipal Airport;KS;United States;4;39-04-21N;095-37-33W;39-04-21N;095-37-50W;268;268;P +KTOR;--;---;Torrington, Torrington Municipal Airport;WY;United States;4;42-03-53N;104-09-10W;42-03-45N;104-09-31W;1282;1277; +KTPA;72;211;Tampa, Tampa International Airport;FL;United States;4;27-57-41N;082-32-25W;27-58-04N;082-31-33W;8;11;P +KTPH;--;---;Tonopah, Tonopah Airport;NV;United States;4;38-03-37N;117-05-14W;38-03-49N;117-05-44W;1654;1652; +KTPL;--;---;Temple / Miller Automatic Weather Observing / Reporting System;TX;United States;4;31-09N;097-24W;;;208;; +KTQE;--;---;Tekamah, Tekamah Municipal Airport;NE;United States;4;41-46-01N;096-10-40W;41-46-02N;096-10-29W;313;312; +KTQH;--;---;Tahlequah, Tahlequah Municipal Airport;OK;United States;4;35-55-44N;095-00-16W;;;266;; +KTRI;--;---;Bristol / Johnson / Kingsport, Tri-City Regional Airport;TN;United States;4;36-28-47N;082-23-56W;36-28-54N;082-24-26W;463;474; +KTRK;--;---;Truckee-Tahoe;CA;United States;4;39-19N;120-08W;;;1798;; +KTRL;--;---;Terrell, Terrell Municipal Airport;TX;United States;4;32-42-49N;096-16-06W;32-42-58N;096-16-07W;144;144; +KTRM;--;---;Thermal, Desert Resorts Thermal Regional Airport;CA;United States;4;33-37-40N;116-09-36W;33-38-05N;116-09-47W;-34;-35; +KTTA;--;---;Sanford, Sanford-Lee County Regional Airport;NC;United States;4;35-34-57N;079-06-05W;;;75;; +KTTD;--;---;Portland, Portland-Troutdale Airport;OR;United States;4;45-33-04N;122-24-32W;45-33-03N;122-23-49W;11;14; +KTTF;--;---;Monroe, Custer Airport;MI;United States;4;41-56-24N;083-26-05W;;;188;; +KTTN;--;---;Trenton, Mercer County Airport;NJ;United States;4;40-16-35N;074-48-59W;40-16-39N;074-48-58W;64;59; +KTTS;--;---;NASA Shuttle Facility;FL;United States;4;28-37N;080-43W;;;3;; +KTUL;72;356;Tulsa, Tulsa International Airport;OK;United States;4;36-11-51N;095-53-11W;36-11-32N;095-54-13W;206;207;P +KTUP;72;332;Tupelo, Tupelo Regional Airport;MS;United States;4;34-16-05N;088-46-12W;34-15-54N;088-45-59W;106;105; +KTUS;72;274;Tucson, Tucson International Airport;AZ;United States;4;32-07-53N;110-57-19W;32-07-28N;110-56-25W;805;786;P +KTVC;--;---;Traverse City, Cherry Capital Airport;MI;United States;4;44-44-12N;085-34-12W;44-44-38N;085-35-06W;190;190; +KTVF;--;---;Thief River Automatic Weather Observing / Reporting System;MN;United States;4;48-04N;096-11W;;;340;; +KTVL;--;---;South Lake Tahoe, Lake Tahoe Airport;CA;United States;4;38-53-38N;119-59-43W;38-53-47N;119-59-50W;1909;1925; +KTVR;--;---;Vicksburg, Vicksburg / Tallulah Regional Airport;LA;United States;4;32-20-53N;091-01-48W;32-21-11N;091-01-29W;26;26; +KTWF;--;---;Twin Falls, Joslin Field-Magic Valley Regional Airport;ID;United States;4;42-28-43N;114-28-34W;42-29-03N;114-28-55W;1265;1266; +KTWM;--;---;Two Harbors;MN;United States;4;47-03N;091-45W;;;328;; +KTWX;--;---;Topeka NEXRAD;KS;United States;4;39-00N;096-14W;;;431;; +KTXK;--;---;Texarkana, Texarkana Regional-Webb Field;AR;United States;4;33-27-22N;093-59-15W;33-27-21N;093-59-38W;118;111; +KTYR;--;---;Tyler, Tyler Pounds Field;TX;United States;4;32-21-31N;095-24-14W;32-21- N;095-24- W;165;165; +KTYS;72;326;Knoxville, McGhee Tyson Airport;TN;United States;4;35-49-05N;083-59-09W;35-49-29N;083-59-10W;299;302;P +KTZR;--;---;Columbus, Bolton Field Airport;OH;United States;4;39-54-03N;083-08-14W;;;276;; +KU15;--;---;Challis, Challis Airport;ID;United States;4;44-31-22N;114-12-54W;44-31-12N;114-12-54W;1534;1536; +KU16;--;---;Eagle Range;UT;United States;4;41-03N;113-04W;;;1292;; +KU17;--;---;Bullfrog Marina;UT;United States;4;37-30N;110-42W;;;1110;; +KU24;--;---;Delta;UT;United States;4;39-20N;112-35W;;;1414;; +KU28;--;---;Green River Range;UT;United States;4;39-00N;110-10W;;;1241;; +KU31;--;---;Austin;NV;United States;4;39-30N;117-05W;;;2014;; +KU42;--;---;Salt Lake City, Salt Lake City Municipal 2 Airport;UT;United States;4;40-37-10N;111-59-34W;;;1403;; +KU67;74;420;Roosevelt;UT;United States;4;40-18N;109-59W;;;1553;1556; +KU71;--;---;Vernal;UT;United States;4;40-28N;109-32W;;;1612;; +KU73;--;---;Jerome, Jerome County Airport;ID;United States;4;42-43-39N;114-27-11W;42-43-31N;114-27-15W;1233;1222; +KU78;--;---;Soda Springs / Tigert;ID;United States;4;42-39N;111-35W;;;1780;; +KUAO;--;---;Aurora, Aurora State Airport;OR;United States;4;45-14-56N;122-45-56W;45-15-03N;122-45-57W;59;59; +KUCA;--;---;Utica, Oneida County Airport;NY;United States;4;43-08-42N;075-23-04W;43-08-50N;075-22-52W;227;228; +KUDG;--;---;Darlington, Darlington County Jetport Airport;SC;United States;4;34-26-57N;079-53-25W;;;59;; +KUES;--;---;Waukesha, Waukesha County Airport;WI;United States;4;43-02-28N;088-14-13W;;;278;; +KUEX;--;---;Grand Island Nexrad;NE;United States;4;40-19N;098-26W;;;626;; +KUGN;--;---;Chicago / Waukegan, Waukegan Regional Airport;IL;United States;4;42-25N;087-52W;;;222;; +KUIL;72;797;Quillayute, Quillayute State Airport;WA;United States;4;47-56-15N;124-33-18W;47-56-03N;124-33-32W;59;54;P +KUIN;--;---;Quincy, Quincy Regional-Baldwin Field Airport;IL;United States;4;39-56-33N;091-11-40W;;;234;; +KUKF;--;---;North Wilkesboro, Wilkes County Airport;NC;United States;4;36-13N;81-05W;;;396;; +KUKI;--;---;Ukiah, Ukiah Municipal Airport;CA;United States;4;39-07-33N;123-12-03W;;;187;; +KUKL;--;---;Burlington, Coffey County Airport;KS;United States;4;38-18-09N;095-43-30W;;;358;; +KUKT;--;---;Quakertown, Quakertown Airport;PA;United States;4;40-26-06N;075-22-54W;;;160;; +KULM;--;---;New Ulm Municipal Automatic Weather Observing / Reporting System;MN;United States;4;44-19N;094-30W;;;308;; +KUNO;--;---;West Plains, West Plains Municipal Airport;MO;United States;4;36-52-45N;091-54-18W;36-52-44N;091-54-16W;374;372; +KUNU;--;---;Juneau, Dodge County Airport;WI;United States;4;43-25-36N;088-42-12W;;;285;; +KUNV;--;---;State College, University Park Airport;PA;United States;4;40-51N;077-51W;;;378;; +KUOX;--;---;Oxford, University-Oxford Airport;MS;United States;4;34-23-04N;089-32-08W;;;138;; +KUTS;--;---;Huntsville, Huntsville Municipal Airport;TX;United States;4;30-44-38N;095-35-10W;30-44-34N;095-35-08W;111;104; +KUUU;--;---;Newport, Newport State Airport;RI;United States;4;41-31-48N;071-17-01W;41-31-53N;071-17-00W;52;51; +KUVA;--;---;Uvalde, Garner Field Airport;TX;United States;4;29-12-40N;099-44-36W;;;287;; +KUZA;--;---;Rock Hill, Rock Hill - York County Airport;SC;United States;4;34-59-02N;081-03-21W;34-59-14N;081-03-36W;204;202; +KVAD;74;781;Moody Air Force Base;GA;United States;4;30-58N;083-12W;;;71;71; +KVAY;--;---;Mount Holly, South Jersey Regional Airport;NJ;United States;4;39-56-26N;074-50-28W;39-56-22N;074-50-38W;16;15; +KVBG;72;393;Vandenberg Air Force Base;CA;United States;4;34-45N;120-34W;34-44N;120-33W;112;121;P +KVBT;--;---;Bentonville, Bentonville Municipal Airport/Louise M Thaden Field;AR;United States;4;36-21N;094-13W;;;395;; +KVCB;--;---;Vacaville, Nut Tree Airport;CA;United States;4;38-22-40N;121-57-27W;38-22-32N;121-57-31W;34;33; +KVCT;72;255;Victoria, Victoria Regional Airport;TX;United States;4;28-51-45N;096-55-47W;28-50-43N;096-55-13W;35;31;P +KVCV;--;---;George Air Force Base / Victorvi;CA;United States;4;34-35N;117-23W;;;876;; +KVDF;--;---;Tampa, Vandenberg Airport;FL;United States;4;28-00-50N;082-20-43W;;;7;; +KVDI;--;---;Vidalia, Vidalia Municipal Airport;GA;United States;4;32-11-33N;082-22-19W;;;84;; +KVDW;--;---;Vedauwoo;WY;United States;4;41-09N;105-24W;;;2542;; +KVEL;--;---;Vernal, Vernal Airport;UT;United States;4;40-26-39N;109-30-42W;40-26-47N;109-30-42W;1607;1604; +KVGT;--;---;Las Vegas, North Las Vegas Airport;NV;United States;4;36-12-42N;115-11-45W;;;672;; +KVIH;--;---;Rolla / Vichy, Rolla National Airport;MO;United States;4;38-07-55N;091-45-55W;38-07-56N;091-45-54W;350;333; +KVIS;--;---;Visalia Municipal Automatic Weather Observing / Reporting System;CA;United States;4;36-19N;119-24W;;;89;; +KVJI;--;---;Abingdon;VA;United States;4;36-41N;082-02W;;;631;; +KVKS;--;---;Vicksburg Municipal;MS;United States;4;32-14N;090-56W;;;32;; +KVLD;--;---;Valdosta, Valdosta Regional Airport;GA;United States;4;30-47N;083-17W;;;62;; +KVLG;--;---;The Villages;FL;United States;4;28-58N;081-58W;;;27;; +KVNY;--;---;Van Nuys, Van Nuys Airport;CA;United States;4;34-12-45N;118-29-27W;34-12-29N;118-29-27W;243;245; +KVOK;--;---;Volk / Camp Douglas;WI;United States;4;43-56N;090-16W;;;277;; +KVPC;--;---;Cartersville, Cartersville Airport;GA;United States;4;34-07-42N;084-50-50W;34-07-22N;084-51-02W;233;222; +KVPS;72;221;Valparaiso / Eglin Air Force Base;FL;United States;4;30-29N;086-31W;30-29N;086-31W;26;29;P +KVPZ;--;---;Valparaiso, Porter County Municipal Airport;IN;United States;4;41-27-11N;086-59-53W;41-26-58N;087-00-33W;234;231; +KVQN;--;---;Volens;VA;United States;4;36-57N;078-59W;;;185;; +KVQQ;--;---;Jacksonville, Cecil Field Airport;FL;United States;4;30-13-07N;081-52-36W;;;25;; +KVRB;--;---;Vero Beach, Vero Beach Municipal Airport;FL;United States;4;27-39-20N;080-25-05W;27-39-05N;080-25-04W;7;10; +KVRX;--;---;Vermillion Area;LA;United States;4;28-35N;092-27W;;;1;; +KVSF;--;---;Springfield, Hartness State Springfield Airport;VT;United States;4;43-20-33N;072-31-18W;43-20-34N;072-31-19W;175;175; +KVTA;--;---;Newark, Newark Heath Airport;OH;United States;4;40-01-22N;082-27-45W;40-01-25N;082-27-49W;269;268; +KVTI;--;---;Vinton, Vinton Veterans Memorial Airpark Airport;IA;United States;4;42-13-07N;092-01-33W;;;258;; +KVTN;72;567;Valentine, Miller Field;NE;United States;4;42-51-31N;100-33-05W;42-51-41N;100-32-56W;789;788;P +KVTP;--;---;La Veta Mountain, La Veta Pass;CO;United States;4;37-30-04N;105-10-01W;;;3114;; +KVTX;--;---;Los Angeles Nexrad;CA;United States;4;34-25N;119-11W;;;856;; +KVUJ;--;---;Albemarle, Stanly County Airport;NC;United States;4;35-25-00N;080-09-03W;;;186;; +KVUO;--;---;Vancouver, Pearson Airpark;WA;United States;4;45-37-24N;122-39-23W;45-37-26N;122-39-20W;7;5; +KVUW;--;---;Eugene Island;LA;United States;4;28-15N;091-50W;;;1;; +KVVG;--;---;The Villages;FL;United States;4;28-58N;081-58W;;;27;; +KVVV;--;---;Ortonville, Ortonville Muncipal-Martinson Field Airport;MN;United States;4;45-18-20N;096-25-28W;;;335;; +KVWU;--;---;Waskish, Waskish Municipal Airport;MN;United States;4;48-09-15N;094-31-01W;;;360;; +KVYS;--;---;Peru, Illinois Valley Regional-Walter A Duncan Field Airport;IL;United States;4;41-21-07N;089-09-11W;;;199;; +KW08;--;---;Weirwood / Kellam Field;VA;United States;4;37-28N;075-53W;;;12;; +KW11;--;---;Menomonie, Menomonie Municipal Airport-Score Field;WI;United States;4;44-53-32N;091-52-04W;;;273;; +KW22;--;---;Buckhannon, Upshur County Regional Airport;WV;United States;4;39-00N;080-16W;;;498;; +KW30;74;595;Ocean City;MD;United States;4;38-20N;075-05W;;;4;4; +KW39;--;---;Norfolk / Chesapeak;VA;United States;4;36-54N;075-43W;;;23;; +KW44;--;---;Asheboro, Asheboro Municipal Airport;NC;United States;4;35-39-14N;079-53-42W;;;205;; +KW51;--;---;Cape Charles Coast Guard Station;VA;United States;4;37-15N;076-00W;;;2;; +KW60;--;---;West Cameron 560;LA;United States;4;28-09N;093-21W;;;0;; +KW63;--;---;Clarksville / Marks;VA;United States;4;36-36N;078-34W;;;128;; +KW71;--;---;Smith Point / Sunnybank;VA;United States;4;37-53N;076-11W;;;1;; +KW76;--;---;West Cameron B522;LA;United States;4;28-23N;093-30W;;;29;; +KW77;--;---;Sanford, Sanford-Lee County Brick Field Airport;NC;United States;4;35-26N;079-11W;;;131;; +KW99;--;---;Petersburg, Grant County Airport;WV;United States;4;38-59N;079-08W;;;293;; +KWAL;72;402;Wallops Island, Wallops Flight Facility Airport;VA;United States;4;37-56-26N;075-27-47W;37-56-26N;075-28-01W;12;14; +KWDD;71;273;Belle River;;Canada;4;42-18N;082-42W;;;184;; +KWDG;--;---;Enid / Woodring Municipal;OK;United States;4;36-23N;097-47W;;;356;; +KWDR;--;---;Winder, Winder-Barrow Airport;GA;United States;4;33-58-56N;083-40-05W;;;287;; +KWEY;--;---;West Yellowstone;MT;United States;4;44-39N;111-06W;;;2031;; +KWHP;--;---;Los Angeles, Whiteman Airport;CA;United States;4;34-15;118-24W;;;306;; +KWJF;--;---;Lancaster, General William J. Fox Airfield Airport;CA;United States;4;34-44-27N;118-13-08W;;;715;; +KWLD;--;---;Winfield / Arkansas City, Strother Field;KS;United States;4;37-10-05N;097-02-13W;37-10-11N;097-01-59W;353;350; +KWMC;72;583;Winnemucca, Winnemucca Municipal Airport;NV;United States;4;40-54-07N;117-48-26W;40-54-18N;117-48-24W;1311;1310;P +KWRB;--;---;Warner Robins Air Force Base;GA;United States;4;32-38N;083-36W;;;90;; +KWRI;--;---;Mcguire Air Force Base;NJ;United States;4;40-01N;074-36W;;;41;; +KWRL;--;---;Worland, Worland Municipal Airport;WY;United States;4;43-57-57N;107-57-03W;43-58-22N;107-57-02W;1288;1271; +KWST;--;---;Westerly, Westerly State Airport;RI;United States;4;41-20-59N;071-47-56W;41-21-02N;071-48-24W;24;21; +KWTR;--;---;Whitaker;WY;United States;4;41-41N;104-87W;;;1888;; +KWVI;--;---;Watsonville, Watsonville Municipal Airport;CA;United States;4;36-56-22N;121-47-20W;36-56-03N;121-47-12W;49;43; +KWVL;--;---;Waterville Automatic Weather Observing / Reporting System;ME;United States;4;44-32N;069-41W;;;101;; +KWWD;--;---;Wildwood Automatic Weather Observing / Reporting System;NJ;United States;4;39-01N;074-55W;;;7;; +KWWR;74;641;Woodward, West Woodward Airport;OK;United States;4;36-26-12N;099-31-16W;36-26N;099-32W;667;667; +KWYS;--;---;West Yellowstone;MT;United States;4;44-41N;111-07W;;;2025;; +KX53;--;---;Clewiston;FL;United States;4;26-45N;080-57W;;;6;; +KX80;--;---;Jupiter Inlet Coast Guard Station;FL;United States;4;27-02N;080-07W;;;1;; +KX81;--;---;Lake Worth Inlet;FL;United States;4;26-46N;080-03W;;;1;; +KX82;--;---;Fort Pierce Coast Guard Station;FL;United States;4;27-28N;080-18W;;;1;; +KX84;--;---;Islamorada Coast Guard Station;FL;United States;4;24-57N;080-35W;;;1;; +KX86;--;---;Fowey Rocks Coast Guard Station;FL;United States;4;25-35N;080-06W;;;1;; +KX87;--;---;Miami Beach Coast Guard Station;FL;United States;4;25-46N;080-08W;;;1;; +KX88;--;---;Marathon Coast Guard Station;FL;United States;4;24-43N;081-07W;;;1;; +KX89;--;---;Ft. Myers Beach Coast Guard Station;FL;United States;4;26-27N;081-57W;;;1;; +KX90;--;---;Venice Long Range Navigation;FL;United States;4;27-05N;082-27W;;;1;; +KX91;--;---;Egmont Key Coast Guard Station;FL;United States;4;27-36N;082-46W;;;1;; +KXBP;--;---;Bridgeport, Bridgeport Municipal Airport;TX;United States;4;33-10-31N;097-49-42W;;;260;; +KXCN;--;---;Green Canyon 184;LA;United States;4;27-46N;091-31W;;;0;; +KXMR;74;794;Cape Kennedy;FL;United States;4;28-28N;080-33W;28-28N;080-33W;3;3; +KXNA;--;---;Fayetteville/Springdale, Northwest Arkansas Regional Airport;AR;United States;4;36-16-55N; 094-18-25W;;;392;; +KXVG;--;---;Longville, Longville Municipal Airport;MN;United States;4;46-59-25N;094-12-14W;;;407;; +KXVW;--;---;Vandenberg Range;CA;United States;4;34-43N;120-34W;;;100;; +KY12;--;---;Airlake;MN;United States;4;44-38N;093-14W;;;292;; +KY15;--;---;Cheboygan, Cheboygan County Airport;MI;United States;4;45-39-13N;084-31-09W;;;195;; +KY26;--;---;Mobridge;SD;United States;4;45-32N;100-26W;;;508;; +KY39;--;---;Olivia, Olivia Regional Airport;MN;United States;4;44-46-43N;095-01-58W;;;328;; +KY68;--;---;Tracy, Tracy Municipal Airport;MN;United States;4;44-14-56N;095-36-26W;;;408;; +KYAK;--;---;Yakutat, Yakutat Airport;AK;United States;4;59-30-37N;139-39-46W;59-30-48N;139-40-15W;10;10; +KYIP;--;---;Detroit, Willow Run Airport;MI;United States;4;42-14-12N;083-31-34W;42-14-05N;083-31-18W;218;215; +KYKM;72;781;Yakima, Yakima Air Terminal;WA;United States;4;46-33-51N;120-32-01W;46-34-14N;120-32-27W;333;324;P +KYKN;--;---;Yankton Automatic Weather Observing / Reporting System;SD;United States;4;42-55N;097-23W;;;398;; +KYNG;72;525;Youngstown, Youngstown-Warren Regional Airport;OH;United States;4;41-15-16N;080-40-26W;41-15-48N;080-40-25W;364;360; +KYUM;72;280;Yuma / Yuma International;AZ;United States;4;32-39N;114-36W;32-52N;114-20W;65;63;P +KZAB;--;---;Albuquerque Radar Site;NM;United States;4;35-10N;106-34W;;;1621;; +KZLC;--;---;Salt Lake City;UT;United States;4;40-47N;111-57W;;;1288;; +KZSE;--;---;Auburn;WA;United States;4;47-17N;122-11W;;;99;; +KZZV;--;---;Zanesville, Zanesville Municipal Airport;OH;United States;4;39-56-40N;081-53-32W;39-56-50N;081-53-32W;274;268; +LATI;13;615;Tirana;;Albania;6;41-20N;019-47E;41-20N;019-47E;89;90;P +LBBG;15;655;Burgas;;Bulgaria;6;42-29N;027-29E;;;16;28;P +LBGO;--;---;Gorna Orechovista;;Bulgaria;6;43-09N;025-36E;;;;; +LBPD;15;625;Plovdiv;;Bulgaria;6;42-08N;024-45E;;;179;185;P +LBRS;15;535;Rousse;;Bulgaria;6;43-51N;025-57E;;;37;45;P +LBSF;15;614;Sofia Observ. ;;Bulgaria;6;42-39N;023-23E;42-39N;023-23E;586;595;P +LBWN;15;552;Varna;;Bulgaria;6;43-12N;027-55E;;;41;43;P +LCEN;--;---;Ercan;;Cyprus;6;35-09N;033-30E;;;91;; +LCLK;17;609;Larnaca Airport;;Cyprus;6;34-53N;033-38E;34-53N;033-38E;2;2;P +LCNC;17;607;Athalassa;;Cyprus;6;35-09N;033-24E;35-09N;033-24E;162;161; +LCPH;17;600;Paphos Airport;;Cyprus;6;34-43N;032-29E;34-43N;032-29E;11;8;P +LCRA;17;601;Akrotiri;;Cyprus;6;34-35N;032-59E;34-35N;032-59E;23;0; +LDDD;14;240;Zagreb / Maksimir;;Croatia;6;45-49N;016-02E;45-49N;016-02E;123;128; +LDDU;14;474;Dubrovnik / Cilipi;;Croatia;6;42-34N;018-16E;;;157;165; +LDLO;--;---;Losinj Island;;Croatia;6;44-33-57N;014-23-35E;;;45;; +LDOC;--;---;Cepin;;Croatia;;45-31N;018-33E;;;72;; +LDOR;14;370;Slavonski Brod;;Croatia;6;45-10N;018-00E;45-10N;018-00E;88;89; +LDOS;14;280;Osijek / Cepin;;Croatia;6;45-27;018-48E;;;88;; +LDPL;14;307;Pula Aerodrome;;Croatia;6;45-54N;013-55E;;;63;63; +LDRI;13;116;Rijeka / Omisalj;;Croatia;6;45-13N;014-35E;;;85;; +LDSB;--;---;Brac;;Croatia;6;43-17-09N;016-40-47E;;;541;; +LDSH;14;447;Hvar;;Croatia;6;43-10N;016-27E;;;20;25; +LDSP;14;444;Split / Resnik;;Croatia;6;43-32N;016-18E;;;19;21; +LDVA;14;246;Varazdin;;Croatia;6;46-18N;016-23E;;;167;168; +LDZA;14;241;Zagreb / Pleso;;Croatia;6;45-44N;016-04E;;;106;107; +LDZD;14;431;Zadar / Zemunik;;Croatia;6;44-06N;015-21E;;;82;; +LEAB;08;280;Albacete / Los Llanos;;Spain;6;38-57N;001-51W;38-57N;001-51W;702;704;P +LEAL;08;360;Alicante / El Altet;;Spain;6;38-17N;000-33W;;;43;31;P +LEAM;08;487;Almeria / Aeropuerto;;Spain;6;36-51N;002-23W;36-51N;002-23W;15;21;P +LEAS;08;011;Asturias / Aviles;;Spain;6;43-33N;006-02W;;;127;130; +LEBA;08;410;Cordoba / Aeropuerto;;Spain;6;37-51N;004-51W;;;90;92;P +LEBB;08;025;Bilbao / Sondica;;Spain;6;43-18N;002-56W;;;42;37;P +LEBG;08;075;Burgos / Villafria;;Spain;6;42-22N;003-38W;;;894;891;P +LEBL;08;181;Barcelona / Aeropuerto;;Spain;6;41-17N;002-04E;41-17N;002-04E;4;6;P +LEBZ;08;330;Badajoz / Talavera La Real;;Spain;6;38-53N;006-49W;38-53N;006-49W;185;192;P +LECH;08;233;Calamocha;;Spain;6;40-56N;001-18W;;;890;889; +LECO;08;002;La Coruna / Alvedro;;Spain;6;43-18N;008-23W;43-18N;008-23W;97;103; +LECV;08;219;Madri-Colmenar;;Spain;6;40-39N;003-44W;;;;; +LEGA;--;---;Granada / Armilla;;Spain;6;37-8N;003-38-08W;;;700;; +LEGE;08;184;Gerona / Costa Brava;;Spain;6;41-54N;002-46E;;;143;129; +LEGR;08;419;Granada / Aeropuerto;;Spain;6;37-11N;003-47W;;;567;570;P +LEGT;08;224;Madrid / Getafe;;Spain;6;40-18N;003-43W;;;620;617; +LEHI;08;335;Hinojosa Del Duque;;Spain;6;38-31N;005-07W;;;540;540; +LEIB;08;373;Ibiza / Es Codola;;Spain;6;38-52N;001-23E;;;7;12;P +LEJR;08;451;Jerez De La Fronteraaeropuerto;;Spain;6;36-45N;006-04W;;;27;28;P +LELC;08;433;Murcia / San Javier;;Spain;6;37-47N;000-48W;37-47N;000-48W;5;3;P +LELL;--;---;Sabadell;;Spain;6;41-31N;002-06E;;;250;; +LELN;08;055;Leon / Virgen Del Camino;;Spain;6;42-35N;005-39W;42-35N;005-39W;926;914;P +LELO;08;084;Logrono / Agoncillo;;Spain;6;42-27N;002-20W;42-27N;002-20W;353;363;P +LEMD;08;221;Madrid / Barajas;;Spain;6;40-27N;003-33W;40-30N;003-35W;609;582;P +LEMG;08;482;Malaga / Aeropuerto;;Spain;6;36-40N;004-29W;36-40N;004-29W;16;7;P +LEMH;08;314;Menorca / Mahon;;Spain;6;39-52N;004-14E;39-52N;004-14E;87;82;P +LEMO;08;397;Moron De La Frontera;;Spain;6;37-09N;005-37W;;;87;88; +LEPA;08;306;Palma De Mallorca / Son San Juan;;Spain;6;39-33N;002-44E;;;4;8;P +LEPP;08;085;Pamplona / Noain;;Spain;6;42-46N;001-38W;;;459;453; +LERI;08;429;Murcia / Alcantarilla;;Spain;6;37-57N;001-14W;;;75;75; +LERS;08;175;Reus / Aeropuerto;;Spain;6;41-09N;001-10E;;;71;76; +LERT;08;449;Rota;;Spain;6;36-39N;006-21W;36-39N;006-21W;26;26; +LESA;08;202;Salamanca / Matacan;;Spain;6;40-57N;005-30W;40-57N;005-30W;793;795;P +LESO;08;029;San Sebastian / Fuenterrabia;;Spain;6;43-21N;001-48W;;;5;8; +LEST;08;042;Santiago / Labacolla;;Spain;6;42-54N;008-26W;;;370;367;P +LETO;08;227;Madrid / Torrejon;;Spain;6;40-29N;003-27W;;;607;611; +LEVC;08;284;Valencia / Aeropuerto;;Spain;6;39-30N;000-28W;39-30N;000-28W;69;62;P +LEVD;08;140;Valladolid / Villanubla;;Spain;6;41-43N;004-51W;41-43N;004-51W;849;846;P +LEVS;08;223;Madrid / Cuatro Vientos;;Spain;6;40-23N;003-47W;;;690;687; +LEVT;08;080;Vitoria;;Spain;6;42-53N;002-43W;;;513;510; +LEVX;08;045;Vigo / Peinador;;Spain;6;42-13N;008-38W;;;264;255;P +LEXJ;08;021;Santander / Parayas;;Spain;6;43-26N;003-49W;;;6;9; +LEZA;--;---;Zaragoza United States Air Force Operated Base In Foreign Country ;;Spain;6;41-40N;001-03W;;;263;; +LEZG;08;160;Zaragoza / Aeropuerto;;Spain;6;41-40N;001-01W;41-40N;001-01W;263;258;P +LEZL;08;391;Sevilla / San Pablo;;Spain;6;37-25N;005-54W;37-25N;005-54W;34;31;P +LFAT;07;003;Le Touquet;;France;6;50-31N;001-37E;;;10;14;P +LFBA;07;524;Agen;;France;6;44-11N;000-36E;;;61;60;P +LFBC;07;502;Cazaux;;France;6;44-32N;001-08W;44-32N;001-08W;25;33;P +LFBD;07;510;Bordeaux / Merignac;;France;6;44-50N;000-42W;44-50N;000-42W;49;61;P +LFBE;07;530;Bergerac;;France;6;44-49N;000-31E;;;51;52;P +LFBF;07;631;Toulouse / Francazal;;France;6;43-32N;001-22E;;;164;166;P +LFBG;07;412;Cognac;;France;6;45-40N;000-19W;45-40N;000-19W;30;31;P +LFBH;07;315;La Rochelle;;France;6;46-09N;001-09W;;;4;10;P +LFBI;07;335;Poitiers;;France;6;46-35N;000-19E;46-35N;000-19E;129;120;P +LFBK;--;---;Montlucon / Gueret;;France;6;46-13N;002-22E;;;415;; +LFBL;07;434;Limoges;;France;6;45-52N;001-11E;45-52N;001-11E;396;402;P +LFBM;07;607;Mont-De-Marsan;;France;6;43-55N;000-30W;43-55N;000-30W;62;63;P +LFBN;07;330;Niort;;France;6;46-19N;000-24W;;;61;61;P +LFBO;07;630;Toulouse / Blagnac;;France;6;43-38N;001-22E;43-38N;001-22E;152;153;P +LFBP;07;610;Pau;;France;6;43-23N;000-25W;;;188;185;P +LFBS;07;503;Biscarosse;;France;6;44-26N;001-15W;44-26N;001-15W;33;39;P +LFBT;07;621;Tarbes / Ossun;;France;6;43-11N;000-00;;;379;363;P +LFBV;07;438;Brive;;France;6;45-09N;001-28E;;;111;117;P +LFBX;07;428;Perigueux;;France;6;45-12N;000-49E;;;100;97; +LFBY;07;603;Dax;;France;6;43-41N;001-04W;43-41N;001-04W;32;32;P +LFBZ;07;602;Biarritz;;France;6;43-28N;001-32W;43-28N;001-32W;75;71;P +LFCG;07;627;St-Girons;;France;6;43-00N;001-06E;43-00N;001-06E;414;412;P +LFCI;07;632;Albi;;France;6;43-55N;002-07E;;;172;178;P +LFCR;07;552;Rodez;;France;6;44-24N;002-29E;;;581;580; +LFDH;07;622;Auch;;France;6;43-41N;000-36E;;;125;128;P +LFFS;--;---;Suippes Range Met ;;France;6;49-09N;004-32E;;;199;; +LFGJ;--;---;Dole Tavaux;;France;6;47-02-34N;005-26-06E;;;196;; +LFHP;07;471;Le Puy;;France;6;45-05N;003-46E;;;832;833;P +LFIG;07;555;Cassagnes-Begonhes;;France;6;44-11N;002-31E;;;1020;; +LFJL;07;093;Metz-Nancy-Lorraine;;France;6;48-59N;006-15E;;;264;; +LFKB;07;790;Bastia;;France;6;42-33N;009-29E;42-33N;009-29E;8;12;P +LFKC;07;754;Calvi;;France;6;42-32N;008-48E;;;64;58;P +LFKF;07;780;Figari;;France;6;41-30N;009-06E;;;26;23;P +LFKJ;07;761;Ajaccio;;France;6;41-55N;008-48E;41-55N;008-48E;6;9;P +LFKS;07;765;Solenzara;;France;6;41-55N;009-24E;41-55N;009-24E;8;22;P +LFLA;07;265;Auxerre;;France;6;47-48N;003-33E;47-48N;003-33E;207;212;P +LFLB;07;491;Chambery / Aix-Les-Bains;;France;6;45-39N;005-53E;;;235;239;P +LFLC;07;460;Clermont-Ferrand;;France;6;45-47N;003-10E;45-47N;003-10E;332;330;P +LFLD;07;255;Bourges;;France;6;47-04N;002-22E;47-04N;002-22E;161;166;P +LFLL;07;481;Lyon / Satolas;;France;6;45-44N;005-05E;45-44N;005-05E;248;240;P +LFLM;07;385;Macon;;France;6;46-18N;004-48E;46-18N;004-48E;221;217;P +LFLN;07;379;Saint-Yan;;France;6;46-25N;004-01E;;;242;244;P +LFLQ;07;577;Montelimar;;France;6;44-35N;004-44E;44-35N;004-44E;73;74;P +LFLS;07;486;Grenoble / St. Geoirs;;France;6;45-22N;005-20E;;;384;386;P +LFLV;07;374;Vichy;;France;6;46-10N;003-24E;;;249;251;P +LFLW;07;549;Aurillac;;France;6;44-54N;002-25E;;;640;639;P +LFLX;07;354;Chateauroux;;France;6;46-51N;001-43E;;;160;157;P +LFLY;07;480;Lyon / Bron;;France;6;45-43N;004-57E;45-43N;004-57E;200;201;P +LFMA;07;649;Aix Les Milles;;France;6;43-30N;005-22E;;;111;111;P +LFMC;07;675;Le Luc;;France;6;43-23N;006-23E;;;80;78;P +LFMD;07;684;Cannes;;France;6;43-33N;006-57E;;;3;9;P +LFME;07;645;Nimes / Courbessac;;France;6;43-52N;004-24E;43-52N;004-24E;60;62;P +LFMH;07;475;St-Etienne Boutheon;;France;6;45-32N;004-18E;;;404;402;P +LFMI;07;647;Istres;;France;6;43-31N;004-56E;;;23;24;P +LFMK;07;635;Carcassonne;;France;6;43-13N;002-19E;43-13N;002-19E;130;130;P +LFML;07;650;Marseille / Marignane;;France;6;43-27N;005-14E;43-27N;005-13E;6;36;P +LFMN;07;690;Nice;;France;6;43-39N;007-12E;43-39N;007-12E;4;10;P +LFMO;07;579;Orange;;France;6;44-08N;004-50E;;;60;55;P +LFMP;07;747;Perpignan;;France;6;42-44N;002-52E;42-44N;002-52E;43;48;P +LFMT;07;643;Montpellier;;France;6;43-35N;003-58E;;;5;6;P +LFMU;--;---;Beziers / Vias;;France;6;43-19N;003-21E;;;17;; +LFMX;07;588;St-Auban-Sur-Durance;;France;6;44-04N;006-00E;44-04N;006-00E;460;461;P +LFMY;07;648;Salon;;France;6;43-36N;005-06E;;;59;60;P +LFNB;--;---;Mende / Brenoux;;France;6;44-30N;003-32E;;;1024;; +LFOA;--;---;Avord;;France;6;47-03-12N;002-37-57E;;;177;; +LFOB;07;055;Beauvais;;France;6;49-28N;002-07E;;;109;111;P +LFOC;07;140;Chateaudun;;France;6;48-03N;001-23E;;;134;127;P +LFOE;07;038;Evreux;;France;6;49-01N;001-13E;;;141;146;P +LFOF;07;139;Alencon;;France;6;48-27N;000-07E;48-27N;000-07E;144;141;P +LFOH;07;028;La Heve;;France;6;49-31N;000-04E;;;100;103;P +LFOI;07;005;Abbeville;;France;6;50-08N;001-50E;50-08N;001-50E;74;77;P +LFOJ;07;249;Orleans;;France;6;47-59N;001-45E;47-59N;001-45E;126;125;P +LFOK;--;---;Chalons-Vatry;;France;6;48-46-34N;004-11-04E;;;179;; +LFOP;07;037;Rouen;;France;6;49-23N;001-11E;49-23N;001-11E;157;157;P +LFOR;07;143;Chartres;;France;6;48-28N;001-31E;;;155;156;P +LFOS;07;033;Vittefleur / St. Vale;;France;6;49-50N;000-39E;;;83;; +LFOT;07;240;Tours;;France;6;47-27N;000-43E;47-27N;000-43E;108;112;P +LFOW;07;061;Saint-Quentin;;France;6;49-49N;003-12E;49-49N;003-12E;98;101;P +LFPB;07;150;Paris / Le Bourget;;France;6;48-58N;002-27E;;;66;65;P +LFPC;07;057;Creil Fafb ;;France;6;49-15N;002-31E;;;88;; +LFPG;07;157;Paris-Aeroport Charles De Gaulle;;France;6;49-01N;002-32E;;;118;109;P +LFPM;07;153;Melun;;France;6;48-37N;002-41E;;;95;92;P +LFPN;07;146;Toussus Le Noble;;France;6;48-46N;001-06E;;;164;161;P +LFPO;07;149;Paris-Orly;;France;6;48-44N;002-24E;48-44N;002-24E;89;96;P +LFPV;07;147;Villacoublay;;France;6;48-46N;002-12E;;;177;179;P +LFPW;--;---;Paris Met Center;;France;6;48-50N;002-20E;;;75;; +LFQB;07;168;Troyes;;France;6;48-20N;004-01E;;;118;118;P +LFQG;07;260;Nevers;;France;6;47-00N;003-06E;;;180;181;P +LFQH;07;276;Chatillon-Sur-Seine;;France;6;47-51N;004-33E;;;264;; +LFQI;07;017;Cambrai;;France;6;50-13N;003-09E;;;78;77;P +LFQQ;07;015;Lille;;France;6;50-34N;003-06E;50-34N;003-06E;48;52;P +LFQV;07;075;Charleville;;France;6;49-47N;004-38E;;;149;150;P +LFRA;07;230;Angers;;France;6;47-30N;000-34W;;;57;58;P +LFRB;07;110;Brest;;France;6;48-27N;004-25W;48-27N;004-25W;99;103;P +LFRC;07;024;Cherbourg / Maupertus;;France;6;49-39N;001-28W;49-39N;001-28W;138;139; +LFRD;07;125;Dinard;;France;6;48-35N;002-04W;;;65;60; +LFRH;07;205;Lann Bihoue;;France;6;47-46N;003-27W;;;52;44;P +LFRI;07;306;La Roche-Sur-Yon;;France;6;46-42N;001-23W;;;90;91;P +LFRJ;07;106;Landivisiau;;France;6;48-31N;004-09W;;;106;115;P +LFRK;07;027;Caen;;France;6;49-11N;000-27W;;;78;67;P +LFRL;07;109;Lanveoc Poulmic;;France;6;48-17N;004-26W;;;87;82;P +LFRM;07;235;Le Mans;;France;6;47-56N;000-12E;;;59;52;P +LFRN;07;130;Rennes;;France;6;48-04N;001-44W;48-04N;001-44W;37;37;P +LFRO;--;---;Lannion / Servel;;France;6;48-45N;003-28W;;;89;; +LFRQ;07;201;Quimper;;France;6;47-58N;004-10W;;;92;94;P +LFRS;07;222;Nantes;;France;6;47-10N;001-36W;47-10N;001-36W;27;27;P +LFRT;07;120;Saint-Brieuc;;France;6;48-32N;002-51W;;;138;136;P +LFRU;--;---;Morlaix / Ploujean;;France;6;48-36N;003-49W;;;86;; +LFRZ;07;217;St-Nazaire;;France;6;47-19N;002-10W;;;3;4;P +LFSA;07;288;Besancon;;France;6;47-15N;005-59E;;;307;309;P +LFSB;07;299;Bale-Mulhouse;;France;6;47-36N;007-31E;;;270;271;P +LFSC;07;197;Colmar;;France;6;47-55N;007-24E;;;211;217;P +LFSD;07;280;Dijon;;France;6;47-16N;005-05E;47-16N;005-05E;222;227;P +LFSF;07;090;Metz / Frescaty;;France;6;49-05N;006-08E;;;190;191;P +LFSI;07;169;St-Dizier;;France;6;48-38N;004-54E;;;139;140;P +LFSL;07;179;Toul / Rosieres;;France;6;48-47N;005-29E;;;285;298;P +LFSN;07;180;Nancy / Essey;;France;6;48-41N;006-13E;48-41N;006-13E;225;217;P +LFSO;07;181;Nancy / Ochey;;France;6;48-35N;005-58E;;;336;350;P +LFSQ;07;295;Belfort;;France;6;47-38N;006-52E;;;422;423;P +LFSR;07;070;Reims;;France;6;49-18N;004-02E;49-18N;004-02E;95;99;P +LFST;07;190;Strasbourg;;France;6;48-33N;007-38E;;;153;154;P +LFSX;07;292;Luxeuil;;France;6;47-47N;006-21E;;;278;273;P +LFTH;07;667;Hyeres;;France;6;43-06N;006-09E;;;3;4;P +LFTU;07;680;St-Raphael;;France;6;43-25N;006-45E;43-25N;006-45E;2;6;P +LFTW;07;646;Nimes / Garons;;France;6;43-45N;004-25E;;;94;96;P +LFVP;71;805;Saint-Pierre;;Saint Pierre and Miquelon;4;46-46N;056-10W;46-46N;056-10W;3;5;P +LFXA;07;482;Amberieu;;France;6;45-59N;005-20E;;;250;257;P +LFYR;07;247;Romorantin;;France;6;47-19N;001-41E;;;85;86;P +LGAD;16;682;Andravida Airport ;;Greece;6;37-55N;021-17E;;;10;14;P +LGAL;16;627;Alexandroupoli Airport ;;Greece;6;40-51N;025-55E;;;7;3;P +LGAT;16;716;Athinai Airport ;;Greece;6;37-54N;023-44E;37-54N;023-44E;28;15;P +LGAV;--;---;Athens Eleftherios Venizelos International Airport;;Greece;6;37-56N;023-56E;;;94 +LGBL;16;665;Anchialos Airport ;;Greece;6;39-13N;022-48E;;;25;15; +LGEL;16;718;Elefsis Airport ;;Greece;6;38-04N;023-33E;;;44;31; +LGHI;16;706;Chios Airport ;;Greece;6;38-20N;026-08E;;;5;4;P +LGIR;16;754;Heraklion Airport ;;Greece;6;35-20N;025-11E;35-20N;025-11E;37;39;P +LGKA;16;614;Kastoria Airport ;;Greece;6;40-27N;021-17E;;;604;;P +LGKC;--;---;Kithira Airport;;Greece;6;36-17-21N;023-01-24E;;;321;; +LGKF;16;685;Kefalhnia Airport ;;Greece;6;38-07N;020-30E;;;19;22; +LGKL;16;726;Kalamata Airport ;;Greece;6;37-04N;022-01E;;;6;8; +LGKO;16;742;Kos Airport ;;Greece;6;36-47N;027-04E;;;129;;P +LGKP;16;765;Karpathos Airport;;Greece;6;35-24-51N;027-08-54E;;;6;; +LGKR;16;641;Kerkyra Airport ;;Greece;6;39-37N;019-55E;;;2;4;P +LGKV;16;624;Chrysoupoli Airport ;;Greece;6;40-59N;024-36E;;;5;5;P +LGKZ;16;632;Kozani Airport ;;Greece;6;40-18N;021-47E;;;634;627; +LGLM;16;650;Limnos Airport ;;Greece;6;39-55N;025-14E;;;5;4;P +LGLR;16;648;Larissa Airport ;;Greece;6;39-38N;022-25E;;;73;74; +LGMK;--;---;Mikonos Island, Mikonos Airport;;Greece;6;37-26-09N;025-20-45E;;;123;; +LGMT;16;667;Mytilini Airport ;;Greece;6;39-04N;026-36E;;;3;5;P +LGNX;--;---;Cyclades Islands, Naxos Airport;;Greece;6;37-04-47N;025-22-01E;;;3;; +LGPA;--;---;Paros Community Airport;;Greece;6;37-00-40N;025-07-32E;;;36;; +LGPZ;16;643;Aktion Airport ;;Greece;6;38-37N;020-46E;;;4;4;P +LGRD;--;---;Rhodes / Maritsa;;Greece;6;36-23N;028-07E;;;62;; +LGRP;16;749;Rhodes Airport ;;Greece;6;36-24N;028-05E;36-23N;028-07E;4;11;P +LGRX;16;687;Araxos Airport ;;Greece;6;38-09N;021-25E;38-10N;021-25E;11;12; +LGSA;16;746;Souda Airport ;;Greece;6;35-29N;024-07E;;;146;151;P +LGSK;--;---;Skiathos Island;;Greece;6;39-11N;023-30E;;;15;; +LGSM;16;723;Samos Airport ;;Greece;6;37-42N;026-55E;;;2;7; +LGSO;--;---;Syros Airport;;Greece;6;37-25-16N;024-56-54E;;;73;; +LGSR;--;---;Santorini Island;;Greece;6;36-24N;025-29E;;;38;; +LGTG;16;699;Tanagra Airport ;;Greece;6;38-19N;023-32E;;;148;140; +LGTP;16;710;Tripolis Airport;;Greece;6;37-32N;022-24E;;;644;652; +LGTS;16;622;Thessaloniki Airport ;;Greece;6;40-31N;022-58E;40-31N;022-58E;8;4;P +LGTT;16;715;Tatoi;;Greece;6;38-06N;023-47E;;;239;235; +LGZA;--;---;Zakinthos Airport ;;Greece;6;37-45N;020-53E;;;3;; +LHBC;12;992;Bekescsaba;;Hungary;6;46-41N;021-10E;;;88;90;P +LHBM;12;840;Budapest Met Center;;Hungary;6;47-31N;019-02E;;;129;; +LHBP;12;839;Budapest / Ferihegy;;Hungary;6;47-26N;019-16E;;;151;185; +LHBS;12;838;Budaors;;Hungary;6;47-27N;018-58E;;;132;; +LHDC;12;882;Debrecen;;Hungary;6;47-29N;021-36E;47-29N;021-38E;108;109;P +LHKE;12;970;Kecskemet;;Hungary;6;46-55N;019-45E;;;113;123;P +LHKV;12;930;Kaposvar;;Hungary;6;46-23N;017-50E;;;144;145; +LHMC;12;772;Miskolc;;Hungary;6;48-05N;020-46E;48-06N;020-47E;232;236;P +LHNY;12;892;Nyiregyhaza / Napkor;;Hungary;6;47-58N;021-59E;;;141;142;P +LHPA;12;825;Papa;;Hungary;6;47-12N;017-30E;;;145;146;P +LHPP;12;942;Pecs / Pogany;;Hungary;6;46-06N;018-14E;46-00N;018-14E;201;203;P +LHSA;--;---;Szentkiralyszabadja;;Hungary;6;47-04N;017-59E;;;280;; +LHSK;12;935;Siofok;;Hungary;6;46-55N;018-03E;46-55N;018-03E;108;109;P +LHSN;12;860;Szolnok;;Hungary;6;47-07N;020-14E;47-10N;020-14E;89;94;P +LHSY;12;812;Szombathely;;Hungary;6;47-16N;016-38E;47-16N;016-38E;220;221;P +LHTA;--;---;Taszar;;Hungary;6;46-24N;017-55E;;;160;; +LHTL;--;---;Tokol;;Hungary;6;47-21N;018-59E;;;101;; +LHUD;12;982;Szeged;;Hungary;6;46-15N;020-06E;46-15N;020-06E;82;83;P +LIBA;16;261;Amendola;;Italy;6;41-32N;015-43E;;;57;60;P +LIBC;16;350;Crotone;;Italy;6;39-00N;017-04E;;;155;161;P +LIBD;16;270;Bari / Palese Macchie;;Italy;6;41-08N;016-47E;;;34;49;P +LIBE;16;258;Monte S. Angelo;;Italy;6;41-42N;015-57E;;;838;844; +LIBG;16;324;Grottaglie;;Italy;6;40-31N;017-24E;;;64;69; +LIBH;16;325;Marina Di Ginosa;;Italy;6;40-26N;016-53E;;;2;12;P +LIBN;16;332;Lecce;;Italy;6;40-14N;018-09E;;;48;61; +LIBP;16;230;Pescara;;Italy;6;42-26N;014-12E;42-26N;014-12E;10;11;P +LIBQ;16;344;Monte Scuro;;Italy;6;39-20N;016-24E;;;1710;1720; +LIBR;16;320;Brindisi;;Italy;6;40-39N;017-57E;40-39N;017-57E;15;10;P +LIBS;16;252;Campobasso;;Italy;6;41-34N;014-39E;;;793;807;P +LIBT;16;232;Termoli;;Italy;6;42-00N;015-00E;;;16;44; +LIBU;16;316;Latronico;;Italy;6;40-05N;016-01E;;;888;896; +LIBV;16;312;Gioia Del Colle;;Italy;6;40-46N;016-56E;;;345;350; +LIBW;16;337;Bonifati;;Italy;6;39-35N;015-53E;39-35N;015-53E;484;485; +LIBY;16;360;S. Maria Di Leuca;;Italy;6;39-49N;018-21E;;;104;112;P +LIBZ;16;300;Potenza;;Italy;6;40-38N;015-48E;40-38N;015-48E;823;843;P +LICA;16;362;Lamezia Terme;;Italy;6;38-54N;016-15E;;;15;;P +LICB;--;---;Comiso As Usaf ;;Italy;6;36-56N;014-36E;;;220;; +LICC;16;460;Catania / Fontanarossa;;Italy;6;37-28N;015-03E;37-28N;015-03E;11;17;P +LICD;16;490;Lampedusa;;Italy;6;35-30N;012-36E;;;16;20;P +LICE;16;450;Enna;;Italy;6;37-34N;014-17E;;;940;965; +LICF;16;420;Messina;;Italy;6;38-12N;015-33E;38-12N;015-33E;59;51;P +LICG;16;470;Pantelleria;;Italy;6;36-49N;011-58E;36-49N;011-58E;191;170;P +LICJ;16;405;Palermo / Punta Raisi;;Italy;6;38-11N;013-06E;38-11N;013-06E;21;21;P +LICL;16;453;Gela;;Italy;6;37-05N;014-13E;;;11;33;P +LICM;--;---;Calopezzati ;;Italy;6;39-33N;016-48E;;;179;; +LICO;16;480;Cozzo Spadaro;;Italy;6;36-41N;015-08E;;;46;51;P +LICP;16;410;Palermo Boccadifalco;;Italy;6;38-06N;013-18E;;;107;117; +LICR;16;422;Reggio Calabria;;Italy;6;38-04N;015-39E;;;11;21; +LICT;16;429;Trapani / Birgi;;Italy;6;37-55N;012-30E;37-55N;012-30E;7;14;P +LICU;16;400;Ustica;;Italy;6;38-42N;013-11E;38-42N;013-11E;250;251;P +LICZ;16;459;Catania / Sigonella;;Italy;6;37-24N;014-55E;;;22;22; +LIEA;16;520;Alghero;;Italy;6;40-38N;008-17E;40-38N;008-17E;23;40;P +LIEB;16;550;Capo Bellavista;;Italy;6;39-56N;009-43E;;;138;150;P +LIEC;16;564;Capo Carbonara;;Italy;6;39-06N;009-31E;;;116;118; +LIED;16;546;Decimomannu;;Italy;6;39-21N;008-58E;;;29;28; +LIEE;16;560;Cagliari / Elmas;;Italy;6;39-15N;009-04E;39-15N;009-03E;4;5;P +LIEF;16;539;Capo Frasca;;Italy;6;39-45N;008-28E;;;89;95;P +LIEG;16;506;Guardiavecchia;;Italy;6;41-13N;009-24E;;;158;159;P +LIEH;16;522;Capo Caccia;;Italy;6;40-34N;008-10E;40-34N;008-10E;200;204; +LIEL;16;542;Capo S. Lorenzo;;Italy;6;39-30N;009-38E;;;4;5; +LIEN;16;538;Fonni;;Italy;6;40-07N;009-15E;;;1022;1029; +LIEO;16;531;Olbia / Costa Smeralda;;Italy;6;40-54N;009-31E;;;11;13; +LIEP;16;541;Perdasdefogu;;Italy;6;39-40N;009-26E;;;608;606; +LIMC;16;066;Milano / Malpensa;;Italy;6;45-37N;008-44E;;;234;211;P +LIME;16;076;Bergamo / Orio Al Serio;;Italy;6;45-40N;009-42E;;;238;237; +LIMF;16;059;Torino / Caselle;;Italy;6;45-13N;007-39E;45-13N;007-39E;301;287;P +LIMG;16;122;Albenga;;Italy;6;44-03N;008-07E;;;45;49; +LIMH;16;052;Pian Rosa;;Italy;6;45-56N;007-42E;;;3480;3488;P +LIMJ;16;120;Genova / Sestri;;Italy;6;44-25N;008-51E;;;2;3;P +LIMK;16;061;Torino / Bric Della Croce;;Italy;6;45-02N;007-44E;;;709;710; +LIML;16;080;Milano / Linate;;Italy;6;45-26N;009-17E;45-26N;009-17E;107;103;P +LIMN;16;064;Novara / Cameri;;Italy;6;45-31N;008-40E;;;178;169; +LIMO;16;072;Monte Bisbino;;Italy;6;45-52N;009-04E;;;1319;1322; +LIMP;--;---;Parma;;Italy;6;44-49-17N;010-17-41E;;;50;; +LIMS;16;084;Piacenza;;Italy;6;44-55N;009-44E;;;134;138;P +LIMT;16;124;Passo Della Cisa;;Italy;6;44-26N;009-56E;;;1039;1040; +LIMU;16;153;Capo Mele;;Italy;6;43-57N;008-10E;43-57N;008-10E;220;221;P +LIMV;16;119;Passo Dei Giovi;;Italy;6;44-38N;008-56E;;;468;475; +LIMY;16;115;Monte Malanotte;;Italy;6;44-15N;007-48E;;;1741;1742; +LIMZ;--;---;Cuneo / Levaldigi;;Italy;6;44-32-47N;007-37-20E;;;386;; +LIPA;16;036;Aviano;;Italy;6;46-02N;012-36E;;;128;128; +LIPB;16;020;Bolzano;;Italy;6;46-28N;011-20E;;;1459;1461;P +LIPC;16;148;Cervia;;Italy;6;44-13N;012-18E;;;6;10; +LIPD;16;044;Udine / Campoformido;;Italy;6;46-02N;013-11E;46-02N;013-11E;93;94;P +LIPE;16;140;Bologna / Borgo Panigale;;Italy;6;44-32N;011-18E;44-32N;011-18E;36;49; +LIPF;16;138;Ferrara;;Italy;6;44-50N;011-37E;;;10;10; +LIPH;16;099;Treviso / S. Angelo;;Italy;6;45-39N;012-11E;;;18;23; +LIPI;16;045;Udine / Rivolto;;Italy;6;45-59N;013-02E;;;51;53;P +LIPK;16;147;Forli;;Italy;6;44-12N;012-04E;;;27;32; +LIPL;16;088;Brescia / Ghedi;;Italy;6;45-25N;010-17E;;;102;97; +LIPO;--;---;Brescia / Montichia;;Italy;6;45-24-02N;010-18-59E;;;104;; +LIPP;--;---;Dova Area Control Center;;Italy;6;45-24N;011-52E;;;14;; +LIPQ;16;108;Ronchi Dei Legionari;;Italy;6;45-49N;013-29E;;;12;12; +LIPR;16;149;Rimini;;Italy;6;44-02N;012-37E;;;12;13;P +LIPS;16;098;Treviso / Istrana;;Italy;6;45-41N;012-06E;;;45;46; +LIPT;16;094;Vicenza;;Italy;6;45-34N;011-31E;;;39;53; +LIPX;16;090;Verona / Villafranca;;Italy;6;45-23N;010-52E;;;67;68;P +LIPY;16;191;Falconara;;Italy;6;43-37N;013-22E;;;12;10;P +LIPZ;16;105;Venezia / Tessera;;Italy;6;45-30N;012-20E;45-30N;012-20E;2;6;P +LIQB;16;172;Arezzo;;Italy;6;43-28N;011-51E;;;248;249; +LIQC;16;294;Capri;;Italy;6;40-33N;014-12E;;;160;161; +LIQD;--;---;Porretta Pass;;Italy;6;44-02N;010-56E;;;932;; +LIQI;--;---;Gran Sasso Mountain Range ;;Italy;6;42-27N;013-42E;;;2138;; +LIQJ;16;214;Civitavecchia;;Italy;6;42-02N;011-50E;;;3;4; +LIQK;16;310;Capo Palinuro;;Italy;6;40-01N;015-17E;;;184;185;P +LIQN;16;221;Rieti;;Italy;6;42-25N;012-51E;;;389;; +LIQO;16;168;Monte Argentario;;Italy;6;42-23N;011-10E;;;630;631; +LIQP;16;129;Isola Di Palmaria;;Italy;6;44-02N;009-50E;;;192;191; +LIQR;16;204;Radicofani;;Italy;6;42-54N;011-46E;;;816;828; +LIQV;16;164;Volterra;;Italy;6;43-24N;010-52E;;;555;575; +LIQW;16;125;Sarzana / Luni;;Italy;6;44-05N;009-59E;;;9;10; +LIQZ;16;280;Ponza;;Italy;6;40-55N;012-57E;;;184;185;P +LIRA;16;239;Roma / Ciampino;;Italy;6;41-47N;012-35E;;;129;105; +LIRB;16;224;Vigna Di Valle;;Italy;6;42-05N;012-13E;;;262;266; +LIRE;16;245;Pratica Di Mare;;Italy;6;41-39N;012-27E;41-39N;012-26E;6;21; +LIRF;16;242;Roma Fiumicino;;Italy;6;41-48N;012-14E;41-48N;012-14E;2;3; +LIRG;16;234;Guidonia;;Italy;6;42-00N;012-44E;;;88;89; +LIRH;16;244;Frosinone;;Italy;6;41-38N;013-18E;;;180;185; +LIRI;--;---;Pontecagnano Air Force Base ;;Italy;6;40-37N;014-55E;;;40;; +LIRJ;16;197;M. Calamita;;Italy;6;42-44N;010-24E;;;396;397; +LIRK;16;219;Monte Terminillo;;Italy;6;42-28N;012-59E;;;1874;1875;P +LIRL;16;243;Latina;;Italy;6;41-33N;012-54E;;;25;26; +LIRM;16;253;Grazzanise;;Italy;6;41-03N;014-04E;;;9;10; +LIRN;16;289;Napoli / Capodichino;;Italy;6;40-51N;014-18E;40-53N;014-18E;88;72;P +LIRP;16;158;Pisa / S. Giusto;;Italy;6;43-41N;010-23E;43-40N;010-23E;2;6;P +LIRQ;16;170;Firenze / Peretola;;Italy;6;43-48N;011-12E;;;40;38;P +LIRS;16;206;Grosseto;;Italy;6;42-45N;011-04E;;;5;7;P +LIRT;16;263;Trevico;;Italy;6;41-03N;015-14E;;;1085;1093; +LIRU;16;235;Roma / Urbe;;Italy;6;41-57N;012-30E;;;18;24; +LIRV;16;216;Viterbo;;Italy;6;42-26N;012-03E;;;300;308; +LIRZ;16;181;Perugia;;Italy;6;43-05N;012-30E;43-05N;012-30E;208;205;P +LIVC;16;134;Monte Cimone;;Italy;6;44-12N;010-42E;;;2165;2173;P +LIVD;16;033;Dobbiaco;;Italy;6;46-44N;012-13E;;;1222;1226; +LIVE;--;---;Resia Pass ;;Italy;6;46-50N;010-30E;;;1800;; +LIVF;16;179;Frontone;;Italy;6;43-31N;012-44E;;;570;574; +LIVM;16;146;Punta Marina;;Italy;6;44-27N;012-18E;;;2;6; +LIVO;16;040;Tarvisio;;Italy;6;46-30N;013-35E;;;777;778;P +LIVP;16;022;Paganella;;Italy;6;46-09N;011-02E;;;2125;2129; +LIVR;16;021;Passo Rolle;;Italy;6;46-18N;011-47E;;;2004;2006; +LIVT;16;110;Trieste;;Italy;6;45-39N;013-45E;;;8;20;P +LIYW;16;037;Aviano Usaf ;;Italy;6;46-02N;012-37E;;;126;; +LJLJ;14;014;Ljubljana / Brnik;;Slovenia;6;46-13N;014-29E;46-13N;014-29E;385;362; +LJMB;14;026;Maribor / Slivnica;;Slovenia;6;46-29N;015-41E;;;264;265; +LJMS;13;031;Murska Sobota;;Slovenia;6;46-39N;016-11E;;;188;; +LJPZ;13;105;Portoroz;;Slovenia;6;45-31N;013-34E;;;95;; +LKHO;11;774;Holesov;;Czech Republic;6;49-19N;017-34E;;;224;224; +LKKU;--;---;Kunovice;;Czech Republic;6;49-01-46N;017-26-23E;;;177;; +LKKV;11;414;Karlovy Vary;;Czech Republic;6;50-12N;012-55E;;;603;604; +LKKZ;11;968;Kosice;;Slovakia;6;48-40N;021-13E;48-42N;021-16E;230;231;P +LKLB;--;---;Liberec;;Czech Republic;6;50-46-06N;015-01-30E;;;405;; +LKMT;11;782;Ostrava / Mosnov;;Czech Republic;6;49-41N;018-07E;49-47N;018-16E;256;256;P +LKPP;11;826;Piestany;;Slovakia;6;48-37N;017-50E;;;163;164; +LKPR;11;518;Praha / Ruzyne;;Czech Republic;6;50-06N;014-15E;50-06N;014-17E;365;365;P +LKSL;11;903;Sliac;;Slovakia;6;48-39N;019-09E;;;314;315;P +LKTB;11;723;Brno / Turany;;Czech Republic;6;49-09N;016-42E;;;241;246;P +LLBG;40;180;Ben-Gurion International Airport;;Israel;6;32-00N;034-54E;32-00N;034-54E;40;49;P +LLBS;40;191;Beer-Sheva;;Israel;6;31-14N;034-47E;31-14N;034-47E;275;280;P +LLET;40;199;Eilat;;Israel;6;29-33N;034-57E;29-33N;034-57E;12;12;P +LLHA;40;155;Sde-Haifa Haifa;;Israel;6;32-48N;035-02E;;;8;8;P +LLIB;--;---;Galilee / Pina;;Israel;6;32-58-48N;035-34-12E;;;;; +LLJR;40;290;Jerusalem Airport;;Israel;6;31-52N;035-13E;31-52N;035-13E;749;759;P +LLOV;40;198;Ovda;;Israel;6;30-00N;034-50E;;;432;445; +LLSD;--;---;Tel Aviv / Sde-Dov Airport;;Israel;6;32-06-53N;034-46-56E;;;13;; +LMML;16;597;Luqa;;Malta;6;35-51N;014-29E;35-51N;014-29E;91;91;P +LOAG;--;---;Krems-Langenlois;;Austria;6;48-26-46N;015-38-01E;;;312;; +LOAN;--;---;Niederosterreich / Wiener Neustadt-Ost Flugplatz;;Austria;6;47-50-36N;016-15-29E;;;272;; +LOAV;11;181;Niederosterreich / Lugplatz Voslau;;Austria;6;47-57-52N;016-15-34E;;;233;; +LOGG;--;---;Punitz-Gussing;;Austria;6;47-08-51N;016-19-04E;;;290;; +LOIH;--;---;Hohenems-Dornbirn;;Austria;6;47-23-05N;009-42-02E;;;418;; +LOLF;--;---;Oberosterreich / Freistadt Flugplatz;;Austria;6;48-30-53N;014-24-32E;;;685;; +LOLW;--;---;Wels;;Austria;6;48-10N;014-02E;;;;; +LOWG;11;240;Graz-Thalerhof-Flughafen;;Austria;6;47-00N;015-26E;47-00N;015-27E;340;347;P +LOWI;11;120;Innsbruck-Flughafen;;Austria;6;47-16N;011-21E;;;581;593;P +LOWK;11;231;Klagenfurt-Flughafen;;Austria;6;46-39N;014-20E;;;448;476;P +LOWL;11;010;Linz / Hoersching-Flughafen;;Austria;6;48-14N;014-11E;48-14N;014-11E;298;313;P +LOWS;11;150;Salzburg-Flughafen;;Austria;6;47-48N;013-00E;;;430;450;P +LOWW;11;036;Wien / Schwechat-Flughafen;;Austria;6;48-07N;016-34E;;;183;190;P +LOWZ;--;---;Zell Am See;;Austria;6;47-17-33N;012-47-15E;;;754;; +LOXA;11;157;Aigen Im Ennstal;;Austria;6;47-32N;014-08E;;;638;649;P +LOXL;11;011;Horsching Aus-Afb ;;Austria;6;48-14N;014-11E;48-14N;014-11E;313;298; +LOXS;11;122;Schwaz Heliport ;;Austria;6;47-20N;011-42E;;;543;; +LOXT;11;030;Tulln;;Austria;6;48-19N;016-07E;;;175;176; +LOXZ;11;165;Zeltweg;;Austria;6;47-12N;014-45E;;;677;682;P +LPAZ;08;515;Santa Maria Acores ;;Portugal;6;36-58N;025-10W;;;100;100;P +LPBG;08;575;Braganca;;Portugal;6;41-48N;006-44W;;;691;692;P +LPBJ;08;562;Beja;;Portugal;6;38-01N;007-52W;;;246;247;P +LPFL;08;501;Flores Acores ;;Portugal;6;39-27N;031-08W;;;28;29;P +LPFR;08;554;Faro / Aeroporto;;Portugal;6;37-01N;007-58W;37-01N;007-58W;7;8;P +LPFU;08;521;Funchal / S. Catarina;;Portugal;1;32-41N;016-46W;32-41N;016-46W;58;49;P +LPHR;08;505;Horta / Castelo Branco Acores ;;Portugal;6;38-31N;028-43W;;;40;41;P +LPLA;08;509;Lajes Acores ;;Portugal;6;38-46N;027-06W;38-44N;027-05W;52;54;P +LPMA;--;---;Aeroporto Da Madeira;;Portugal;6;32-41-52N;016-46-28W;;;59;; +LPMR;--;---;Monte Real Mil.;;Portugal;6;39-49-52N;008-53-14W;;;57;; +LPMT;--;---;Montijo Mil.;;Portugal;6;38-42-14N;009-02-09W;;;14;; +LPOV;--;---;Ovar Mil.;;Portugal;6;40-54-57N;008-38-45W;;;17;; +LPPD;08;512;Ponta Delgada / Nordela Acores ;;Portugal;6;37-44N;025-42W;;;71;72;P +LPPR;08;545;Porto / Pedras Rubras;;Portugal;6;41-14N;008-41W;41-14N;008-41W;69;77;P +LPPS;08;524;Porto Santo;;Portugal;1;33-04N;016-21W;;;97;82;P +LPPT;08;536;Lisboa / Portela;;Portugal;6;38-46N;009-08W;38-46N;009-08W;114;123; +LPST;--;---;Sintra Mil.;;Portugal;6;38-49-52N;009-20-22W;;;134;; +LPTN;--;---;Tancos Mil.;;Portugal;6;39-28-31N;008-21-52W;;;81;; +LPVR;08;567;Vila Real;;Portugal;6;41-16N;007-43W;;;561;562; +LQBI;13;228;Bihac;;Serbia and Montenegro;6;44-49N;015-53E;44-49N;015-53E;250;246; +LQBK;13;242;Banja Luka;;Serbia and Montenegro;6;44-47N;017-13E;;;156;; +LQLV;14;640;Livno;;Bosnia and Herzegovina;6;43-50N;017-01E;;;724;728; +LQMO;13;348;Mostar;;Serbia and Montenegro;6;43-21N;017-48E;43-21N;017-48E;108;99; +LQSA;13;353;Sarajevo / Butmir;;Serbia and Montenegro;6;43-49N;018-20E;43-49N;018-20E;511;510; +LQTZ;13;257;Tuzla;;Serbia and Montenegro;6;44-33N;018-42E;;;306;; +LRAR;15;200;Arad;;Romania;6;46-12N;021-24E;46-10N;021-19E;117;118;P +LRBC;15;150;Bacau;;Romania;6;46-35N;026-58E;46-35N;026-59E;184;190;P +LRBM;15;014;Baia Mare;;Romania;6;47-40N;023-35E;47-40N;023-35E;218;194; +LRBS;15;420;Bucuresti / Imh;;Romania;6;44-30N;026-08E;44-30N;026-08E;90;91;P +LRCK;15;481;Kogalniceanu;;Romania;6;44-20N;028-26E;;;97;102; +LRCL;15;120;Cluj-Napoca;;Romania;6;46-47N;023-34E;46-47N;023-34E;410;413;P +LRCS;15;292;Caransebes;;Romania;6;45-25N;022-15E;;;241;242;P +LRCV;15;450;Craiova;;Romania;6;44-14N;023-52E;44-14N;023-52E;192;195;P +LRIA;15;090;Iasi;;Romania;6;47-10N;027-38E;47-10N;027-38E;102;104;P +LROD;15;080;Oradea;;Romania;6;47-03N;021-56E;47-03N;021-56E;135;140;P +LROP;15;421;Bucuresti Otopeni;;Romania;6;44-33N;026-06E;;;95;95; +LRSB;15;260;Sibiu;;Romania;6;45-48N;024-09E;45-48N;024-09E;443;444;P +LRSM;15;010;Satu Mare;;Romania;6;47-48N;022-53E;47-47N;022-53E;123;124;P +LRSV;15;023;Suceava / Salcea;;Romania;6;47-39N;026-15E;47-39N;026-15E;351;351; +LRTC;15;335;Tulcea;;Romania;6;45-11N;028-49E;45-11N;028-49E;4;6; +LRTM;15;145;Tirgu Mures;;Romania;6;46-32N;024-32E;46-32N;024-32E;308;309;P +LRTR;15;247;Timisoara;;Romania;6;45-46N;021-15E;45-46N;021-15E;86;88;P +LSGC;--;---;Les Eplatures;;Switzerland;6;47-05-03N;006-47-37E;;;1027;; +LSGG;06;700;Geneve-Cointrin;;Switzerland;6;46-15N;006-08E;;;420;416;P +LSGL;06;710;Lausanne;;Switzerland;6;46-33N;006-37E;;;616;615; +LSGN;06;604;Neuchatel;;Switzerland;6;47-00N;006-57E;;;485;487; +LSGS;06;720;Sion;;Switzerland;6;46-13N;007-20E;;;482;481;P +LSMP;06;610;Payerne;;Switzerland;6;46-49N;006-57E;46-49N;006-57E;490;491;P +LSZA;06;770;Lugano;;Switzerland;6;46-00N;008-58E;;;273;276; +LSZB;--;---;Bern / Belp ;;Switzerland;6;46-55N;007-30E;;;505;; +LSZG;06;632;Grenchen;;Switzerland;6;47-10-53N;007-24-59E;;;430;; +LSZH;06;670;Zurich-Kloten;;Switzerland;6;47-29N;008-32E;;;436;432;P +LSZR;06;691;Saint Gallen-Altenrhein;;Switzerland;6;47-29-06N;009-33-43E;;;398;; +LTAB;--;---;Ankara / Guvercin Lik;;Turkey;6;39-56N;032-45E;;;819;; +LTAC;17;128;Ankara / Esenboga;;Turkey;6;40-07N;032-59E;;;953;949;P +LTAD;17;129;Ankara / Etimesgut;;Turkey;6;39-57N;032-41E;;;799;806;P +LTAE;17;120;Murted Tur-Afb ;;Turkey;6;40-05N;032-34E;;;843;; +LTAF;17;352;Adana / Sakirpasa;;Turkey;6;36-59N;035-18E;36-59N;035-18E;20;20; +LTAG;17;350;Adana / Incirlik;;Turkey;6;37-00N;035-25E;37-00N;035-25E;73;66;P +LTAH;17;190;Afyon;;Turkey;6;38-45N;030-32E;;;1034;1034;P +LTAI;17;300;Antalya;;Turkey;6;36-42N;030-44E;36-54N;030-47E;50;57;P +LTAJ;17;260;Gaziantep;;Turkey;6;37-05N;037-22E;;;701;701;P +LTAK;17;370;Iskenderun;;Turkey;6;36-35N;036-10E;;;3;3;P +LTAN;17;244;Konya;;Turkey;6;37-58N;032-33E;37-58N;032-33E;1032;1022;P +LTAP;17;082;Merzifon;;Turkey;6;40-51N;035-35E;40-50N;035-31E;545;535;P +LTAQ;17;029;Samsun;;Turkey;6;41-16N;036-18E;;;162;168; +LTAR;17;090;Sivas;;Turkey;6;39-45N;037-01E;;;1285;1285;P +LTAS;17;022;Zonguldak;;Turkey;6;41-27N;031-48E;41-27N;031-48E;136;136;P +LTAT;17;200;Malatya / Erhac;;Turkey;6;38-26N;038-05E;38-26N;038-05E;862;849;P +LTAU;17;195;Kayseri / Erkilet;;Turkey;6;38-47N;035-29E;38-47N;035-29E;1053;1054;P +LTAV;--;---;Sivrihisar;;Turkey;6;39-27N;031-21E;;;96;; +LTAW;17;086;Tokat;;Turkey;6;40-18N;036-34E;;;608;608; +LTAY;--;---;Cardak;;Turkey;6;37-47N;029-42E;;;849;; +LTAZ;--;---;Nevsehir;;Turkey;6;38-46-12N;034-32-30E;;;945;; +LTBA;17;060;Istanbul / Ataturk;;Turkey;6;40-58N;028-49E;;;48;37;P +LTBD;17;234;Aydin;;Turkey;6;37-51N;027-51E;;;57;57;P +LTBE;17;116;Bursa;;Turkey;6;40-11N;029-04E;;;101;100;P +LTBF;17;150;Balikesir;;Turkey;6;39-37N;027-55E;;;101;102;P +LTBG;17;115;Bandirma;;Turkey;6;40-19N;027-58E;40-19N;027-58E;51;49;P +LTBH;17;112;Canakkale;;Turkey;6;40-08N;026-24E;;;3;3;P +LTBI;17;124;Eskisehir;;Turkey;6;39-47N;030-34E;39-47N;030-34E;785;785;P +LTBJ;17;219;Izmir / Adnan Menderes;;Turkey;6;38-16N;027-09E;;;125;120; +LTBL;17;218;Izmir / Cigli;;Turkey;6;38-30N;027-01E;;;5;5;P +LTBM;17;240;Isparta;;Turkey;6;37-45N;030-33E;37-45N;030-33E;997;997;P +LTBO;17;188;Usak;;Turkey;6;38-40N;029-25E;;;919;919;P +LTBQ;--;---;Topel Tur-Afb ;;Turkey;6;40-44N;030-05E;;;50;; +LTBR;--;---;Bursa / Yenisehir, Mil-Civ;;Turkey;6;40-15-19N;029-33-45E;;;233;; +LTBS;17;295;Dalaman;;Turkey;6;36-42N;028-47E;;;7;2; +LTBT;17;184;Akhisar;;Turkey;6;38-55N;027-51E;;;93;93;P +LTBU;--;---;Corlu;;Turkey;6;41-08N;027-55E;;;173;; +LTBV;17;290;Bodrum;;Turkey;6;37-02N;027-25E;;;27;27;P +LTCA;17;202;Elazig;;Turkey;6;38-36N;039-17E;;;902;882;P +LTCC;17;280;Diyarbakir;;Turkey;6;37-53N;040-11E;37-53N;040-11E;686;677;P +LTCD;17;092;Erzincan;;Turkey;6;39-44N;039-30E;;;1156;1215;P +LTCE;17;096;Erzurum;;Turkey;6;39-55N;041-16E;;;1756;1758;P +LTCF;17;098;Kars;;Turkey;6;40-36N;043-05E;;;1775;1775;P +LTCG;17;038;Trabzon;;Turkey;6;41-00N;039-43E;;;35;30;P +LTCH;17;270;Urfa;;Turkey;6;37-08N;038-46E;;;547;547;P +LTCI;17;170;Van;;Turkey;6;38-27N;043-19E;;;1667;1661;P +LTCJ;17;282;Batman;;Turkey;6;37-52N;041-10E;;;540;540; +LTCK;--;---;Mus Tur-Afb ;;Turkey;6;38-45N;041-40E;;;1266;; +LTFA;--;---;Izmir \ Kaklic;;Turkey;6;38-31N;026-59E;;;4;; +LTFC;--;---;Suleyman Demirel;;Turkey;6;37-51N;030-22E;;;864;; +LTFE;--;---;Bodrum Milas Airport;;Turkey;6;37-14-53N;027-40-55E;;;6;; +LTFH;--;---;Samsun / Carsamba;;Turkey;6;41-15-15N;036-34-03E;;;5;; +LTFJ;--;---;Istanbul / Sabiha Gokcen;;Turkey;6;40-53-55N;029-18-33E;;;95;; +LUBL;--;---;Baltsi-Leadoveni - The North of Moldova;;Moldova;6;47-50-03N;027-46-09E;;;231 +LUCH;--;---;Kaxul - The South of Moldova;;Moldova;6;45-50-38N;028-15-55E;;;199;; +LUKK;--;---;Chisinau International Airport;;Moldova;6;46-55-40N;028-55-51E;;;122;; +LWOH;13;578;Ohrid;;Macedonia, The Republic of;6;41-07N;020-48E;;;760;761; +LWSK;13;586;Skopje-Petrovec;;Macedonia, The Republic of;6;41-58N;021-39E;41-57N;021-38E;238;239;P +LXGB;08;495;Gibraltar;;Gibraltar;6;36-09N;005-21W;36-15N;005-33W;5;0; +LYBE;13;272;Beograd / Surcin;;Serbia and Montenegro;6;44-49N;020-17E;;;96;99;P +LYNI;13;388;Nis;;Serbia and Montenegro;6;43-20N;021-54E;43-20N;021-54E;202;202;P +LYPG;--;---;Podgorica Titograd ;;Serbia and Montenegro;6;42-26N;019-17E;;;53;; +LYPR;13;481;Pristina;;Serbia and Montenegro;6;42-39N;021-09E;;;573;576;P +LYPZ;14;105;Portoroz / Secovlje;;Slovenia;6;45-29N;013-37E;;;2;3; +LYTI;13;462;Podgorica / Golubovci;;Serbia and Montenegro;6;42-22N;019-15E;42-22N;019-15E;33;33;P +LYTV;13;457;Tivat;;Serbia and Montenegro;6;42-24N;018-44E;;;5;5;P +LYVR;13;183;Vrsac;;Serbia and Montenegro;6;45-09N;021-19E;;;83;85;P +LZIB;11;816;Bratislava Ivanka;;Slovakia;6;48-12N;017-12E;48-10N;017-12E;133;142;P +LZKC;11;993;Kamenica Nad Cirochou;;Slovakia;6;48-56N;022-00E;;;177;; +LZKZ;--;---;Kosice, Barca;;Slovakia;6;48-39-47N;021-14-28E;;;232;; +LZLU;11;927;Lucenec;;Slovakia;6;48-20N;019-44E;;;214;; +LZNI;--;---;Nitra;;Slovakia;6;48-16-46N;018-07-58E;;;134;; +LZPE;--;---;Prievidza;;Slovakia;6;48-45-59N;018-35-18E;;;260;; +LZPP;--;---;Piestany;;Slovakia;6;48-37-30N;017-49-43E;;;163;; +LZSL;--;---;Sliac;;Slovakia;6;48-38-17N;019-08-03E;;;318;; +LZTT;11;934;Poprad / Tatry;;Slovakia;6;49-04N;020-15E;49-04N;020-15E;694;695;P +LZZI;--;---;Dolny Hricov;;Slovakia;6;49-14N;018-36-49E;;;312;; +MBPV;--;---;Providenciales;;Turks and Caicos Islands;4;21-46-25N;072-15-57W;;;5;; +MDBH;78;482;Barahona;;Dominican Republic;4;18-12N;071-06W;;;3;;P +MDHE;78;484;Herrera;;Dominican Republic;4;18-28N;069-58W;;;58;; +MDLR;--;---;La Romana International Airport;;Dominican Republic;4;18-25N;068-57W;;;8;; +MDPC;78;479;Punta Cana;;Dominican Republic;4;18-34N;068-22W;;;12;;P +MDPP;78;457;Puerto Plata International;;Dominican Republic;4;19-45N;070-33W;;;15;; +MDSD;78;485;Las Americas;;Dominican Republic;4;18-26N;069-40W;;;18;;P +MDSI;--;---;San Isidro Air Force Base;;Dominican Republic;4;18-30N;069-46W;;;111;; +MDST;78;460;Santiago;;Dominican Republic;4;19-27N;070-42W;;;183;;P +MGCB;78;631;Coban;;Guatemala;4;15-28N;090-19W;;;1316;; +MGFL;78;615;Flores;;Guatemala;4;16-55N;089-53W;;;115;115; +MGGT;78;641;Guatemala Aeropuertola Aurora ;;Guatemala;4;14-35N;090-31W;14-35N;090-31W;1489;1489; +MGHT;78;627;Huehuetenango;;Guatemala;4;15-19N;091-28W;;;1901;1901; +MGPB;78;637;Puerto Barrios;;Guatemala;4;15-43N;088-36W;15-43N;088-36W;1;1; +MGQZ;--;---;Quezaltenango;;Guatemala;4;14-50N;091-31W;;;2500;; +MGRT;78;639;Retalhuleu;;Guatemala;4;14-32N;091-40W;;;239;; +MGSJ;78;647;San Jose;;Guatemala;4;13-55N;090-49W;13-55N;090-49W;2;2; +MGTK;--;---;Tikal;;Guatemala;4;16-54N;089-51W;;;128;; +MGZA;--;---;Zacapa;;Guatemala;4;14-58N;089-32W;;;490;; +MHAM;78;700;Amapala;;Honduras;4;13-16N;087-39W;;;5;; +MHCA;78;714;Catacamas;;Honduras;4;14-54N;085-56W;;;442;442;P +MHCH;78;724;Choluteca;;Honduras;4;13-18N;087-11W;13-18N;087-11W;48;48;P +MHIC;78;501;Islas Del Cisne;;Honduras;4;17-24N;083-56W;17-24N;083-56W;9;11;P +MHLC;78;705;La Ceiba Airport ;;Honduras;4;15-44N;086-52W;;;3;26;P +MHLE;78;719;La Esperanza;;Honduras;4;14-19N;088-09W;;;1100;1674; +MHLM;78;708;La Mesa San Pedro Sula ;;Honduras;4;15-27N;087-56W;;;31;31;P +MHNJ;78;701;Guanaja;;Honduras;4;16-28N;085-55W;16-28N;085-55W;2;2;P +MHNO;78;701;Guanaja;;Honduras;4;16-28N;086-04W;;;2;; +MHPL;78;711;Puerto Lempira;;Honduras;4;15-13N;083-48W;;;13;13;P +MHRO;78;703;Roatan;;Honduras;4;16-19N;086-31W;;;5;2;P +MHSC;78;718;Coronel Enrique Soto Cano Air Base;;Honduras;4;14-23N;087-37W;14-23N;087-37W;628;628; +MHSR;78;717;Santa Rosa De Copan;;Honduras;4;14-47N;088-47W;;;1079;1079;P +MHTE;78;706;Tela;;Honduras;4;15-43N;087-29W;;;3;3;P +MHTG;78;720;Tegucigalpa;;Honduras;4;14-03N;087-13W;14-02N;087-15W;994;1007;P +MHYR;78;707;Yoro;;Honduras;4;15-10N;087-07W;;;670;670; +MKJP;78;397;Kingston / Norman Manley;;Jamaica;4;17-56N;076-47W;17-56N;076-47W;3;14;P +MKJS;78;388;Montego Bay / Sangster;;Jamaica;4;18-30N;077-55W;;;1;8;P +MMAA;--;---;Acapulco / G. Alvarez;;Mexico;4;16-46N;099-45W;;;5;; +MMAN;76;394;Aerop. Internacional Monterrey, N. L.;;Mexico;4;25-52N;100-14W;25-52N;100-12W;448;450; +MMAS;76;571;Aguascalientes, Ags.;;Mexico;4;21-53N;102-18W;;;1874;; +MMBT;--;---;Bahias De Huatulco ;;Mexico;4;15-47N;096-16W;;;143;; +MMCB;76;726;Cuernavaca, Mor.;;Mexico;4;18-53N;099-14W;;;1618;; +MMCE;--;---;Ciudad Del Carmen ;;Mexico;4;18-39N;091-48W;;;2;; +MMCL;76;412;Culiacan, Sin.;;Mexico;4;24-49N;107-24W;;;39;; +MMCM;76;750;Chetumal, Q. Roo;;Mexico;4;18-29N;088-18W;;;9;; +MMCN;76;253;Santa Rosalia, B. C. S.;;Mexico;4;27-19N;112-18W;;;75;; +MMCP;76;695;Campeche, Camp.;;Mexico;4;19-51N;090-33W;;;5;; +MMCS;--;---;Ciudad Juarez International ;;Mexico;4;31-38N;106-26W;;;1171;; +MMCT;--;---;Chichen-Itza;;Mexico;4;20-38-30N;088-26-58W;;;31;; +MMCU;--;---;Chihuahua International Airport;;Mexico;4;28-42N;105-58W;;;1360;; +MMCV;--;---;Ciudad Victoria Airport;;Mexico;4;23-43N;098-58W;;;238;; +MMCZ;--;---;Cozumel Civ / Mil ;;Mexico;4;20-32N;086-56W;;;5;; +MMDO;--;---;Durango Airport;;Mexico;4;24-08N;104-32W;;;1857;; +MMEP;76;556;Tepic, Nay.;;Mexico;4;21-31N;104-54W;;;922;; +MMGL;--;---;Don Miguel / Guadalaj;;Mexico;4;20-31N;103-19W;;;1528;; +MMGM;--;---;Guaymas International Airport;;Mexico;4;27-58N;110-56W;;;27;; +MMHO;76;160;Hermosillo, Son.;;Mexico;4;29-04N;110-57W;;;211;; +MMIA;76;658;Colima ;;Mexico;4;19-16N;103-35W;;;723;; +MMIO;76;390;Saltillo, Coah.;;Mexico;4;25-27N;100-59W;;;1790;; +MMIT;--;---;Ixtepec Ox;;Mexico;4;16-27N;095-05W;;;61;; +MMLC;--;---;Lazaro Cardenas;;Mexico;4;17-59N;102-13W;;;12;; +MMLM;--;---;Los Mochis Airport;;Mexico;4;25-41N;109-05W;;;4;; +MMLO;--;---;Del Bajio / Leon;;Mexico;4;21-00N;101-29W;;;1819;; +MMLP;--;---;La Paz International Airport;;Mexico;4;24-04N;110-22W;;;21;; +MMLT;76;305;Loreto, B. C. S.;;Mexico;4;26-01N;111-21W;;;15;; +MMMA;--;---;Matamoros International ;;Mexico;4;25-46N;097-32W;;;8;; +MMMD;76;644;Merida / lic Manuel Crecencio;;Mexico;4;20-56N;089-39W;20-57N;089-40W;10;11; +MMML;--;---;Mexicali International Airport ;;Mexico;4;32-38N;117-00W;;;22;; +MMMM;--;---;Morelia New;;Mexico;4;19-51N;101-02W;;;1833;; +MMMT;--;---;Minatitlan;;Mexico;4;18-06N;094-35W;;;40;; +MMMV;76;342;Monclova, Coah.;;Mexico;4;26-53N;101-25W;26-54N;101-25W;615;586; +MMMX;--;---;Mexico City / Licenci;;Mexico;4;19-26N;099-06W;;;2238;; +MMMY;--;---;Monterrey / Gen Maria;;Mexico;4;25-47N;100-06W;;;387;; +MMMZ;--;---;Mazatlan / G. Buelna;;Mexico;4;23-10N;106-16W;;;10;; +MMNL;--;---;Nuevo Laredo International ;;Mexico;4;27-26N;099-34W;;;148;; +MMOX;--;---;Oaxaca / Xoxocotlan;;Mexico;4;16-58N;096-44W;;;1528;; +MMPA;--;---;Poza Rica / Palizada;;Mexico;4;20-31N;097-28W;;;15;; +MMPB;76;685;Puebla, Pue.;;Mexico;4;19-03N;098-10W;;;2179;; +MMPG;76;243;Piedras Negras, Coah.;;Mexico;4;28-42N;100-31W;;;250;; +MMPN;--;---;Uruapan / Gen Rayon;;Mexico;4;19-24N;102-02W;;;1593;; +MMPR;--;---;Puerto Vallarta / Lic;;Mexico;4;20-41N;105-15W;;;6;; +MMPS;--;---;Puerto Escondido ;;Mexico;4;15-52N;097-05W;;;88;; +MMQT;76;625;Queretaro, Qro.;;Mexico;4;20-36N;100-23W;;;1813;; +MMRX;--;---;Reynosa International Airport ;;Mexico;4;26-01N;098-14W;;;39;; +MMSD;--;---;San Jose Del Cabo ;;Mexico;4;23-09N;109-42W;;;109;; +MMSP;76;539;San Luis Potosi, S. L. P.;;Mexico;4;22-09N;100-59W;;;1870;; +MMTC;76;382;Torreon, Coah.;;Mexico;4;25-32N;103-27W;25-32N;103-27W;1124;1150; +MMTG;76;843;Tuxtla Gutierrez, Chis.;;Mexico;4;16-45N;093-07W;;;528;; +MMTJ;--;---;Tijuana International Airport ;;Mexico;4;32-33N;116-58W;;;152;; +MMTL;76;634;Tulancingo ;;Mexico;4;20-05N;098-22W;;;2181;; +MMTM;--;---;Tampico / Gen Fj Mina;;Mexico;4;22-17N;097-52W;;;24;; +MMTO;--;---;Toluca / Jose Maria ;;Mexico;4;19-21N;099-34W;;;2576;; +MMTP;--;---;Tapachula ;;Mexico;4;14-47N;092-23W;;;29;; +MMUN;--;---;Cancun International Airport;;Mexico;4;21-02N;086-52W;;;5;; +MMVA;--;---;Villahermosa ;;Mexico;4;18-00N;092-49W;;;13;; +MMVR;--;---;Veracruz / Las Bajadas / General Heriberto Jara;;Mexico;4;19-09N;096-11W;;;32;; +MMZC;--;---;Zacatecas Airport;;Mexico;4;22-54N;102-41W;;;2140;; +MMZH;--;---;Ixtapa-Zihuatanejo;;Mexico;4;17-36N;101-28W;;;6;; +MMZO;--;---;Manzanillo International ;;Mexico;4;19-09N;104-34W;;;8;; +MMZP;--;---;Zapopan Military ;;Mexico;4;20-45N;103-28W;;;1625;; +MNBL;78;745;Bluefields;;Nicaragua;4;12-00N;086-46W;;;5;5;P +MNCH;78;739;Chinandega;;Nicaragua;4;12-38N;087-08W;;;53;60;P +MNJG;78;734;Jinotega;;Nicaragua;4;13-05N;085-59W;;;985;1032;P +MNJU;78;735;Juigalpa;;Nicaragua;4;12-06N;085-22W;;;90;90;P +MNMG;78;741;Managua A. C. Sandino;;Nicaragua;4;12-09N;086-10W;12-07N;086-11W;50;56;P +MNPC;78;730;Puerto Cabezas;;Nicaragua;4;14-03N;083-22W;14-02N;083-24W;20;20;P +MNRS;78;733;Rivas;;Nicaragua;4;11-25N;085-50W;;;53;70;P +MPBO;--;---;Bocas Del Toro International;;Panama;4;09-21N;082-15W;;;3;; +MPCH;--;---;Changuinola / Captain Manuel Nino;;Panama;4;09-28N;082-31W;;;6;; +MPDA;78;793;David;;Panama;4;08-24N;082-25W;;;29;26;P +MPFS;78;801;Ft Sherman Rocob ;;Panama;4;09-20N;079-59W;09-20N;079-59W;52;52; +MPHO;78;806;Howard Air Force Base;;Panama;4;08-55N;079-36W;08-55N;079-36W;16;13;P +MPLB;--;---;Albrook Afs / Balboa ;;Panama;4;08-58N;079-33W;;;9;; +MPMG;--;---;Marcos A. Gelabert;;Panama;4;08-59N;079-31W;;;13;; +MPNU;--;---;Augusto Vergara;;Panama;4;07-50N;080-17W;;;21;; +MPSA;78;795;Santiago;;Panama;4;08-05N;080-57W;;;83;88;P +MPTO;78;792;Tocumen;;Panama;4;09-03N;079-22W;;;45;;P +MRCH;--;---;Chacarita;;Costa Rica;4;09-59N;084-47W;;;2;; +MRLB;78;774;Liberia;;Costa Rica;4;10-37N;085-26W;;;80;80; +MRLM;78;767;Puerto Limon;;Costa Rica;4;10-00N;083-03W;;;5;3;P +MRNC;78;755;Nicoya;;Costa Rica;4;10-09N;085-27W;;;120;; +MROC;78;762;Juan Santamaria;;Costa Rica;4;10-00N;084-13W;09-59N;084-13W;920;939;P +MRPM;78;772;Palmar Sur;;Costa Rica;4;08-57N;083-28W;;;15;16; +MRPV;--;---;Tobias Bolanos International;;Costa Rica;4;09-57N;084-09W;;;994;; +MSAC;78;650;Acajutla;;El Salvador;4;13-34N;089-50W;13-34N;089-50W;15;15;P +MSLP;78;666;El Salvador Intl. Airport / Comalapa;;El Salvador;4;13-26N;089-03W;;;25;25; +MSSA;78;655;Santa Ana / El Palmar;;El Salvador;4;13-59N;089-34W;;;725;; +MSSM;78;670;San Miguel / El Papalon;;El Salvador;4;13-27N;088-07W;;;80;; +MSSS;78;663;San Salvador / Ilopango;;El Salvador;4;13-42N;089-07W;13-42N;089-07W;616;621;P +MTCH;78;409;Cap-Haitien;;Haiti;4;19-45N;072-11W;;;2;3; +MTPP;78;439;Port-Au-Prince / Aeroport International;;Haiti;4;18-34N;072-18W;18-33N;072-21W;31;34; +MUBA;78;268;Baracoa, Oriente;;Cuba;4;20-21N;074-30W;;;9;9; +MUBY;--;---;Bayamo ;;Cuba;4;20-24N;076-37W;;;64;; +MUCA;78;346;Venezuela, Ciego De Avila;;Cuba;4;21-47N;078-47W;;;26;26; +MUCC;--;---;Cayo Coco / Jardines Del Ray;;Cuba;4;22-27-40N;078-19-42W;;;4;; +MUCF;78;244;Cienfuegos, Las Villas;;Cuba;4;22-09N;080-24W;;;39;39; +MUCL;--;---;Cayo Largo Del Sur;;Cuba;4;21-37N;081-33W;;;2;; +MUCM;78;255;Camaguey Aeropuerto;;Cuba;4;21-25N;077-51W;21-25N;077-51W;122;118; +MUCU;78;264;Santiago De Cuba, Oriente;;Cuba;4;19-58N;075-51W;;;69;55; +MUGM;78;367;Guantanamo, Oriente;;Cuba;4;19-54N;075-08W;19-54N;075-08W;23;23; +MUGT;78;267;Guantanamo, Oriente;;Cuba;4;20-05N;075-09W;;;8;8; +MUHA;78;224;Aeropuerto Jose Marti, Rancho-Boyeros, Habana;;Cuba;4;22-59N;082-24W;;;59;75; +MUHG;--;---;Holguin Civ / Mil ;;Cuba;4;20-47N;076-19W;;;106;; +MUMO;--;---;Moa Military ;;Cuba;4;20-39N;074-55W;;;5;; +MUMZ;78;256;Manzanillo, Oriente;;Cuba;4;20-20N;077-07W;;;60;60; +MUNG;78;221;Nueva Gerona, Isla De Pinos;;Cuba;4;21-50N;082-47W;;;23;23; +MUPR;78;315;Pinar Del Rio, Pinar Del Rio;;Cuba;4;22-25N;083-41W;;;37;37; +MUVR;78;229;Varadero, Matanzas;;Cuba;4;23-08N;081-17W;;;3;3; +MUVT;78;357;Las Tunas, Las Tunas;;Cuba;4;20-57N;076-57W;;;106;106; +MWCB;--;---;Gerrard Smith Intl. / Cayman Brac;;Cayman Islands;4;19-41-13N;079-52-58;;;2;; +MWCR;78;384;Owen Roberts Airportgrand Cayman;;Cayman Islands;4;19-17N;081-21W;19-18N;081-22W;3;3; +MYBS;78;070;Alice Town, Bimini;;Bahamas, The;4;25-44N;079-18W;;;2;3;P +MYEG;78;092;Georgetown, Exuma;;Bahamas, The;4;23-28-30N;075-46-00W;;;2;3;P +MYGF;78;062;Freeport, Grand Bahama;;Bahamas, The;4;26-33N;078-42W;;;2;11;P +MYGW;78;061;West End, Grand Bahama;;Bahamas, The;4;26-42N;078-58W;;;2;4;P +MYIG;78;121;Matthew Town, Inagua;;Bahamas, The;4;20-57N;073-41W;;;2;4;P +MYNN;78;073;Nassau Airport;;Bahamas, The;4;25-03N;077-28W;25-03N;077-28W;3;7;P +MYSM;78;088;Cockburn Town, San Salvador;;Bahamas, The;4;24-03N;074-32W;;;3;5;P +MZBZ;78;583;Belize / Phillip Goldston Intl. Airport;;Belize;4;17-32N;088-18W;17-32N;088-18W;5;5;P +NCRG;91;843;Rarotonga;;Cook Islands;5;21-12S;159-49W;21-12S;159-49W;7;7;P +NEXC;--;---;Charleston, Navelexcen;SC;United States;4;32-54-56N;079-58-45W;32-54-56N;079-58-45W;8;11; +NFFN;91;680;Nandi;;Fiji;5;17-45S;177-27E;17-45S;177-27E;13;18;P +NFNA;91;683;Nausori;;Fiji;5;18-03S;178-34E;;;5;7;P +NFNK;91;691;Lakemba;;Fiji;5;18-14S;178-48W;;;2;3; +NFNR;91;650;Rotuma;;Fiji;5;12-30S;177-03E;12-30S;177-03E;26;26;P +NFTF;91;792;Fua'Amotu;;Tonga;5;21-14S;175-09W;21-14S;175-09W;38;41; +NFTL;91;784;Haapai;;Tonga;5;19-48S;174-21W;;;2;3; +NGBR;91;623;Beru;;Kiribati;5;01-21S;176-00E;;;2;3; +NGFO;91;631;Nanumea;;Tuvalu;5;05-40S;176-08E;;;2;3; +NGFU;91;643;Funafuti;;Tuvalu;5;08-31S;179-13E;08-31S;179-13E;1;2;P +NGTA;91;610;Tarawa;;Kiribati;5;01-21N;172-55E;01-21N;172-55E;2;4;P +NGTR;91;629;Arorae;;Kiribati;5;02-40S;176-50E;;;4;7; +NGTU;91;601;Butaritari;;Kiribati;5;03-02N;172-47E;;;1;; +NIUE;91;822;Alofi / Niue;;Cook Islands;5;19-04S;169-55W;;;20;22;P +NLWF;91;754;Maopoopo Ile Futuna ;;France;5;14-19S;178-07W;;;6;36;P +NLWW;91;753;Hihifo Ile Wallis ;;France;5;13-14S;176-10W;13-14S;176-10W;23;27;P +NSAP;91;762;Apia / Upolu Island;;Samoa;5;13-48S;171-47W;13-48S;171-47W;2;2; +NSFA;91;759;Faleolo Intl / Apia;;Samoa;5;13-49S;172-00W;;;5;; +NSTU;91;765;Pago Pago / Int. Airport;;United States Minor Outlying Islands;5;14-20S;170-43W;14-20S;170-43W;3;3;P +NTAA;91;938;Tahiti-Faaa;;French Polynesia;5;17-33S;149-37W;17-33S;149-37W;2;2;P +NTAT;91;954;Tubuai;;French Polynesia;5;23-21S;149-29W;23-21S;149-29W;2;3;P +NTTB;91;930;Bora-Bora;;French Polynesia;5;16-27S;151-45W;16-29S;151-45W;4;3;P +NTTG;91;941;Rangiroa / Tuamoto Island;;French Polynesia;5;14-58S;147-40W;14-58S;147-40W;3;3; +NTTO;91;944;Hao;;French Polynesia;5;18-04S;140-57W;18-04S;140-57W;2;7;P +NTTX;91;952;Mururoa;;French Polynesia;5;21-49S;138-48W;21-49S;138-49W;2;3;P +NVSC;91;551;Sola Vanua Lava ;;Vanuatu;5;13-51S;167-33E;13-51S;167-33E;17;18;P +NVSL;91;555;Lamap Malekula ;;Vanuatu;5;16-25S;167-48E;;;26;26;P +NVSS;91;554;Pekoa Airport Santo ;;Vanuatu;5;15-31S;167-13E;15-31S;167-13E;41;44;P +NVVV;91;557;Bauerfield Efate ;;Vanuatu;5;17-42S;168-18E;17-42S;168-18E;20;21;P +NWWE;91;596;Moue Ile Des Pins ;;New Caledonia;5;22-36S;167-27E;;;96;97; +NWWK;91;577;Koumac Nlle-Caledonie ;;New Caledonia;5;20-34S;164-17E;20-34S;164-17E;23;18;P +NWWL;91;582;Ouanaham Ile Lifou ;;New Caledonia;5;20-46S;167-14E;20-46S;167-14E;28;29;P +NWWN;91;592;Noumea Nlle-Caledonie ;;New Caledonia;5;22-16S;166-27E;22-16S;166-27E;69;72;P +NWWR;91;587;La Roche Ile Mare ;;New Caledonia;5;21-29S;168-02E;;;43;42; +NWWV;91;579;Ouloup Ile Ouvea ;;New Caledonia;5;20-39S;166-35E;;;7;7; +NWWW;91;590;La Tontouta Nlle-Caledonie ;;New Caledonia;5;22-01S;166-13E;22-01S;166-13E;16;14;P +NZAA;93;119;Auckland Airport;;New Zealand;5;37-01S;174-48E;37-01S;174-48E;7;6;P +NZCH;93;780;Christchurch;;New Zealand;5;43-29S;172-33E;43-29S;172-33E;38;30;P +NZCI;93;986;Chatham Island;;New Zealand;5;43-57S;176-34W;43-57S;176-34W;44;48;P +NZCM;89;674;Williams Field;;Antarctica;7;77-52S;166-58E;;;8;8; +NZDN;93;890;Dunedin Aerodrome;;New Zealand;5;45-56S;170-12E;45-56S;170-12E;1;2; +NZGS;93;291;Gisborne Aerodrome;;New Zealand;5;38-40S;177-59E;38-40S;177-59E;5;8; +NZHK;93;614;Hokitika Aerodrome;;New Zealand;5;42-43S;170-59E;42-43S;170-59E;45;44; +NZIR;--;---;Ice Runway;;Antarctica;7;77-52S;166-32E;;;2;; +NZKI;93;677;Kaikoura ;;New Zealand;5;42-25S;173-42E;42-25S;173-42E;101;99; +NZNP;93;308;New Plymouth Aerodrome;;New Zealand;5;39-01S;174-11E;39-01S;174-11E;28;36;P +NZNV;93;844;Invercargill Aerodrome;;New Zealand;5;46-42S;168-33E;46-25S;168-20E;0;4;P +NZOH;93;401;Ohakea;;New Zealand;5;40-12S;175-22E;40-12S;175-23E;50;52; +NZPP;93;417;Paraparaumu Aerodrome;;New Zealand;5;40-54S;174-59E;40-54S;174-59E;7;12;P +NZRN;93;997;Raoul Island, Kermadec Island;;New Zealand;5;29-15S;177-55W;29-15S;177-55W;38;49;P +NZRO;93;246;Rotorua Aerodrome;;New Zealand;5;38-07S;176-19E;38-07S;176-19E;285;294; +NZSP;89;009;Amundsen-Scott South Pole Station;;Antarctica;7;90-00S;00-00;90-00S;000-00;2830;2835;P +NZTG;93;186;Tauranga Aerodrome Aws;;New Zealand;5;37-40S;176-12E;;;4;5; +NZWD;--;---;Williams Field, Antarctic;;New Zealand;5;77-53S;166-39E;;;12;; +NZWN;93;436;Wellington Airport;;New Zealand;5;41-20S;174-48E;;;12;8; +NZWP;93;112;Whenuapai;;New Zealand;5;36-47S;174-38E;36-47S;174-38E;30;27; +OAFR;40;974;Farah;;Afghanistan;2;32-22N;062-11E;;;700;700; +OAFZ;40;904;Faizabad;;Afghanistan;2;37-07N;070-31E;;;1200;1200; +OAHR;40;938;Herat;;Afghanistan;2;34-13N;062-13E;34-13N;062-13E;964;964; +OAJL;40;954;Jalalabad;;Afghanistan;2;34-26N;070-28E;;;580;580; +OAJS;40;932;Jabul-Saraj;;Afghanistan;2;35-08N;069-15E;;;1630;1630; +OAKB;40;948;Kabul Airport;;Afghanistan;2;34-38N;069-12E;;;1789;; +OAMS;40;911;Mazar-I-Sharif;;Afghanistan;2;36-42N;067-12E;;;378;378; +OASD;40;957;Shindand;;Afghanistan;2;33-24N;062-17E;;;1150;1150; +OASG;40;908;Shebirghan;;Afghanistan;2;36-40N;065-43E;;;360;360; +OAZB;40;920;Zebak;;Afghanistan;2;36-30N;071-15E;;;2600;2600; +OAZG;40;986;Zaranj;;Afghanistan;2;31-00N;061-51E;;;478;478; +OBBI;41;150;Bahrain International Airport ;;Bahrain;2;26-16N;050-39E;;;2;2; +OEAB;41;112;Abha;;Saudi Arabia;2;18-14N;042-39E;;;2090;2093;P +OEAH;40;420;Al Ahsa;;Saudi Arabia;2;25-18N;049-29E;;;179;178;P +OEBA;41;055;Al Baha;;Saudi Arabia;2;20-18N;041-38E;;;1652;1662;P +OEBH;41;084;Bisha;;Saudi Arabia;2;19-59N;042-37E;;;1167;1163;P +OEDF;40;415;Dammam-King Fahd International Airport;;Saudi Arabia;2;26-28N;049-47E;;;22;; +OEDR;40;416;Dhahran;;Saudi Arabia;2;26-16N;050-09E;26-16N;050-10E;26;17;P +OEDW;40;435;Dawadmi;;Saudi Arabia;2;24-30N;044-21E;;;990;991;P +OEGN;41;140;Gizan;;Saudi Arabia;2;16-54N;042-35E;16-52N;042-35E;6;7;P +OEGS;40;405;Gassim;;Saudi Arabia;2;26-18N;043-46E;;;648;650;P +OEGT;40;360;Guriat;;Saudi Arabia;2;31-24N;037-16E;;;509;504;P +OEHL;40;394;Hail;;Saudi Arabia;2;27-26N;041-41E;27-31N;041-44E;1015;1013;P +OEJB;--;---;Jubail Naval ;;Saudi Arabia;2;27-03N;049-24E;;;8;; +OEJD;41;026;Jeddah ;;Saudi Arabia;2;21-30N;039-12E;;;15;; +OEJN;41;024;Jeddah King Abdul Aziz International Airport ;;Saudi Arabia;2;21-42N;039-11E;21-40N;039-09E;15;17;P +OEKK;40;377;Hafr Al-Batin;;Saudi Arabia;2;27-54N;045-32E;;;413;414; +OEKM;41;114;Khamis Mushait;;Saudi Arabia;2;18-18N;042-48E;18-18N;042-48E;2066;2056;P +OEMA;40;430;Madinah;;Saudi Arabia;2;24-33N;039-42E;24-33N;039-43E;654;636;P +OEMK;41;030;Makkah;;Saudi Arabia;2;21-26N;039-46E;;;310;240;P +OENG;41;128;Najran;;Saudi Arabia;2;17-37N;044-25E;;;1212;1210;P +OEPA;40;373;Al Qaysumah;;Saudi Arabia;2;28-19N;046-07E;28-20N;046-07E;358;360;P +OERF;40;362;Rafha;;Saudi Arabia;2;29-37N;043-29E;;;449;444;P +OERK;40;437;King Khaled International Airport;;Saudi Arabia;2;24-56N;046-43E;24-56N;046-43E;614;612;P +OERR;40;357;Arar;;Saudi Arabia;2;30-54N;041-08E;;;555;549;P +OERY;40;438;Riyadh;;Saudi Arabia;2;24-43N;046-44E;24-42N;046-44E;635;620;P +OESH;41;136;Sharurah;;Saudi Arabia;2;17-28N;047-07E;;;720;725;P +OESK;40;361;Al-Jouf;;Saudi Arabia;2;29-47N;040-06E;;;689;689;P +OETB;40;375;Tabuk;;Saudi Arabia;2;28-22N;036-36E;28-22N;036-35E;778;768;P +OETF;41;036;Taif;;Saudi Arabia;2;21-29N;040-33E;;;1478;1454;P +OETR;40;356;Turaif;;Saudi Arabia;2;31-41N;038-44E;;;813;852;P +OEWD;41;061;Wadi Al Dawasser Airport;;Saudi Arabia;2;20-30N;045-12E;;;624;622;P +OEWJ;40;400;Wejh;;Saudi Arabia;2;26-12N;036-28E;26-14N;036-26E;20;21;P +OEYN;40;439;Yenbo;;Saudi Arabia;2;24-09N;038-04E;;;8;10;P +OIAA;40;831;Abadan;;Iran;2;30-22N;048-15E;;;3;11;P +OIAG;40;833;Omidieh;;Iran;2;30-46N;049-40E;;;29;27;P +OIAH;40;835;Gach Saran Du Gunbadan;;Iran;2;30-26N;050-46E;;;738;699;P +OIAI;40;812;Masjed-Soleyman;;Iran;2;31-59N;049-16E;;;372;372;P +OIAJ;--;---;Omidiyeh;;Iran;2;30-50-07N;049-32-06E;;;26;; +OIAM;--;---;Bandar Mahshahr / Mahshahr;;Iran;2;30-33-23N;049-09-07E;;;2;; +OIAW;40;811;Ahwaz;;Iran;2;31-20N;048-40E;;;20;22;P +OIBA;--;---;Abumusa Island / Abumusa;;Iran;2;25-52-33N;055-02-01E;;;7;; +OIBB;40;858;Bushehr Civ / Afb ;;Iran;2;28-59N;050-50E;;;19;; +OIBK;--;---;Kish Island / Kish;;Iran;2;26-31-36N;053-58-54E;;;30;; +OIBL;40;883;Bandar Lengeh;;Iran;2;26-35N;054-50E;;;14;14;P +OIBS;--;---;Sirri Island / Sirri;;Iran;2;25-54-34N;054-32-22;;;13;; +OICC;40;766;Kermanshah;;Iran;2;34-16N;047-07E;34-21N;047-09E;1320;1322;P +OICG;40;765;Ghasre-Shirin;;Iran;2;34-31N;045-35E;;;378;; +OICI;--;---;Ilam;;Iran;2;33-35-09N;046-24-20E;;;1334;; +OICK;--;---;Khorram Abad;;Iran;2;33-26-11N;048-17-09E;;;1155;; +OICS;40;747;Sanandaj;;Iran;2;35-20N;047-00E;;;1373;1373;P +OIFK;40;785;Kashan;;Iran;2;33-59N;051-27E;;;982;982;P +OIFM;40;800;Esfahan;;Iran;2;32-28N;051-43E;32-37N;051-40E;1590;1550;P +OIFS;40;798;Shahre-Kord;;Iran;2;32-20N;050-51E;;;2078;1991;P +OIGG;40;719;Rasht;;Iran;2;37-12N;049-38E;;;-7;37;P +OIHH;--;---;Hamadan;;Iran;2;34-52-05N;048-33-08E;;;1757;; +OIHR;40;769;Arak;;Iran;2;34-06N;049-24E;;;1720;1720;P +OIII;40;754;Tehran-Mehrabad;;Iran;2;35-41N;051-21E;35-41N;051-19E;1204;1191;P +OIIK;40;731;Ghazvin;;Iran;2;36-15N;050-00E;;;1278;1278;P +OIIP;--;---;Karaj / Payam;;Iran;2;35-46-34N;050-49-36E;;;1271;; +OIIS;40;757;Semnan;;Iran;2;35-33N;053-23E;;;1171;1171;P +OIKB;40;875;Bandarabbass;;Iran;2;27-13N;056-22E;27-13N;056-22E;10;10;P +OIKK;40;841;Kerman;;Iran;2;30-15N;056-58E;30-15N;056-58E;1748;1754;P +OIKM;40;854;Bam;;Iran;2;29-06N;058-24E;;;1067;1067;P +OIKQ;--;---;Gheshm Island / Dayrestan;;Iran;2;26-45-18N;055-54-08E;;;12;; +OIMB;40;809;Birjand;;Iran;2;32-52N;059-12E;32-52N;059-12E;1491;1491;P +OIMC;--;---;Sarakhs;;Iran;2;36-30-04N;061-03-54E;;;288;; +OIMH;40;762;Torbat-Heydarieh;;Iran;2;35-16N;059-13E;;;1333;1333;P +OIMM;40;745;Mashhad;;Iran;2;36-16N;059-38E;36-16N;059-38E;989;980;P +OIMN;40;723;Bojnourd;;Iran;2;37-28N;057-20E;;;1074;1074; +OIMS;40;743;Sabzevar;;Iran;2;36-13N;057-40E;;;941;941;P +OIMT;40;791;Tabas;;Iran;2;33-36N;056-55E;;;710;711; +OING;40;738;Gorgan;;Iran;2;36-49N;054-28E;36-51N;054-28E;155;155;P +OINN;--;---;Noshahr;;Iran;2;36-39-48N;051-27-53;;;0;; +OINR;40;732;Ramsar;;Iran;2;36-54N;050-40E;;;-23;-20;P +OISA;40;818;Abadeh;;Iran;2;31-11N;052-40E;;;2004;2004; +OISF;40;859;Fasa;;Iran;2;28-58N;053-41E;;;1383;1383;P +OISL;--;---;Lar;;Iran;2;27-40-26N;054-22-53E;;;792;; +OISS;40;848;Shiraz;;Iran;2;29-32N;052-35E;29-32N;052-35E;1486;1491;P +OISY;--;---;Yasouj / National;;Iran;2;30-41-49N;051-33E;;;1825;; +OITK;40;703;Khoy;;Iran;2;38-33N;044-58E;;;1107;1107;P +OITL;--;---;Ardabil;;Iran;2;38-19-35N;048-25-28E;;;1315;; +OITM;--;---;Maragheh / Sahand;;Iran;2;37-20-55N;046-07-35E;;;1340;; +OITR;40;712;Orumieh;;Iran;2;37-32N;045-05E;;;1297;1312;P +OITS;40;727;Saghez;;Iran;2;36-15N;046-16E;;;1493;1493;P +OITT;40;706;Tabriz;;Iran;2;38-05N;046-17E;38-08N;046-15E;1367;1361;P +OITZ;40;729;Zanjan;;Iran;2;36-41N;048-29E;;;1663;1663;P +OIYY;40;821;Yazd;;Iran;2;31-54N;054-24E;;;1238;1230;P +OIZB;40;829;Zabol;;Iran;2;31-20N;061-29E;;;489;489;P +OIZC;40;898;Chahbahar;;Iran;2;25-25N;060-45E;;;6;6;P +OIZH;40;856;Zahedan;;Iran;2;29-28N;060-53E;29-28N;060-53E;1370;1370;P +OIZI;40;879;Iranshahr;;Iran;2;27-12N;060-42E;;;591;591;P +OIZJ;40;893;Jask;;Iran;2;26-38N;057-46E;;;3;4; +OJAI;40;272;Queen Alia Airport;;Jordan;6;31-40N;035-58E;;;721;; +OJAM;40;270;Amman Airport;;Jordan;6;31-59N;035-59E;31-59N;035-59E;767;768;P +OJAQ;40;340;Aqaba Airport;;Jordan;6;29-38N;035-01E;;;53;51; +OJBD;40;255;Irbid;;Jordan;6;32-33N;035-51E;32-33N;035-51E;618;619;P +OJHF;40;260;H-5'Safawi;;Jordan;6;32-12N;037-08E;;;668;670;P +OJHR;40;250;H-4'Irwaished;;Jordan;6;32-30N;038-12E;;;686;688;P +OJMF;40;265;Mafraq;;Jordan;6;32-22N;036-15E;32-22N;036-16E;686;687; +OJMN;40;310;Ma'An;;Jordan;6;30-10N;035-47E;30-10N;035-47E;1069;1070;P +OKBK;40;582;Kuwait Internationalairport;;Kuwait;2;29-13N;047-59E;29-13N;047-59E;55;55;P +OLBA;40;100;Beyrouth Aeroport ;;Lebanon;6;33-49N;035-29E;33-49N;035-29E;29;19; +OMAA;41;217;Abu Dhabi International Airport;;United Arab Emirates;2;24-26N;054-39E;24-26N;054-39E;16;27; +OMAB;--;---;Buhasa;;United Arab Emirates;2;23-37N;053-23E;;;94;; +OMAD;41;216;Abu Dhabi Bateen Airport;;United Arab Emirates;2;24-26N;054-28E;;;5;3; +OMAL;41;218;Al Ain International Airport;;United Arab Emirates;2;24-16N;055-36E;;;265;262; +OMDB;41;194;Dubai International Airport;;United Arab Emirates;2;25-15N;055-20E;;;8;5; +OMFJ;41;198;Fujairah;;United Arab Emirates;2;25-06N;056-20E;;;28;28; +OMRK;41;184;Ras Al Khaimah International Airport;;United Arab Emirates;2;25-37N;055-56E;;;31;31; +OMSJ;41;196;Sharjah International Airport;;United Arab Emirates;2;25-20N;055-31E;;;35;33; +OOBR;41;244;Buraimi;;Oman;2;24-14N;055-47E;;;299;; +OOFD;41;262;Fahud;;Oman;2;22-21N;056-29E;;;170;; +OOKB;41;240;Khassab;;Oman;2;26-13N;056-14E;;;3;; +OOMA;41;288;Masirah;;Oman;2;20-40N;058-54E;20-40N;058-54E;19;19;P +OOMS;41;256;Seeb, International Airport;;Oman;2;23-35N;058-17E;23-35N;058-17E;8;17;P +OOSA;41;316;Salalah;;Oman;2;17-02N;054-05E;17-02N;054-05E;20;17;P +OOSH;41;246; Sohar Majis;;Oman;2;24-28N;056-38E;;;4;; +OOSQ;41;254;Saiq;;Oman;2;23-04N;057-39E;;;1755;; +OOSR;41;268;Sur;;Oman;2;22-32N;059-29E;;;14;; +OOTH;41;314;Thumrait;;Oman;2;17-40N;054-02E;;;467;; +OPDI;41;624;Dera Ismail Khan;;Pakistan;2;31-49N;070-55E;31-49N;070-55E;172;173;P +OPJA;41;715;Jacobabad;;Pakistan;2;28-18N;068-28E;28-18N;068-28E;55;56;P +OPJI;41;756;Jiwani;;Pakistan;2;25-04N;061-48E;25-04N;061-48E;56;57;P +OPKC;41;780;Karachi Airport;;Pakistan;2;24-54N;067-08E;24-54N;067-08E;21;22;P +OPKD;41;764;Hyderabad Airport;;Pakistan;2;25-23N;068-25E;;;40;41;P +OPLA;41;641;Lahore Airport;;Pakistan;2;31-31N;074-24E;;;216;217;P +OPLH;41;640;Lahore City;;Pakistan;2;31-33N;074-20E;31-33N;074-20E;214;215;P +OPMI;41;592;Mianwali;;Pakistan;2;32-33N;071-31E;;;210;212;P +OPMT;41;675;Multan;;Pakistan;2;30-12N;071-26E;30-12N;071-26E;122;123;P +OPNH;41;749;Nawabshah;;Pakistan;2;26-15N;068-22E;26-15N;068-22E;37;38;P +OPPG;41;739;Panjgur;;Pakistan;2;26-58N;064-06E;26-58N;064-06E;980;981;P +OPPS;41;530;Peshawar;;Pakistan;2;34-01N;071-35E;34-01N;071-35E;359;360;P +OPQT;41;660;Quetta Airport;;Pakistan;2;30-15N;066-53E;;;1587;1589;P +OPRN;41;571;Islamabad Airport;;Pakistan;2;33-37N;073-06E;33-37N;073-06E;507;508;P +OPRS;41;533;Risalpur;;Pakistan;2;34-04N;071-59E;;;315;317;P +OPSB;41;697;Sibi;;Pakistan;2;29-33N;067-53E;;;133;134;P +OPSK;--;---;Sukkur;;Pakistan;2;27-43-19N;068-47-31E;;;60;; +OPSR;41;594;Sargodha;;Pakistan;2;32-03N;072-40E;32-03N;072-40E;187;188;P +ORBB;40;650;Baghdad;;Iraq;2;33-14N;044-14E;33-14N;044-14E;34;34;P +ORBM;40;608;Mosul;;Iraq;2;36-19N;043-09E;36-19N;043-09E;223;223;P +ORBS;--;---;Saddam Irq-Afb / Civ ;;Iraq;2;33-16N;044-14E;;;34;; +ORMS;40;688;Shaibah / Basrah;;Iraq;2;30-25N;047-39E;;;19;; +OSAP;40;007;Aleppo International Airport;;Syria;6;36-11N;037-12E;36-20N;037-13E;393;384;P +OSDI;40;080;Damascus Int. Airport;;Syria;6;33-25N;036-31E;33-25N;036-31E;608;609;P +OSDZ;40;045;Deir Ezzor;;Syria;6;35-19N;040-09E;35-19N;040-09E;215;212;P +OSKL;40;001;Kamishli;;Syria;6;37-03N;041-13E;37-03N;041-13E;455;455;P +OSLK;40;022;Lattakia;;Syria;6;35-32N;035-46E;35-30N;035-47E;7;7;P +OSPR;40;061;Palmyra;;Syria;6;34-33N;038-18E;;;408;404;P +OTBD;41;170;Doha International Airport;;Qatar;2;25-15N;051-34E;25-16N;051-33E;11;10; +OYAA;41;480;Aden;;Yemen;2;12-40N;045-02E;;;3;3; +OYAR;41;443;Riyan;;Yemen;2;14-39N;049-23E;;;16;25; +OYAT;41;437;Ataq;;Yemen;2;14-31N;046-51E;;;1067;1067; +OYHD;41;431;Hodeidah;;Yemen;2;14-45N;042-59E;;;115;115; +OYMB;41;350;Marib ;;Yemen;2;15-26N;045-20E;;;1000;; +OYMC;41;477;Mokha;;Yemen;2;13-15N;044-08E;;;4;3; +OYMK;41;382;Mokha ;;Yemen;2;13-15N;043-17E;;;3;; +OYSH;--;---;Sa'Ada / Sadah ;;Yemen;2;16-58N;043-44E;;;1890;; +OYSN;41;404;Sana'A;;Yemen;2;15-31N;044-11E;15-23N;044-12E;2206;2190; +OYSQ;41;494;Socotra;;Yemen;2;12-38N;053-54E;12-38N;053-54E;45;47; +OYSY;--;---;Sayun;;Yemen;2;15-58N;048-48E;;;701;; +OYTZ;41;466;Taiz;;Yemen;2;13-41N;044-08E;;;1402;1385; +OYZM;41;326;Al-Hazm ;;Yemen;2;16-12N;044-47E;;;1900;; +PAAK;--;---;Atka, Atka Airport;AK;United States;4;52-13-13N;174-12-23W;;;17;; +PAAP;--;---;Port Alexander, Port Alexander Seaplane Base;AK;United States;4;56-15N;134-39W;;;0;; +PAAQ;70;274;Palmer, Palmer Municipal Airport;AK;United States;4;61-36N;149-05W;;;74;; +PABA;70;086;Barter Island, Barter Island LRRS Airport;AK;United States;4;70-08-02N;143-34-37W;70-08N;143-38W;2;15;P +PABE;70;219;Bethel, Bethel Airport;AK;United States;4;60-46-47N;161-50-16W;60-47N;161-50W;38;46;P +PABG;--;---;Big Delta Arctic Weather;AK;United States;4;64-00N;145-43W;;;389;; +PABI;70;267;Delta Junction/Ft Greely, Allen Army Airfield;AK;United States;4;64-00N;145-44W;64-00N;145-44W;389;391;P +PABL;00;000;Buckland, Buckland Airport;AK;United States;4;65-58-56N;161-09-07W;;;7;; +PABN;--;---;Nabesna, Devil Mountain Lodge Airport;AK;United States;4;62-24N;143-00W;;;878;; +PABR;70;026;Barrow, Wiley Post-Will Rogers Memorial Airport;AK;United States;4;71-17-07N;156-45-57W;71-17-21N;156-47-02W;13;10;P +PABT;70;174;Bettles, Bettles Airport;AK;United States;4;66-55N;151-31W;66-54N;151-31W;196;196;P +PABV;--;---;Birchwood, Birchwood Airport;AK;United States;4;61-25N;149-31W;;;29;; +PACD;70;316;Cold Bay, Cold Bay Airport;AK;United States;4;55-13-15N;162-43-40W;55-12-05N;162-42-50W;30;29;P +PACL;--;---;Clear;AK;United States;4;64-18N;149-07W;;;168;; +PACP;70;360;Cape Saint Elias;AK;United States;4;59-48N;144-36W;;;18;; +PACR;--;---;Circle City Airport;AK;United States;4;65-50N;144-04W;;;182;; +PACS;--;---;Cape Sarichef Airport;AK;United States;4;54-36N;164-56W;;;9;; +PACV;70;296;Cordova, Merle K (Mudhole) Smith Airport;AK;United States;4;60-29-30N;145-28-40W;;;13;13; +PACY;70;298;Yakataga;AK;United States;4;60-05N;142-30W;;;4;11; +PACZ;70;212;Cape Romanzof, Cape Romanzof LRRS Airport;AK;United States;4;61-47N;166-02W;;;139;; +PADE;--;---;Deering, Deering/New Airport;AK;United States;4;66-05N;162-45W;;;5;; +PADK;70;454;Adak Island, Adak Airport;AK;United States;4;51-52-40N;176-38-45W;51-52-50N;176-38-33W;6;4; +PADL;70;321;Dillingham, Dillingham Airport;AK;United States;4;59-03N;158-31W;;;26;29; +PADQ;70;350;Kodiak, Kodiak Airport;AK;United States;4;57-45N;152-30W;57-45N;152-30W;22;34;P +PADT;--;---;Slana Airport;AK;United States;4;62-42N;143-59W;;;730;; +PADU;70;489;Unalaska, Unalaska Airport;AK;United States;4;53-54N;166-32W;;;7;; +PAEC;--;---;Chulitna, Chulitna Airport;AK;United States;4;62-53N;149-50W;;;381;; +PAED;70;272;Anchorage, Elmendorf Air Force Base;AK;United States;4;61-15-11N;149-47-38W;;;65;59; +PAEG;--;---;Eagle, Eagle Airport;AK;United States;4;64-46-35N;141-09-03W;;;268;; +PAEH;70;305;Cape Newenham, Cape Newenham LRRS Airport;AK;United States;4;58-39N;162-04W;;;165;; +PAEI;70;265;Fairbanks, Eielson Air Force Base;AK;United States;4;64-39N;147-06W;64-39N;147-04W;167;167; +PAEL;--;---;Elfin Cove, Elfin Cove Seaplane Base;AK;United States;4;58-12N;136-21W;;;0;; +PAEM;--;---;Emmonak, Emmonak Airport;AK;United States;4;62-47N;164-30W;;;4;; +PAEN;70;259;Kenai, Kenai Municipal Airport;AK;United States;4;60-34-23N;151-14-42W;60-34-25N;151-14-13W;30;25; +PAER;--;---;Merrill Pass West;AK;United States;4;61-15N;153-49W;;;358;; +PAFA;70;261;Fairbanks, Fairbanks International Airport;AK;United States;4;64-48-14N;147-52-34W;64-49-11N;147-51-29W;132;140;P +PAFB;--;---;Wainwright U. S. Army Airfield;AK;United States;4;64-50N;147-37W;;;137;; +PAFE;--;---;Kake, Kake Airport;AK;United States;4;56-57N;133-54W;;;52;; +PAFK;--;---;Farewell Lake, Farewell Lake Seaplane Base;AK;United States;4;62-32-33N;153-37-21W;;;321;; +PAFM;70;171;Ambler, Ambler Airport;AK;United States;4;67-06N;157-51W;;;88;; +PAFR;70;270;Ft. Richardson / Bryant U. S. Army Heliport, Ak;AK;United States;4;61-16N;149-39W;61-16N;149-39W;115;115; +PAFW;--;---;Farewell Lake;AK;United States;4;62-32N;153-37W;;;323;; +PAGA;70;222;Galena, Edward G. Pitka Sr. Airport;AK;United States;4;64-44N;156-56W;64-44N;156-56W;46;49; +PAGB;--;---;Galbraith Lake, Galbraith Lake Airport;AK;United States;4;68-29N;149-29W;;;814;; +PAGK;70;271;Gulkana, Gulkana Airport;AK;United States;4;62-09N;145-27W;;;481;481;P +PAGL;--;---;Golovin, Golovin Airport;AK;United States;4;64-32-36N;163-02-22W;;;8;; +PAGM;70;204;Gambell, Gambell Airport;AK;United States;4;63-46N;171-44W;;;8;; +PAGN;70;383;Angoon;AK;United States;4;57-30N;134-35W;;;0;1; +PAGS;70;367;Gustavus, Gustavus Airport;AK;United States;4;58-25N;135-42W;;;10;9; +PAGT;--;---;Nightmute;AK;United States;4;60-28N;164-42W;;;4;; +PAGY;70;362;Skagway;AK;United States;4;59-28N;135-18W;;;16;5; +PAHD;70;341;Homer / Municipal;AK;United States;4;59-38N;151-30W;;;24;22; +PAHN;--;---;Haines, Haines Airport;AK;United States;4;59-15N;135-31W;;;5;; +PAHO;--;---;Homer, Homer Airport;AK;United States;;59-39N;151-29W;;;26;; +PAHP;--;---;Hooper Bay, Hooper Bay Airport;AK;United States;4;61-31N;166-08W;;;5;; +PAHS;--;---;Huslia, Huslia Airport;AK;United States;4;65-42N;156-23W;;;55;; +PAHV;--;---;Healy, Healy River Airport;AK;United States;4;63-52N;148-58W;;;394;; +PAHY;--;---;Hydaburg, Hydaburg Seaplane Base;AK;United States;4;55-12N;132-50W;;;0;; +PAHZ;--;---;Hayes River, Hayes River Airport;AK;United States;4;61-59N;152-05W;;;305;; +PAII;--;---;Egegik, Egegik Airport;AK;United States;4;58-11-07N;157-23-08W;;;28;; +PAIK;--;---;Kinana / Bob Baker Me;AK;United States;4;66-59N;160-26W;;;46;; +PAIL;70;340;Iliamna, Iliamna Airport;AK;United States;4;59-45N;154-54W;;;57;49;P +PAIM;70;173;Utopia Creek, Indian Mountain LRRS Airport;AK;United States;4;66-59N;153-42W;;;372;; +PAIN;--;---;McKinley Park, McKinley National Park Airport;AK;United States;4;63-44N;148-55W;;;524;; +PAIZ;--;---;Lazy Mtn / Wolverine;AK;United States;4;61-38N;149-02W;;;236;; +PAJB;--;---;Biorka Island Supplementary Aviation Weather Reporting Station;AK;United States;4;56-51N;135-32W;;;15;; +PAJC;--;---;Chignik, Chignik Airport;AK;United States;4;56-18-41N;158-22-24W;;;6;; +PAJN;70;381;Juneau, Juneau International Airport;AK;United States;4;58-21-17N;134-34-34W;58-21-48N;134-34-33W;6;8;P +PAJO;--;---;Johnstone Point;AK;United States;4;60-29N;146-36W;;;14;; +PAJV;--;---;Sutton;AK;United States;4;61-43N;148-53W;;;265;; +PAKK;--;---;Koyuk, Koyuk Airport;AK;United States;4;64-56-02N;161-09-29W;;;37;; +PAKN;70;326;King Salmon, King Salmon Airport;AK;United States;4;58-40-36N;156-38-57W;58-40-50N;156-39-28W;17;10;P +PAKO;70;482;Nikolski;AK;United States;4;52-57N;168-51W;;;21;;P +PAKP;--;---;Anaktuvuk Pass, Anaktuvuk Pass Airport;AK;United States;4;68-08-01N;151-44-36W;;;641;; +PAKT;70;395;Ketchikan, Ketchikan International Airport;AK;United States;4;55-21-20N;131-42-49W;55-21-10N;131-42-24W;27;25; +PAKU;--;---;Kuparuk, Ugnu-Kuparuk Airport;AK;United States;4;70-19N;149-35W;;;20;; +PAKV;--;---;Kaltag, Kaltag Airport;AK;United States;4;64-19N;158-44W;;;54;; +PAKW;70;389;Klawock, Klawock Airport;AK;United States;4;55-35N;133-05W;;;24;; +PALH;--;---;Anchorage, Lake Hood Seaplane Base;AK;United States;4;61-11N;149-58W;;;22;; +PALJ;--;---;Port Alsworth, Port Alsworth Airport;AK;United States;4;60-12N;154-19W;;;85;; +PALK;--;---;Snowshoe Lake;AK;United States;4;62-02N;142-40W;;;735;; +PALP;--;---;Deadhorse, Alpine Airstrip;AK;United States;4;70-20N;150-56W;;;5;; +PALR;--;---;Chandalar Lake, Chandalar Lake Airport;AK;United States;4;67-30N;148-29W;;;585;; +PALU;70;104;Cape Lisburne, Cape Lisburne LRRS Airport;AK;United States;4;68-53N;166-06W;;;4;; +PALV;--;---;Big River Lake;AK;United States;4;60-49N;152-18W;;;12;; +PAMC;70;231;McGrath, McGrath Airport;AK;United States;4;62-58N;155-37W;62-58N;155-37W;103;103;P +PAMD;70;343;Middleton Island, Middleton Island Airport;AK;United States;4;59-26N;146-18W;;;27;14; +PAMH;70;246;Minchumina, Minchumina Airport;AK;United States;4;63-52-50N;152-18-02W;;;208;214; +PAML;--;---;Manley Hot Springs, Manly Hot Springs Airport;AK;United States;4;64-59N;150-38W;;;82;; +PAMM;--;---;Metlakatla, Metlakatla Seaplane Base;AK;United States;4;55-07-52N;131-34-41W;;;0;; +PAMR;--;---;Anchorage, Merrill Field Airport;AK;United States;4;61-13N;149-51W;;;42;; +PAMX;--;---;McCarthy;AK;United States;4;61-26N;142-56W;;;455;; +PAMY;--;---;Mekoryuk, Mekoryuk Airport;AK;United States;4;60-22N;166-16W;;;15;; +PANC;70;273;Anchorage, Ted Stevens Anchorage International Airport;AK;United States;4;61-10-28N;149-59-46W;61-10-25N;150-00-39W;44;48;P +PANI;70;232;Aniak, Aniak Airport;AK;United States;4;61-34-53N;159-32-34W;;;27;26; +PANN;70;260;Nenana, Nenana Municipal Airport;AK;United States;4;64-33N;149-05W;;;110;; +PANR;--;---;Funter Bay Seaplane;AK;United States;4;58-15N;134-54W;;;0;; +PANT;70;398;Annette, Annette Island Airport;AK;United States;4;55-02-32N;131-34-20W;55-02N;131-34W;36;34;P +PANV;--;---;Anvik, Anvik Airport;AK;United States;4;62-38-54N;160-11-23W;;;94;; +PAOH;--;---;Hoonah, Hoonah Seaplane Base;AK;United States;4;58-07N;135-27W;;;0;; +PAOM;70;200;Nome, Nome Airport;AK;United States;4;64-30-43N;165-26-42W;64-30-32N;165-25-50W;11;4;P +PAOR;70;291;Northway, Northway Airport;AK;United States;4;62-57-40N;141-55-44W;62-57-44N;141-56-10W;523;522; +PAOT;70;133;Kotzebue, Ralph Wien Memorial Airport;AK;United States;4;66-53-04N;162-35-54W;66-53-12N;162-36-31W;3;5;P +PAPB;--;---;St. George, St. George Airport;AK;United States;4;56-34-43N;169-39-41W;;;38;; +PAPC;70;119;Port Clarence, Port Clarence Coast Guard Station;AK;United States;4;65-15N;166-51W;;;3;5; +PAPG;70;386;Petersburg;AK;United States;4;56-49N;132-58W;;;0;; +PAPH;70;333;Port Heiden, Port Heiden Airport;AK;United States;4;56-57N;158-38W;;;29;;P +PAPM;--;---;Platinum;AK;United States;4;59-01N;161-49W;;;3;; +PAPO;--;---;Point Hope, Point Hope Airport;AK;United States;4;68-21N;166-48W;;;4;; +PAPR;--;---;Prospect Creek, Prospect Creek Airport;AK;United States;4;66-48-46N;150-38-38W;;;335;; +PAPT;70;249;Puntilla;AK;United States;4;62-06N;152-45W;;;560;; +PAQT;70;364;Nuiqsut, Nuiqsut Airport;AK;United States;4;70-12-36N;151-00-20W;70-12-49N;150-59-18W;12;17; +PARC;--;---;Arctic Village, Arctic Village Airport;AK;United States;4;68-06-52N;145-34-45W;;;638;; +PARD;--;---;Red Dog, Red Dog Airport;AK;United States;4;68-01-53N;162-54-11W;;;297;; +PARL;--;---;Central, Central Airport;AK;United States;4;65-34-26N;144-46-59W;;;284;; +PASA;--;---;Savoonga Airport;AK;United States;4;63-41N;170-30W;;;16;; +PASC;--;---;Deadhorse, Deadhorse Airport;AK;United States;4;70-12N;148-28W;;;17;; +PASD;--;---;Sand Point;AK;United States;4;55-19N;160-31W;;;7;; +PASG;--;---;Skagway, Skagway Airport;AK;United States;4;59-27-19N;136-19-23W;59-27-19N;136-19-23W;13;7; +PASH;--;---;Shishmaref Automatic Weather Observing / Reporting System;AK;United States;4;66-16N;166-03W;;;2;; +PASI;70;371;Sitka, Sitka Airport;AK;United States;4;57-02-53N;135-21-53W;57-02-53N;135-21-53W;6;14; +PASK;--;---;Selawik;AK;United States;4;66-37N;160-00W;;;8;; +PASL;--;---;Sleetmute;AK;United States;4;61-43N;157-09W;;;54;; +PASM;--;---;St. Mary's, St. Mary's Airport;AK;United States;4;62-03N;163-18W;;;95;; +PASN;70;308;St. Paul Island, St. Paul Island Airport;AK;United States;4;57-10N;170-13W;57-09N;170-13W;19;9;P +PASO;--;---;Seldovia, Seldovia Airport;AK;United States;4;59-27N;151-42W;;;9;; +PASP;--;---;Sheep Mountain, Sheep Mountain Airport;AK;United States;4;61-48-43N;147-30-25W;;;838;; +PASV;70;235;Sparrevohn Airways Facilities Sector;AK;United States;4;61-06N;155-34W;;;484;; +PASW;70;255;Skwentna;AK;United States;4;61-58N;151-11W;;;45;; +PASX;--;---;Soldotna;AK;United States;4;60-29N;151-02W;;;33;; +PASY;70;414;Shemya, Eareckson As;AK;United States;4;52-43-00N;174-07-00E;52-44N;174-06E;29;28;P +PATA;70;178;Tanana, Calhoun Memorial Airport;AK;United States;4;65-10N;152-06W;;;69;67; +PATC;70;117;Tin City Airways Facilities Sector;AK;United States;4;65-34N;167-55W;;;83;; +PATG;--;---;Togiac Village Automatic Weather Observing / Reporting System;AK;United States;4;59-03N;160-24W;;;6;; +PATJ;--;---;Tok;AK;United States;4;63-19N;142-43W;;;509;; +PATK;70;251;Talkeetna, Talkeetna Airport;AK;United States;4;62-19-14N;150-05-37W;;;109;109; +PATL;--;---;Tatalina Automatic Weather Observing / Reporting System;AK;United States;4;62-54N;155-59W;;;294;; +PATO;--;---;Portage, Portage Glacier;AK;United States;4;60-47N;148-50W;;;29;; +PATW;--;---;Cantwell, Cantwell Airport;AK;United States;4;63-24N;148-57W;;;668;; +PAUM;70;162;Umiat;AK;United States;4;69-22N;152-08W;;;81;85; +PAUN;70;207;Unalakleet;AK;United States;4;63-53N;160-48W;;;6;6;P +PAUO;--;---;Willow Airport ;AK;United States;4;61-45N;150-03W;;;67;; +PAVD;--;---;Valdez 2;AK;United States;4;61-08N;146-16W;;;37;; +PAVL;--;---;Kivalina, Kivalina Airport;AK;United States;4;67-44N;164-33W;;;4;; +PAVW;--;---;Valdez Weather Station Office;AK;United States;4;61-08N;146-21W;;;10;; +PAWD;70;277;Seward;AK;United States;4;60-07N;149-27W;;;9;18; +PAWG;70;387;Wrangell;AK;United States;4;56-29N;132-22W;;;13;13; +PAWI;70;030;Wainwright, Wainwright Airport;AK;United States;4;70-38N;159-51W;;;12;; +PAWN;--;---;Noatak, Noatak Airport;AK;United States;4;67-34N;162-59W;;;27;; +PAWR;--;---;Whittier;AK;United States;4;60-46N;148-41W;;;9;; +PAWS;--;---;Wasilla, Wasilla Airport;AK;United States;4;61-34-19N;149-32-26W;;;106;; +PAXK;--;---;Paxson;AK;United States;4;63-02N;145-30W;;;809;; +PAYA;70;361;Yakutat;AK;United States;4;59-31N;139-40W;59-31N;139-40W;11;9;P +PAZK;--;---;Eureka, Skelton Airport;AK;United States;4;61-56N;147-10W;;;1002;; +PBTI;--;---;Barter Island Distant Early Warning ;AK;United States;4;70-08N;143-35W;;;2;; +PFYU;70;194;Fort Yukon, Fort Yukon Airport;AK;United States;4;66-34N;145-16W;66-35N;145-05W;433;431;P +PGAC;91;217;Guam, Mariana Island;GU;United States;5;13-55N;144-50E;;;111;; +PGNT;91;233;Sabanettan / Tinian Island;GU;United States;5;14-96N;145-06E;14-58N;145-36E;80;80; +PGRO;91;221;Rota Island, N. Mariana Is, Rota International Airport;GU;United States;5;14-11N;145-15E;;;185;; +PGSN;91;232;Saipan Island, Saipan International Airport;Northern Mariana Islands;United States;5;15-07N;145-44E;15-07N;145-45W;66;3; +PGUA;91;218;Andersen, Mariana Is, Andersen Air Force Base;GU;United States;5;13-35N;144-56E;13-35N;144-55E;187;187; +PGUM;91;212;Agana, Guam International Airport;GU;United States;5;13-29N;144-48E;13-21N;144-48E;91;; +PGWT;91;233;Tinian Island, N. Mariana Is, West Tinian Airport;GU;United States;5;14-59N;145-37E;;;82;; +PHBK;91;162;Kekaha, Pacific Missile Test Facility Barking Sands;HI;United States;5;22-02-11N;159-47-11W;22-02-00N;159-47-00W;4;3; +PHHI;91;170;Wheeler Air Force Base / Oahu;HI;United States;5;21-29N;158-02W;21-29N;158-02W;255;256; +PHHN;--;---;Hana, Hana Airport;HI;United States;5;20-47-44N;156-00-52W;;;24;; +PHIK;--;---;Hickam Air Force Base / Oahu ;HI;United States;5;21-19N;157-55W;;;4;; +PHJH;--;---;Lahaina / West Maui;HI;United States;5;21-01N;156-38W;;;40;; +PHJR;91;178;Oahu, Kalaeloa Airport;HI;United States;5;21-18-30N;158-04-05W;21-18-20N;158-04-28W;10;15; +PHKO;--;---;Kailua / Kona, Keahole Airport;HI;United States;5;19-44-27N;156-03-02W;19-44-08N;156-02-30W;13;27; +PHLI;91;165;Lihue, Lihue Airport;HI;United States;5;21-59-02N;159-20-28W;21-59-13N;159-20-36W;45;31; +PHMK;91;186;Kaunakakai, Molokai Airport;HI;United States;5;21-09N;157-06W;21-09N;157-06W;138;134; +PHMU;--;---;Kamuela, Waimea-Kohala Airport;HI;United States;5;20-00N;155-40W;;;814;; +PHNG;91;176;Kaneohe, Marine Corps Air Station;HI;United States;5;21-27-14N;157-45-56W;21-26-27N;157-46-32W;5;1; +PHNL;91;182;Honolulu, Honolulu International Airport;HI;United States;5;21-19-39N;157-56-35W;21-19-26N;157-55-47W;3;4; +PHNY;--;---;Lanai City Airport;HI;United States;5;20-47N;156-57W;;;399;; +PHOG;91;190;Kahului, Kahului Airport;HI;United States;5;20-53-33N;156-26-13W;20-54-02N;156-25-44W;16;12; +PHSF;--;---;Bradshaw Army Air Field / Hawaii;HI;United States;5;19-47N;155-33W;;;1887;; +PHTO;91;285;Hilo, Hilo International Airport;HI;United States;5;19-43-20N;155-03-21W;19-43-16N;155-03-46W;11;12; +PHWH;91;293;South Kona / Hawaii;HI;United States;5;19-06N;155-45W;;;808;; +PJON;91;275;Johnston Island, Johnston Atoll Airport;;United States Minor Outlying Islands;5;16-44N;169-32W;16-44N;169-31W;2;2; +PKMJ;91;376;Majuro Atoll, Marshall Islands Int. Airp.;;Marshall Islands;5;07-04N;171-17E;07-05N;171-23E;2;3; +PKMR;--;---;Majuro Atoll, NWS Office;;Marshall Islands;5;07-05N;171-12E;;;4;; +PKWA;91;366;Kwajalein, Bucholz AAF, Kwajalein KMR ATOL Airport;;Marshall Islands;5;08-43N;167-44E;08-44N;167-44E;3;2; +PLCH;91;490;Christmas / Cassidy;;New Zealand;5;01-59N;157-29W;;;3;; +PLFA;91;487;Fanning Island;;New Zealand;5;03-51N;159-22W;03-54N;159-23W;5;3; +PMDY;91;066;Sand Island, Henderson Field Airport;HI;United States;5;28-13N;177-22W;28-13N;177-22W;4;6; +POLI;70;063;Oliktok Distant Early Warning ;AK;United States;4;70-30N;149-53W;;;5;; +PPIZ;70;121;Point Lay, Point Lay LRRS Airport;AK;United States;4;69-43N;163-00W;;;8;;P +PTKK;91;334;Weno Island, Chuuk Int. Airp.;;Micronesia, Federated States of;5;07-28N;151-51E;07-28N;151-51E;3;2; +PTKR;--;---;Koror, Palau, NWS Office;;Palau;5;07-20N;134-29E;;;30;; +PTPN;91;348;Pohnpei Island, Pohnpei Int. Airp.;;Micronesia, Federated States of;5;06-59N;158-12E;06-58N;158-13E;2;; +PTRO;91;408;Babelthuap Island, Babelthuap/Koror Airport;;Palau;5;07-22N;134-32E;07-20N;134-29E;54;; +PTSA;91;356;Kosrae Island, Kosrae Airport;;Micronesia, Federated States of;5;05-21N;162-57E;;;3;; +PTTK;91;355;Kosrae Carolines / V;;Micronesia, Federated States of;5;05-21N;162-57E;;;2;; +PTTP;--;---;Pohnpei, NWS Office;;Micronesia, Federated States of;5;06-58N;158-13E;;;39;; +PTYA;91;413;Yap Island, Yap Int. Airp.;;Micronesia, Federated States of;5;09-29N;138-05E;09-29N;138-05E;28;; +PWAK;91;245;Wake Island, Wake Island Army Airfield Airport;GU;United States;5;19-17N;166-39E;19-17N;166-39E;4;4; +RCAY;46;745;Kangshan Tw-Afb ;;Taiwan;2;22-47N;120-16E;;;10;; +RCBS;46;736;Chinmem / Shatou Air Force Base ;;Taiwan;2;24-26N;118-22E;24-26N;118-26E;9;12; +RCDC;46;750;Pingtung South Air Force Base ;;Taiwan;2;22-41N;120-28E;22-40N;120-27E;24;24; +RCFG;46;689;Mazu;;Taiwan;2;26-10N;119-56E;26-09N;119-57E;91;30; +RCFN;--;---;Feng Nin Tw-Afb ;;Taiwan;2;22-46N;121-05E;;;42;; +RCFS;46;772;Chia Tung;;Taiwan;2;22-25N;120-33E;;;20;; +RCGM;46;697;Taoyuan Ab = 589650;;Taiwan;2;25-04N;121-14E;25-03N;121-15E;45;48; +RCKH;46;740;Kaohsiung International Airport;;Taiwan;2;22-35N;120-21E;;;9;; +RCKU;46;746;Chiayi Tw-Afb ;;Taiwan;2;23-28N;120-23E;23-28N;120-23E;25;25; +RCKW;46;752;Hengchun;;Taiwan;2;21-56N;120-50E;;;13;; +RCLG;46;751;Taichung Tw-Afb ;;Taiwan;2;24-11N;120-39E;24-11N;120-39E;112;112; +RCLM;46;810;Dongsha;;Taiwan;2;20-40N;116-43E;20-43N;116-43E;6;3; +RCLY;46;762;Lan Yu;;Taiwan;2;22-02N;121-33E;;;325;; +RCMJ;46;747;Donggang;;Taiwan;2;22-28N;120-26E;22-28N;120-26E;8;8; +RCMQ;46;770;Wuchia Observatory;;Taiwan;2;24-16N;120-37E;24-16N;120-37E;5;203; +RCMS;46;764;Ilan;;Taiwan;2;24-45N;121-46E;;;9;; +RCNN;46;743;Tainan Tw-Afb ;;Taiwan;2;22-57N;120-12E;22-57N;120-13E;19;16; +RCNO;46;730;Dongshi;;Taiwan;2;23-16N;119-40E;;;45;; +RCPO;46;756;Hsinchu Tw-Afb ;;Taiwan;2;24-49N;120-56E;;;8;; +RCQC;46;734;Makung Ab;;Taiwan;2;23-35N;119-37E;23-35N;119-37E;31;31; +RCQS;46;760;Chihhang Tw-Afb ;;Taiwan;2;22-48N;121-11E;;;37;; +RCSQ;46;758;Pingtung North Air Force Base ;;Taiwan;2;22-42N;120-29E;;;29;; +RCSS;46;696;Sungshan / Taipei;;Taiwan;2;25-04N;121-33E;;;6;; +RCTP;46;686;Chiang Kai Shek;;Taiwan;2;25-05N;121-13E;;;33;; +RCUK;46;738;Pa Kuei / Bakuai;;Taiwan;2;24-56N;121-18E;;;141;; +RCYU;46;763;Hulien Ab;;Taiwan;2;24-02N;121-37E;24-01N;121-37E;16;14; +RJAA;47;686;New Tokyo Inter-National Airport;;Japan;2;35-46N;140-23E;;;41;44; +RJAF;47;709;Matsumoto Airport;;Japan;2;36-10N;137-56E;;;668;661; +RJAH;47;715;Hyakuri Ab;;Japan;2;36-11N;140-25E;;;32;35; +RJAI;--;---;Ichikawa ;;Japan;2;35-44N;139-55E;;;31;; +RJAK;47;716;Kasumigaura Ab;;Japan;2;36-02N;140-12E;;;26;29; +RJAM;47;991;Minamitorishima;;Japan;2;24-18N;153-58E;24-18N;153-58E;8;9;P +RJAO;47;971;Chichijima;;Japan;2;27-05N;142-11E;27-05N;142-11E;3;8;P +RJAT;47;721;Fuji Ab;;Japan;2;35-19N;138-52E;;;680;683; +RJAW;47;981;Iwojima;;Japan;2;24-47N;141-19E;24-47N;141-20E;113;116; +RJBB;47;774;Kansai International Airport;;Japan;2;34-25N;135-15E;;;5;8; +RJBD;47;782;Nankishirahama Airport;;Japan;2;33-40N;135-21E;;;105;108; +RJBH;--;---;Hiroshimanishi;;Japan;2;34-22N;132-26E;;;5;; +RJBT;--;---;Tajima;;Japan;2;35-31N;134-48E;;;210;; +RJCA;47;477;Asahikawa Ab;;Japan;2;43-48N;142-22E;;;115;118; +RJCB;47;490;Obihiro Airport;;Japan;2;42-44N;143-13E;;;149;152; +RJCC;47;425;Chitose Ab;;Japan;2;42-48N;141-40E;;;27;30; +RJCH;47;488;Hakodate Airport;;Japan;2;41-46N;140-49E;;;33;36; +RJCJ;47;434;Chitose Japanese Air Self Defense Force ;;Japan;2;42-49N;141-41E;;;27;; +RJCK;47;489;Kushiro Airport;;Japan;2;43-02N;144-12E;;;95;98; +RJCM;47;481;Memambetsu Airport;;Japan;2;43-53N;144-10E;;;33;36; +RJCN;47;483;Nakashibetsu Airport;;Japan;2;43-34N;144-58E;;;66;69; +RJCO;47;479;Sapporo Ab;;Japan;2;43-07N;141-23E;;;8;11; +RJCR;--;---;Rebun Island;;Japan;2;45-27N;141-02E;;;27;; +RJCS;47;418;Kushiro;;Japan;2;42-59N;144-24E;;;32;37;P +RJCT;--;---;Tokachi Japanese Ground Self Defense Force ;;Japan;2;42-54N;143-10E;;;84;; +RJCW;47;441;Wakkanai Airport;;Japan;2;45-24N;141-48E;;;8;11; +RJCY;47;423;Muroran;;Japan;2;42-19N;140-59E;;;40;49; +RJDB;47;858;Iki Airport;;Japan;2;33-45N;129-47E;;;13;16; +RJDC;47;786;Yamaguchi Ube Airport;;Japan;2;33-56N;131-17E;;;5;8; +RJDK;--;---;Kamigoto;;Japan;2;33-01N;129-11E;;;20;; +RJDM;47;860;Metabaru Ab;;Japan;2;33-19N;130-25E;;;16;19; +RJDO;--;---;Ojika Island ;;Japan;2;33-13N;129-03E;;;20;; +RJDT;47;799;Tsushima Airport;;Japan;2;34-17N;129-20E;;;63;66; +RJEB;47;474;Mombetsu Airport;;Japan;2;44-15N;143-32E;;;6;9; +RJEC;47;476;Asahikawa Airport;;Japan;2;43-40N;142-27E;;;208;211; +RJEO;--;---;Okushiri Island;;Japan;2;42-04N;139-27E;;;36;; +RJER;--;---;Rishiri Island;;Japan;2;45-15N;141-11E;;;30;; +RJFA;47;803;Ashiya Ab;;Japan;2;33-53N;130-39E;;;30;33; +RJFC;47;836;Yakushima;;Japan;2;30-23N;130-40E;;;36;38; +RJFE;47;844;Fukue Airport;;Japan;2;32-40N;128-50E;;;77;80; +RJFF;47;808;Fukuoka Airport;;Japan;2;33-35N;130-27E;33-35N;130-27E;9;12; +RJFG;47;870;Tanegashima Airport;;Japan;2;30-33N;130-57E;;;92;95; +RJFK;47;851;Kagoshima Airport;;Japan;2;31-48N;130-43E;;;272;275; +RJFM;47;857;Miyazaki Airport;;Japan;2;31-52N;131-27E;;;6;9; +RJFN;47;854;Nyutabaru Ab;;Japan;2;32-05N;131-27E;;;79;82; +RJFO;47;852;Oita Airport;;Japan;2;33-29N;131-44E;;;5;8; +RJFR;47;853;Kitakyushu Airport;;Japan;2;33-50N;130-57E;;;3;6; +RJFS;--;---;Saga Airport;;Japan;2;33-09N;130-18E;;;2;5; +RJFT;47;856;Kumamoto Airport;;Japan;2;32-50N;130-51E;;;193;196; +RJFU;47;855;Nagasaki Airport;;Japan;2;32-55N;129-55E;32-55N;129-55E;2;5; +RJFW;47;811;Sasebo Usn;;Japan;2;33-09N;129-43E;;;19;22; +RJFY;47;850;Kanoya Ab;;Japan;2;31-22N;130-50E;31-21N;130-50E;65;68; +RJFZ;47;840;Tsuiki Ab;;Japan;2;33-41N;131-03E;;;17;20; +RJKA;47;872;Amami Airport;;Japan;2;28-26N;129-43E;;;4;7; +RJKB;47;942;Okinoerabu;;Japan;2;27-26N;128-42E;;;27;29; +RJKI;--;---;Kikai Island;;Japan;2;28-19N;129-56E;;;6;; +RJKN;47;910;Tokunoshima Island;;Japan;2;27-50N;128-53E;;;5;; +RJNF;47;706;Fukui Airport;;Japan;2;36-08N;136-14E;;;5;8; +RJNG;47;634;Gifu Ab;;Japan;2;35-23N;136-52E;;;39;42; +RJNH;47;681;Hamamatsu Ab;;Japan;2;34-45N;137-42E;34-44N;137-40E;45;48; +RJNK;47;704;Komatsu Ab;;Japan;2;36-23N;136-25E;;;6;9; +RJNN;47;635;Nagoya Airport;;Japan;2;35-15N;136-56E;;;14;17; +RJNO;47;739;Oki Airport;;Japan;2;36-11N;133-20E;;;92;95; +RJNT;47;707;Toyama Airport;;Japan;2;36-39N;137-11E;;;24;27; +RJNY;47;658;Shizuhama Ab;;Japan;2;34-49N;138-18E;;;7;10; +RJOA;47;789;Hiroshima Airport;;Japan;2;34-26N;132-55E;;;331;334; +RJOB;47;793;Okayama Airport;;Japan;2;34-45N;133-51E;;;241;244; +RJOC;47;790;Izumo Airport;;Japan;2;35-25N;132-54E;;;2;5; +RJOE;47;730;Akeno Ab;;Japan;2;34-32N;136-41E;;;6;9; +RJOF;47;788;Hofu Ab;;Japan;2;34-02N;131-33E;34-02N;131-32E;2;5; +RJOH;47;743;Miho Ab;;Japan;2;35-29N;133-15E;;;6;9; +RJOI;47;764;Iwakuni Marine Corps Air Station;;Japan;2;34-08N;132-14E;34-08N;132-14E;2;5; +RJOK;47;883;Kochi Airport;;Japan;2;33-32N;133-40E;;;7;10; +RJOM;47;882;Matsuyama Airport;;Japan;2;33-49N;132-42E;;;4;7; +RJOO;47;771;Osaka International Airport;;Japan;2;34-47N;135-27E;;;12;15; +RJOP;47;884;Komatsujima Ab;;Japan;2;34-00N;134-38E;34-00N;134-38E;3;6; +RJOR;47;794;Tottori Airport;;Japan;2;35-32N;134-10E;;;15;18; +RJOS;47;881;Tokushima Ab;;Japan;2;34-08N;134-37E;34-08N;134-36E;8;11; +RJOT;47;880;Takamatsu Airport;;Japan;2;34-13N;134-01E;;;185;188; +RJOW;47;783;Iwami Airport;;Japan;2;34-40N;131-48E;;;54;57; +RJOY;47;779;Yao Airport;;Japan;2;34-36N;135-36E;;;10;13; +RJOZ;47;787;Ozuki Ab;;Japan;2;34-03N;131-03E;34-03N;131-03E;4;7; +RJSA;47;542;Aomori Airport;;Japan;2;40-44N;140-42E;;;199;202; +RJSC;47;553;Yamagata Airport;;Japan;2;38-25N;140-22E;;;105;108; +RJSD;47;700;Sado Airport;;Japan;2;38-03N;138-25E;;;23;26; +RJSF;47;557;Fukushima Airport;;Japan;2;37-14N;140-26E;;;372;375; +RJSH;47;515;Hachinohe Ab;;Japan;2;40-33N;141-28E;40-33N;141-28E;46;49; +RJSI;47;549;Hanamaki Airport;;Japan;2;39-26N;141-08E;;;90;93; +RJSK;47;545;Akita Airport;;Japan;2;39-37N;140-13E;;;93;96; +RJSM;47;580;Misawa Ab;;Japan;2;40-42N;141-23E;40-41N;141-22E;36;39; +RJSN;47;573;Niigata Airport;;Japan;2;37-57N;139-07E;;;1;4; +RJSO;47;516;Ominato Ab;;Japan;2;41-14N;141-08E;41-14N;141-09E;7;10; +RJSR;--;---;Odate-Noshiro Airport;;Japan;2;40-11N;140-12E;;;84;87; +RJSS;47;569;Sendai Airport;;Japan;2;38-08N;140-55E;;;1;4; +RJST;47;591;Matsushima Ab;;Japan;2;38-24N;141-13E;;;2;5; +RJSU;47;567;Kasuminome Ab;;Japan;2;38-14N;140-55E;;;7;10; +RJSY;--;---;Shonai;;Japan;2;38-49N;139-47E;;;22;; +RJTA;47;679;Atsugi United States Naval Air Station;;Japan;2;35-27N;139-27E;35-27N;139-28E;62;65; +RJTC;47;660;Tachikawa Ab;;Japan;2;35-42N;139-24E;;;95;98; +RJTD;47;662;Tokyo;;Japan;2;35-41N;139-46E;;;5;36;P +RJTE;47;688;Tateyama Ab;;Japan;2;34-59N;139-50E;34-59N;139-50E;3;6; +RJTF;47;683;Chofu Airport;;Japan;2;35-40N;139-32E;;;41;44; +RJTH;47;738;Hachijojima Airport;;Japan;2;33-07N;139-47E;;;92;95; +RJTI;47;687;Tokyo Heliport;;Japan;2;35-38N;139-51E;;;5;8; +RJTJ;47;643;Iruma Ab;;Japan;2;35-50N;139-25E;35-50N;139-25E;90;93; +RJTK;47;661;Kisarazu Ab;;Japan;2;35-24N;139-55E;;;3;6; +RJTL;47;727;Shimofusa Ab;;Japan;2;35-48N;140-01E;35-47N;140-01E;30;33; +RJTO;47;735;Oshima Airport;;Japan;2;34-47N;139-22E;;;38;41; +RJTQ;47;737;Miyakejima Airport;;Japan;2;34-04N;139-34E;;;20;23; +RJTR;47;680;Zama Airfield;;Japan;2;35-31N;139-24E;;;109;112; +RJTT;47;671;Tokyo International Airport;;Japan;2;35-33N;139-47E;;;5;8; +RJTU;47;692;Utsunomiya Ab;;Japan;2;36-31N;139-52E;;;102;105; +RJTX;47;696;Yokosuka Fwf;;Japan;2;35-17N;139-40E;;;49;53; +RJTY;47;642;Yokota Ab;;Japan;2;35-45N;139-21E;;;139;142; +RKJJ;47;158;Kwangju Ab;;Korea, South;2;35-07N;126-49E;35-07N;126-49E;13;13; +RKJK;47;141;Kunsan Ab;;Korea, South;2;35-55N;126-37E;35-54N;126-37E;10;10; +RKJY;47;167;Yosu Airport;;Korea, South;2;34-50N;127-37E;;;21;20; +RKNC;47;104;Chunchon Ab;;Korea, South;2;37-52N;127-43E;37-53N;127-43E;76;75; +RKNF;--;---;Whang Ryeong;;Korea, South;2;37-45N;128-40E;;;1407;; +RKNH;47;118;Hoengsong Ab;;Korea, South;2;37-26N;127-57E;37-26N;126-58E;100;101; +RKNN;47;107;Kangnung Ab;;Korea, South;2;37-45N;128-57E;37-45N;128-57E;11;6; +RKNO;--;---;Keo Jin;;Korea, South;2;38-28N;128-28E;;;107;; +RKNR;--;---;Kotar Range;;Korea, South;2;37-06N;128-54E;;;792;; +RKNW;47;114;Wonju;;Korea, South;2;37-20N;127-57E;;;150;150;P +RKPC;47;182;Cheju International Airport;;Korea, South;2;33-30N;126-30E;;;36;28; +RKPK;47;153;Pusan / Kimhae International Airport;;Korea, South;2;35-11N;128-56E;35-11N;128-56E;4;6; +RKPM;47;187;Mosulpo Ab;;Korea, South;2;33-12N;126-16E;33-12N;126-16E;27;27; +RKPS;47;161;Sach'On Ab;;Korea, South;2;35-05N;128-05E;35-05N;128-05E;8;8; +RKPU;47;152;Ulsan;;Korea, South;2;35-33N;129-19E;;;32;33;P +RKSB;47;106;Tonghae Radar Site;;Korea, South;2;37-30N;129-08E;37-52N;126-48E;31;32;P +RKSC;--;---;Sv Ri San;;Korea, South;2;37-21N;126-55E;;;406;; +RKSD;--;---;Maesanri;;Korea, South;2;37-21N;127-16E;;;144;; +RKSF;47;117;Seoul / Yongdungp'O Rokaf Wc;;Korea, South;2;37-30N;126-56E;;;49;; +RKSG;47;127;Pyongtaek Ab;;Korea, South;2;36-56N;127-00E;;;16;16; +RKSH;--;---;Command Post Tango;;Korea, South;2;37-31N;126-59E;;;73;; +RKSI;47;113;Incheon International Airport;;Korea, South;2;37-28N;126-27E;;;7;; +RKSJ;--;---;Taesong-San;;Korea, South;2;38-12N;127-33E;;;1182;; +RKSL;47;108;Seoul;;Korea, South;2;37-34N;126-58E;;;86;87;P +RKSM;47;111;Seoul E Ab;;Korea, South;2;37-26N;127-07E;37-26N;127-07E;20;20; +RKSN;69;010;Koon-Ni Range;;Korea, South;2;37-02N;126-45E;;;15;; +RKSO;47;122;Osan Ab;;Korea, South;2;37-06N;127-02E;37-06N;127-02E;11;12; +RKSP;47;103;Paengnyongdo Ab;;Korea, South;2;37-58N;124-40E;37-58N;124-40E;171;177; +RKSQ;--;---;Yeonpyeungdo;;Korea, South;2;37-42N;125-42E;;;91;; +RKSS;47;110;Seoul / Kimp'O International Airport;;Korea, South;2;37-33N;126-48E;37-33N;126-48E;18;18; +RKST;--;---;Camp Casey / Tongduch;;Korea, South;2;37-55N;127-03E;;;60;; +RKSU;--;---;Yeoju Range;;Korea, South;2;37-26N;127-38E;37-26N;127-38E;43;43; +RKSV;--;---;Pyoripsan;;Korea, South;2;37-47N;126-22E;;;250;; +RKSW;47;120;Suwon Ab;;Korea, South;2;37-15N;127-00E;;;24;24; +RKSX;--;---;Camp Stanley / H-207;;Korea, South;2;37-43N;127-06E;;;71;; +RKSY;--;---;Yongsan / H-208 Hp;;Korea, South;2;37-31N;126-59E;;;12;; +RKTA;47;136;Andong;;Korea, South;2;36-33N;128-43E;;;139;142;P +RKTB;--;---;Paekado;;Korea, South;2;37-01N;126-03E;;;46;; +RKTD;47;132;Taejon Kor-Afb ;;Korea, South;2;36-20N;127-23E;;;63;; +RKTE;47;124;Songmu Ab;;Korea, South;2;36-24N;127-30E;;;79;79; +RKTF;47;133;Taejon;;Korea, South;2;36-18N;127-24E;;;77;78;P +RKTG;--;---;Camp Walker H-805 ;;Korea, South;2;35-51N;128-35E;;;75;; +RKTH;47;139;Pohang Ab;;Korea, South;2;35-59N;129-25E;35-59N;129-25E;20;20; +RKTI;47;125;Jung Won Rok-Ab ;;Korea, South;2;37-02N;127-53E;;;91;; +RKTM;47;126;Mangilsan Ab;;Korea, South;2;36-56N;126-27E;;;302;; +RKTN;47;142;Taegu Ab;;Korea, South;2;35-54N;128-39E;35-54N;128-39E;35;37; +RKTP;--;---;Hae Mi;;Korea, South;2;36-24N;126-21E;;;31;; +RKTS;--;---;Sangju;;Korea, South;2;36-25N;128-10E;;;150;; +RKTT;47;143;Taegu;;Korea, South;2;35-53N;128-37E;;;58;61;P +RKTU;47;128;Chongju Ab;;Korea, South;2;36-42N;127-30E;36-42N;127-30E;58;66; +RKTV;--;---;Chungju;;Korea, South;2;37-04N;127-53E;;;59;; +RKTW;--;---;Woong Cheon;;Korea, South;2;36-12N;126-33E;;;13;; +RKTY;47;134;Yechon Ab;;Korea, South;2;36-38N;128-21E;36-37N;128-21E;108;120; +RKXX;--;---;Nightmare Range;;Korea, South;2;38-04N;127-21E;;;;; +ROAH;47;930;Naha Airport;;Japan;2;26-11N;127-39E;;;3;6; +RODE;47;938;Iejima Auxiliary Ab;;Japan;2;26-43N;127-47E;26-43N;127-47E;70;73; +RODN;47;931;Kadena Ab;;Japan;2;26-21N;127-46E;26-21N;127-45E;45;48; +ROHF;47;935;Hamby U. S. Army Airfield;;Japan;2;26-18N;127-46E;;;5;6; +ROIG;47;918;Ishigakijima;;Japan;2;24-20N;124-10E;24-20N;124-10E;6;7;P +ROKJ;47;929;Kumejima;;Japan;2;26-20N;126-48E;;;4;5; +ROMD;47;945;Minamidaitojima;;Japan;2;25-50N;131-14E;25-50N;131-14E;16;20;P +ROMY;47;927;Miyakojima;;Japan;2;24-47N;125-17E;;;40;41;P +RORA;--;---;Aguni Island;;Japan;2;26-36N;127-14E;;;29;; +RORH;--;---;Hateruma;;Japan;2;24-04N;123-48E;;;13;; +RORK;--;---;Kitadaito Island;;Japan;2;25-55N;131-20E;;;22;; +RORS;--;---;Shimoji-Shima Island;;Japan;2;24-50N;125-09E;;;16;; +RORT;--;---;Tarama Island;;Japan;2;24-39N;124-42E;;;9;; +RORY;--;---;Yoron Island;;Japan;2;27-03N;128-24E;;;16;; +ROTM;47;933;Futenma Marine Corps Air Facility;;Japan;2;26-16N;127-45E;;;75;78; +ROYN;47;911;Yonaguni Airport;;Japan;2;24-28N;122-59E;;;16;19; +RPLB;98;426;Subic Bay Weather Station;;Philippines;5;14-48N;120-16E;14-48N;120-16E;18;19; +RPLC;--;---;Clarkfield Pampanga International Airport;;Philippines;5;15-11N;120-33E;;;148;; +RPLI;98;223;Laoag;;Philippines;5;18-11N;120-32E;18-11N;120-32E;4;5;P +RPLL;98;429;Ninoy Aquino Inter-National Airport;;Philippines;5;14-31N;121-00E;;;14;15;P +RPMD;98;753;Davao Airport;;Philippines;5;07-07N;125-39E;07-07N;125-39E;17;18;P +RPMK;98;327;Clark Ab;;Philippines;5;15-10N;120-34E;15-10N;120-34E;196;196; +RPMP;98;444;Legaspi;;Philippines;5;13-08N;123-44E;13-08N;123-44E;16;17;P +RPMR;98;536;Romblon;;Philippines;5;12-35N;122-16E;;;46;47;P +RPMS;98;428;Sangley Point;;Philippines;5;14-30N;120-55E;14-30N;120-55E;3;4; +RPMT;98;646;Mactan;;Philippines;5;10-18N;123-58E;10-18N;123-58E;23;24;P +RPMZ;98;836;Zamboanga;;Philippines;5;06-54N;122-04E;06-54N;122-04E;5;6;P +RPUA;98;232;Aparri;;Philippines;5;18-22N;121-38E;;;2;3;P +RPUB;98;328;Baguio;;Philippines;5;16-25N;120-36E;16-25N;120-36E;1500;1501;P +RPUD;98;440;Daet;;Philippines;5;14-08N;122-59E;;;3;4;P +RPUH;98;531;San Jose;;Philippines;5;12-21N;121-02E;;;2;3;P +RPUI;98;324;Iba;;Philippines;5;15-20N;119-58E;;;4;5; +RPUK;98;431;Calapan;;Philippines;5;13-25N;121-11E;;;39;41;P +RPUN;--;---;Naga / Luzon Island;;Philippines;5;13-35N;123-16E;;;43;; +RPUO;98;135;Basco;;Philippines;5;20-27N;121-58E;20-27N;121-58E;10;11;P +RPUQ;98;222;Vigan;;Philippines;5;17-34N;120-23E;;;31;33; +RPUR;98;333;Baler;;Philippines;5;15-46N;121-34E;;;4;6; +RPUT;98;233;Tuguegarao;;Philippines;5;17-37N;121-44E;;;61;62; +RPUV;98;446;Virac;;Philippines;5;13-35N;124-14E;;;39;40; +RPUW;--;---;Marinduque Island;;Philippines;5;13-22N;121-50E;;;5;; +RPVA;98;550;Tacloban;;Philippines;5;11-15N;125-00E;;;2;3;P +RPVD;98;642;Dumaguete;;Philippines;5;09-18N;123-18E;;;5;8; +RPVF;98;546;Catarman;;Philippines;5;12-29N;124-38E;;;4;5; +RPVG;98;558;Guiuan;;Philippines;5;11-02N;126-44E;11-02N;126-44E;56;60; +RPVI;98;637;Iloilo;;Philippines;5;10-42N;122-34E;;;7;8;P +RPVM;98;543;Masbate;;Philippines;5;12-22N;123-37E;;;6;6;P +RPVP;98;618;Puerto Princesa;;Philippines;5;09-45N;118-44E;09-45N;118-44E;14;16;P +RPVR;98;538;Roxas;;Philippines;5;11-35N;122-45E;;;3;4; +RPVT;98;644;Tagbilaran;;Philippines;5;09-36N;123-51E;;;7;8; +RPWB;98;851;Gen. Santos;;Philippines;5;06-07N;125-11E;;;14;15; +RPWC;98;746;Cotobato;;Philippines;5;07-10N;124-13E;;;58;62; +RPWE;98;752;Butuan;;Philippines;5;09-56N;125-31E;;;45;46; +RPWG;98;741;Dipolog;;Philippines;5;08-36N;123-21E;;;3;5;P +RPWL;98;748;Cagayan De Oro;;Philippines;5;08-29N;124-38E;;;5;6; +RPWS;98;653;Surigao;;Philippines;5;09-48N;125-30E;09-48N;125-30E;54;55;P +RPWY;98;751;Malaybalay;;Philippines;5;08-09N;125-05E;;;626;627; +RPXT;98;435;Alabat;;Philippines;5;14-05N;122-01E;;;4;5; +SAAC;87;395;Concordia Aerodrome;;Argentina;3;31-18S;058-01W;;;35;38;P +SAAG;87;497;Gualeguaychu Aerodrome;;Argentina;3;33-00S;058-37W;;;23;21;P +SAAJ;87;548;Junin Aerodrome;;Argentina;3;34-33S;060-55W;;;82;81;P +SAAP;87;374;Parana Aerodrome;;Argentina;3;31-47S;060-29W;;;74;78;P +SAAR;87;480;Rosario Aerodrome;;Argentina;3;32-55S;060-47W;;;25;25;P +SAAU;87;385;Villaguay Aerodrome;;Argentina;3;31-51S;059-05W;;;40;43; +SAAV;87;371;Sauce Viejo Aerodrome;;Argentina;3;31-42S;060-49W;;;17;18; +SABA;87;585;Buenos Aires Observatorio;;Argentina;3;34-35S;058-29W;;;25;25; +SABE;87;582;Aeroparque Bs. As. Aerodrome;;Argentina;3;34-34S;058-25W;;;6;6; +SACI;87;349;Pilar Observatorio;;Argentina;3;31-40S;063-53W;;;338;338; +SACO;87;344;Cordoba Aerodrome;;Argentina;3;31-19S;064-13W;31-19S;064-13W;484;474;P +SACP;87;322;Chepes;;Argentina;3;31-20S;066-36W;;;658;658; +SACT;--;---;Gobernador Gordillo;;Argentina;3;30-22S;066-18W;;;457;; +SACV;87;244;Villa De Maria Del Rio Seco;;Argentina;3;29-54S;063-41W;;;341;341;P +SADD;87;568;Don Torcuato Aerodrome;;Argentina;3;34-29S;058-37W;;;5;4; +SADF;--;---;San Fernando, BA;;Argentina;3;34-27-11S;058-35-23W;;;3;; +SADL;87;593;La Plata Aerodrome;;Argentina;3;34-58S;057-54W;;;21;19; +SADP;87;571;El Palomar Aerodrome;;Argentina;3;34-36S;058-36W;;;18;12; +SAEZ;87;576;Ezeiza Aerodrome;;Argentina;3;34-49S;058-32W;34-49S;058-32W;20;20;P +SAME;87;418;Mendoza Aerodrome;;Argentina;3;32-50S;068-47W;32-50S;068-47W;705;704;P +SAMI;87;416;San Martin;;Argentina;3;33-05S;068-25W;;;653;653; +SAMJ;87;305;Jachal;;Argentina;3;30-15S;068-45W;;;1165;1165; +SAMM;87;506;Malargue Aerodrome;;Argentina;3;35-30S;069-35W;;;1426;1425;P +SAMR;87;509;San Rafael Aerodrome;;Argentina;3;34-35S;068-24W;34-35S;068-24W;745;748;P +SAMS;87;412;San Carlos;;Argentina;3;33-46S;069-02W;;;940;940; +SAMU;87;405;Uspallata;;Argentina;3;32-36S;069-20W;;;1844;1891; +SANC;87;222;Catamarca Aero.;;Argentina;3;28-36S;065-46W;;;454;454;P +SANE;87;129;Santiago Del Estero Aero.;;Argentina;3;27-46S;064-18W;;;198;199;P +SANI;87;211;Tinogasta;;Argentina;3;28-04S;067-34W;;;1201;1201; +SANL;87;217;La Rioja Aero.;;Argentina;3;29-23S;066-49W;;;438;429;P +SANO;87;214;Chilecito;;Argentina;3;29-13S;067-26W;;;950;; +SANT;87;121;Tucuman Aerodrome;;Argentina;3;26-51S;065-06W;;;440;450;P +SANU;87;311;San Juan Aerodrome;;Argentina;3;31-34S;068-52W;;;597;598;P +SANW;87;257;Ceres Aerodrome;;Argentina;3;29-53S;061-57W;29-53S;061-57W;87;88;P +SAOC;87;453;Rio Cuarto Aerodrome;;Argentina;3;33-07S;064-14W;;;420;421;P +SAOD;87;328;Villa Dolores Aerodrome;;Argentina;3;31-57S;065-08W;;;561;569; +SAOL;87;534;Laboulaye;;Argentina;3;34-08S;063-22W;34-08S;063-22W;136;137; +SAOM;87;467;Marcos Juarez Aerodrome;;Argentina;3;32-42S;062-09W;;;110;114;P +SAOR;87;448;Villa Reynolds Aerodrome;;Argentina;3;33-44S;065-23W;;;485;486; +SAOU;87;436;San Luis Aerodrome;;Argentina;3;33-16S;066-21W;33-16S;066-21W;710;713;P +SARC;87;166;Corrientes Aero.;;Argentina;3;27-27S;058-46W;;;62;62; +SARE;87;155;Resistencia Aero.;;Argentina;3;27-27S;059-03W;27-27S;059-03W;53;52;P +SARF;87;162;Formosa Aerodrome;;Argentina;3;26-12S;058-14W;;;59;60;P +SARI;87;097;Iguazu Aerodrome;;Argentina;3;25-44S;054-28W;;;270;270;P +SARL;87;289;Paso De Los Libres Aerodrome;;Argentina;3;29-41S;057-09W;;;69;70;P +SARM;87;393;Monte Caseros Aerodrome;;Argentina;3;30-16S;057-39W;30-16S;057-39W;53;54; +SARP;87;178;Posadas Aero.;;Argentina;3;27-22S;055-58W;27-22S;055-58W;131;133;P +SARS;87;149;Presidencia Roque Saenz Pena Aerodrome;;Argentina;3;26-49S;060-27W;;;91;92;P +SASA;87;047;Salta Aerodrome;;Argentina;3;24-51S;065-29W;24-51S;065-29W;1238;1221;P +SASJ;87;046;Jujuy Aerodrome;;Argentina;3;24-23S;065-05W;;;921;905;P +SASO;87;016;Oran Aerodrome;;Argentina;3;23-09S;064-19W;;;357;357; +SASQ;87;007;La Quiaca Observatorio;;Argentina;3;22-06S;065-36W;;;3462;3459; +SASR;87;065;Rivadavia;;Argentina;3;24-10S;062-54W;;;205;205; +SAST;87;022;Tartagal Aerodrome;;Argentina;3;22-39S;063-49W;;;450;450;P +SATK;87;078;Las Lomitas;;Argentina;3;24-42S;060-35W;24-42S;060-35W;130;130;P +SATR;--;---;Reconquista, SF;;Argentina;3;29-12-37S;059-41-27W;;;49;; +SATU;87;286;Curuzu Cuatia Aerodrome;;Argentina;3;29-47S;057-59W;;;80;73; +SAVB;87;800;El Bolson Aerodrome;;Argentina;3;41-58S;071-31W;;;337;337; +SAVC;87;860;Comodoro Rivadavia Aerodrome;;Argentina;3;45-47S;067-30W;45-47S;067-27W;58;46;P +SAVE;87;803;Esquel Aerodrome;;Argentina;3;42-56S;071-09W;;;789;785;P +SAVO;87;784;San Antonio Oeste Aerodrome;;Argentina;3;40-47S;065-06W;;;20;20;P +SAVP;87;814;Paso De Indios;;Argentina;3;43-49S;068-53W;;;460;460; +SAVT;87;828;Trelew Aerodrome;;Argentina;3;43-12S;065-16W;;;39;43;P +SAVV;87;791;Viedma Aerodrome;;Argentina;3;40-51S;063-01W;;;6;7;P +SAVY;--;---;Puerto Madryn, CHT;;Argentina;3;42-45-33S;065-06-10W;;;136;; +SAWA;87;903;Lago Argentino Aerodrome;;Argentina;3;50-20S;072-18W;;;223;220;P +SAWD;87;896;Puerto Deseado Aerodrome;;Argentina;3;47-44S;065-55W;47-44S;065-55W;81;80; +SAWE;87;934;Rio Grande B. A.;;Argentina;3;53-48S;067-45W;53-48S;067-45W;13;22; +SAWG;87;925;Rio Gallegos Aerodrome;;Argentina;3;51-37S;069-17W;;;20;19;P +SAWH;87;938;Ushuaia Aerodrome;;Argentina;3;54-48S;068-19W;54-48S;068-19W;16;14;P +SAWJ;87;909;San Julian Aerodrome;;Argentina;3;49-19S;067-45W;;;58;62;P +SAWP;87;852;Perito Moreno Aerodrome;;Argentina;3;46-31S;071-01W;;;429;429;P +SAWR;87;880;Gobernador Gregores Aerodrome;;Argentina;3;48-47S;070-10W;;;358;357; +SAWU;87;912;Santa Cruz Aerodrome;;Argentina;3;50-01S;068-34W;;;113;111; +SAZA;87;642;Azul Airport;;Argentina;3;36-45S;059-50W;36-44S;059-50W;132;132; +SAZB;87;750;Bahia Blanca Aerodrome;;Argentina;3;38-44S;062-10W;;;75;83;P +SAZD;87;648;Dolores Aerodrome;;Argentina;3;36-21S;057-44W;;;10;9;P +SAZE;87;679;Pigue Aerodrome;;Argentina;3;37-36S;062-23W;;;304;304; +SAZG;87;532;General Pico Aerodrome;;Argentina;3;35-42S;063-45W;;;139;145; +SAZH;87;688;Tres Arroyos;;Argentina;3;38-20S;060-15W;;;115;115;P +SAZM;87;692;Mar Del Plata Aerodrome;;Argentina;3;37-56S;057-35W;37-56S;057-35W;18;21;P +SAZN;87;715;Neuquen Aerodrome;;Argentina;3;38-57S;068-08W;38-57S;068-08W;270;271;P +SAZP;87;544;Pehuajo Aerodrome;;Argentina;3;35-52S;061-54W;;;87;86; +SAZQ;87;736;Rio Colorado;;Argentina;3;39-01S;064-05W;;;79;79; +SAZR;87;623;Santa Rosa Aerodrome;;Argentina;3;36-34S;064-16W;36-34S;064-16W;190;191;P +SAZS;87;765;Bariloche Aerodrome;;Argentina;3;41-09S;071-10W;;;845;840;P +SAZT;87;645;Tandil Aerodrome;;Argentina;3;37-14S;059-15W;;;175;175;P +SAZV;87;663;Villa Gesell;;Argentina;3;37-14S;057-02W;;;7;; +SAZY;87;761;Chapelco;;Argentina;3;40-05S;071-08W;;;779;; +SBAA;82;861;Conceicao Do Araguaia;;Brazil;3;08-15S;049-17W;;;157;; +SBAF;83;748;Afonsos Aeroporto ;;Brazil;3;22-52S;043-22W;;;34;; +SBAN;83;419;Anapolis Braz-Afb ;;Brazil;3;16-14S;048-58W;;;1137;; +SBAR;83;095;Aracaju Aeroporto ;;Brazil;3;10-59S;037-04W;;;8;9; +SBAT;82;965;Alta Floresta Aeroporto ;;Brazil;3;09-52S;056-06W;09-52S;056-06W;288;288; +SBBC;82;410;Benjamin Constant;;Brazil;3;04-23S;070-02W;;;65;; +SBBE;82;193;Belem Aeroporto ;;Brazil;3;01-23S;048-29W;01-23S;048-29W;16;16; +SBBG;83;981;Bage Aeroporto ;;Brazil;3;31-21S;054-07W;31-21S;054-07W;180;180; +SBBH;83;583;Belo Horizonte Aeroporto ;;Brazil;3;19-51S;043-57W;19-51S;043-57W;785;785; +SBBI;83;842;Curitiba;;Brazil;3;25-26S;049-16W;;;924;; +SBBQ;83;689;Barbacena;;Brazil;3;21-15S;043-46W;;;1171;1171; +SBBR;83;378;Brasilia Aeroporto ;;Brazil;3;15-52S;047-56W;15-52S;047-56W;1061;1061; +SBBU;83;722;Bauru;;Brazil;3;22-19S;049-04W;;;590;; +SBBV;82;022;Boa Vista Aeropor-To ;;Brazil;3;02-50N;060-42W;02-50N;060-42W;140;140; +SBBW;83;359;Barra Do Garcas;;Brazil;3;15-52S;052-23W;;;350;350; +SBCC;--;---;Cachimbo;;Brazil;3;09-20S;054-57W;;;536;; +SBCF;83;587;Belo Horizonte;;Brazil;3;19-56S;043-56W;;;850;; +SBCG;83;612;Campo Grande Aeroporto ;;Brazil;3;20-28S;054-40W;20-28S;054-40W;567;567; +SBCI;82;764;Maranhao / Carolina Airport;;Brazil;3;07-19S;047-28W;;;183;; +SBCJ;--;---;Carajas / Maraba;;Brazil;3;06-07S;050-00W;;;621;; +SBCO;83;967;Porto Alegre;;Brazil;3;30-01S;051-13W;;;47;; +SBCP;83;698;Campos;;Brazil;3;21-45S;041-20W;21-45S;041-20W;11;11; +SBCR;83;552;Corumba;;Brazil;3;19-05S;057-30W;;;130;; +SBCT;83;840;Curitiba Aeroporto ;;Brazil;3;25-31S;049-10W;25-31S;049-10W;908;908; +SBCV;83;497;Caravelas Aeropor-To ;;Brazil;3;17-38S;039-15W;17-38S;039-15W;4;4; +SBCY;83;362;Cuiaba Aeroporto ;;Brazil;3;15-39S;056-06W;15-39S;056-06W;187;182; +SBCZ;82;704;Cruzeiro Do Sul;;Brazil;3;07-38S;072-40W;;;170;; +SBDN;83;716;Presidente Prudente;;Brazil;3;22-07S;051-23W;;;436;; +SBEG;82;111;Eduardo Gomes International;;Brazil;3;03-02S;060-03W;;;2;; +SBEK;82;640;Jacareacanga;;Brazil;3;06-16S;057-44W;06-16S;057-44W;98;98; +SBES;83;759;S. P. Aldeia Aerodrome ;;Brazil;3;22-49S;042-06W;;;10;11; +SBFI;83;827;Foz Do Iguacu Aeroporto ;;Brazil;3;25-31S;054-35W;25-31S;054-35W;180;180; +SBFL;83;899;Florianopolis Aeroporto ;;Brazil;3;27-40S;048-33W;27-40S;048-33W;5;5; +SBFN;82;400;Fernando De Noronha;;Brazil;3;03-51S;032-25W;03-51S;032-25W;56;45; +SBFZ;82;398;Fortaleza Aeropor-To ;;Brazil;3;03-47S;038-32W;03-47S;038-32W;25;25; +SBGA;83;375;Gama;;Brazil;3;16-03S;048-03W;;;700;; +SBGL;83;746;Galeao;;Brazil;3;22-49S;043-15W;22-49S;043-15W;6;42; +SBGO;83;424;Goiania Aeroporto ;;Brazil;3;16-38S;049-13W;;;747;; +SBGR;--;---;Guarulhos Civ / Mil ;;Brazil;3;23-26S;046-28W;;;750;; +SBGW;83;708;Guaratingueta;;Brazil;3;22-47S;045-12W;;;537;537; +SBHT;82;353;Altamira;;Brazil;3;03-12S;052-12W;;;74;; +SBIH;82;444;Itaituba;;Brazil;3;04-15S;056-00W;;;34;; +SBIL;83;349;Ilheus Aeroporto ;;Brazil;3;14-49S;039-02W;;;4;; +SBIZ;82;564;Imperatriz;;Brazil;3;05-32S;047-30W;;;123;; +SBJF;83;692;Juiz De Fora;;Brazil;3;21-46S;043-21W;;;939;939; +SBJP;82;798;Joao Pessoa;;Brazil;3;07-06S;034-52W;;;7;; +SBJR;83;111;Rio / Jacarepagua;;Brazil;3;22-59S;043-22W;;;3;; +SBKG;82;795;Campina Grande;;Brazil;3;07-13S;035-53W;;;548;; +SBKP;83;721;Campinas Aeroporto ;;Brazil;3;23-00S;047-08W;23-00S;047-08W;661;661; +SBLO;83;768;Londrina Aeroporto ;;Brazil;3;23-20S;051-08W;23-20S;051-08W;569;570; +SBLP;83;288;Bom Jesus Da Lapa;;Brazil;3;13-16S;043-25W;13-16S;043-25W;440;440; +SBMA;82;562;Maraba;;Brazil;3;05-21S;049-09W;;;95;; +SBME;--;---;Macae;;Brazil;3;22-21S;041-46W;;;2;; +SBMG;83;767;Maringa;;Brazil;3;23-25S;051-57W;;;542;542; +SBMK;83;437;Montes Claros;;Brazil;3;16-43S;043-52W;16-44S;043-52W;646;647; +SBMN;82;332;Manaus Aeroporto ;;Brazil;3;03-09S;059-59W;03-09S;059-59W;84;84; +SBMO;82;993;Maceio Aeroporto ;;Brazil;3;09-31S;035-47W;09-31S;035-47W;117;115; +SBMQ;82;098;Macapa;;Brazil;3;00-02N;050-03W;;;15;; +SBMS;82;591;Mocoro / 17 Rosado;;Brazil;3;05-12S;037-22W;;;23;; +SBMT;83;779;Marte Civ / Mil ;;Brazil;3;23-31S;046-38W;;;722;; +SBMY;82;533;Manicore;;Brazil;3;05-49S;061-18W;;;50;; +SBNT;82;599;Natal Aeroporto;;Brazil;3;05-55S;035-15W;05-55S;035-15W;52;49; +SBOI;82;017;Oiapoque;;Brazil;3;03-50N;051-50W;;;39;39; +SBPA;83;971;Porto Alegre Aero-Porto ;;Brazil;3;30-00S;051-11W;30-00S;051-11W;3;3; +SBPB;82;288;Parnaiba Aeroporto ;;Brazil;3;02-55S;041-45W;;;5;; +SBPC;83;681;Pocos De Caldas;;Brazil;3;21-51S;046-34W;;;1260;; +SBPF;83;914;Passo Fundo;;Brazil;3;28-15S;052-24W;;;684;; +SBPG;83;844;Paranagua;;Brazil;3;25-31S;048-31W;;;5;; +SBPK;83;985;Pelotas;;Brazil;3;31-52S;052-21W;;;13;13; +SBPL;82;984;Petrolina Aeropor-To ;;Brazil;3;09-21S;040-33W;;;375;; +SBPN;83;063;Porto Nacional Aeroporto ;;Brazil;3;10-42S;048-24W;10-42S;048-24W;261;290; +SBPP;83;703;Ponta Pora Aeropor-To ;;Brazil;3;22-33S;055-42W;;;660;; +SBPS;--;---;Porto Seguro;;Brazil;3;16-26S;039-04W;;;51;; +SBPV;82;824;Porto Velho Aeroporto ;;Brazil;3;08-46S;063-55W;08-46S;063-55W;102;102; +SBQV;83;344;Vitoria Da Conquista;;Brazil;3;14-57S;040-53W;14-51S;040-50W;840;1042; +SBRB;82;917;Rio Branco;;Brazil;3;10-00S;067-48W;;;142;143; +SBRF;82;899;Recife Aeroporto ;;Brazil;3;08-04S;034-51W;;;19;; +SBRJ;83;755;Rio De Janeiro Aeroporto ;;Brazil;3;22-54S;043-10W;;;3;; +SBRP;--;---;Leite Lopes / Ribeir ;;Brazil;3;21-08S;047-47W;;;549;; +SBRS;83;738;Resende;;Brazil;3;22-29S;044-28W;;;440;; +SBSA;83;726;Sao Carlos;;Brazil;3;22-01S;047-53W;;;856;; +SBSC;83;741;Santa Cruz Aeropor-To ;;Brazil;3;22-56S;043-43W;22-56S;043-43W;3;3; +SBSJ;--;---;Sao Jose Dos Campo ;;Brazil;3;23-14S;045-52W;;;646;; +SBSL;82;281;Sao Luiz Aeroporto ;;Brazil;3;02-36S;044-14W;02-36S;044-14W;53;53; +SBSM;83;937;Santa Maria Aero-Porto ;;Brazil;3;29-43S;053-42W;;;85;; +SBSN;82;244;Santarem-Aeroporto;;Brazil;3;02-26S;054-43W;02-26S;054-43W;72;72; +SBSP;83;780;Sao Paulo/Congonhas Aeroporto;;Brazil;3;23-37S;046-39W;23-37S;046-39W;803;802; +SBST;83;818;Santos Aeroporto ;;Brazil;3;23-56S;046-18W;;;3;3; +SBSV;83;248;Salvador Aeroporto ;;Brazil;3;12-54S;038-20W;12-56S;038-21W;6;13; +SBTE;82;579;Teresina Aeroporto ;;Brazil;3;05-03S;042-49W;05-03S;042-49W;69;69; +SBTF;82;317;Tefe;;Brazil;3;03-22S;064-41W;;;47;47; +SBTK;82;807;Tarauaca;;Brazil;3;08-10S;070-46W;;;190;; +SBTT;82;411;Tabatinga;;Brazil;3;03-40S;069-40W;;;85;; +SBTU;82;361;Tucurui;;Brazil;3;03-43S;049-43W;;;40;; +SBUA;82;106;Sao Gabriel Da Cachoeira;;Brazil;3;00-08S;067-05W;;;90;; +SBUF;82;986;Paulo Afonso;;Brazil;3;09-24S;038-13W;;;253;; +SBUG;83;928;Uruguaiana Aeroporto ;;Brazil;3;29-47S;057-02W;29-47S;057-02W;74;74; +SBUL;--;---;Uberlandia ;;Brazil;3;18-53S;048-14W;;;943;; +SBUR;83;576;Uberaba;;Brazil;3;19-47S;047-58W;19-46S;047-57W;807;809; +SBVH;83;208;Vilhena Aeroporto ;;Brazil;3;12-42S;060-06W;12-44S;060-08W;612;652; +SBVT;83;649;Vitoria Aeroporto ;;Brazil;3;20-16S;040-17W;20-16S;040-17W;4;4; +SBXV;83;319;Xavantina ;;Brazil;3;14-42S;052-21W;;;315;; +SBYA;82;067;Iauarete;;Brazil;3;00-37N;069-12W;;;120;; +SBYS;83;671;Pirassununga;;Brazil;3;21-59S;047-20W;21-59S;047-21W;597;598; +SCAR;85;406;Arica;;Chile;3;18-20S;070-20W;18-21S;070-21W;58;58;P +SCBA;85;874;Balmaceda;;Chile;3;45-55S;071-41W;45-54S;071-43W;520;520;P +SCCC;85;886;Chile Chico;;Chile;3;46-33S;071-42W;;;325;325;P +SCCH;85;672;Chillan;;Chile;3;36-34S;072-02W;36-34S;072-02W;124;148;P +SCCI;85;934;Punta Arenas;;Chile;3;53-00S;070-51W;53-02S;070-51W;37;33;P +SCCY;85;864;Coyhaique;;Chile;3;45-35S;072-07W;;;310;;P +SCDA;85;418;Iquique / Diego Arac;;Chile;3;20-32S;070-11W;;;52;; +SCEL;85;574;Pudahuel;;Chile;3;33-23S;070-47W;33-23S;070-47W;475;476;P +SCER;85;543;Quintero Santiago;;Chile;3;32-47S;071-31W;32-47S;071-31W;8;8;P +SCFA;85;442;Antofagasta;;Chile;3;23-26S;070-26W;23-25S;070-28W;135;137;P +SCHA;85;470;Copiapo;;Chile;3;27-18S;070-25W;27-18S;070-25W;291;291;P +SCHR;85;892;Cochrane;;Chile;3;47-14S;072-33W;;;167;167;P +SCIC;85;629;Curico;;Chile;3;34-58S;071-14W;;;228;;P +SCIE;85;682;Concepcion;;Chile;3;36-46S;073-03W;;;12;;P +SCIP;85;469;Isla De Pascua;;Chile;3;27-09S;109-25W;27-10S;109-26W;51;41;P +SCLL;85;486;Vallenar;;Chile;3;28-36S;070-46W;;;538;526;P +SCRA;85;460;Chanaral;;Chile;3;26-19S;070-37W;26-19S;070-37W;30;30;P +SCSE;85;488;La Serena;;Chile;3;29-54S;071-12W;;;142;;P +SCTC;85;743;Temuco;;Chile;3;38-45S;072-38W;;;114;;P +SCTE;85;799;Puerto Montt;;Chile;3;41-25S;073-05W;41-26S;073-07W;85;84;P +SCVD;85;766;Valdivia;;Chile;3;39-37S;073-05W;;;19;;P +SEAM;84;147;Ambato / Chachoan;;Ecuador;3;01-12S;078-34W;;;2520;; +SEBC;84;101;Bahia De Caraquez;;Ecuador;3;00-35S;080-24W;;;3;; +SECU;84;239;Cuenca / Mariscal Lamar;;Ecuador;3;02-53S;078-59W;02-53S;078-58W;2530;2531;P +SEES;84;018;Esmeraldas-Tachina;;Ecuador;3;00-58N;079-38W;00-59N;079-39W;7;8;P +SEGU;84;203;Guayaquil / Simon Bolivar;;Ecuador;3;02-09S;079-53W;02-09S;079-53W;4;9;P +SEIB;84;043;Ibarra / Atahualpa;;Ecuador;3;00-21N;078-08W;;;2228;; +SELO;84;265;Catamayo / Camilo Ponce Enriquez;;Ecuador;3;04-00S;079-22W;;;1239;1238;P +SELT;84;123;Latacunga;;Ecuador;3;00-55S;078-37W;;;2785;; +SEMA;84;279;Macara / J. M. Velasco I.;;Ecuador;3;04-22S;079-56W;;;430;; +SEMH;84;248;Machala / General M. Serrano;;Ecuador;3;03-15S;079-58W;;;4;10; +SEMT;84;117;Manta;;Ecuador;3;00-57S;080-41W;;;13;14;P +SEPA;84;163;Pastaza / Rio Amazonas;;Ecuador;3;01-30S;078-03W;;;1043;1054;P +SEQU;84;071;Quito / Mariscal Sucre;;Ecuador;3;00-09S;078-29W;00-08S;078-29W;2811;2812;P +SESA;84;200;Salinas / General Ulpiano Paez;;Ecuador;3;02-12S;080-59W;;;4;8;P +SEST;84;008;San Cristobal Galapagos ;;Ecuador;3;00-54S;089-36W;00-54S;089-37W;6;6;P +SETI;84;131;Tiputini ;;Ecuador;3;00-47S;075-31W;;;220;; +SETU;84;027;Tulcan / El Rosal;;Ecuador;3;00-49N;077-42W;;;2950;; +SFAL;88;891;Stanley Airport;;Falkland Islands, Islas Malvinas;3;51-41S;057-46W;;;23;; +SGAS;86;218;Asuncion / Aeropuerto;;Paraguay;3;25-16S;057-38W;25-16S;057-38W;101;101; +SGCO;86;134;Concepcion;;Paraguay;3;23-25S;057-18W;;;74;74; +SGEN;86;297;Encarnacion;;Paraguay;3;27-19S;055-50W;;;91;91; +SGES;--;---;Aeropuerto Guarany;;Paraguay;3;25-27S;054-51W;;;849;; +SGME;86;068;Mariscal Estigarribia;;Paraguay;3;22-01S;060-36W;;;172;181; +SGNA;86;017;Nueva Asuncion;;Paraguay;3;20-43S;061-55W;20-43S;061-55W;318;315; +SKAR;80;211;Armenia / El Eden;;Colombia;3;04-30N;075-43W;;;1204;1219;P +SKAS;80;372;Puerto Asis;;Colombia;3;00-30N;076-30W;;;254;;P +SKBG;80;094;Bucaramanga / Palonegro;;Colombia;3;07-06N;073-12W;;;1189;;P +SKBO;80;222;Bogota / Eldorado;;Colombia;3;04-43N;074-09W;04-42N;074-09W;2547;2548;P +SKBQ;80;028;Barranquilla / Ernestocortissoz;;Colombia;3;10-53N;074-47W;10-54N;074-46W;14;30;P +SKBU;80;252;Buenaventura;;Colombia;3;03-51N;076-58W;;;14;15;P +SKCC;80;097;Cucuta / Camilo Daza;;Colombia;3;07-56N;072-31W;;;250;317;P +SKCG;80;022;Cartagena / Rafael Nunez;;Colombia;3;10-27N;075-31W;;;1;12;P +SKCL;80;259;Cali / Alfonso Bonillaaragon;;Colombia;3;03-33N;076-23W;03-33N;076-23W;961;969;P +SKEJ;80;091;Barrancabermeja / Yariguies;;Colombia;3;07-01N;073-48W;;;126;134;P +SKIB;80;214;Ibague / Perales;;Colombia;3;04-26N;075-09W;;;928;;P +SKIP;80;370;Ipiales / San Luis;;Colombia;3;00-49N;077-38W;;;2961;;P +SKLC;80;084;Apartado / Los Cedros;;Colombia;3;07-49N;076-42W;;;20;;P +SKLT;80;398;Leticia / Vasquez Cobo;;Colombia;3;04-10S;069-57W;04-10S;069-57W;84;84;P +SKMD;80;110;Medellin / Olaya Herrera;;Colombia;3;06-13N;075-36W;;;1490;1499;P +SKMR;80;063;Monteria / Los Garzones;;Colombia;3;08-49N;075-51W;;;20;26;P +SKMU;80;361;Mitu;;Colombia;3;01-08N;070-03W;;;207;; +SKNV;80;315;Neiva / Benito Salas;;Colombia;3;02-58N;075-18W;;;439;443;P +SKPC;80;139;Puerto Carreno / A. Guauquea;;Colombia;3;06-10N;067-30W;;;55;;P +SKPE;80;210;Pereira / Matecana;;Colombia;3;04-49N;075-44W;;;1342;1342;P +SKPP;80;308;Popayan / Guillermo;;Colombia;3;02-28N;076-36W;02-27N;076-36W;1730;1730; +SKPS;80;342;Pasto / Antonio Narin;;Colombia;3;01-25N;077-16W;;;1826;; +SKPV;80;002;Providencia Isla / El Embrujo;;Colombia;4;13-22N;081-21W;;;6;;P +SKRG;80;112;Rionegro / J. M. Cordova;;Colombia;3;06-08N;075-26W;;;2140;2142;P +SKRH;80;035;Riohacha / Almirante Padilla;;Colombia;3;11-32N;072-56W;11-32N;072-56W;4;4;P +SKSJ;80;322;San Jose Del Guaviare;;Colombia;3;02-34N;072-38W;;;155;155;P +SKSM;80;009;Santa Marta / Simon Bolivar;;Colombia;3;11-08N;074-14W;;;4;14;P +SKSP;80;001;San Andres Isla / Sesquicentenario;;Colombia;4;12-35N;081-43W;12-35N;081-42W;1;6;P +SKUC;80;099;Arauca / Santiago Perez;;Colombia;3;07-04N;070-44W;;;128;128;P +SKUI;80;144;Quibdo / El Carano;;Colombia;3;05-43N;076-37W;;;53;;P +SKVP;80;036;Valledupar / Alfonso Lopez;;Colombia;3;10-26N;073-15W;;;138;;P +SKVV;80;234;Villavicencio / Vanguardia;;Colombia;3;04-10N;073-37W;;;423;431;P +SLAP;85;151;Apolo;;Bolivia;3;14-44S;068-30W;;;1415;; +SLAS;85;175;Ascencion De Guarayos;;Bolivia;3;15-43S;063-06W;;;247;; +SLCA;85;315;Camiri;;Bolivia;3;20-00S;063-32W;;;798;;P +SLCB;85;223;Cochabamba;;Bolivia;3;17-25S;066-11W;17-23S;066-10W;2548;2570;P +SLCN;85;230;Charana;;Bolivia;3;17-35S;069-36W;;;4054;;P +SLCO;85;041;Cobija;;Bolivia;3;11-02S;068-47W;11-01S;068-47W;235;260;P +SLCP;85;196;Concepcion;;Bolivia;3;16-09S;062-01W;;;497;; +SLET;85;245;Santa Cruz / El Trompillo;;Bolivia;3;17-48S;063-11W;17-48S;063-10W;418;414;P +SLGY;85;033;Guayaramerin;;Bolivia;3;10-49S;065-21W;;;130;; +SLJE;85;247;San Jose De Chiquitos;;Bolivia;3;17-48S;060-44W;;;284;;P +SLJO;85;104;San Joaquin;;Bolivia;3;13-04S;064-49W;;;140;;P +SLJV;85;195;San Javier;;Bolivia;3;16-16S;062-28W;;;534;; +SLLP;85;201;La Paz / Alto;;Bolivia;3;16-31S;068-11W;16-30S;068-11W;4058;4038;P +SLMG;85;114;Magdalena;;Bolivia;3;13-20S;064-07W;;;140;; +SLOR;85;242;Oruro;;Bolivia;3;17-58S;067-04W;;;3072;;P +SLPO;85;293;Potosi;;Bolivia;3;19-33S;065-44W;;;3935;; +SLPS;85;289;Puerto Suarez;;Bolivia;3;18-59S;057-49W;;;134;;P +SLRB;85;268;Robore;;Bolivia;3;18-19S;059-46W;;;276;;P +SLRI;85;043;Riberalta;;Bolivia;3;11-00S;066-07W;;;141;;P +SLRQ;85;141;Rurrenabaque;;Bolivia;3;14-28S;067-34W;14-28S;067-35W;204;274;P +SLRY;85;140;Reyes;;Bolivia;3;14-19S;067-23W;;;140;; +SLSA;85;123;Santa Ana;;Bolivia;3;13-46S;065-26W;;;144;; +SLSB;85;152;San Borja;;Bolivia;3;14-52S;066-52W;;;194;; +SLSI;85;207;San Ignacio De Velasco;;Bolivia;3;16-23S;060-58W;;;413;;P +SLSM;85;153;San Ignacio De Moxos;;Bolivia;3;14-55S;065-36W;;;160;; +SLSU;85;283;Sucre;;Bolivia;3;19-01S;065-18W;;;2904;; +SLTJ;85;364;Tarija;;Bolivia;3;21-33S;064-42W;;;1854;; +SLTR;85;154;Trinidad;;Bolivia;3;14-49S;064-55W;14-45S;064-48W;155;236;P +SLVM;85;345;Villamontes;;Bolivia;3;21-15S;063-27W;;;398;; +SLVR;85;244;Viru-Viru;;Bolivia;3;17-38S;063-08W;;;373;;P +SLYA;85;365;Yacuiba;;Bolivia;3;21-57S;063-39W;;;645;;P +SMJP;--;---;Johan A. Pengel;;Suriname;3;05-27N;055-11W;;;16;; +SMZY;81;225;Zanderij;;Suriname;3;05-27N;055-12W;05-27N;055-12W;15;15;P +SOCA;81;405;Cayenne / Rochambeau;;French Guiana;3;04-50N;052-22W;04-50N;052-22W;105;9;P +SOOM;81;401;Saint-Laurent-Du-Maroni;;French Guiana;3;05-30N;054-02W;05-30N;054-02W;4;9;P +SPAY;84;593;Atalaya;;Peru;3;10-44S;073-47W;;;450;451; +SPCL;84;515;Pucallpa;;Peru;3;08-25S;074-36W;08-22S;074-35W;148;149; +SPEO;84;531;Chimbote;;Peru;3;09-10S;078-31W;;;20;21; +SPGM;84;534;Tingo Maria;;Peru;3;09-08S;075-57W;;;664;665; +SPHI;84;452;Chiclayo;;Peru;3;06-47S;079-50W;06-47S;079-50W;29;34; +SPHO;84;673;Ayacucho;;Peru;3;13-08S;074-13W;;;2740;2749; +SPHY;84;688;Andahuayla;;Peru;3;13-43S;073-21W;;;3444;; +SPHZ;84;542;Anta Huaraz ;;Peru;3;09-21S;077-36W;;;2750;2760; +SPIM;84;628;Lima-Callao / Aerop. Internacional Jorgechavez;;Peru;3;12-00S;077-07W;12-01S;077-02W;12;13; +SPJA;84;440;Rioja;;Peru;3;06-03S;077-09W;;;792;; +SPJI;84;474;Juanjui;;Peru;3;07-13S;076-43W;;;350;363; +SPJL;84;735;Juliaca;;Peru;3;15-29S;070-09W;;;3826;3827; +SPJN;84;721;San Juan;;Peru;3;15-23S;075-10W;;;60;60; +SPJR;84;472;Cajamarca;;Peru;3;07-08S;078-28W;;;2620;2622; +SPME;84;370;Tumbes;;Peru;3;03-33S;080-24W;;;25;27; +SPMS;84;425;Yurimaguas;;Peru;3;05-54S;076-05W;;;179;184; +SPNC;84;564;Huanuco;;Peru;3;09-54S;075-45W;;;1859;1860; +SPPY;84;444;Chachapoyas;;Peru;3;06-13S;077-50W;;;2540;2540; +SPQT;84;377;Iquitos;;Peru;3;03-45S;073-15W;03-45S;073-15W;125;126; +SPQU;84;752;Arequipa;;Peru;3;16-19S;071-33W;16-19S;071-33W;2538;2539; +SPRU;84;501;Trujillo;;Peru;3;08-06S;079-02W;;;26;30; +SPSO;84;691;Pisco;;Peru;3;13-45S;076-17W;13-45S;076-13W;8;7; +SPST;84;455;Tarapoto;;Peru;3;06-27S;076-23W;;;281;282; +SPTN;84;782;Tacna;;Peru;3;18-04S;070-18W;;;468;469; +SPTU;84;658;Puerto Maldonado;;Peru;3;12-38S;069-12W;;;265;266; +SPUR;84;401;Piura;;Peru;3;05-11S;080-36W;;;49;55; +SPYL;84;390;Talara;;Peru;3;04-34S;081-15W;04-34S;081-15W;85;90; +SPZO;84;686;Cuzco;;Peru;3;13-33S;071-59W;;;3248;3249; +SUAA;86;575;Melilla;;Uruguay;3;34-47S;056-15W;;;53;48; +SUAG;86;330;Artigas;;Uruguay;3;30-23S;056-30W;;;123;120;P +SUCA;86;560;Colonia;;Uruguay;3;34-27S;057-50W;;;23;22;P +SUDU;86;530;Durazno;;Uruguay;3;33-21S;056-30W;;;93;92; +SULS;--;---;Capitan Corbeta;;Uruguay;3;34-52S;055-06W;;;30;; +SUME;86;490;Mercedes;;Uruguay;3;33-15S;058-04W;;;22;17; +SUMO;86;440;Melo;;Uruguay;3;32-22S;054-13W;;;100;100; +SUMU;86;580;Carrasco;;Uruguay;3;34-50S;056-00W;;;32;32;P +SUPE;--;---;Maldonado / Punta Est;;Uruguay;3;34-55S;054-55W;;;15;; +SUPU;86;430;Paysandu;;Uruguay;3;32-20S;058-02W;;;61;61; +SURV;86;350;Rivera;;Uruguay;3;30-53S;055-32W;;;205;241; +SUSO;86;360;Salto;;Uruguay;3;31-23S;057-57W;;;34;33;P +SUTB;86;370;Tacuarembo;;Uruguay;3;31-42S;055-59W;;;134;134; +SUTR;86;500;Treinta Y Tres;;Uruguay;3;33-13S;054-23W;;;46;46;P +SVAC;80;427;Acarigua;;Venezuela;3;09-33N;069-14W;;;226;225;P +SVBC;80;419;Barcelona;;Venezuela;3;10-07N;064-41W;10-07N;064-41W;7;7;P +SVBI;80;440;Barinas;;Venezuela;3;08-37N;070-13W;;;203;204;P +SVBM;80;410;Barquisimeto;;Venezuela;3;10-04N;069-19W;10-04N;069-19W;613;614;P +SVBS;80;413;Maracay-B. A. Sucre;;Venezuela;3;10-15N;067-39W;10-15N;067-39W;436;437;P +SVCB;80;444;Ciudad Bolivar;;Venezuela;3;08-09N;063-33W;08-07N;063-32W;43;48;P +SVCL;80;442;Calabozo;;Venezuela;3;08-56N;067-25W;;;100;101;P +SVCP;--;---;Carupano / Gen. Jose;;Venezuela;3;10-40N;063-16W;;;10;; +SVCR;80;403;Coro;;Venezuela;3;11-25N;069-41W;11-25N;069-41W;16;17;P +SVCS;--;---;Caracas / Oscar Macha;;Venezuela;3;10-18N;066-49W;;;654;; +SVCU;80;420;Cumana;;Venezuela;3;10-27N;064-11W;;;2;4;P +SVFM;80;416;Caracas / La Carlota;;Venezuela;3;10-30N;066-53W;10-30N;066-53W;835;835;P +SVGD;80;448;Guasdualito;;Venezuela;3;07-14N;070-48W;07-14N;070-48W;130;131;P +SVGI;80;423;Guiria;;Venezuela;3;10-35N;062-19W;;;13;14;P +SVGU;80;428;Guanare;;Venezuela;3;09-01N;069-44W;;;163;163;P +SVHG;--;---;Higuerote;;Venezuela;3;10-28N;066-06W;;;4;; +SVJC;--;---;Paraguana / Josefa;;Venezuela;3;11-47N;070-09W;;;23;; +SVJM;80;431;San Juan De Los Morros;;Venezuela;3;09-55N;067-20W;;;429;429;P +SVLF;--;---;La Fria;;Venezuela;3;08-15N;072-16W;;;98;; +SVLO;80;405;La Orchila;;Venezuela;3;11-48N;066-11W;11-48N;066-11W;3;3;P +SVMC;80;407;Maracaibo-La Chinita;;Venezuela;3;10-34N;071-44W;10-34N;071-44W;66;65;P +SVMD;80;438;Merida;;Venezuela;3;08-36N;071-11W;;;1479;1498;P +SVMG;--;---;Margarita / Del Carib;;Venezuela;3;10-55N;063-59W;;;23;; +SVMI;80;415;Caracas / Maiquetia Aerop. Intl. Simon Bolivar;;Venezuela;3;10-36N;066-59W;10-36N;066-59W;43;48;P +SVMN;80;425;Mene Grande;;Venezuela;3;09-49N;070-56W;09-49N;070-56W;27;28;P +SVMP;--;---;Metropolitano Private ;;Venezuela;3;10-08N;066-47W;;;175;; +SVMT;80;435;Maturin;;Venezuela;3;09-45N;063-11W;09-45N;063-11W;65;66;P +SVPA;80;457;Puerto Ayacucho;;Venezuela;3;05-36N;067-30W;05-36N;067-30W;73;74;P +SVPC;80;412;Pto. Cabello;;Venezuela;3;10-30N;068-00W;;;2;2;P +SVPM;--;---;Paramillo Private ;;Venezuela;3;07-48N;072-12W;;;1000;; +SVPR;--;---;Guayana / Manuel Car ;;Venezuela;3;08-18N;062-44W;;;144;; +SVSA;80;447;San Antonio Del Tachira;;Venezuela;3;07-51N;072-27W;07-51N;072-27W;377;378;P +SVSE;80;462;Santa Elena De Uairen;;Venezuela;3;04-36N;061-07W;04-36N;061-07W;907;907;P +SVSO;80;475;Sto. Domingo;;Venezuela;3;07-35N;072-04W;;;327;327;P +SVSP;--;---;San Felipe;;Venezuela;3;10-17N;068-45W;;;232;; +SVSR;80;450;San Fernando De Apure;;Venezuela;3;07-54N;067-25W;07-52N;067-26W;47;48;P +SVST;--;---;San Tome Private ;;Venezuela;3;08-57N;064-09W;;;262;; +SVSZ;--;---;Santa Barbara Zulia;;Venezuela;3;08-59N;071-57W;;;10;; +SVTM;80;453;Tumeremo;;Venezuela;3;07-18N;061-27W;07-18N;061-27W;180;181;P +SVTR;80;478;Temblador;;Venezuela;3;09-01N;062-37W;;;30;30;P +SVVA;80;472;Valencia;;Venezuela;3;10-10N;067-56W;;;430;431;P +SVVG;--;---;El Vigia / Perez Alph;;Venezuela;3;08-38N;071-40W;;;100;; +SVVL;80;426;Valera;;Venezuela;3;09-21N;070-37W;09-21N;070-37W;582;582;P +SVVP;80;434;Valle De La Pascua;;Venezuela;3;09-13N;066-01W;;;125;; +SWBC;82;113;Barcelos;;Brazil;3;00-59S;062-35W;;;40;; +SYCJ;--;---;Georgetown/Cheddi Jagan International Airport;;Guyana;3;06-29N;058-15W;;;29;; +SYGT;81;001;Georgetown;;Guyana;3;06-48N;058-09W;;;1;2; +SYTM;81;002;Timehri Airport;;Guyana;3;06-30N;058-15W;;;28;30; +TAKA;--;---;Takao Radar Site;;Japan;2;35-34N;133-14E;;;15;; +TAPA;78;862;Vc Bird International Airport Antigua;;Antigua and Barbuda;4;17-07N;061-47W;;;8;10; +TBPB;78;954;Grantley Adams;;Barbados;4;13-04N;059-29W;13-04N;059-30W;50;56;P +TBPO;--;---;Bridgetown City ;;Barbados;4;13-06N;059-37W;;;50;; +TDCF;78;906;Canefield Airport;;Dominica;4;15-32N;061-24W;;;5;5; +TDPD;78;905;Melville Hall Airport;;Dominica;4;15-32N;061-18W;;;13;14; +TDPR;78;907;Roseau;;Dominica;4;15-18N;061-24W;;;72;72; +TFFF;78;925;Le Lamentin;;Martinique;4;14-36N;061-00W;14-36N;061-00W;5;7;P +TFFJ;78;894;Gustavia, Saint Barthelemy;;Guadeloupe;4;17-54N;062-51W;17-54N;062-52W;48;52;P +TFFR;78;897;Le Raizet, Guadeloupe;;Guadeloupe;4;16-16N;061-31W;16-16N;061-32W;11;11;P +TGPY;78;958;Point Salines Airport;;Grenada;4;12-00N;061-47W;;;6;7; +TIST;78;543;Charlotte Amalie St. Thomas, Cyril E. King Airport;;Virgin Islands;4;18-20N;064-59W;;;7;; +TISX;78;547;Christiansted, Henry E. Rohlsen Airport;;Virgin Islands;4;17-42N;064-48W;17-42N;064-48W;20;17; +TJBQ;78;514;Aquadilla, Rafael Hernandez Airport;PR;United States;4;18-30N;067-08W;18-30N;067-08W;72;69; +TJMZ;--;---;Mayaguez, Eugenio Maria de Hostos Airport;PR;United States;4;18-16N;067-09W;;;9;; +TJNR;78;535;Roosevelt Roads, Roosevelt Roads Naval Station, Ofstie Field;PR;United States;4;18-15-19N;065-38-36W;18-59-20N;065-38-20W;12;10;P +TJPS;--;---;Ponce, Mercedita Airport;PR;United States;4;18-01N;066-34W;;;8;; +TJSJ;--;---;San Juan, Luis Munoz Marin International Airport;PR;United States;4;18-27N;066-00W;;;3;; +TKPK;78;858;Golden Rock;;Saint Kitts and Nevis;4;17-18N;062-41W;;;48;48; +TKPN;78;859;Charlestown / Newcast;;Antigua and Barbuda;4;17-12N;062-35W;;;17;; +TLPC;78;947;Vigie;;Saint Lucia;4;14-01N;061-00W;;;2;2; +TLPL;78;948;Hewanorra International Airport;;Saint Lucia;4;13-45N;060-57W;;;3;10; +TNCA;78;982;Queen Beatrix Airport;;Aruba;4;12-30N;070-01W;;;18;33;P +TNCB;78;990;Flamingo Airport, Bonaire;;Netherlands Antilles;4;12-09N;068-17W;;;6;7;P +TNCC;78;988;Hato Airport, Curacao;;Netherlands Antilles;4;12-12N;068-58W;12-12N;068-58W;9;67;P +TNCE;78;873;Roosevelt Airport Saint Eustatius;;Netherlands Antilles;4;17-29N;062-59W;;;38;39;P +TNCM;78;866;Juliana Airport, Saint Maarten;;Netherlands Antilles;4;18-03N;063-07W;18-03N;063-07W;4;9;P +TQPF;--;---;Wallblake;;Anguilla;4;18-12-17N;063-03-18W;;;31;; +TRPM;--;---;Blackburne / Plymouth;;Antigua and Barbuda;4;16-45N;062-10W;;;12;; +TTCP;--;---;Crown Pt./ Scarborou;;Trinidad and Tobago;4;11-09N;060-51W;;;8;; +TTPP;78;970;Piarco International Airport, Trinidad;;Trinidad and Tobago;4;10-37N;061-21W;10-35N;061-21W;12;15;P +TTPT;78;962;Crown Point Airport, Tobago;;Trinidad and Tobago;4;11-09N;060-50W;11-09N;060-50W;3;6;P +TUPJ;78;550;Beef Island, Tortola;;British Virgin Islands;4;18-27N;064-32W;;;4;; +TVSV;78;951;Arnos Vale;;Saint Vincent and the Grenadines;4;13-08N;061-12W;;;9;13; +TXKF;78;016;Bermuda;;Bermuda;4;32-22N;064-41W;;;6;;P +UAAA;36;870;Almaty;;Kazakhstan;2;43-14N;076-56E;43-14N;076-56E;847;851;P +UACC;--;---;Astana;;Kazakhstan;2;51-12N;071-27E;;;;; +UAFM;--;---;Bishkek/Manas Airport;;Kyrgyzstan;2;42-51N;074-35E;;;;; +UAII;38;328;Shymkent;;Kazakhstan;2;42-19N;069-42E;42-18N;069-36E;552;604; +UAKK;35;394;Karaganda;;Kazakhstan;2;49-48N;073-09E;;;553;; +UAOO;38;062;Kzyl-Orda;;Kazakhstan;2;44-51N;065-30E;44-46N;065-32E;129;130;P +UARR;35;108;Uralsk;;Kazakhstan;2;51-15N;051-17E;51-15N;051-24E;36;37;P +UATA;35;746;Aralskoe More;;Kazakhstan;2;46-47N;061-39E;46-47N;061-40E;56;62;P +UATE;--;---;Aktau;;Kazakhstan;2;43-52-12N;051-06E;;;;; +UATT;35;229;Aktjubinsk;;Kazakhstan;2;50-17N;057-09E;50-17N;057-09E;227;219;P +UAUU;--;---;Kostanay;;Kazakhstan;2;53-12-23N;063-33-03E;;;182;; +UBBB;37;864;Baku / Bine Airport;;Azerbaijan;6;40-27N;050-04E;40-27N;050-04E;-6;-1; +UBBG;--;---;Gyanca Airport;;Azerbaijan;6;40-44N;046-24E;;;330;; +UEEE;24;959;Jakutsk;;Russia;2;62-01N;129-43E;62-05N;129-45E;103;101;P +UELL;30;393;Cul'Man;;Russia;2;56-50N;124-52E;56-50N;124-52E;859;858;P +UERP;--;---;Polyarny;;Russia;2;66-24-02N;112-01-49E;;;509;; +UERR;--;---;Mirny;;Russia;2;62-31-48N;114-01-48E;;;347;; +UEST;--;---;Tiksi;;Russia;2;71-42N;128-54E;;;7;; +UGEE;37;789;Yerevan;;Armenia;6;40-08N;044-28E;40-08N;044-28E;890;907;P +UGGG;37;549;Tbilisi;;Georgia;6;41-41N;044-57E;41-41N;044-57E;467;490; +UGMM;37;541;Muhrani;;Georgia;6;41-56N;044-35E;;;551;551; +UHBP;31;329;Ekimchan;;Russia;2;53-04N;132-59E;53-04N;132-56E;543;542;P +UHHH;31;735;Habarovsk;;Russia;2;48-31N;135-10E;48-31N;135-10E;72;76;P +UHHO;31;655;Troickoe;;Russia;2;49-27N;136-34E;49-27N;136-34E;29;33;P +UHMA;25;563;Anadyr;;Russia;2;64-47N;177-34E;64-47N;177-34E;62;61;P +UHMD;25;594;Buhta Providenja;;Russia;2;64-25N;173-14W;64-26N;173-14W;3;17;P +UHMG;--;---;Chaybukha;;Russia;2;61-57N;160-25E;;;;; +UHMM;25;913;Magadan;;Russia;2;59-33N;150-47E;59-35N;150-47E;118;116;P +UHPP;32;540;Petropavlovsk-Kamchatskij;;Russia;2;53-05N;158-35E;52-58N;158-45E;24;84; +UHSS;32;150;Yuzhno-Sakhalinsk;;Russia;2;46-57N;142-43E;46-56N;142-44E;31;24;P +UHWW;31;960;Vladivostok;;Russia;2;43-07N;131-56E;43-06N;131-54E;184;183;P +UIAA;30;758;Chita;;Russia;2;52-05N;113-29E;52-01N;113-20E;685;671;P +UIBB;--;---;Bratsk / Irkutsk;;Russia;2;56-22-15N;101-41-55E;;;490;; +UIII;30;710;Irkutsk;;Russia;2;52-16N;104-19E;52-22N;104-11E;513;469;P +UIIO;30;713;Ust'Ordynskij;;Russia;2;52-49N;104-46E;;;525;526; +UIKB;30;253;Bodajbo;;Russia;2;57-51N;114-14E;57-51N;114-12E;278;275; +UIKK;30;230;Kirensk;;Russia;2;57-46N;108-04E;57-46N;108-07E;258;259;P +UINN;29;698;Nizhneudinsk;;Russia;2;54-53N;099-02E;54-53N;099-02E;410;411;P +UIUH;30;739;Horinsk;;Russia;2;52-10N;109-47E;52-10N;109-46E;666;666;P +UIUU;30;823;Ulan-Ude;;Russia;2;51-50N;107-36E;51-48N;107-26E;510;515;P +UKBB;33;347;Boryspil;;Ukraine;6;50-20N;030-58E;;;121;122; +UKCC;--;---;Donetsk;;Ukraine;6;48-05N;037-45E;;;;; +UKDD;--;---;Dnipropetrovs'k;;Ukraine;6;48-32N;034-40E;;;;; +UKDE;--;---;Zaporizhzhia / Mokraya;;Ukraine;6;47-52-02N;035-18-59E;;;114;; +UKDR;--;---;Krivyy Rih / Dnipropetrovs'k;;Ukraine;6;48-03N;033-13-12E;;;;; +UKFF;33;946;Simferopol;;Ukraine;6;44-41N;034-08E;45-09N;033-59E;180;181;P +UKHH;34;300;Kharkiv;;Ukraine;6;49-58N;036-08E;49-56N;036-17E;154;155;P +UKII;33;815;Kisinev;;Moldova;6;47-01N;028-59E;47-01N;028-52E;180;173; +UKKE;--;---;Cherkasy;;Ukraine;6;49-24-58N;031-59-47E;;;114;; +UKKK;33;345;Kyiv;;Ukraine;6;50-24N;030-34E;50-24N;030-27E;166;167;P +UKKM;--;---;Hostomel;;Ukraine;6;50-36-01N;030-11-37E;;;157;; +UKLI;--;---;Ivano-Frankivsk;;Ukraine;6;48-53-03N;024-41-10E;;;280;; +UKLL;33;393;L'Viv;;Ukraine;6;49-49N;023-57E;49-49N;023-57E;319;323;P +UKLN;--;---;Chernovsty;;Ukraine;6;48-15-36N;025-58-54E;;;252;; +UKLR;33;301;Rivne;;Ukraine;6;50-35N;026-08E;;;231;; +UKLU;--;---;Uzhhorod;;Ukraine;6;48-38-05N;022-15-53E;;;117;; +UKON;--;---;Mykolaiv;;Ukraine;6;47-03-29N;031-55-15E;;;56;; +UKOO;33;837;Odesa;;Ukraine;6;46-26N;030-46E;46-29N;030-38E;42;42;P +ULAA;22;550;Arhangel'Sk;;Russia;6;64-30N;040-44E;64-35N;040-30E;13;8;P +ULAK;22;887;Kotlas;;Russia;6;61-14N;046-43E;61-14N;046-38E;56;56;P +ULLI;26;063;St. Peterburg;;Russia;6;59-58N;030-18E;59-58N;030-18E;4;6;P +ULMM;22;113;Murmansk;;Russia;6;68-58N;033-03E;68-58N;033-03E;51;51;P +ULOL;26;477;Velikie Luki;;Russia;6;56-21N;030-37E;56-23N;030-36E;98;106;P +ULTT;26;038;Tallinn;;Estonia;6;59-23N;024-35E;59-27N;024-48E;44;34; +ULWT;27;051;Tot'Ma;;Russia;6;59-53N;042-45E;;;134;134;P +ULWW;27;037;Vologda;;Russia;6;59-19N;039-55E;59-17N;039-52E;131;130;P +UMBB;--;---;Brest;;Belarus;6;52-06-30N;023-53-48E;;;143;; +UMGG;--;---;Gomel';;Belarus;6;52-31-36N;031-01-06E;;;144;; +UMII;26;666;Vitebsk;;Belarus;6;55-10N;030-13E;55-10N;030-08E;176;176;P +UMKK;--;---;Kaliningrad/Khrabrovo Airport;;Russia;6;54-43-12N;020-30E;;;21;; +UMMG;--;---;Grodno;;Belarus;6;53-36-06N;024-03-18E;;;135;; +UMMM;--;---;Loshitsa / Minsk International 1;;Belarus;6;53-51-54N;027-32-30E;;;228;; +UMMS;26;850;Minsk;;Belarus;6;53-56N;027-38E;53-52N;027-32E;234;231;P +UMRR;26;422;Riga;;Latvia;6;56-58N;024-03E;56-58N;024-04E;7;7;P +UMRW;26;314;Ventspils;;Latvia;6;57-24N;021-32E;57-22N;021-33E;3;3; +UNAA;--;---;Abakan;;Russia;2;53-45N;091-24E;;;245;; +UNBB;29;838;Barnaul;;Russia;2;53-26N;083-31E;53-20N;083-42E;252;184;P +UNEE;--;---;Kemerovo;;Russia;2;55-19-48N;086-04-48E;;;260;; +UNII;29;263;Enisejsk;;Russia;2;58-27N;092-09E;58-27N;092-09E;78;79;P +UNNN;29;634;Novosibirsk;;Russia;2;55-05N;082-54E;55-02N;082-54E;177;176;P +UNOO;--;---;Omsk;;Russia;2;54-58N;073-18E;;;122; +UNWW;--;---;Novokuznetsk;;Russia;2;53-44N;087-11E;;;308;; +URKA;--;---;Anapa / Vitiazevo;;Russia;6;44-54N;037-19E;;;;; +URKK;34;929;Krasnodar;;Russia;6;45-02N;039-09E;45-02N;039-09E;33;34;P +URMM;37;054;Mineral'Nye Vody;;Russia;6;44-14N;043-04E;44-13N;043-06E;314;316;P +URMN;--;---;Nalchik;;Russia;6;43-30-46N;043-38-12E;;;445;; +URMT;--;---;Stavropol / Shpakovskoye;;Russia;6;45-20N;042-00E;;;;; +URRR;34;731;Rostov-Na-Donu;;Russia;6;47-16N;039-49E;47-15N;039-49E;77;75;P +URSS;37;171;Adler;;Russia;6;43-26N;039-54E;;;16;13;P +URWA;--;---;Astrakhan;;Russia;6;46-17N;048-00-23E;;;0;; +URWI;34;861;Elista;;Russia;6;46-22N;044-20E;46-19N;044-18E;150;155; +URWW;34;560;Volgograd;;Russia;6;48-47N;044-22E;48-41N;044-21E;145;134;P +USCC;--;---;Chelyabinsk-Balandino;;Russia;2;55-10N;061-24E;;;;; +USHH;23;933;Hanty-Mansijsk;;Russia;2;61-01N;069-02E;60-58N;069-04E;40;46;P +USNN;--;---;Nizhnevartovsk;;Russia;2;60-56N;076-29E;;;54;; +USPP;--;---;Perm'/Bolshoe Savino;;Russia;2;58-00N;056-15E;;;170;; +USRR;23;849;Surgut;;Russia;2;61-15N;073-30E;61-15N;073-30E;44;56;P +USSS;28;440;Ekaterinburg;;Russia;2;56-50N;060-38E;56-48N;060-38E;237;283;P +UTAA;--;---;Ashgabat;;Turkmenistan;2;37-59N;058-22E;;;;; +UTDD;38;836;Dushanbe;;Tajikistan;2;38-33N;068-47E;38-35N;068-47E;803;800;P +UTED;38;579;Dzizak;;Uzbekistan;2;40-07N;067-50E;;;345;345;P +UTNN;--;---;Nukus / Karakalpakstan;;Uzbekistan;2;42-28-48N;059-37-48E;;;;; +UTNU;--;---;Urgench;;Uzbekistan;2;41-35N;060-38-42E;;;98;; +UTSM;38;413;Tamdy;;Uzbekistan;2;41-44N;064-37E;41-44N;064-37E;238;237;P +UTSS;38;696;Samarkand;;Uzbekistan;2;39-34N;066-57E;39-41N;066-57E;724;724;P +UTST;38;927;Termez;;Uzbekistan;2;37-14N;067-16E;37-17N;067-19E;302;310;P +UTTT;38;457;Tashkent;;Uzbekistan;2;41-16N;069-16E;41-16N;069-16E;489;488;P +UUBP;26;898;Brjansk;;Russia;6;53-15N;034-19E;53-14N;034-23E;217;216;P +UUDD;--;---;Moscow / Domodedovo;;Russia;6;55-24N;037-54E;;;179;; +UUEE;--;---;Moscow / Sheremet'Ye ;;Russia;6;55-59N;037-30E;;;190;; +UUEM;27;402;Tver;;Russia;6;56-54N;035-53E;;;137;146;P +UUOO;34;122;Voronez;;Russia;6;51-39N;039-15E;51-40N;039-16E;154;104; +UUWW;--;---;Moscow / Vnukovo ;;Russia;6;55-39N;037-16E;;;203;; +UUYT;23;803;Ust'- Kulom;;Russia;2;61-41N;053-41E;;;139;144;P +UUYY;23;804;Syktyvkar;;Russia;2;61-43N;050-50E;61-40N;050-51E;119;119;P +UWGG;--;---;Nizhny Novgorod/Strigino;;Russia;6;56-19-48N;044-00E;;;;; +UWKD;--;---;Kazan';;Russia;6;55-47N;049-12E;;;;; +UWLW;--;---;Ulyanovsk;;Russia;6;54-21N;048-23E;;;;; +UWOO;--;---;Orenburg / Tsentralny;;Russia;2;51-46-48N;055-07-12E;;;109;; +UWPP;27;962;Penza;;Russia;6;53-07N;045-01E;53-08N;045-01E;174;177;P +UWSS;--;---;Saratov / Tsentralny;;Russia;6;51-34-12N;046-04-12E;;;166;; +UWUU;--;---;Ufa;;Russia;2;54-43-48N;055-55-48E;;;;; +UWWW;28;900;Samara;;Russia;2;53-12N;050-09E;;;44;; +VAAH;42;647;Ahmadabad;;India;2;23-04N;072-38E;23-04N;072-38E;55;55;P +VAAK;42;934;Akola;;India;2;20-42N;077-04E;;;305;309;P +VAAU;43;014;Aurangabad Chikalthan Aerodrome;;India;2;19-51N;075-24E;19-51N;075-24E;582;579;P +VABB;43;003;Bombay / Santacruz;;India;2;19-07N;072-51E;19-05N;072-51E;8;14;P +VABI;42;080;Bilaspur;;India;2;31-15N;076-40E;;;589;587;P +VABJ;42;634;Bhuj-Rudramata;;India;2;23-15N;069-40E;23-17N;069-40E;78;80;P +VABM;43;198;Belgaum / Sambra;;India;2;15-51N;074-37E;;;758;747;P +VABP;42;667;Bhopal / Bairagarh;;India;2;23-17N;077-21E;23-17N;077-21E;523;523;P +VABV;42;838;Bhaunagar;;India;2;21-45N;072-12E;;;5;11; +VAGO;43;194;Goa / Dabolim Airport;;India;2;15-23N;073-49E;;;42;52; +VAID;42;754;Indore;;India;2;22-43N;075-48E;22-43N;075-48E;561;567;P +VAJB;42;675;Jabalpur;;India;2;23-12N;079-57E;23-10N;079-57E;391;393;P +VAKD;42;855;Khandwa;;India;2;21-50N;076-22E;;;317;318; +VAKP;43;157;Kolhapur;;India;2;16-42N;074-14E;;;569;570; +VANP;42;867;Nagpur Sonegaon;;India;2;21-06N;079-03E;21-06N;079-03E;308;310;P +VARK;42;737;Rajkot;;India;2;22-18N;070-47E;;;134;138;P +VASL;43;117;Sholapur;;India;2;17-40N;075-54E;;;477;479;P +VBBM;48;019;Bhamo;;Myanmar;2;24-16N;097-12E;;;111;113; +VBBS;48;094;Pathein;;Myanmar;2;16-46N;094-46E;16-46N;094-46E;9;10;P +VBCI;48;109;Coco Island;;Myanmar;2;14-07N;093-22E;14-07N;093-22E;2;3;P +VBHL;48;010;Homalin;;Myanmar;2;24-52N;094-55E;;;130;131; +VBKG;48;060;Kengtung;;Myanmar;2;21-18N;099-37E;21-18N;099-37E;827;828; +VBKP;48;071;Kyaukpyu;;Myanmar;2;19-25N;093-33E;;;5;5; +VBLS;48;035;Lashio;;Myanmar;2;22-56N;097-45E;;;747;749; +VBMK;48;008;Myitkyina;;Myanmar;2;25-22N;097-24E;25-22N;097-24E;145;147;P +VBML;48;053;Meiktila;;Myanmar;2;20-50N;095-50E;20-53N;095-54E;214;220;P +VBMM;48;103;Moulmein;;Myanmar;2;16-30N;097-37E;16-30N;097-37E;21;22; +VBPA;48;099;Hpa-An;;Myanmar;2;16-45N;097-40E;;;9;10; +VBPR;48;077;Prome;;Myanmar;2;18-48N;095-13E;;;58;60; +VBPT;48;001;Putao;;Myanmar;2;27-20N;097-25E;;;409;; +VBRM;48;042;Mandalay;;Myanmar;2;21-59N;096-06E;21-59N;096-06E;74;76; +VBRN;48;110;Mergui;;Myanmar;2;12-26N;098-36E;12-26N;098-36E;36;37;P +VBRR;48;096;Mingaladon;;Myanmar;2;16-54N;096-11E;16-54N;096-11E;28;29; +VBSY;48;080;Sandoway;;Myanmar;2;18-28N;094-21E;18-28N;094-21E;9;11;P +VBTV;48;108;Dawei;;Myanmar;2;14-06N;098-13E;14-06N;098-13E;16;17;P +VCBI;43;450;Katunayake;;Sri Lanka;2;07-10N;079-53E;;;8;8;P +VCCA;43;421;Anuradhapura;;Sri Lanka;2;08-20N;080-25E;;;89;89;P +VCCB;43;436;Batticaloa;;Sri Lanka;2;07-43N;081-42E;;;5;12;P +VCCC;43;467;Ratmalana;;Sri Lanka;2;06-49N;079-53E;;;5;5;P +VCCT;43;418;Trincomalee;;Sri Lanka;2;08-35N;081-15E;08-35N;081-15E;3;7;P +VDKC;48;995;Kompong-Cham;;Cambodia;2;12-00N;105-27E;12-00N;105-27E;16;16; +VDPP;48;991;Phnom-Penh / Pochentong;;Cambodia;2;11-33N;104-51E;11-33N;104-51E;10;10;P +VDSR;48;966;Siemreap;;Cambodia;2;13-22N;103-51E;13-22N;103-51E;15;15;P +VEAT;42;724;Agartala;;India;2;23-53N;091-15E;23-53N;091-15E;15;16;P +VEBD;42;398;Siliguri;;India;2;26-38N;088-19E;26-41N;088-20E;126;131;P +VEBS;42;971;Bhubaneswar;;India;2;20-15N;085-50E;20-15N;085-50E;45;46;P +VECC;42;809;Calcutta / Dum Dum;;India;2;22-39N;088-27E;22-39N;088-27E;4;6;P +VECX;43;368;Car Nicobar;;India;2;09-09N;092-49E;09-09N;092-49E;10;14;P +VEGK;42;379;Gorakhpur;;India;2;26-45N;083-22E;26-45N;083-22E;76;77;P +VEGT;42;410;Gauhati;;India;2;26-06N;091-35E;26-06N;091-35E;47;54;P +VEGY;42;591;Gaya;;India;2;24-45N;084-57E;24-45N;084-57E;110;116;P +VEIM;42;623;Imphal Tulihal;;India;2;24-46N;093-54E;24-46N;093-54E;780;781;P +VEJH;42;886;Jharsuguda;;India;2;21-55N;084-05E;21-55N;084-05E;228;230;P +VEJS;42;798;Jamshedpur;;India;2;22-49N;086-11E;22-49N;086-11E;140;142;P +VELR;42;309;North Lakhimpur;;India;2;27-14N;094-07E;;;101;102;P +VEMN;42;314;Dibrugarh / Mohanbari;;India;2;27-29N;095-01E;27-29N;095-01E;110;111;P +VEPB;43;333;Port Blair;;India;2;11-40N;092-43E;11-40N;092-43E;73;79;P +VEPT;42;492;Patna;;India;2;25-36N;085-06E;25-36N;085-06E;51;60;P +VERC;42;701;M. O. Ranchi;;India;2;23-19N;085-19E;23-19N;085-19E;652;652; +VGCB;41;992;Cox's Bazar;;Bangladesh;2;21-26N;091-58E;21-26N;091-58E;2;4;P +VGEG;41;978;Chittagong Patenga ;;Bangladesh;2;22-16N;091-49E;22-15N;091-49E;4;6;P +VGIS;41;907;Ishurdi;;Bangladesh;2;24-08N;089-03E;24-09N;089-02E;13;14;P +VGJR;41;936;Jessore;;Bangladesh;2;23-11N;089-10E;23-11N;089-10E;6;7;P +VGRJ;41;895;Rajshahi;;Bangladesh;2;24-22N;088-42E;24-22N;088-42E;17;20;P +VGSY;41;891;Sylhet;;Bangladesh;2;24-54N;091-53E;24-54N;091-53E;34;35;P +VGTJ;41;923;Dhaka;;Bangladesh;2;23-46N;090-23E;23-46N;090-23E;8;9;P +VGZR;41;922;Kurmitola, Dia;;Bangladesh;2;23-51N;090-24E;;;9;10;P +VHCH;45;001;Cheung Chau;;Hong Kong;2;22-12N;114-01E;;;79;; +VHHH;45;007;Hong Kong Inter-National Airport;;Hong Kong;2;22-20N;114-11E;;;5;24; +VIAG;42;260;Agra;;India;2;27-09N;077-58E;27-09N;077-58E;168;169;P +VIAL;42;475;Allahabad / Bamhrauli;;India;2;25-27N;081-44E;25-27N;081-44E;97;98;P +VIAR;42;071;Amritsar;;India;2;31-38N;074-52E;31-42N;074-48E;229;234;P +VIBN;42;479;Varanasi / Babatpur;;India;2;25-27N;082-52E;;;81;85; +VIBY;42;189;Bareilly;;India;2;28-22N;079-24E;28-22N;079-24E;167;169;P +VICX;42;367;Kanpur / Chakeri;;India;2;26-24N;080-24E;26-24N;080-24E;123;126; +VIDD;42;182;New Delhi / Safdarjung;;India;2;28-35N;077-12E;28-35N;077-12E;211;216;P +VIDP;42;181;New Delhi / Palam;;India;2;28-34N;077-07E;;;220;233; +VIGR;42;361;Gwalior;;India;2;26-14N;078-15E;26-14N;078-15E;205;207;P +VIHR;42;131;Hissar;;India;2;29-10N;075-44E;;;216;221;P +VIJN;42;463;Jhansi;;India;2;25-27N;078-35E;;;250;251; +VIJO;42;339;Jodhpur;;India;2;26-18N;073-01E;26-18N;073-01E;217;224;P +VIJP;42;348;Jaipur / Sanganer;;India;2;26-49N;075-48E;26-49N;075-48E;385;390;P +VIKO;42;452;Kota Aerodrome;;India;2;25-09N;075-51E;;;273;274;P +VILK;42;369;Lucknow / Amausi;;India;2;26-45N;080-53E;26-45N;080-53E;122;128;P +VIST;42;571;Satna;;India;2;24-34N;080-50E;;;315;317;P +VIUD;42;542;Udaipur Dabok;;India;2;24-37N;073-53E;24-37N;073-53E;509;514; +VLAP;48;957;Attopeu;;Laos;2;14-48N;106-50E;;;105;105; +VLIP;48;955;Pakse;;Laos;2;15-07N;105-10E;15-08N;105-47E;102;102;P +VLLB;48;930;Luang-Prabang;;Laos;2;19-53N;102-08E;;;305;305;P +VLSB;48;938;Sayaboury;;Laos;2;19-14N;101-44E;19-14N;101-44E;326;326; +VLSK;48;947;Savannakhet;;Laos;2;16-33N;104-39E;;;155;145;P +VLSV;48;952;Saravane;;Laos;2;15-41N;106-26E;;;168;168;P +VLTK;48;946;Thakhek;;Laos;2;17-23N;104-39E;;;52;152; +VLVT;48;940;Vientiane;;Laos;2;17-57N;102-34E;17-59N;102-34E;171;171;P +VMMC;45;011;Taipa;;Macau;2;22-10N;113-34E;;;114;;P +VNBW;44;438;Bhairawa Airport;;Nepal;2;27-31N;083-27E;;;109;109; +VNJL;44;424;Jumla;;Nepal;2;29-17N;082-10E;;;2300;; +VNKT;44;454;Kathmandu Airport;;Nepal;2;27-42N;085-22E;27-42N;085-22E;1337;1337; +VNPK;44;434;Pokhara Airport;;Nepal;2;28-13N;084-00E;;;827;827; +VNSI;44;449;Simra Airport;;Nepal;2;27-10N;084-59E;;;137;137; +VNSK;44;416;Surkhet;;Nepal;2;28-36N;081-37E;;;720;720; +VNTJ;44;474;Taplejung;;Nepal;2;27-21N;087-40E;;;1732;1732; +VNVT;44;478;Biratnagar Airport;;Nepal;2;26-29N;087-16E;;;72;72; +VOBG;--;---;Bangalore / Hindustan;;India;2;12-57N;077-40E;;;888;; +VOBI;43;205;Bellary;;India;2;15-09N;076-51E;;;448;449; +VOBZ;43;181;Vijayawada / Gannavaram;;India;2;16-32N;080-48E;16-32N;080-48E;21;24; +VOCB;43;321;Coimbatore / Peelamedu;;India;2;11-02N;077-03E;;;396;399;P +VOCC;43;353;Cochin / Willingdon;;India;2;09-57N;076-16E;09-56N;076-14E;1;3;P +VOCP;43;241;Cuddapah;;India;2;14-29N;078-50E;;;129;130; +VOHY;43;128;Hyderabad Airport;;India;2;17-27N;078-28E;17-27N;078-28E;530;545; +VOMD;43;360;Madurai;;India;2;09-50N;078-05E;;;139;131; +VOML;43;284;Mangalore / Bajpe;;India;2;12-55N;074-53E;12-58N;074-54E;102;102;P +VOMM;43;279;Madras / Minambakkam;;India;2;13-00N;080-11E;13-00N;080-11E;10;16;P +VOTR;43;344;Tiruchchirapalli;;India;2;10-46N;078-43E;10-46N;078-43E;85;88;P +VOTV;43;372;Thiruvananthapuram;;India;2;08-28N;076-57E;;;4;8; +VOVR;43;303;Vellore;;India;2;12-55N;079-09E;;;213;214; +VRGN;43;599;Gan;;Maldives;2;00-41S;073-09E;00-41S;073-09E;2;2; +VRMM;43;555;Male;;Maldives;2;04-12N;073-32E;04-12N;073-32E;2;2; +VTBC;48;480;Chanthaburi;;Thailand;2;12-36N;102-07E;12-36N;102-07E;3;4;P +VTBD;48;456;Don Muang;;Thailand;2;13-55N;100-36E;13-55N;100-36E;4;12;P +VTBG;48;450;Kanchanaburi;;Thailand;2;14-01N;099-32E;;;28;29;P +VTBI;48;430;Prachin Buri;;Thailand;2;14-03N;101-22E;;;5;6;P +VTBJ;48;465;Phetchaburi;;Thailand;2;13-09N;100-04E;;;2;4;P +VTBP;48;500;Prachuap Khirikhan;;Thailand;2;11-50N;099-50E;11-48N;099-48E;4;5;P +VTBS;48;459;Chon Buri;;Thailand;2;13-22N;100-59E;;;1;2;P +VTBU;48;478;Rayong;;Thailand;2;12-38N;101-21E;12-38N;101-21E;3;5;P +VTCC;48;327;Chiang Mai;;Thailand;2;18-47N;098-59E;18-47N;098-59E;312;314;P +VTCH;48;300;Mae Hong Son;;Thailand;2;19-18N;097-50E;;;267;269;P +VTCL;48;328;Lampang;;Thailand;2;18-17N;099-31E;18-16N;099-30E;241;242;P +VTCN;48;331;Nan;;Thailand;2;18-46N;100-46E;;;200;201;P +VTCP;48;330;Phrae;;Thailand;2;18-10N;100-10E;;;161;162;P +VTCR;48;303;Chiang Rai;;Thailand;2;19-55N;099-50E;;;394;395;P +VTCS;48;325;Mae Sariang;;Thailand;2;18-10N;097-56E;;;212;213;P +VTPH;48;475;Hua Hin;;Thailand;2;12-35N;099-57E;;;5;6;P +VTPM;48;375;Mae Sot;;Thailand;2;16-40N;098-33E;16-42N;098-33E;196;197;P +VTPN;48;400;Nakhon Sawan;;Thailand;2;15-48N;100-10E;15-40N;100-08E;34;35;P +VTPS;48;378;Phitsanulok;;Thailand;2;16-47N;100-16E;16-49N;100-16E;44;45;P +VTPT;48;376;Tak;;Thailand;2;16-53N;099-09E;;;121;124;P +VTPU;48;351;Uttaradit;;Thailand;2;17-37N;100-06E;17-37N;100-06E;63;64;P +VTSA;48;570;Satun;;Thailand;2;06-39N;100-05E;;;4;6;P +VTSB;48;551;Surat Thani;;Thailand;2;09-07N;099-21E;09-07N;099-21E;10;11;P +VTSD;48;517;Chumphon;;Thailand;2;10-29N;099-11E;;;3;5;P +VTSH;48;568;Songkhla;;Thailand;2;07-12N;100-36E;07-12N;100-36E;4;5;P +VTSK;48;580;Pattani;;Thailand;2;06-47N;101-09E;06-47N;101-09E;5;9;P +VTSN;48;552;Nakhon Si Thammarat;;Thailand;2;08-28N;099-58E;;;7;9;P +VTSP;48;565;Phuket Airport;;Thailand;2;08-07N;098-19E;08-06N;098-18E;6;10;P +VTSR;48;532;Ranong;;Thailand;2;09-59N;098-37E;09-58N;098-38E;7;8;P +VTSS;48;569;Hat Yai;;Thailand;2;06-55N;100-26E;06-56N;100-25E;27;35;P +VTST;48;567;Trang;;Thailand;2;07-31N;099-37E;;;14;16;P +VTUB;48;383;Mukdahan;;Thailand;2;16-32N;104-43E;;;138;139;P +VTUC;48;403;Chaiyaphum;;Thailand;2;15-48N;102-02E;15-48N;102-02E;182;183;P +VTUD;48;354;Udon Thani;;Thailand;2;17-23N;102-48E;17-23N;102-48E;177;182;P +VTUK;48;381;Khon Kaen;;Thailand;2;16-26N;102-50E;;;165;166;P +VTUL;48;353;Loei;;Thailand;2;17-27N;101-44E;;;253;254;P +VTUM;48;352;Nong Khai;;Thailand;2;17-52N;102-43E;;;174;175;P +VTUN;48;431;Nakhon Ratchasima;;Thailand;2;14-58N;102-05E;14-58N;102-05E;187;188;P +VTUP;48;357;Nakhon Phanom;;Thailand;2;17-25N;104-47E;17-25N;104-47E;146;148;P +VTUR;48;405;Roi Et;;Thailand;2;16-03N;103-41E;;;140;142;P +VTUS;48;356;Sakon Nakhon;;Thailand;2;17-09N;104-08E;;;171;172;P +VTUU;48;407;Ubon Ratchathani;;Thailand;2;15-15N;104-52E;15-15N;104-52E;123;127;P +VVDN;48;855;Da Nang;;Vietnam;2;16-02N;108-11E;16-02N;108-11E;7;7;P +VVGL;--;---;Hanoi / Gialam;;Vietnam;2;21-02N;105-51E;;;12;; +VVNB;48;820;Ha Noi;;Vietnam;2;21-01N;105-48E;21-01N;105-48E;6;6;P +VVNT;48;877;Nha Trang;;Vietnam;2;12-15N;109-12E;12-15N;109-12E;10;10;P +VVPB;48;852;Hue;;Vietnam;2;16-24N;107-41E;;;17;17;P +VVPK;48;866;Pleiku City;;Vietnam;2;13-59N;108-00E;13-59N;108-00E;801;801; +VVQN;48;870;Quy Nhon;;Vietnam;2;13-46N;109-13E;13-46N;109-13E;6;6;P +VVTS;48;900;Ho Chi Minh;;Vietnam;2;10-49N;106-40E;10-49N;106-40E;19;19;P +VVVH;48;845;Vinh;;Vietnam;2;18-42N;105-40E;;;6;6;P +VYSW;48;062;Sittwe;;Myanmar;2;20-08N;092-53E;20-08N;092-53E;4;5;P +VYYY;48;097;Yangon;;Myanmar;2;16-46N;096-10E;16-46N;096-10E;14;15;P +WAAA;97;180;Ujung Pandang / Hasanuddin;;Indonesia;5;05-04S;119-33E;05-04S;119-33E;14;14;P +WAAB;97;192;Bau-Bau / Beto Ambiri;;Indonesia;5;05-28S;122-37E;05-28S;122-37E;2;2; +WAAU;97;146;Kendari / Woltermon-Ginsidi;;Indonesia;5;04-06S;122-26E;04-05S;122-25E;50;50;P +WABB;97;560;Biak / Mokmer;;Indonesia;5;01-11S;136-07E;01-12S;136-07E;11;11;P +WABI;97;682;Nabire;;Indonesia;5;03-20S;135-30E;;;3;3;P +WABN;97;796;Kokonao / Timuka;;Indonesia;5;04-43S;136-26E;;;3;3;P +WABO;97;570;Serui / Yendosa;;Indonesia;5;01-52S;136-14E;;;3;3;P +WABT;97;780;Enarotali;;Indonesia;5;03-55S;136-22E;03-55S;136-22E;1770;1770;P +WAJI;97;580;Sarmi;;Indonesia;5;01-50S;138-43E;01-50S;138-43E;3;3;P +WAJJ;97;690;Jayapura / Sentani;;Indonesia;5;02-34S;140-29E;02-35S;140-31E;99;99;P +WAJW;97;686;Wamena / Wamena;;Indonesia;5;04-04S;138-57E;04-06S;138-57E;1660;1660;P +WAKK;97;980;Merauke / Mopah;;Indonesia;5;08-28S;140-23E;08-31S;140-25E;3;3;P +WAKT;97;876;Tanah Merah / Tanah Merah;;Indonesia;5;06-06S;140-18E;;140-18E;16;16;P +WAMA;97;406;Galela / Gamarmalamu;;Indonesia;5;01-49N;127-50E;;;8;; +WAMG;97;048;Gorontalo / Jalaluddin;;Indonesia;5;00-31N;123-04E;00-38N;122-51E;2;2;P +WAMH;97;008;Tahuna;;Indonesia;5;03-35N;125-28E;03-35N;125-28E;38;38; +WAMI;97;028;Toli-Toli / Lalos;;Indonesia;5;01-01N;120-48E;01-01N;120-48E;2;2; +WAML;97;072;Palu / Mutiara;;Indonesia;5;00-41S;119-44E;00-55S;119-54E;6;6;P +WAMM;97;014;Menado / Dr. Sam Ratulangi;;Indonesia;5;01-32N;124-55E;01-33N;124-56E;80;80;P +WAMP;97;096;Poso / Kasiguncu;;Indonesia;5;01-23S;120-44E;01-24S;120-43E;2;2;P +WAMT;97;430;Ternate / Babullah;;Indonesia;5;00-47N;127-23E;00-50N;127-23E;23;23;P +WAMW;97;086;Luwuk / Bubung;;Indonesia;5;00-54S;122-47E;00-54S;122-47E;2;2;P +WAPA;97;722;Amahai;;Indonesia;5;03-21S;128-53E;;;10;10; +WAPH;97;460;Labuha / Taliabu;;Indonesia;5;01-37S;124-33E;01-37S;124-33E;3;3; +WAPI;97;900;Saumlaki;;Indonesia;5;07-59S;131-18E;07-59S;131-18E;24;24;P +WAPN;97;600;Sanana;;Indonesia;5;02-05S;126-00E;02-05S;126-00E;2;2;P +WAPP;97;724;Ambon / Pattimura;;Indonesia;5;03-42S;128-05E;03-42S;128-05E;12;12;P +WAPR;97;700;Namlea;;Indonesia;5;03-15S;127-05E;;;20;20; +WASF;97;630;Fak-Fak / Torea;;Indonesia;5;02-53S;132-15E;;;130;130;P +WASK;97;760;Kaimana / Utarom;;Indonesia;5;03-40S;133-45E;03-40S;133-45E;3;3;P +WASR;97;530;Manokwari / Rendani;;Indonesia;5;00-53S;134-03E;00-53S;134-03E;3;3;P +WASS;97;502;Sorong / Jefman;;Indonesia;5;00-56S;131-07E;00-56S;131-07E;3;3;P +WBGB;96;441;Bintulu;;Malaysia;5;03-12N;113-02E;03-12N;113-02E;2;5;P +WBGG;96;413;Kuching;;Malaysia;5;01-29N;110-20E;01-29N;110-20E;27;27;P +WBGR;96;449;Miri;;Malaysia;5;04-20N;113-59E;;;17;18;P +WBGS;96;421;Sibu;;Malaysia;5;02-20N;111-50E;;;8;8;P +WBKK;96;471;Kota Kinabalu;;Malaysia;5;05-56N;116-03E;05-57N;116-03E;3;3;P +WBKL;96;465;Labuan;;Malaysia;5;05-18N;115-15E;05-17N;115-14E;30;30;P +WBKS;96;491;Sandakan;;Malaysia;5;05-54N;118-04E;05-54N;118-04E;12;13;P +WBKT;96;477;Kudat;;Malaysia;5;06-55N;116-50E;06-55N;116-50E;3;5;P +WBKW;96;481;Tawau;;Malaysia;5;04-16N;117-53E;04-16N;117-52E;18;20;P +WBSB;96;315;Brunei Airport;;Brunei;5;04-56N;114-56E;04-56N;114-56E;22;15; +WIAA;96;001;Sabang / Cut Bau;;Indonesia;5;05-52N;095-19E;05-52N;095-19E;126;126;P +WIAG;96;273;Menggala / Astra Ksetra;;Indonesia;5;04-27S;105-11E;04-37S;105-13E;19;19; +WIAM;96;801;Tasikmalaya / Cibeureum;;Indonesia;5;07-20S;108-15E;07-21S;108-15E;335;335;P +WIAR;96;881;Madiun / Iswahyudi;;Indonesia;5;07-37S;111-31E;07-37S;111-26E;110;110;P +WIAS;96;947;Malang / Abdul Rahkmansaleh;;Indonesia;5;07-58S;112-42E;07-56S;112-43E;526;526;P +WIBB;96;109;Pakanbaru / Simpangtiga;;Indonesia;5;00-28N;101-27E;00-28N;101-27E;31;31;P +WIIA;96;739;Curug / Budiarto;;Indonesia;5;06-14S;106-39E;06-17S;106-34E;46;46;P +WIIB;96;781;Bandung / Husein;;Indonesia;5;06-54S;107-35E;06-54S;107-35E;740;740;P +WIIH;96;747;Jakarta Halim Perdanakusuma;;Indonesia;5;06-15S;106-54E;;;30;30;P +WIII;96;749;Jakarta / Soekarno-Hatta;;Indonesia;5;06-07S;106-39E;06-08S;106-40E;8;8; +WIIJ;96;853;Jogyakarta / Adisucipto;;Indonesia;5;07-47S;110-26E;07-47S;110-26E;107;107;P +WIIK;96;773;Kalijati;;Indonesia;5;06-33S;107-40E;06-33S;107-40E;110;110; +WIIL;96;805;Cilacap;;Indonesia;5;07-44S;109-01E;07-44S;109-01E;6;6;P +WIIS;96;839;Semarang / Ahmadyani;;Indonesia;5;06-59S;110-23E;06-59S;110-23E;3;3;P +WIIT;96;295;Telukbetung / Beranti;;Indonesia;5;05-16S;105-11E;05-14S;105-11E;96;96;P +WIKB;96;087;Batan, Sumatra;;Indonesia;5;01-07N;104-07E;;;24;; +WIKD;96;249;Tanjungpandan / Buluh Tumbang;;Indonesia;5;02-45S;107-45E;02-45S;107-46E;44;44;P +WIKK;96;237;Pangkalpinang / Pangkalpinang;;Indonesia;5;02-10S;106-08E;02-10S;106-08E;33;33;P +WIKN;96;091;Tanjungpinang / Kijang;;Indonesia;5;00-55N;104-32E;00-55N;104-32E;18;18;P +WIKS;96;179;Singkep / Dabo;;Indonesia;5;00-29S;104-35E;00-29S;104-35E;31;31;P +WIMB;96;075;Gunung Sitoli / Binaka;;Indonesia;5;01-30N;097-38E;01-30N;097-38E;6;6;P +WIMG;96;163;Padang / Tabing;;Indonesia;5;00-53S;100-21E;00-53S;100-21E;3;3;P +WIMM;96;035;Medan / Polonia;;Indonesia;5;03-34N;098-41E;03-34N;098-40E;25;25;P +WIMS;96;073;Sibolga / Pinangsori;;Indonesia;5;01-33N;098-53E;01-33N;098-54E;3;3;P +WIOI;96;533;Singkawang Ii;;Indonesia;5;01-05N;109-40E;01-05N;109-40E;38;38; +WIOK;96;615;Ketapang / Rahadi Usmaman;;Indonesia;5;01-51S;109-58E;;;9;9; +WION;96;147;Ranai / Ranai;;Indonesia;5;03-57N;108-23E;03-55N;108-23E;2;2;P +WIOO;96;581;Pontianak / Supadio;;Indonesia;5;00-09S;109-24E;00-09S;109-24E;3;3;P +WIOS;96;559;Sintang;;Indonesia;5;00-07N;111-32E;;;30;30; +WIPA;96;195;Jambi / Sultan Taha;;Indonesia;5;01-38S;103-39E;01-38S;103-39E;25;25;P +WIPH;96;207;Kerinci / Depati Parbo;;Indonesia;5;02-46S;101-22E;;101-22E;782;782; +WIPL;96;253;Bengkulu / Padangkemiling;;Indonesia;5;03-53S;102-20E;03-52S;102-21E;16;16;P +WIPP;96;221;Palembang / Talangbetutu;;Indonesia;5;02-54S;104-42E;02-54S;104-42E;10;10;P +WIPR;96;171;Rengat / Japura;;Indonesia;5;00-28N;102-19E;00-21S;102-20E;46;46;P +WITC;96;015;Meulaboh / Cut Nyak Dhien;;Indonesia;5;04-15N;096-07E;04-15N;096-07E;90;90; +WITM;96;009;Lhokseumawe / Malikussaleh;;Indonesia;5;05-14N;097-12E;05-14N;097-12E;87;87;P +WITT;96;011;Banda Aceh / Blangbintang;;Indonesia;5;05-31N;095-25E;05-31N;095-25E;21;21;P +WMBA;48;620;Sitiawan;;Malaysia;5;04-13N;100-42E;04-13N;100-42E;7;8;P +WMKC;48;615;Kota Bharu;;Malaysia;5;06-10N;102-17E;06-10N;102-17E;5;5;P +WMKD;48;657;Kuantan;;Malaysia;5;03-37N;103-13E;03-47N;103-13E;18;16;P +WMKJ;48;679;Johore Bharu / Senai;;Malaysia;5;01-38N;103-40E;;;37;40;P +WMKK;48;647;Sebang/KL International Airport;;Malaysia;5;02-44N;101-42E;03-07N;101-33E;21;22;P +WMKL;48;600;Langkawi;;Malaysia;5;06-20N;099-44E;06-20N;099-44E;8;7;P +WMKM;48;665;Malacca;;Malaysia;5;02-16N;102-15E;;;11;9;P +WMKP;48;601;Penang / Bayan Lepas;;Malaysia;5;05-18N;100-16E;05-18N;100-16E;3;4;P +WMSA;--;---;Subang/Sultan Abdul Aziz Shah Airport;;Malaysia;5;03-07N;101-32E;;;27;; +WPDL;97;390;Dilli / Dilli Airport;;East Timor;5;08-34S;125-34E;08-33S;125-33E;6;6;P +WPEC;97;395;Baucau;;East Timor;5;08-30S;126-24E;08-30S;126-24E;522;522; +WPOC;97;385;Oe-Cusse / Oe Cusse;;East Timor;5;09-12S;124-22E;;124-22E;5;5;P +WRBB;96;685;Banjarmasin / Syamsuddin Noor;;Indonesia;5;03-26S;114-45E;03-27S;114-46E;20;20;P +WRBI;96;645;Pangkalan Bun / Iskandar;;Indonesia;5;02-42S;110-42E;02-42S;111-41E;25;25; +WRBK;96;695;Kotabaru;;Indonesia;5;03-24S;116-13E;;;18;18; +WRBM;96;595;Muaratewe / Beringin;;Indonesia;5;00-57S;114-54E;00-57S;114-54E;60;60; +WRBP;96;655;Palangkaraya / Panarung;;Indonesia;5;01-00S;114-00E;01-00S;114-00E;27;27;P +WRKC;97;300;Maumere / Wai Oti;;Indonesia;5;08-38S;122-15E;08-38S;122-14E;3;3;P +WRKK;97;372;Kupang / El Tari;;Indonesia;5;10-10S;123-40E;10-10S;123-40E;108;108;P +WRKL;97;310;Larantuka;;Indonesia;5;08-16S;122-58E;;;9;; +WRKM;97;320;Alor / Mali;;Indonesia;5;08-13S;124-34E;;;12;12; +WRKR;97;378;Rote / Baa;;Indonesia;5;10-44S;123-04E;;;1;1; +WRKS;97;380;Sabu / Tardamu;;Indonesia;5;10-30S;121-50E;10-30S;121-50E;26;26; +WRLB;96;505;Longbawan / Juvai Semaring;;Indonesia;5;03-44N;115-41E;;;550;; +WRLG;96;525;Tanjung Selor;;Indonesia;5;02-51N;117-20E;;;50;50; +WRLK;96;529;Tanjung Redep / Berau;;Indonesia;5;02-07N;117-27E;02-07N;117-27E;26;26; +WRLL;96;633;Balikpapan / Sepinggan;;Indonesia;5;01-16S;116-54E;01-16S;116-54E;3;3;P +WRLR;96;509;Tarakan / Juwata;;Indonesia;5;03-20N;117-34E;03-20N;117-34E;6;6;P +WRLS;96;607;Samarinda / Temindung;;Indonesia;5;00-37S;117-09E;00-37S;117-09E;230;230;P +WRRA;97;240;Ampenan / Selaparang;;Indonesia;5;08-32S;116-04E;08-34S;116-06E;3;3;P +WRRB;97;270;Bima;;Indonesia;5;08-33S;118-42E;08-33S;118-41E;2;2; +WRRR;97;230;Denpasar / Ngurah-Rai;;Indonesia;5;08-45S;115-10E;08-45S;115-10E;1;1;P +WRRS;97;260;Sumbawa Besar / Sumbawa Besar;;Indonesia;5;08-26S;117-25E;08-30S;117-25E;3;3;P +WRRW;97;340;Waingapu / Mau Hau;;Indonesia;5;09-40S;120-20E;09-40S;120-19E;12;12;P +WRSJ;96;935;Surabaya / Juanda;;Indonesia;5;07-22S;112-46E;07-23S;112-47E;3;3;P +WRSP;96;933;Surabaya / Perak;;Indonesia;5;07-13S;112-43E;07-13S;112-43E;3;3;P +WRSQ;96;845;Surakarta / Adisumarmo;;Indonesia;5;07-52S;110-55E;07-31S;110-45E;104;104;P +WRSS;96;937;Surabaya;;Indonesia;5;07-13S;113-43E;;;3;3; +WSAP;48;694;Singapore / Paya Lebar;;Singapore;5;01-22N;103-55E;01-22N;103-55E;18;32; +WSSS;48;698;Singapore / Changi Airport;;Singapore;5;01-22N;103-59E;01-22N;103-59E;5;16;P +YAYE;--;---;Ayers Rock;;Australia;5;25-11S;130-58E;;;496;; +YBAF;94;575;Archerfield Aerodrome;;Australia;5;27-34S;153-00E;;;23;18; +YBAM;94;568;Amberley Aerodrome;;Australia;5;27-38S;152-43E;;;27;31;P +YBAS;94;326;Alice Springs Aerodrome;;Australia;5;23-48S;133-53E;23-48S;133-54E;545;547;P +YBBN;94;578;Brisbane Airport M. O;;Australia;5;27-23S;153-06E;27-25S;153-05E;4;5;P +YBCG;94;592;Coolangatta Airport Aws;;Australia;5;28-10S;153-30E;;;6;6; +YBCS;94;287;Cairns Airport;;Australia;5;16-53S;145-45E;16-53S;145-45E;3;7;P +YBCV;94;510;Charleville Airport;;Australia;5;26-24S;146-16E;26-25S;146-16E;306;304;P +YBGL;94;380;Gladstone;;Australia;5;23-51S;151-15E;23-51S;151-16E;75;76;P +YBLR;94;346;Longreach Airport;;Australia;5;23-26S;144-16E;23-26S;144-16E;192;193;P +YBMA;94;332;Mount Isa Amo;;Australia;5;20-40S;139-28E;20-40S;139-29E;342;341;P +YBMK;94;367;Mackay Mo;;Australia;5;21-07S;149-12E;21-07S;149-13E;30;32;P +YBOK;94;552;Oakey Aerodrome;;Australia;5;27-25S;151-44E;;;407;407;P +YBPN;94;365;Proserpine Airport;;Australia;5;20-29S;148-32E;;;25;18; +YBRK;94;374;Rockhampton Airport;;Australia;5;23-23S;150-28E;23-23S;150-28E;10;14;P +YBRM;94;203;Broome Airport;;Australia;5;17-57S;122-13E;17-57S;122-14E;17;9;P +YBTL;94;294;Townsville Amo;;Australia;5;19-15S;146-45E;19-15S;146-45E;6;9;P +YBWP;94;171;Weipa City;;Australia;5;12-38S;141-53E;;;12;; +YDGV;94;150;Gove Airport;;Australia;5;12-16S;136-49E;12-16S;136-49E;52;54;P +YDTC;94;238;Tennant Creek Airport;;Australia;5;19-38S;134-10E;19-38S;134-10E;375;376;P +YDYL;94;462;Yulara Aws;;Australia;5;25-11S;130-58E;;;493;492; +YMAV;--;---;Avalon, Avalon Airport;;Australia;5;38-02S;144-29E;;;8;; +YMAY;94;896;Albury Airport;;Australia;5;36-04S;146-57E;;;165;171; +YMDV;94;960;Devonport East;;Australia;5;41-10S;146-22E;;;47;; +YMEN;94;864;Goldstream Aws;;Australia;5;37-44S;145-24E;;;76;84; +YMES;94;907;East Sale Aerodrome;;Australia;5;38-06S;147-08E;38-06S;147-08E;5;8;P +YMHB;94;975;Hobart Airport;;Australia;5;42-50S;147-29E;42-50S;147-30E;4;27;P +YMLT;94;968;Launceston Airport;;Australia;5;41-32S;147-12E;41-32S;147-12E;171;178;P +YMLV;94;865;Laverton Aerodrome;;Australia;5;37-51S;144-44E;37-52S;144-45E;18;21;P +YMMB;94;870;Moorabbin Airport Aws;;Australia;5;37-58S;145-06E;;;13;13;P +YMMG;94;821;Mount Gambier Aerodrome;;Australia;5;37-44S;140-47E;37-44S;140-47E;65;69;P +YMMI;94;693;Mildura Airport;;Australia;5;34-13S;142-05E;34-14S;142-05E;50;52;P +YMML;94;866;Melbourne Airport;;Australia;5;37-40S;144-50E;37-44S;144-50E;132;141;P +YMMQ;94;998;Macquarie Island;;Australia;5;54-29S;158-57E;54-29S;158-56E;6;8;P +YMWY;94;957;Wynyard West;;Australia;5;40-59S;145-43E;;;11;; +YPAD;94;672;Adelaide Airport;;Australia;5;34-56S;138-31E;34-56S;138-31E;6;4;P +YPAL;94;802;Albany Airport;;Australia;5;34-56S;117-48E;34-56S;117-48E;71;69;P +YPBH;94;689;Broken Hill Patton Street;;Australia;5;31-58S;141-28E;;;315;;P +YPCC;96;996;Cocos Island Airport;;Christmas Island;5;12-11S;096-49E;12-11S;096-50E;3;3;P +YPCD;94;653;Ceduna Airport;;Australia;5;32-07S;133-42E;32-07S;133-42E;23;17;P +YPDB;94;205;Derby;;Australia;5;17-18S;123-37E;17-19S;123-38E;8;9;P +YPDN;94;120;Darwin Airport;;Australia;5;12-24S;130-52E;12-26S;130-52E;31;30;P +YPEA;94;612;Bullsbrook Pearce Amo;;Australia;5;31-40S;116-01E;;;45;49;P +YPED;95;676;Edinburgh M. O.;;Australia;5;34-42S;138-37E;;;20;20;P +YPFT;94;646;Forrest Airport;;Australia;5;30-50S;128-06E;30-50S;128-06E;160;156; +YPGN;94;403;Geraldton Airport;;Australia;5;28-47S;114-42E;28-48S;114-42E;37;34;P +YPKG;94;637;Kalgoorlie Boulder Amo;;Australia;5;30-47S;121-27E;30-46S;121-27E;367;370;P +YPKU;94;216;Kununurra Kununurra Aws ;;Australia;5;15-46S;128-42E;;;44;45;P +YPLC;94;674;Leigh Creek Airport;;Australia;5;30-35S;138-25E;;;261;259; +YPLM;94;302;Learmonth Airport;;Australia;5;22-14S;114-05E;22-14S;114-05E;5;6;P +YPMR;94;430;Meekatharra Airport;;Australia;5;26-36S;118-32E;26-36S;118-31E;522;518;P +YPPD;94;312;Port Hedland Pardoo;;Australia;5;20-06S;119-34E;20-22S;118-37E;9;10;P +YPPF;95;677;Parafield Airport;;Australia;5;34-47S;138-38E;;;17;10;P +YPPH;94;610;Belmont Perth Airport ;;Australia;5;31-56S;115-57E;31-55S;115-58E;20;29;P +YPTN;--;---;Tindal / Katherine;;Australia;5;14-26S;132-16E;;;108;109;P +YPWR;94;659;Woomera Aerodrome;;Australia;5;31-08S;136-49E;31-09S;136-48E;165;167;P +YPXM;96;995;Christmas Island Aerodrome;;Christmas Island;5;10-26S;105-41E;10-27S;105-42E;279;262;P +YSBK;94;765;Bankstown Airport Aws;;Australia;5;33-55S;150-59E;;;9;8; +YSCB;94;926;Canberra;;Australia;5;35-18S;149-11E;35-18S;149-11E;575;580;P +YSCH;94;791;Coffs Harbour Mo;;Australia;5;30-19S;153-07E;30-19S;153-07E;5;6;P +YSCM;94;923;Cooma;;Australia;5;36-14S;149-05E;;;778;; +YSCN;94;755;Camden Airport;;Australia;5;34-02S;150-41E;;;70;; +YSDU;94;719;Dubbo;;Australia;5;32-12S;148-34E;32-12S;148-34E;275;275;P +YSNF;94;996;Norfolk Island Airport;;Australia;5;29-02S;167-56E;29-02S;167-56E;113;109;P +YSNW;94;750;Nowra Ran Air Station;;Australia;5;34-57S;150-32E;34-57S;150-32E;122;110;P +YSRI;94;753;Richmond Aus-Afb ;;Australia;5;33-36S;150-47E;;;21;; +YSSY;94;767;Sydney Airport;;Australia;5;33-57S;151-11E;33-57S;151-11E;6;3;P +YSTW;94;762;Tamworth Airport;;Australia;5;31-05S;150-50E;;;410;; +YSWG;94;910;Wagga Airport;;Australia;5;35-09S;147-27E;35-09S;147-27E;221;213;P +YSWM;94;776;Williamtown Aerodrome;;Australia;5;32-47S;151-49E;32-47S;151-49E;9;8;P +ZBAA;54;511;Beijing;;China;2;39-56N;116-17E;39-48N;116-28E;55;55; +ZBHH;53;463;Hohhot;;China;2;40-49N;111-41E;40-49N;111-41E;1065;1065; +ZBTJ;--;---;Tianjin / Zhangguizhu;;China;2;39-11N;117-21E;;;3;; +ZBYN;53;772;Taiyuan;;China;2;37-47N;112-33E;37-47N;112-33E;779;779; +ZGCS;57;679;Changsha;;China;2;28-12N;113-05E;28-12N;112-58E;46;46; +ZGGG;59;287;Guangzhou;;China;2;23-10N;113-20E;23-08N;113-19E;8;42; +ZGHA;--;---;Changsha;;China;2;28-14N;112-52E;;;;; +ZGHK;59;758;Haikou;;China;2;20-02N;110-21E;20-02N;110-21E;15;15; +ZGKL;57;957;Guilin;;China;2;25-20N;110-18E;25-20N;110-18E;166;166; +ZGNN;59;431;Nanning;;China;2;22-49N;108-21E;22-49N;108-21E;73;73; +ZGOW;59;316;Shantou;;China;2;23-24N;116-41E;23-21N;116-40E;3;3; +ZGSZ;59;493;Shenzhen;;China;2;22-33N;114-06E;;;18;18; +ZGZJ;59;658;Zhanjiang;;China;2;21-13N;110-24E;21-13N;110-24E;28;28; +ZHCC;57;083;Zhengzhou;;China;2;34-43N;113-39E;34-43N;113-39E;111;111; +ZHHH;57;494;Wuhan;;China;2;30-37N;114-08E;30-35N;114-16E;23;23; +ZJSY;--;---;Sanya/Fenghuang;;China;2;18-18N;109-24E;;;27;; +ZKKC;47;025;Kimchaek;;Korea, North;2;40-40N;129-12E;;;19;23;P +ZKPY;47;058;Pyongyang;;Korea, North;2;39-02N;125-47E;39-02N;125-47E;36;38;P +ZLIC;53;614;Yinchuan;;China;2;38-29N;106-13E;38-29N;106-13E;1112;1112; +ZLJQ;52;533;Jiuquan;;China;2;39-46N;098-29E;39-46N;098-31E;1478;1478; +ZLLL;--;---;Lanzhou / Zhongchuan;;China;2;36-01-12N;103-45E;;;;; +ZLSN;57;036;Xi'An;;China;2;34-18N;108-56E;34-18N;108-56E;398;398; +ZLXN;52;866;Xining;;China;2;36-37N;101-46E;36-43N;101-45E;2262;2262; +ZLXY;--;---;Xian/Xianyang;;China;2;34-26N;108-45E;;;479;; +ZLYA;53;845;Yan An;;China;2;36-36N;109-30E;36-36N;109-30E;959;959; +ZMUB;--;---;Ulan-Bator;;Mongolia;2;47-51N;106-46E;;;;; +ZPPP;56;778;Kunming;;China;2;25-01N;102-41E;25-01N;102-41E;1892;1892; +ZSAM;59;134;Xiamen;;China;2;24-29N;118-05E;24-27N;118-04E;139;139; +ZSCN;58;606;Nanchang;;China;2;28-36N;115-55E;28-40N;115-55E;50;50; +ZSFZ;58;847;Fuzhou;;China;2;26-05N;119-17E;26-05N;119-17E;85;85; +ZSGZ;57;993;Ganzhou;;China;2;25-51N;114-57E;25-51N;114-56E;125;125; +ZSHC;58;457;Hangzhou;;China;2;30-14N;120-10E;30-14N;120-10E;43;43; +ZSNJ;58;238;Nanjing;;China;2;32-00N;118-48E;32-00N;118-48E;12;12; +ZSOF;58;321;Hefei;;China;2;31-52N;117-14E;31-52N;117-14E;36;36; +ZSPD;--;---;Shanghai / Pudong;;China;2;31-07N;121-46E;;;4;; +ZSQD;54;857;Qingdao;;China;2;36-04N;120-20E;36-04N;120-20E;77;77; +ZSSS;58;367;Shanghai / Hongqiao;;China;2;31-10N;121-26E;31-10N;121-26E;7;3; +ZSTN;54;823;Jinan;;China;2;36-41N;116-59E;36-41N;116-59E;58;58; +ZUCK;57;516;Chongqing;;China;2;29-31N;106-29E;29-31N;106-29E;351;351; +ZUGY;57;816;Guiyang;;China;2;26-35N;106-43E;26-29N;106-39E;1074;1074; +ZULS;55;591;Lhasa;;China;2;29-40N;091-08E;29-40N;091-08E;3650;3650; +ZUUU;56;294;Chengdu;;China;2;30-40N;104-01E;30-40N;104-01E;508;508; +ZWHM;52;203;Hami;;China;2;42-49N;093-31E;42-49N;093-31E;739;739; +ZWSH;51;709;Kashi;;China;2;39-28N;075-59E;39-28N;075-59E;1291;1291; +ZWTN;51;828;Hotan;;China;2;37-08N;079-56E;37-08N;079-56E;1375;1375; +ZWWW;--;---;Urum-Qi / Diwopu;;China;2;43-54N;087-28E;;;654;; +ZWYN;51;431;Yining;;China;2;43-57N;081-20E;43-57N;081-20E;663;663; +ZYCC;54;161;Changchun;;China;2;43-54N;125-13E;43-54N;125-13E;238;238; +ZYHB;--;---;Harbin;;China;2;46-01-12N;126-34-48E;;;;; +ZYQQ;50;745;Qiqihar;;China;2;47-23N;123-55E;47-23N;123-55E;148;148; +ZYTL;54;662;Dalian;;China;2;38-54N;121-38E;38-59N;121-38E;97;97; +ZYTX;--;---;Shenyang / Taokian;;China;2;41-48N;123-24E;;;35; diff --git a/pingcheck b/pingcheck new file mode 100755 index 0000000..6997c2a --- /dev/null +++ b/pingcheck @@ -0,0 +1,22 @@ +#!/bin/bash + +host=$1 +file=$2 +text=$3 +SERVERIP=$host +NOTIFYEMAIL=test@example.com + +ping -c 3 $SERVERIP > /dev/null 2>&1 +if [ $? -ne 0 ] +then + # Use your favorite mailer here: + #mailx -s "Server $SERVERIP is down" -t "$NOTIFYEMAIL" < /dev/null + echo $1 + echo $2 + echo $3 + #/usr/bin/ambestream -v -t "${3}" -4 -my KD8TUZ -d 127.0.0.1 -bi 7500 -bl 1000 -p 40000 KD8TUZ B /root/systemissues/$2.dvtool + /usr/local/bin/voicetransmit KD8TUZ_B /root/systemissues/$2.dvtool + +fi + +exit 0 diff --git a/playWxAlert b/playWxAlert new file mode 100755 index 0000000..2707c91 --- /dev/null +++ b/playWxAlert @@ -0,0 +1,100 @@ +#!/bin/bash +######################################################################## +# +# +# description: This script will play the weather alert audio files +# that get created by the getWxAlert script. +# +# history: +# Original script written from kc6hur, modified by w0anm +# +# $Id: playWxAlert 84 2012-07-20 02:35:35Z $ +######################################################################## + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# Check Arguments... +# has only one argument, county info +if [ "$#" = "1" ] ; then + COUNTY=$1 + COUNTY_NAME=$1 +fi + +# has two arguments, county info and county name +if [ "$#" = "2" ] ; then + COUNTY=$1 + COUNTY_NAME=$2 +fi + +# if no arguments, then use what is defined in configure file. +if [ "$1" = "" ] ; then + # extract County Information and County Name + COUNTY_NAME=`echo $COUNTY | awk 'BEGIN { FS="," } { print $2} '` + COUNTY=`echo $COUNTY | awk 'BEGIN { FS="," } { print $1} '` +fi + +if [ "$COUNTY" = "NOTSET" ] || [ "$COUNTY" = "" ] ; then + echo "ERROR - The COUNTY variable in ${CUSTOM}/wx_scripts.conf is not set" + echo "or missing, aborting..." + exit 1 +fi + +if [ "$COUNTY" = "help" ] ; then # If no arguments + echo "Usage playWxAlert " + echo " where =State County, for example: WIC002" + echo " See http://alerts.weather.gov/ for more informaton" + echo + echo " Or you can edit the wx_scripts.conf file to include the COUNTY variable." + echo + exit 1 +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + if [ -f ${LOCAL}/active ] ; then + echo "${0##*/}: ERROR - Node is busy, must be idle to run." + exit 1 + fi +fi + +# Set if ACTIVE_PLAY is false, +if [ $ACTIVE_PLAY = "FALSE" ] ; then + touch ${LOCAL}/active +fi + +# if argument is not a directory, abort and do nothing. send error +if [ ! -d $WXALERT_SPOOLDIR/$COUNTY ] ; then + # msg to log file. + log "Directory $WXALERT_SPOOLDIR/$COUNTY is not present, aborting..." + exit 1 +fi + +# if full summary selected, then play the complete summary, else +# play the truncated alert. +if [ "$FULL_ALERT" = "Y" ] ; then + if [ -f ${CUSTOM}/custom_wavplay ] ; then + ${CUSTOM}/custom_wavplay custom/wx/alert/$COUNTY/FULLCOMPLETE_ALERT &> /dev/null 2>&1 + else + /usr/sbin/asterisk -rx "rpt localplay /custom/wx/alert/$COUNTY/FULLCOMPLETE_ALERT" &> /dev/null 2>&1 + fi +else + if [ -f ${CUSTOM}/custom_wavplay ] ; then + ${CUSTOM}/custom_wavplay custom/wx/alert/$COUNTY/COMPLETE_ALERT &> /dev/null 2>&1 + else + # /usr/sbin/asterisk -rx "rpt localplay 27539 /custom/wx/alert/$COUNTY/COMPLETE_ALERT" &> /dev/null 2>&1 + voicetransmit KD8TUZ_B /custom/wx/alert/$COUNTY/ALERT.dvtool &> /dev/null 2>&1 + fi +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + rm ${LOCAL}/active +fi + +exit 0 + diff --git a/playWxAlertBg b/playWxAlertBg new file mode 100755 index 0000000..9b0dfed --- /dev/null +++ b/playWxAlertBg @@ -0,0 +1,158 @@ +#!/bin/bash +# +# $Id: playWxAlertBg 74 2011-04-20 19:55:19Z $ +# +# Play weather alerts Announcements +# Normally placed in background from getWxAlert. +# by W0ANM +# + +# My process id +MYPROC=$$ + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# multiple zone support. +# if COUNTY not an argument, then use what is defined in configure file. +if [ "$1" = "" ] ; then + COUNTY=$COUNTY +else + COUNTY=$1 +fi + +# if argument is not a directory, abort and do nothing. send error +if [ ! -d /custom/wx/alert/$COUNTY ] ; then + # msg to log file. + log "COUNTY directory $COUNTY is not present, aborting..." + exit 1 +fi + +WXALERT_TEXT=${WXALERT_SPOOLDIR}/$COUNTY/alert.txt +NO_WXALERT_MSG=$LOCAL/no_wxalert_msg + +# store the PID +echo "$$" > $WXALERT_SPOOLDIR/$COUNTY/playWxAlertBg.pid + +########## +PlayMsg () { +# /usr/sbin/asterisk -rx "rpt localplay 27539 /custom/wx/alert/$COUNTY/ALERT" &> /dev/null 2>&1 +# /usr/local/bin/texttransmit N8MFN__B -f /custom/wx/alert/OHC017/wx_new.txt +# /home/irlp/custom/dstartx + #/usr/local/bin/voicetransmit N8MFN _B /custom/wx/alert/$COUNTY/ALERT.dvtool +# /root/voice-ann/ambestream -t "Current Wx Alert" -v -4 -my N8MFN -d 141.148.63.71 -bi 7500 -bl 1000 -p 40000 XLX265 B /custom/wx/alert/OHC017/ALERT.dvtool > /dev/null 2>&1 + /root/voice-ann/ambestream -t "Current Wx Alert" -v -4 -my N8MFN -d 10.147.17.8 -bi 7500 -bl 1000 -p 40000 N8MFN B /custom/wx/alert/OHC017/ALERT.dvtool > /dev/null 2>&1 +# curl -X POST https://home.kb8pmy.net/api/webhook/play_weather_alert +# curl -X POST -H 'Content-type: application/json' --data '{"text":"WRJI518, Testing intergration!"}' https://hooks.slack.com/services/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 +# curl -X POST --silent --data-urlencode "payload={\"text\": \"$(cat /custom/wx/alert/$COUNTY/alert.txt | sed "s/\"/'/g")\"}" "$2" https://hooks.slack.com/services/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 + +} # end PlayMsg + +########## +PlayAlert() { + + # Play Alert Message + log "$Msg" + PlayMsg +} + + +####################################################################### +# Main Program + +# Run's in background, called by getWxAlert + +while [ -f $WXALERT_TEXT ] ; do + # initial broadcast + # check if lock file is present. If so, wait for file to be + # removed, this prevents alert announcements from simultaneioulsy + # being sent. + # if NO_WXALERT file is present, skip playing msg + if [ ! -f $NO_WXALERT_MSG ] ; then + while [ -f /tmp/playWxAlertBg-lock ] ; do + sleep 30 + done + + # set lock file + echo $MYPROC > /tmp/playWxAlertBg-lock + + Msg="Playing Wx Alert (initial) for $COUNTY" + PlayAlert + + # clear lock file + rm /tmp/playWxAlertBg-lock + else + log "Skipping Wx Alert (initial) for $COUNTY, $NO_WXALERT_MSG present" + fi + + # play time is initial, 15m, 15m, 15m, 30m, 30m, then every 60m + for SLEEPTIME in 900 900 900 1800 1800 ; do + # for SLEEPTIME in 86400 ; do + # sleep 15 mins (900) + sleep $SLEEPTIME + if [ ! -f $WXALERT_TEXT ] ; then + break + fi + if [ ! -f $NO_WXALERT_MSG ] ; then + # check if lock file is present. If so, wait for file to be + # removed, this prevents alert announcements from simultaneioulsy + # being sent. + while [ -f /tmp/playWxAlertBg-lock ] ; do + sleep 30 + done + # set lock file + echo $MYPROC > /tmp/playWxAlertBg-lock + + Msg="Playing Wx Alert (${SLEEPTIME}s) for $COUNTY" + PlayAlert + + # clear lock file + rm /tmp/playWxAlertBg-lock + else + log "Skipping Wx Alert (${SLEEPTIME}s) for $COUNTY, $NO_WXALERT_MSG present" + fi + done + + while [ -f $WXALERT_TEXT ] ; do + #every 60m + sleep 3600 + if [ ! -f $WXALERT_TEXT ] ; then + break + fi + if [ ! -f $NO_WXALERT_MSG ] ; then + # check if lock file is present. + while [ -f /tmp/playWxAlertBg-lock ] ; do + sleep 30 + done + # set lock file + echo $MYPROC > /tmp/playWxAlertBg-lock + + Msg="Playing Wx Alert (${SLEEPTIME}s) for $COUNTY" + PlayAlert + + # clear lock file + rm /tmp/playWxAlertBg-lock + else + log "Skipping Wx Alert (${SLEEPTIME}s) for $COUNTY, $NO_WXALERT_MSG present" + fi + done +done + +# remove PID file +rm $WXALERT_SPOOLDIR/$COUNTY/playWxAlertBg.pid + +# remove NO_WXALERT_MSG file +if [ -f $NO_WXALERT_MSG ] ; then + rm -r $NO_WXALERT_MSG +fi + +log "Alert over for $COUNTY" + +exit 0 + diff --git a/playWxFor b/playWxFor new file mode 100755 index 0000000..7470929 --- /dev/null +++ b/playWxFor @@ -0,0 +1,59 @@ +#!/bin/bash +######################################################################## +# filename: playWxFor [] +# +# description: This script will play the weather forecast audio files +# that get created by the getWxFor script. +# +# history: +# script based upon kc6hur playWxRpt +# Modified by w0anm for changes see below +# $Id: playWxFor 34 2009-01-14 18:56:08Z $ +######################################################################## + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + if [ -f ${LOCAL}/active ] ; then + echo "${0##*/}: ERROR - Node is busy, must be idle to run." + exit 1 + fi +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + touch ${LOCAL}/active +fi + +# multiple zone support. +# if ZONE not an argument, then use what is defined in configure file. +if [ "$1" = "" ] ; then + ZONE=$ZONE +else + ZONE=$1 +fi + +# if argument is not a directory, abort and do nothing. send error +if [ ! -d /home/irlp/audio/custom/wx/forecast/$ZONE ] ; then + # msg to log file. + log "ZONE directory /home/irlp/audio/custom/wx/forecast/$ZONE is not present, aborting..." + exit 1 +fi + +if [ -f ${CUSTOM}/custom_wavplay ] ; then + ${CUSTOM}/custom_wavplay custom/wx/forecast/$ZONE/forecast &> /dev/null 2>&1 +else + /usr/sbin/asterisk -rx "rpt localplay 27539 /custom/wx/forecast/$ZONE/forecast" &> /dev/null 2>&1 +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + rm ${LOCAL}/active +fi + +exit 0 diff --git a/playWxRpt b/playWxRpt new file mode 100755 index 0000000..9b6f8d2 --- /dev/null +++ b/playWxRpt @@ -0,0 +1,54 @@ +#!/bin/bash +######################################################################## +# +# +# filename: playWxRpt +# +# description: This script will play the weather report audio files +# that get created by the getWxRpt script. +# +# history: +# 20030818 kc6hur Origial release +# +# Modified by W0ANM +# $Id: playWxRpt 31 2009-01-05 02:52:02Z $ +######################################################################## + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# if ICAO_STN not an argument, then use what is defined in configure file. +if [ "$1" = "" ] ; then + ICAO_LIST=$ICAO_STN +else + ICAO_LIST=$1 +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + if [ -f ${LOCAL}/active ] ; then + echo "${0##*/}: ERROR - Node is busy, must be idle to run." + exit 1 + fi +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + touch ${LOCAL}/active +fi + +if [ -f ${CUSTOM}/custom_wavplay ] ; then + ${CUSTOM}/custom_wavplay custom/wx/report/$ICAO_LIST &> /dev/null 2>&1 +else + /usr/sbin/asterisk -rx "rpt localplay 27539 /custom/wx/report/$ICAO_LIST" &> /dev/null 2>&1 +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + rm ${LOCAL}/active +fi + +exit 0 diff --git a/playWxRpt_ug b/playWxRpt_ug new file mode 100755 index 0000000..f39ebd0 --- /dev/null +++ b/playWxRpt_ug @@ -0,0 +1,57 @@ +#!/bin/bash +######################################################################## +# +# +# filename: playWxRpt +# +# description: This script will play the weather report audio files +# that get created by the getWxRpt script. +# +# history: +# 20030818 kc6hur Origial release +# +# Modified by W0ANM +# $Id: playWxRpt 18 2008-04-02 21:17:04Z kovacs $ +######################################################################## + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + + +# if Weather Underground _STN not an argument, then use what is defined in configure file. +if [ "$1" = "" ] ; then + WX_UNDERGRND_STN=${WX_UNDERGRND_STN} +else + WX_UNDERGRND_STN=$1 +fi + +UG_WX_DIR=custom/wx/report_ug/${WX_UNDERGRND_STN} + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + if [ -f ${LOCAL}/active ] ; then + echo "${0##*/}: ERROR - Node is busy, must be idle to run." + exit 1 + fi +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + touch ${LOCAL}/active +fi + +if [ -f ${CUSTOM}/custom_wavplay ] ; then + ${CUSTOM}/custom_wavplay $UG_WX_DIR/current_wx &> /dev/null 2>&1 +else + /usr/sbin/asterisk -rx "rpt localplay 27539 $UG_WX_DIR/current_wx" &> /dev/null 2>&1 +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + rm ${LOCAL}/active +fi + + diff --git a/playWxSkywarn b/playWxSkywarn new file mode 100755 index 0000000..a7c796a --- /dev/null +++ b/playWxSkywarn @@ -0,0 +1,58 @@ +#!/bin/bash +######################################################################## +# +# +# filename: playWxSkywarn +# +# description: This script will play if skywarn spotters will be needed +# based upon getWxSkywarn script. +# +# $Id: playWxSkywarn 31 2009-01-05 02:52:02Z $ +######################################################################## + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + if [ -f ${LOCAL}/active ] ; then + echo "${0##*/}: ERROR - Node is busy, must be idle to run." + exit 1 + fi +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + touch ${LOCAL}/active +fi + +# multiple zone support. +# if ZONE not an argument, then use what is defined in configure file. +if [ "$1" = "" ] ; then + ZONE=$ZONE +else + ZONE=$1 +fi + +# if argument is not a directory, abort and do nothing. send error +if [ ! -d /home/irlp/audio/custom/wx/skywarn/$ZONE ] ; then + # msg to log file. + log "ZONE directory $ZONE is not present, aborting..." + exit 1 +fi + +if [ -f ${CUSTOM}/custom_wavplay ] ; then + ${CUSTOM}/custom_wavplay custom/wx/skywarn/$ZONE/spotter &> /dev/null 2>&1 +else + ${SCRIPT}/wavplay custom/wx/skywarn/$ZONE/spotter &> /dev/null 2>&1 +fi + +if [ $ACTIVE_PLAY = "FALSE" ] ; then + rm ${LOCAL}/active +fi + +exit 0 diff --git a/playbothnews b/playbothnews new file mode 100755 index 0000000..46edf48 --- /dev/null +++ b/playbothnews @@ -0,0 +1,7 @@ +#!/bin/bash + +/home/irlp/custom/playnews ARN +/usr/local/bin/voicetransmit KD8TUZ_B /home/irlp/custom/voice/ARRLstart5.dvtool +sleep 5m + +/home/irlp/custom/playnews ARRL diff --git a/playbothnewsrnlb b/playbothnewsrnlb new file mode 100755 index 0000000..7247fbc --- /dev/null +++ b/playbothnewsrnlb @@ -0,0 +1,8 @@ +#!/bin/bash + +/home/irlp/custom/playnewsrnlb ARN +#/usr/local/bin/voicetransmit KD8TUZ_B /home/irlp/custom/voice/ARRLstart5.dvtool +ambestream -t "${NEWSTYPE} starting in 5 min" -v -4 -my KD8TUZ -d rep.w8rnl.com -bi 7500 -bl 1000 -p 40000 W8RNL B $VOICEDIR/ARRLstart5.dvtool +sleep 5m + +/home/irlp/custom/playnewsrnlb ARRL diff --git a/playbothnewsrnlc b/playbothnewsrnlc new file mode 100755 index 0000000..e0141bd --- /dev/null +++ b/playbothnewsrnlc @@ -0,0 +1,8 @@ +#!/bin/bash + +/home/irlp/custom/playnewsrnlc ARN +#/usr/local/bin/voicetransmit KD8TUZ_B /home/irlp/custom/voice/ARRLstart5.dvtool +ambestream -t "${NEWSTYPE} starting in 5 min" -v -4 -my KD8TUZ -d rep.w8rnl.com -bi 7500 -bl 1000 -p 40000 W8RNL C $VOICEDIR/ARRLstart5.dvtool +sleep 5m + +/home/irlp/custom/playnewsrnlc ARRL diff --git a/playbothnewstuz b/playbothnewstuz new file mode 100755 index 0000000..f95047a --- /dev/null +++ b/playbothnewstuz @@ -0,0 +1,8 @@ +#!/bin/bash + +/home/irlp/custom/playnewstuz ARN +#/usr/local/bin/voicetransmit KD8TUZ_B /home/irlp/custom/voice/ARRLstart5.dvtool +ambestream -t "${NEWSTYPE} starting in 5 min" -v -4 -my KD8TUZ -d 127.0.0.1 -bi 7500 -bl 1000 -p 40000 KD8TUZ B $VOICEDIR/ARRLstart5.dvtool +sleep 5m + +/home/irlp/custom/playnewstuz ARRL diff --git a/playnews2 b/playnews2 new file mode 100755 index 0000000..cc4c929 --- /dev/null +++ b/playnews2 @@ -0,0 +1,80 @@ +#!/bin/bash + +# NEWSTYPE is either ARRL or ARN, Always required as parameter 1 +# +if [ -z "$1" ] + then + echo "No Play type given - ARN or ARRL" + exit 1 + else + NEWSTYPE=${1} + if [ "$NEWSTYPE" != "ARN" ] && [ "$NEWSTYPE" != "ARRL" ] + then + echo "Play type must be ARRL or ARN" + exit 1 + fi +fi + +TMPDIR="/tmp" +VOICEDIR="/home/irlp/custom/voice" +MAXPART=`cat /tmp/"$NEWSTYPE"_MAXPART` + +# send start announcment +# Add 3 second delay to beginning of text +sleep 3 +/usr/local/bin/voicetransmit KD8TUZ_B $VOICEDIR/${NEWSTYPE}start.dvtool + +sleep 10 + +# Start news +PART="1" +while [ "$PART" -le "$MAXPART" ]; do + echo "Playing file $TMPDIR/$NEWSTYPE.part$PART.dvtool" + if [ "$PART" -lt "$MAXPART" ]; then + # Add Station break message with 1second delay + /usr/local/bin/voicetransmit KD8TUZ_B $TMPDIR/$NEWSTYPE.part$PART.dvtool + sleep 1 + /usr/local/bin/voicetransmit KD8TUZ_B $VOICEDIR/${NEWSTYPE}continue.dvtool + + # Break every 2.5 minutes for 20 seconds + # Note this break has to be long enough for network ID's + sleep 20 + else + # Append end message with 2 second delay + /usr/local/bin/voicetransmit KD8TUZ_B $TMPDIR/$NEWSTYPE.part$PART.dvtool + sleep 2 + /usr/local/bin/voicetransmit KD8TUZ_B $VOICEDIR/${NEWSTYPE}stop.dvtool + # Terminate script at end of audio + #cat $TMPDIR/$NEWSTYPE.part$PART.wav $VOICEDIR/${NEWSTYPE}stop.wav > $TMPDIR/$NEWSTYPE.wav + LENGTH=`soxi -D $TMPDIR/$NEWSTYPE.wav 2>/dev/null` + DELAY=${LENGTH/.*} + sleep $DELAY + fi + let "PART += 1" + if [ "$PART" -lt "$MAXPART" ]; then + # Add Station break message with 1 second delay + /usr/local/bin/voicetransmit KD8TUZ_B $TMPDIR/$NEWSTYPE.part$PART.dvtool + sleep 1 + /usr/local/bin/voicetransmit KD8TUZ_B $VOICEDIR/${NEWSTYPE}continue.dvtool + + # Break every 2.5 minutes for 20 seconds + sleep 20 + else + # Append end message with 2 second delay + /usr/local/bin/voicetransmit KD8TUZ_B $TMPDIR/$NEWSTYPE.part$PART.dvtool + sleep 2 + /usr/local/bin/voicetransmit KD8TUZ_B $VOICEDIR/${NEWSTYPE}stop.dvtool + # Terminate script at end of audio + cat $TMPDIR/$NEWSTYPE.part$PART.wav $VOICEDIR/${NEWSTYPE}stop.wav > $TMPDIR/$NEWSTYPE.wav + LENGTH=`soxi -D $TMPDIR/$NEWSTYPE.wav` + DELAY=${LENGTH/.*} + sleep $DELAY + fi + let "PART += 1" +done + +# Remove all files created by playnews +#rm -f $TMPDIR/$NEWSTYPE* + +# Done +exit 0 diff --git a/playnewsrnlb b/playnewsrnlb new file mode 100755 index 0000000..a18f2d0 --- /dev/null +++ b/playnewsrnlb @@ -0,0 +1,33 @@ +#!/bin/bash + +# NEWSTYPE is either ARRL or ARN, Always required as parameter 1 +# +if [ -z "$1" ] + then + echo "No Play type given - ARN or ARRL" + exit 1 + else + NEWSTYPE=${1} + if [ "$NEWSTYPE" != "ARN" ] && [ "$NEWSTYPE" != "ARRL" ] + then + echo "Play type must be ARRL or ARN" + exit 1 + fi +fi + +TMPDIR="/tmp" +VOICEDIR="/home/irlp/custom/voice" + +# send start announcment +# Add 3 second delay to beginning of text +sleep 3 +#/usr/local/bin/voicetransmit KD8TUZ_B $VOICEDIR/${NEWSTYPE}start.dvtool + ambestream -t "${NEWSTYPE} starting....." -v -4 -my KD8TUZ -d rep.w8rnl.com -bi 7500 -bl 1000 -p 40000 W8RNL B $VOICEDIR/${NEWSTYPE}start.dvtool + ambestream -t "$NEWSTYPE News Line." -v -4 -my KD8TUZ -d rep.w8rnl.com -bi 7500 -bl 1000 -p 40000 W8RNL B $TMPDIR/${NEWSTYPE}RNLB.dvtool + ambestream -t "${NEWSTYPE} stopped....." -v -4 -my KD8TUZ -d rep.w8rnl.com -bi 7500 -bl 1000 -p 40000 W8RNL B $VOICEDIR/${NEWSTYPE}stop.dvtool + +# Remove all files created by playnews +#rm -f $TMPDIR/$NEWSTYPE* + +# Done +exit 0 diff --git a/playnewsrnlc b/playnewsrnlc new file mode 100755 index 0000000..c1b8820 --- /dev/null +++ b/playnewsrnlc @@ -0,0 +1,33 @@ +#!/bin/bash + +# NEWSTYPE is either ARRL or ARN, Always required as parameter 1 +# +if [ -z "$1" ] + then + echo "No Play type given - ARN or ARRL" + exit 1 + else + NEWSTYPE=${1} + if [ "$NEWSTYPE" != "ARN" ] && [ "$NEWSTYPE" != "ARRL" ] + then + echo "Play type must be ARRL or ARN" + exit 1 + fi +fi + +TMPDIR="/tmp" +VOICEDIR="/home/irlp/custom/voice" + +# send start announcment +# Add 3 second delay to beginning of text +sleep 3 +#/usr/local/bin/voicetransmit KD8TUZ_B $VOICEDIR/${NEWSTYPE}start.dvtool + ambestream -t "${NEWSTYPE} starting....." -v -4 -my KD8TUZ -d rep.w8rnl.com -bi 7500 -bl 1000 -p 40000 W8RNL C $VOICEDIR/${NEWSTYPE}start.dvtool + ambestream -t "$NEWSTYPE News Line." -v -4 -my KD8TUZ -d rep.w8rnl.com -bi 7500 -bl 1000 -p 40000 W8RNL C $TMPDIR/${NEWSTYPE}RNLB.dvtool + ambestream -t "${NEWSTYPE} stopped....." -v -4 -my KD8TUZ -d rep.w8rnl.com -bi 7500 -bl 1000 -p 40000 W8RNL C $VOICEDIR/${NEWSTYPE}stop.dvtool + +# Remove all files created by playnews +#rm -f $TMPDIR/$NEWSTYPE* + +# Done +exit 0 diff --git a/playnewstuz b/playnewstuz new file mode 100755 index 0000000..49772e1 --- /dev/null +++ b/playnewstuz @@ -0,0 +1,33 @@ +#!/bin/bash + +# NEWSTYPE is either ARRL or ARN, Always required as parameter 1 +# +if [ -z "$1" ] + then + echo "No Play type given - ARN or ARRL" + exit 1 + else + NEWSTYPE=${1} + if [ "$NEWSTYPE" != "ARN" ] && [ "$NEWSTYPE" != "ARRL" ] + then + echo "Play type must be ARRL or ARN" + exit 1 + fi +fi + +TMPDIR="/tmp" +VOICEDIR="/home/irlp/custom/voice" + +# send start announcment +# Add 3 second delay to beginning of text +sleep 3 +#/usr/local/bin/voicetransmit KD8TUZ_B $VOICEDIR/${NEWSTYPE}start.dvtool + ambestream -t "${NEWSTYPE} starting....." -v -4 -my KD8TUZ -d 127.0.0.1 -bi 7500 -bl 1000 -p 40000 KD8TUZ B $VOICEDIR/${NEWSTYPE}start.dvtool + ambestream -t "$NEWSTYPE News Line." -v -4 -my KD8TUZ -d 127.0.0.1 -bi 7500 -bl 1000 -p 40000 KD8TUZ B $TMPDIR/${NEWSTYPE}RNLB.dvtool + ambestream -t "${NEWSTYPE} stopped....." -v -4 -my KD8TUZ -d 127.0.0.1 -bi 7500 -bl 1000 -p 40000 KD8TUZ B $VOICEDIR/${NEWSTYPE}stop.dvtool + +# Remove all files created by playnews +#rm -f $TMPDIR/$NEWSTYPE* + +# Done +exit 0 diff --git a/ryan b/ryan new file mode 100644 index 0000000..f1d0cff --- /dev/null +++ b/ryan @@ -0,0 +1 @@ +23:35 diff --git a/sendtext.sh b/sendtext.sh new file mode 100755 index 0000000..822a846 --- /dev/null +++ b/sendtext.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# +# Script to rotate Allstar Voice IDs, by K0KN 9/2012, last updated 3-8-2013 +# +# Usage - Place numbered ID files in the IDBASE folder in sequential +# order. For example, id1.ulaw, id2.ulaw, id3.ulaw and so forth +# up to the IDMAX number specified. If 8 files are used, for +# example, set IDMAX to 8. +# +# ID is the file specified in RPT.conf for your voice ID. +# + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# Check Arguments... +# has only one argument, county info +if [ "$#" = "1" ] ; then + COUNTY=$1 + COUNTY_NAME="" +fi + +# has two arguments, county info and county name +if [ "$#" = "2" ] ; then + COUNTY=$1 + COUNTY_NAME=$2 +fi + +# if no arguments, then use what is defined in configure file. +if [ "$1" = "" ] ; then + # extract County Information and County Name + COUNTY_NAME=`echo $COUNTY | awk 'BEGIN { FS="," } { print $2} '` + COUNTY=`echo $COUNTY | awk 'BEGIN { FS="," } { print $1} '` + # if name is empty, then use COUNTY + if [ "$COUNTY_NAME" = "" ] ; then + COUNTY_NAME=$COUNTY + fi +fi + +if [ "$COUNTY" = "NOTSET" ] || [ "$COUNTY" = "" ] ; then + echo "ERROR - The COUNTY variable in ${CUSTOM}/wx_scripts.conf is not set" + echo "or missing, aborting..." + exit 1 +fi + +# Read current ID number from file +IDTOUSE=$(sed -n ""$RAN_ID"p" "$CUSTOM"/beacon_no) +IDMAX=$(ls ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon* | wc -l) + +while [ $IDMAX != $IDTOUSE ] +do +CUSTOM=${WXALERT_SPOOLDIR}/${COUNTY} +IDBASE=${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon # base file names +#IDMAX=$(ls ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon* | wc -l) # max ID number + +if [ ! -f $CUSTOM/beacon_no ] ; then + echo "1" >> $CUSTOM/beacon_no +else +echo +fi + +# Read current ID number from file +IDTOUSE=$(sed -n ""$RAN_ID"p" "$CUSTOM"/beacon_no) + +# Increment Variable +IDTOUSE=$(( $IDTOUSE + 1 )) + +echo $IDTOUSE > "${WXALERT_SPOOLDIR}/${COUNTY}"/beacon_no +/usr/local/bin/texttransmit KD8TUZ_B -file ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon${IDTOUSE} +sleep 25 + +done + + IDTOUSE=0 + echo $IDTOUSE > "${WXALERT_SPOOLDIR}/${COUNTY}"/beacon_no + +exit 0 + diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..75d9c0e --- /dev/null +++ b/test.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# + +# Load config file + +if [ -f ${CUSTOM}/wx_scripts.conf ] ; then + source ${CUSTOM}/wx_scripts.conf +else + echo "Missing ${CUSTOM}/wx_scripts.conf file, aborting..." + exit 1 +fi + +# Check Arguments... +# has only one argument, county info +if [ "$#" = "1" ] ; then + COUNTY=$1 + COUNTY_NAME="" +fi + +# has two arguments, county info and county name +if [ "$#" = "2" ] ; then + COUNTY=$1 + COUNTY_NAME=$2 +fi + +# if no arguments, then use what is defined in configure file. +if [ "$1" = "" ] ; then + # extract County Information and County Name + COUNTY_NAME=`echo $COUNTY | awk 'BEGIN { FS="," } { print $2} '` + COUNTY=`echo $COUNTY | awk 'BEGIN { FS="," } { print $1} '` + # if name is empty, then use COUNTY + if [ "$COUNTY_NAME" = "" ] ; then + COUNTY_NAME=$COUNTY + fi +fi + +if [ "$COUNTY" = "NOTSET" ] || [ "$COUNTY" = "" ] ; then + echo "ERROR - The COUNTY variable in ${CUSTOM}/wx_scripts.conf is not set" + echo "or missing, aborting..." + exit 1 +fi + +sed -f /wxtext_conv1.sed ${WXALERT_SPOOLDIR}/${COUNTY}/plist.txt > ${WXALERT_SPOOLDIR}/${COUNTY}/conv_plist.txt + +PLIST=${WXALERT_SPOOLDIR}/${COUNTY}/conv_plist.txt +#PLIST=./plist.txt + +LINES=`wc -l $PLIST | awk '{print $1}'` + +#Starting Count +FILECOUNT=1 + +for STEPS in `seq 1 $LINES` +do + + CONV_LINE=`sed -n "$STEPS p" $PLIST` + bea[$STEPS]=`echo $CONV_LINE | awk 'BEGIN { FS = "issued"} ; {print $1}'` + + iss[$STEPS]=`echo $CONV_LINE | awk 'BEGIN { FS = "issued"} ; {print $2}' | awk 'BEGIN {FS = "until" } ; {print $1}'` + + unt[$STEPS]=`echo $CONV_LINE | awk 'BEGIN { FS = "issued" } ; { print $2 }' | awk 'BEGIN { FS = "until" } ; { print $2 }' | awk 'BEGIN {FS = "by" } ; { print $1 }'` + + echo ${bea[$STEPS]} > ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon${FILECOUNT} + FILECOUNT=`expr $FILECOUNT + 1` + + echo "issued ${iss[$STEPS]}" > ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon${FILECOUNT} + FILECOUNT=`expr $FILECOUNT + 1` + + if [ -n "${unt[$STEPS]}" ] ; then + echo "until ${unt[$STEPS]}" > ${WXALERT_SPOOLDIR}/${COUNTY}/conv_beacon${FILECOUNT} + FILECOUNT=`expr $FILECOUNT + 1` + fi + echo +# echo ${bea[$STEPS]} +# echo "issued ${iss[$STEPS]}" +# if [ -n "${unt[$STEPS]}" ] ; then +# echo "until ${unt[$STEPS]}" +# fi +# echo + +done + +echo + diff --git a/testfile b/testfile new file mode 100755 index 0000000..876b8bb --- /dev/null +++ b/testfile @@ -0,0 +1,3 @@ +Welcome to the Hamilton Wireless Radio Club. Transmitting on +four forty two point six five. The time is (time). For more information +please comtact kay bee eight pee em why diff --git a/testfile.dvtool b/testfile.dvtool new file mode 100755 index 0000000..2950f19 Binary files /dev/null and b/testfile.dvtool differ diff --git a/testfile.wav b/testfile.wav new file mode 100755 index 0000000..46309c8 Binary files /dev/null and b/testfile.wav differ diff --git a/testfile2.wav b/testfile2.wav new file mode 100755 index 0000000..f851bfd Binary files /dev/null and b/testfile2.wav differ diff --git a/text.ul b/text.ul new file mode 100755 index 0000000..7a40f66 --- /dev/null +++ b/text.ul @@ -0,0 +1,139 @@ +ıüüüııüıııışşÿ~~}}||||{{{{{|}zxyzzzz{}~şşşşıııûüüûûüüûúùùûúúûúûûûüüüıüüıüışşÿÿ~}}}~}||{{zzzyywwxxxwwxxxzz{|||}~~~şşşııııüüüüüûûúúûûüüüüûûûûüıüışışşışÿşşşÿ~~ÿÿ~şş~~~~~}}}}~}|}|{||{||||}}||}}~~~~~~~ÿşşşışşııüüıüüüüııışşşşş~}~~|zzyxxwwwxxyz{|}~şüûúù÷õõõôôöøúı~|ywvttttvvuuuwwwy|ıüû÷óññğïîîîïîîîïòòóõøıÿ~{wtsstrprtsrrrsqqssuwy{{}şıüùõğïïîîííîïô÷ùı}zwuroonmllllmmnpsvzÿú÷óñïîíìììíîîğõøüÿ{vutrqpppprtvy|}ıüûûúøøøûûûş}|{{{zz}ÿıûù÷öööö÷ö÷úüşÿ|{ywwvxwuzszynöeÙ½ŞNßßUVme[`ríıvêéëíûîéï÷ü÷ø|xptsjjiikgfhijhjorx~ùôñîííëëìíîîğóóô÷úüüüışşşş|z||{xuvusvxz}~ıûù÷÷õôøùõôóğïîîïîíïòòõúı~zwsrpnnmlkjjjkllnprtv{ÿşûøôïîîìëëììíïòöøûıÿ~|||}ıûù÷õôõøúş|unjhc_][ZXWWWY\ak~éİÕÏÌÈÆÄÄÄÄÅÈÊÍÒÙåÿeWMG?<830.../39CZÕ¿¶¯¬ª¨§¨©¬¯³¸¼ÃÏøO?6-)&#!$(,7JúÓĺ³°¯¬©§§§§©«®±µºÁÍÜsQC:2,(&%"!#'+.7EfØÈ¼³¯®¬©¨¨ª«¬®³·»ÀÊ×í_J=6/+)&$#%(,/7C[äÎÁº¶´°­««¬¬¬­¯³¶º¿ÈÒè]J?93-+*)((*-06?SïÖÊ¿»º¹¶³°¯¯¯¯±´·º½ÃÍØï\LA<60/.,**,.17?OoïÙÇĽ¿»£Ÿ¬¬©­º¼¸Î[ZèÔRDG=1'(1( %,43<ʺ¼·®«°²®³¸·µµ¹µ±¶¸º½ÆİfE2*&*;Hæ©¢§¢Ÿ¢ª°®»ÙÀ»»¸¯«®¯­·ÌY;)!0_ɤ˜›š—šŸ­®ºC\ÒÕÁ³¦¦¨¢«ÉH+ + -O¸˜‘–—¨­Y,D>;Ì­¢£š«Í;#  &>°’“Œ•œ¥­7(=.1Í«¢¡˜š®Î9 +á™“Š‘™Ÿ¨N'80+o®¤¢š—ªÏO )ı˜”Œ’š ©<(<.-㬣¡™™®ÓC    -¸”’“Œ•£²-,;,6§£Ÿ˜ŸÊo!  ++Uš“•“›¥«=)7.4è­¡¡š›»î* ++C”–“š¦¬I*5/6p°¡¢œ¾l# /s›––‘•ª¯:,7/>×­¡¢œ£ØF +$7µ™˜””˜¢«¾/174PÀ§£¢¶Q* /qŸ˜˜’“–ª¯G/96B⯤§¡¬_1 ,F©šš•“—§¬ß19<@c·¦©¨®å56A³›——˜¨­È=;>On¿ª©¬´Ò8)6¼¢™—™¤ª½IDD@Mʳ±´¹ÎE&-8æ­£¥­»ğK?Jpѵ¯¯°¼Ô;'!"*5ê·ª£¡ £¨¯ÂÚiNgͽ´®­²¿ÛC-%"%+2CѸ²®««°·ºÁËËû¹´°´¹ÁÍíI9/,*'(*,29D_áÎÅ¿½½¼¼½»¸·¶¶´¶º¾ÇÒè^G<8400/025?ENTXeõåÚÏÉÆÇÆÄÃÃÈÈÉÏÔØâlSUPJKNKFIORPUjneÿîàÖØÖÓØ×ÑĞØÙÓÜåçëÿaa\NOXXZX[wocoqtúåéûáרßáİã÷øäèìêpbfie\X]lhcjovyúøqrıüıáÓŞ~çİåõğçıoûûryñtoømmqkulfnyşqyûyñôwõğøîöü÷ùğxmú÷ôöuw|unqúşzõş~öøğ}yö{tşø÷~vóùuøğîı{üklıüü|~ônoîñ~ıíşexé~invnmïêomúïpoìzvù|woøî|wîşkõûõìsv÷ÿtùöuóò}ğ|ríş~ïrúòlşõoÿïóşkzìpgùépnêıjwéù_kúòüséûdıëûmúóvúöö}rïìnrëójrçîkgóçooîüyôõrvú~ûnmízròøşotüÿööğğnpíúowüüû÷óøivä÷knö|d}öms÷ïkgóíóuöêjkéõ_aìïlöãêôïõkmïíypşôö{úòou÷üı{{osıt~í÷ôéøvùóò|xøliõï{huírpïêıoèï]i~kloı}tíéøv÷çívoòùfqöp`ñÔîeøíşhñô]oíõqtçïxwéïdîãşefâş_vÿ}foåümùér_ìåroúäíöåîtnïëekêílgğóov}yisåü`uómkpruqøîhjéõkrìŞêsóìzöçé~nğùgsöÿszûsk~äívëëïßèğìëë|oklndf_^ffjmmtjivïäíéáçÜÛàãéáæy{ÿph[^kZU\^Z[hb]şåíêêÜ×áÜÕÛŞØÔÛéòuac]SQRVYUX]WW_a^nêäÜÓÊÇÊÅÁÇÉÉÎ×ááègddSLGA>;;;8:=FPfÔÅ¿»¶´´´µ¸»½¿ÀÆËÏÛjNB6,&"!!!$*4FÚ´©¤¡ ¡¦¬²»ÈĞÊ¿º´´¼Êz=*!(2dº®¥Ÿ¤§­½ÌÊÍÑô®­«ª®¿yA,")5ø·«¢Ÿ¢¦­ºÆËÊÌ¿²­«ª«¯Âg<+!*4ı¶«¢œ¡¤«·¿ÃÆÇ½²­«ªª®¿l?-!&/Eɲ§ŸŸ¡¦®·¼ÀÅÀ·±¯­«­ºÖT7*#&/>縫£Ÿ ¦¬´ºÁžºµ±®®¯·ÎR;.'!"*5Fܺ«¤¡  £§­³¹¿Á¼¹µ²¯¯´¿×W<0+&!!$)/:951.-.,-/16;EhİÆ»·´µ´´·¹ººº¼º»¼½¿ÄËÔëbUMKD?;74111/./26;E[íÏÀ»º¸¸¸¹»¼»»»ºº»¾½¿ÆÌÚæu[QKGA?<864442248;@LfßÔÊÀ¾¿½»º»»º¹»»»½¿ÃÃË×Üèù^WUKHF@=:88755689=BLZıÖÍÈ¿½¼¼»¼¼¼»¼¿ÁÅËÍÙçiOMNMIFIIJMNOLNSSXdúåŞÕÍÌÌÍÍÕío[NKEBA?ACHQ[÷ŞÙÎÊÅÀ¿½»¹¸¸¸¸º½ÃÌÜ_I?962..-.04:@K]ïÔÉþ¹··µ³³´µ´·½ÃÍâ[H?9642/./259?IZûÚÌÆ¿»¸·¶´²³µ·¹½ÂÊØnMA<975200247;ALXsÚÌÄ¿»¸¸¶³³µ¶·º¾ÁËâaPJ?;96433347;?HUfìÕÊþ»¹¸·¶·¸¸º½ÂÉÑï\OF?=;865557;>CLWmâÓÌž½º¹¹¸¹ºº½¿ÄÊÖøx]GB@<::8779;=AIQbúßÑËÅ¿½»»»¹¹º»¾¿ÆÏÚïdWKD?=;:998:<>BIO[sàÔÍÇ¿½¼»»»¼½¿ÃÇÍÕâx^SLGC?><;;;<>@EJQ\wæÚĞËÇÿ¿¿¾¾¾¿ÀÃÆËĞÚëo]TNJFCA??>??ADHLQZeüãØĞÌÈÅÃÂÁÁÁÂÃÆÈÌĞØâöm^VOLIGECBBCDFHKNU\iúæÛÓÎËÈÅÄÂÂÂÂÄÆÉÌĞØáóm^WPLIFDBAAABDFIMQXbsîß×ĞÍÊÇÆÄÄÄÄÄÅÇÊÍĞתíue[TOLIGFEDDEFHJMPW_möäÛÔÎËÉÇÅÄÃÄÄÆÈÊÍĞ×ßîraYSNKHFDCBBBCEHKNT\h~çÜÕÏËÉÇÅÄÄÄÄÅÇÉËÎÒØßë}k_XSOLJHGFFFGHJLNSY`mùçÜÖĞÍËÉÇÆÅÅÅÇÉËÍÒÚàîwg\UOLJGEDCBBCDFILPX_pğßÖÎǾ¹·ÀîéÉÇÉÊÎÖÒÊËÕáø|jSLKJC>==?@ADIKNVawïâÙÑÌÊÇÂÁÂÀ¿ÀÀÁÂÃÅÈËÏÖàq^N?:5222005;CL\é×ÍÉÅÁÀ¿½¼º¹¸¸¹¹º½ÀÅËÖ÷bOD=71-)&%,55;LÛÆÇ½¶¸¹½½»¾½¼»¸¸·³³´¹¼¿×İÜP=3+!#.+5ܯ¬·¬¨²¾ÏÇÃjÙ½·¯®§£©©ª¯½óZH3,) +<#(Íš±¢™«ù3B](/͹­ªœ—ŸŸ ª¿D* *±¦¥Ÿ•›·´¿;-.G>>­Ÿ™—£¶°É5/758:54.'',*(,3=G꾺¶±±µ»½¿ËÍÇÉÍËÈÌÚæö_Zh|ûğâÛÚÕÏÓè|øgQKIEBACEIQY_sïèãߪߪŞßàáãæéééííçææâßßߪßâçîùsgc_[[\\^`chmotz~üöôôñïğğğõ÷÷úûúş~~|{||z{|{|}}}}}||}|~ıüùõòğîíììëëìííïğôøúı~{ywtqrrqrttuvxxwwwvwvvxxz|{{}ş~şüüıúùûûûışş~}{|{yzzzzz{zyzzzzz{{|}}ÿÿÿşşşÿıüıüüıûüüüıııÿıûüüûúùùúúúùùûûûûûûüüûúüüüıüüıüııüııışşş}}~~}|}}||{{{{|{{|yxyzyyyxxxxxxxxxzyxyyyyz{yzzyyzzzz{|||}}~~ÿÿÿşşşııüûûúúùøøøö÷÷õõôôôôóóóôôôôôôôôõôóóóôõôôöööøùùùùúüüıÿ~}|zxvtrqpommmlllkkjiijihhhhhhgghhhhklm{ñÚÏÇÆõ^bUùZkÃö\ÅÍ`oãb^WGY_\ÕÍÁ¿Ú×vZkILPI\ouõêÜØÚÔÈÆÉÑèøfWOOQRjmíÖİÓÖÜäh`TPNIMQXZ^÷vyâî{÷wd__[Xic^y_ÚËÕÆÉÕİïğa^[XdùúâÓØÏÓÕÖûøb]hY^djsúèòŞàíßçösúoak^gme}~ıîíówûvm|`gye{ùöìåé÷àşòíbóni{môöëzoøh{~mq^hk`şpûãlsügúnaü_cğ``|oıáíõÜìïİ÷ó÷zùyíu{ßõàÖğæÛâêñêïòõ{}w|ma^k|etüoíòxîtü~`íúxïbx}uşnë{õñkçccç\_êhfÜraÛtgÕ}iÜY^çQjçYvësìÛæ{ßîeèòW{ßWsæOå×NèÓYãØRåÕQìİWõí`uçï÷á~^øé]yØoîÓznÕãlÔøsÎYoÛJçßLØçN×ñSÙi\Õ`Xãê_hÙ^eĞ\gáQbé_lİôhäsn×zhŞ|sjYşdeå[úåSüß\^ím[Ûã[ÙÓ[úÏ_èÊSôĞQÙ×WÖŞTgòVdÓ_sÈóûĞgwŞU^|PişSjwiïìôèÚenÎTRÎ][ÔYYÉŞZÌãNÖnOÎŞiÍÙa÷î^[u[V÷WOïyeôítoëeWkX]ë_sÔİŞÍÖqĞØaÍêPÏæW×÷]ÎÙaÙåPaSFSNKOO\\]ohozéìèÕÿóÓæÒÈÊÂÄÆÆÎÎÙçèYVaKJVHHZE?M?=K??RJYÖİɼÀ»¸¾º¼¿ºÀ¿»ÄÁÀËÌÏêOG=1.,)(&#"'.4g½¶¨¦¨¦«±¶¾ËÌÆÄ¼³²­«¯²¾äO3*"-ÌÁ£œŸ©¹ÏH38:Dij¨œ£®¿L/("%/¿Ò«§£¤°¹Ã\ELIQŸ®£ŸŸŸ£¬·Ö=/*" #!2û§  ¤¬ºÏU=?DKʸ­£ ŸŸ¥¬¼i=-)% &!/¼À¨£ ¢®·ÇS>??Bϼ²¤¡¢Ÿ¥®¶æ<3+%$% -¾Á©¢Ÿ¡­¸ÇO<>ãÆ¶¦£¢Ÿ¤«±ÍI7,'%#)H¼Ø£Ÿ¨£¯¯ÀUIE:FØË²¦¦¢Ÿ¦«²×G8+'&  #% äÇÇŸ£¦¦®¯ÉSK?8LáÍ®§¦Ÿ ¦©´ÚM4*'""!(Ú̱Ÿ¢ ¤ª°½òOMCSÒ󪨦¤¨®²ÉN>.&")#J³¼ œ£›­§­êÊÉGÛ½Ù¶¬´ª§±®±ÏïB-&)!Ô±·œœŸ˜ «¢´İ¸åK¿Îѯ³²§¬¯¬ºÌâ9.&%%À¸¯›˜£¨¤¹ÌºoV¾Ó̯¶±§®¯­¼Ïí8,&!$(¿º¬œ™¤¨¥»Í¼f]¿ÙÄ®¶®§®­®¾Êr8.'*&n±±›Ÿ©§¯ÉÄË\Ͽʶ®²««°¯¶ÌçA/* )%5²¶¦›Ÿœœ§©ª¿Í¿{m½ËÁ­²¯§®°®ÁÜl5,&*$ذ´œ›Ÿ©¨­ÊÉÀRܼٻ®µ¬ª°¯³ÆŞK2+$%&+¿µ­Ÿ¥©®¾ÁÈsÎÇÍ»¶´®®¯°·ÇåF3,%'$,íɸ¨¡ ¢¢£©­±¸ÀÆÅÕÚÍßïßlYcs~ãÏÌÏĞÚZA;5,)(&'),2:BZä̾¹·¶³±°°±³·¹¼¾ÂÄÅÈÊÊËÎÑÖâ}cSI@;84/.---.17BHO\|ŞÏÈÀ½»¹¸¸¹º¼¾ÃÉÏİù`TLGB?=<<;<=>AEJP[mìÛÒÌÈÄÁ¿¿¿¿ÀÃÆÊÏ×âüfZRMKHFEEEFHJMQX_oğáÚÓÎÌÉÈÇÆÇÇÉËÍÑ×İçønc\XURPOOOQRUY\ajwõêâİÚ×ÕÔÔÔÕ×ÛŞäíûpf^ZVRONMMMMMNNPRTWY\b`lkjí\ÚÃ^\ÔÖÎÍŞZVÿ}cpæjShyzmί°¶°¿É»¶Ê@]n>Û¾çİÄÑ^İÎDDi;9I<:FJADcN>én=yx@_Û^OÔÊWÏ¿gÏÀçâÏÍû\ÈîLÎçSğóúZWXHXXK[UJgİSaÉê]ÃÆ~À½ÓýÌÖÆÓ`ÏÜJYyHC\M0*'" ! (,4Ov´®©©¥¤©¥¨¬ª¯®¯·°½¿ÆB?, "%.]Í·«¤¢œŸ¢¡¥©©­®µ¼ÁH:( &+ÃÔ¯¢ šš™œ¤¦ª£¯°²Æ\:' %'¸â­Ÿ›—šœ˜¢œ¨ª¢´°°gO1  ÎÍÊŸ–˜—›£›£¬¡­µ­ÚK7  Åı¼ •š—¢œª©£µ®±[t,   &.¼N¨£š–𙦠±£¬¹«Ò[H  "½Y¼¥–™¦¡Ÿµ§«Ã¬ÊLn  !¿lÁ¥Ÿ•œ˜¦¡Ÿ·¨­É®ÜFL '$¹_±¦œ—Ÿšš¨¦¶§ºÃµBG+!'^ÀÍŸŸ —›œ˜¡¢ ³¬°Ñ¹V=2)=»Ş¢¡—™œ˜£Ÿ°¯¯Ş¿T7.&I¿Ã —™›˜¡¡°¯·İÍ?4%""ËʱŸš–™™™Ÿ ¦³°Äé\7)#DÁ½ œ–—™˜œ £®³½èS:*$;À᜖—˜—œŸ¢­´½ğK:&#GÀ¼Ÿ›•———œŸ£¯µÀRF0&ÊÊ«—•˜–™Ÿ©´ºè@:# nȳ™•—–˜Ÿ¦³·Ú?:#!!eų™•——˜Ÿ§´¹í>6 (ØÆ«˜–——š¡ªµ¾S<,! 9Ⱥ£›—–—˜› ¦¯¾Ù>0!!,×¾©œ˜——˜›¥­ºÎF4%"(í¾¬œ™——™›¥¬ºÏG4&#)佫œ™——™›¦¬¼×C0#"-ü§œ›—–—™›¡§±Ék7+!&?¾¯¡œ™˜–—›¥­¹áD0%&*ʵ©œ›˜–—™œ¡ª³ÏT6)$'L·­›™——™›Ÿ©®Ä_=+")4º®¢š™—•˜›¨®½N=, )2»­£™˜—”˜›œ©°½F;+,2¹«£™˜—”—›©´ÀG7+/5·§¢˜—˜”˜¬ºÆ=4*!2<¯¥Ÿ–——”šŸ²½Ş83(#:B­¢Ÿ•—˜”›Ÿ¡¹Än3/&)>U¦¡”˜—•Ÿ§ÉÉH//$.LߢŸ›“˜˜— £¬çİ>./$4_ÍŸŸ›”š™˜¤¦°_ü;.0&4øÌ œ•ššš¥©²[^>/4)!-ÜŞ£•™›š¥«²\VB19.&"Û宜Ÿ˜—› ­±ÜCG658-$!7Ñ¿¡›˜›œŸ©°ÊOC;8>81&!'?¾Í—œŸŸ¬¼ËJîÏ\O$!mÚ½›˜œŸ¤¯Ó^<6DCì¿ÎÑ1#(Î夛œ—™ ªÂT>18BOÁ´¸¿: Öã§˜š•–›ŸªÇA5-/>½¬¨ŸŸ¨³ÇI6/,+,.-'!'ìt ›—œ§«ÉA60)-:AŸ¦¯ÂU92..0350)/C½›˜¤¬ÎB5,'-2?Á±¦Ÿ¥­ÄV:.,++.-*$!OAªœ£˜š¥£ºZG.,,.;^¾­¥Ÿ¡§¯Æ[<2///16-)7=ࣜ–Ÿ ©Êq9-++/;£Ÿ¢§´ËR7/-*+,'%Q<Û§›—¥Ÿ«úë8+/,/Hs½«§¡Ÿ¡£©µÆb>73//1+)!577© “¡ŸÈÃV,/-)9Ih³­¨Ÿ¢£¤­·ÇY?83-1-'' ,?$Ÿ©¬‘ šººÉ211)1D@ò±¤¥¦¢ª¯µÑbE91/+&#-4'Ÿ­¨’¡œ›¶³Õ51,*.5/*&&+.Á½®Ÿ¤ŸŸ©¬¸nK8/55;qݽ¯®«©­¯µÄâO;/+#+(5¾Ê« §Ÿ¡««¹yO:/225QìÆ¯®«§ª­¯¼Ôt?3/(#"! &,1Q̺«¨§¥©­³ÄñL<77:?^ײ¯­ª­®²ÂÎK5- %#KøË§¨¦Ÿ¥ªªºÜo:13,.55B_ŞÂ¸±°­®³²»ÉÌüUOGBBA=><8:99?HTå˺··¶¸¼¾ÆÍÔâéìîáŞİÚë^O<52++.,4>EñÌÁ¹¶µ·¸½ÅÊİıjZXW[]`v{óåçãâèìõûytxsv}şøïëêèçéêëîïñôøûüÿ~}yxtolieb_^^^_`dinxşöïîììğíïğçæåßİÜÜÜÜŞßâèíö}rjd^[WTRPOOPSW[`kzïçßÛÙÖÔÓÒÑĞÑÑÓÕÙİåñrd[UPMLLLNORW[_elwùíæßÜÙ×ÕÔÓÔÕÖØÚİàæìòıvnjeb`____`beilpw~ùóîìêéééééëíğöû}yrnljhgfffghijlnqv|ıøóïîììêæèêéëíîñöùü|xvtqooooopruy{ÿûøõóñğğïğññô÷øúış}{xvtqoooooprsuxz{|~şıûúûúúúüüüÿ~~}|||{z{{{{{|}}~ÿşııüûûûùøøùúúûüüışÿ}||}şüıüüıüûüúùù÷÷øøúüı~~}{yxwvutuuvvy{}ıûòççíïñû}ş{yşı}ÿ~|{yxwvtqssrtvuwz|}ÿüúùøööõõõõöööùûúûışÿ}|{z{{{|{{|{}~|~üııüûûûúúúúúúûûûışÿ~}{{zyz{zzz{zz{|}}}~~~ÿşşşÿşşşşşşşÿ~ÿÿ~}}~~}}~ÿÿÿşş~~şşÿÿ}}}|}}|}}}~~~şııüúúúúúúüııış}~}||{|}|{zyyyxxxyyyyxxyzzz{|{|~}ÿışşş~~ş~~~ÿşşşÿ~şııüüüûúúúùùùùúùúûùúûùùúúûûùúúùùø÷÷÷÷öô÷øùşôíıu{~z}ukv|qvşüsp÷{jtxkoşwvëÜâpëÖİãîïÚÑÚenÏÙwÎÈélív_m`ZaXT]__`sí\[oQTfNQYMZéßî_`[W^MTxWYrïëoãÜ}útèãi~h|ßeïÔùıİèáäàÚxìíwÜæßÛêßåèèìáèàètÚë{Òîòßùßrùäièk÷á\îüdøcsnXqibãfWóüY]`^f`jñ^Zsûñníø[pò_jïTeÖeXÛìVëêTéØR~Ïb}ÏëoÖâaâó^íìnßîdÓí[Îå]ÕmSéçjnÖèaĞõhÛWìé]İScÒ^÷Ørkõ×n`ÒfüáPobWeúæYîíj×ZtŞ`ä{c`Ü{@ÏÔAÓĞNeÜõLİÓHîÔgpåĞenÕ\uÑf[ÔuGÚÚH×ÏLÖÄQZÃbCËß;ß¾B[¿SWÈaEÎØ?ÎÌKËyQÄONÃMDÂ\>¼â:¾Ù>¹×9»Ì6ÉÉ<ÜÙEÚáHßÏNÜÉJëÆHLÌ_IÎêLÓÙRŞÕNØÔFÎÜDÏØJlË^MÉeOÑ[ıâ]Øl\ğr÷dØØYÓãXİrwmWÛ^[Ù]ûíùÚRâØOÔå]ßlù[hØ^ôvdİ[iè~æoôuèÚ^àÚëênÕkYäSiøTpae}òï^ÖÙlĞrnÓ]jòmú]ğßdğîf|ûhyseıc^}qzÿ÷æåîøğööíb[å}Zíù~ãöæŞÛòißr_óf_ijmyüpwú|inæpqànïßxŞäıŞtúßdüôxñ\ëæ\æçkîéx|ídmù]yeWò^ZåhjŞlñÔoëÎväÔ^ßß]éryîlùn^^jXUoS[ìZnèqåômğttıvîñïÛààÒÓĞÏĞÑÖØŞñ~^XNKSHGLDIMIOUSgöçÔÒÍÄÃÃÁ¿¾¿ÄÂÆÒÌÒíív^QOFA@:975757:ßǵ¬«¦¤¦¥¦©ª­°²¸¼¿ÉÛlM=6,'&"%)7Aí¼¶¬©¨¦¦¦¨©ª¬­¯³¶º¿ÆÏğS>4,%#"&2=y¾µ«¨¦£¥¤¥¨¨«­¯³¶»ÀÇÕ|S@6-'$#%.>XÁµ­¨¦¥¤¥§¦©¬¬¯²´¼¾ÄĞÚiM?6-&$"&/?f¾³¬¦¥¤£¥¦¦ª«­²³¸¿ÁÍŞëVJ=4,&$#&3Aò»²«¦¥¤¤¥§¨«¬®´µ»¿ÁÎÕá^S@8/'%"%&/CW¿³®§¦¦¤¦¨§«­­´µ¸ÁÀÍŞİ_SG92*&$#%+7/&&"%'2Dy¼²¬§¦¥¤¦¨¨«­®¶¶»ÆÃÓßß\XI:6+&&"&+:Mи¯«§¥¦¥§ª©­®¯¸¸¾ÇÇÙàîZSD93*&& %'-BRÆ´¯©¦¦¦¥¨ªª¯¯±»¸ÁÊÆàİåXXC92)'$!&(/F^¿³¯©§§¦§ª©«¯®µ¹¹ÅÇÌáßnVO?80(($" ()3Kn½²­©§§§§ªª¬°¯¶ººÈÇÏçÛb[N=:.()" "#'*8I⺲¬©§§§§«ª­°¯¸º»ÊÇÏéİcVP=9.')"##)):J麴­©¨§§¨«ª­°¯¸º¼ÉÇÔçß_ZM=9.))#!#$(+9Kß¼´­ª¨¨¨©«ª­¯¯¸¹¼ÆÇÓŞä`ZK=8-))#!#%)+;I༶®ª©©©©««­¯¯·º¼ÇÇÒãâ`XM>9/**$"$ %)+9Hî½·®«ª©©©««­¯°¶¹»ÃÇÏİégZK>:/**%#$ %(*8CjÀº¯¬«©©©««­¯°¶¸¼ÃÆÑÛäg_NC=3,+'$%#$)*3AVÊ»´­««ªª«¬­¯¯´¸ºÀÆËÚßy[RD<6-+)$%##))0>Lξ¶®­««ª«¬¬¯¯´¸¸ÁÂÉÛÖv`[F?9/-+&&%#(*-Mϸ¯®­¬¬¬¬­¯¯´¶¹¿ÃË×Üú^WJ?;1.-(('%)+-:AbÊÀ¶°¯­­­­­®¯±´¸»¿ÆÍÕíq\NH>91.-()''++1:9401./23:@KkÜËÁ½»¸··µ¶··º¼¼ÀÆÈÏØÚìzm\YQHE?:9311/025;AMjÛ̽»¸¸·¶··¹»»¾ÂÅÌĞÕŞáímm^YNGE=:84300249>FXğÒÇ¿¼º¸·¶¶¸¸º½¾ÂÆÊÏÓØàåğoi^SNG?<:523/044:@IdãÑÿ¼¸¹·¶¸·¹»¼¾ÃÆÍÑÕßßëşşl]YQHE>:9421/247?GUèÑÇ¿¼º¸¸¸·¸¹º¼¾ÀÅÉÌÏØİáê|naYQJE=9830/./253)#,Éó«›™™¤¢·xÄA2N==ŞÓ¸´¯º½Ã9/&"2Çͧœšš™§¤ºZÍ@2J>BÜν·´®¹¿Æ8-# 9ÇǤœœ™™™§¦»ZÛ?3E>HÜͺµ³­¹¿×4)õÌ·›š™˜š¢¦©ß[û56E>YØÂ´¶¯­½Ãc.& %ÎÇ­›™™™š¥¨¬iUT38?C~Ú»¯¶­¬¿ÆM+" +¾§›™˜˜˜›¦¨±NME07=Gçη®±¬­½Ë>* 2¼µ¢š—–˜˜œ¨«¹FC:07:PØÌ°¬¯ª­½Ï8) 9¹¯Ÿš––™—œª¬¿@=4058eÌÈ®ª­ª¯¼ô/'Lµ¨™”•™—­°×<8/369ÜǾ«ª«©²½X+$"g¯£›˜’•š˜Ÿ¯¸m:1-55;;¶ª¨¨«´¾;'-ͪœ›–—™š¤³ĞG9+-:5J¿·®©¦§²ºÿ)'d°š—‘“˜™Ÿ­ÃJ<.*68@ȶ­©¦¤®»Ú-!$D¹ š˜‘‘—˜©½PB0)4:>Õ¹­ª©¥«½ñ0"&=» š˜‘‘—˜§¼ZI2+4;Dİ»­«ª§®ÀU.!)B·š—‘’–™¨¾VF2-6>OÛ¹¬­¬ª³Ö;*"/Q¯š—””—œ ©¿`I:47EhÙ½±¯°µ¾]1'):Ùª›˜––𢫾éO@9:IcÛĺµ¹ÂÜA."$/@¿©¡š˜™Ÿ¤®½ßRB;?L_Öû½ÆÑT9,  )2M»«¤Ÿœ›œ §°¿İT@>JZcãÉ¿ÆĞÙU9,$!$+4NŲ©¤ Ÿ ¤ª³ÄâdRNRwÛÔÇÂÉÙgM=0+'%%#$)-5@gĶ®ª§¥§©¬²º¾ÌÙßåßÜÕÓÙŞíhQF?:4/--.-.28=IwÌ¿»µ±°²³´¸¼¿ÃÆÍÎÍØŞâéxWPQHCA>>;:;;;<>DINdæÕËÅ¿¾¾½½¾ÀÁÃÆËÎÏÖáïzk_XURNLLKIHIIHHILMOT]nşèÚÓÎËÉÇÇÈÈÈÊÌÎÒÙâçòyndb]WWWSPPQRRQTVVW[bfi{íèâÛÖÒÑÏÎÎĞĞÒ×Üâæòqfb]WTTQQRUX\bnıíäßÜÚÙÙÚÛÜßåë÷sh`[VTSSTY^erîâÜÖÓĞÏÏÏÒÕÚİàî~j]YROOMMOPV\dwğßÛÙÔÒÑĞÒÒÕÛßäízjb[WSOOOOSW[`lùìâÛÙØÖÕÖ×רİİŞéóıxi^\XTSTTUV[`enıîèäÜÚÚÚÚÙÙÛİßáæíıunc][YVUXZY\djozñéçáİÜÚÚ×ÖÙÛÜÜáíğ{hf`\ZYZYX[_`cjxûöçãáİÜÛÜÛÛÜŞäçíözmhb^^[YYXZ[]_gno~íéäİÜİÜÚÚßߪáåèîùzpld]\ZWWY\\^ghm}úîéæáàŞŞßİİİÛßäçïü|rmg__]Z[[[\^gho÷îêêâİáŞÚŞİİßàååé÷}wkhc]^^^^_cedhomx÷ïéêâßâáàİßææåïôïúojwm^ab^^bd__fkjnôó|ìàèåŞàäâàçêåæëùşvgdda\]_\^^_fenòşöëîèíæÛâàÙİßáæİîsæîeezqX[|]Uab]]gpkùçíæåâÜåߨŞãÙÛæŞÚÛçìéj[VTTKLSNNTa_]ëêüÛÙÙÙÕËĞÕÌÎÔÙÖÔ{ıİ^WaTMEHK>DMFHRj÷ûÑËÔÈÃÈÈÄÀÆÈÄÈÌÒÏÚ`qcFD?:75754=?D_~ξ¼·µ³²·¶¸½¿ÆÇÏåÕoKN@5//,(+/.6H_ŞÀ³³°«­°°³¹ÂÁÅÒÊËÕÑŞdQB6/-)')*,5>NÜ¿¸²®­®®®´¸¹ÃÉÈÌÊÌÎĞv\H4/,%#%%'-9Es½´±«©«ª¬¯´¹¼ÈËÈÑÊÃÌÏâU?/+( "!'/9[É·®«§§¨¨¬¯´¼¾ÈÍÌÒÇÉËÈıQ<,*" *.=ݽ¯«¦¤§¦¨®°¸ÁÆÎÍÏË¿ÅÄÅkO6(')0F϶«¨£¢¤¥ª®´¾ÇÎÖÓÍÇ¿¾¿ÅÖV7,)! !"-:N³­¨¥§§©¯³¹ÌÜfGD:;C49D.4?+5G/>ìMÔº¹³¯­­®¬®¶°¶Ç½ÀèÊÉ\ğ]45*)&968¶¸¹¥¨ª¥¨ª®¯®º¹²Ã¾´ÌƺÜÏ¿|oâ;1/ "'&%;.Y´À®¥«§¦ªª®¯¯º¶µÁ¸¹Ë½ÁŞÃÌjÜV76+&"!#+5.Ó¹Áª§«¦§ªª®¯²·µ¸»¸¼À¾ÆÊÈÏİúT;3, %#!"+2-ҽĪ©«¥¨©©®­±¶²¹º·¿¾¾ÍÆÊÜĞsQB2.#"%#&1+i¿Ë¬©¬¥¨¨¨­­®´±¶¹·¼¾¾ÆÈÈÓÒáZI80'!&#.)>ÉÓ°ª¬¦§§§««­¯¯³µ¶º»¿ÃÇÌÎ×êiL;4*"%!*)2şŞº®­¨©§§«©¬¯­±³²¹º½ÂÄËÎÑÚğZI:1)#%!*)9nÛ¹¯­ª©§©ª©¬­­°±³·º¾ÁÊÍÏŞß}RH;3+'' #"*+6RyŸ³¯®¬¬­¬­®­¯±²·º½ÃÉÎÔÚãç}XOC:5.-*&'&%*,/=GYÖÉÀ¼¹¶µ´±±°¯¯°±´¶¸¼¿ÃÈËÍÓÙâuZL?82-*(&%&(*.5=I`ŞÌü¸´°®­¬«¬­®¯²¶º¾ÂÆÊÍÕßú]MB:3.+)('''),08BRïÍü¸µ³±¯¯±±°±²³µ¸º½ÃÊÑİíscZQKC=70,*)(()*-2:F[çÍÄ¿½¼¼º¸·¶¶µµµµµ¶·¹º¼·¬©®¼ÆÌíL:.)%!#'+.7Jàø³°¯¯¯®­¬««ªªªª«­¯²·¼ÂÓnOB7.( ")3J×½±¬ª¨§§¦¤¥¥¦¦¨©©ª«­¯¶»ÁÎøP?4,%!*9dô«§¥¤££¤¤¥¦§¨©«««¬­¯´¹¿ÌşK;/)"!+:x¿²«§¥¤££¤¤¥§¨©«««««¬®²·½ÉëL:/)!!)4LÕ½±¬ª¨¦¥¥¤¤¤¥¥¦§¨©ª¬®°µºÁÎıL;/( $,:Xλ°ª¦¢ ŸŸŸ ¢¥¨«­¯³¸¼ÃÏrG6,$")4EôÄ´¬¦¢ŸŸ¢¥¨«­°µº¾ÆÔeD5,$!)2CıƵ¬¦¢ŸŸ¡¤§ª­¯´¹½ÃÎ~J9-&'/>eʸ­§£ŸŸ ¤§ª­¯´¹½ÄÍñL:.' &.<[̺®¨£ Ÿ ¤§ª­¯´¸¼ÂËİY@4+$"*4Gê´¬¦¢ ŸŸ¢¦©«®±¶º¾ÇÓ{K;/)"%-:RÓ¼°ª¥¡ŸŸŸ £§ª­¯³¸¼ÀÉØgI9/)"&.=\͹®©¤¡ŸŸŸ¡¤§ª­¯³¸¼ÀÈØeI:/)"%.VE.  #3,ÁŸ¥µ±®I.ܸ¿·ª¡¢­ªŸ¦´¶³¹öBj×MGO@( +23ᦜ«Î·Ã17̶¯®¨£®©¤«¹À»¿XAy×Y>4* +;=𥛜­lÅÆ40×­§¬ªŸ¯°©©´ËǹÎDLØÙC.' KU⨚š­JvÖ60l­¢¦©  «³°­°¾ÇÀÉ~V\÷M5) ?ÑÁ«™£N.$ #v¥Ÿ¢¡¹9,+<¿²²®ª—˜«ŞB˼µ®§›–—œ©ËL7*! *棟›ššŸ»=,*<Ø¿¹³ª—–š¥ÀL4*  <­£¢˜–— Ï/$)@ŞÊÁ·¥™““™¨ÊC/% #ͧ£Ÿš•“˜ªH(#-GyÜ˲•‘“œ­×=,  /·§¢›•‘’›¹6%'4EM[Ëªš’‘•Ÿ±Ø<) +H²©Ÿ—‘“ Ñ0(-9;;HÁ¢–‘’˜£´İ5   *ܶ¦š‘˜®L.-52.0J¯›“’–§²ä, /\·Ÿ”‘¶b=:4*(1ئ™•–š¥²N"  -Q¯š•¡²Åj>/((9½¤œ™šœŸ¥¸: + )Mª˜“™ ©®½K.).K¹¨£££¢£«É/'=¹¤¢ª®¯´ÅS=Bܵ©¦§¬°µ¸¼Éa>2-,-./.,+-2:ENPR[î̽·²°¯®­¬¬­°¶½ÆÏÜı[K?:520//.--.07?L]|âÓȽ·²¯¯¯¯°°²µº¿ÉĞÛêkVJA;730.../159?J\êÓÊþº·µ³²²´¶¸º½ÀÅËÒŞødVLE?;8410//15:>FP`÷İÒËÆÁ¾º·µ´¶·³±¶¾ÈËÈÈÏélmkWH?;72/.,,-0582/.-./038=JeÙÊÃÁ¿½»ººº»»»¼¼½¿ÀÂÄÇÉËÎÒÙå|_QH?:62////137;97656689;>BJSeê×ÌǾ¼º¹¸¸¸¸¹»½¿ÃÇËÑÛévaXPLHD@><;:999:;=?DIO[táÓÌÆÁ¾½»º¹¹¹º»½¾ÁÆÊÏØâùi[SMIFB?><;:::;<=?BGLTbùİÑËÆÁ¾½»»ººº»¼¾ÀÄÈÌÒÛéxbYQLIEB?>=<<<<=>?BFKP[kìÛĞËÆÂ¿¾½¼¼¼¼½¾ÀÃÇËÏ×àñn_WPLIFC@?>==>>?ADGKOYeıãØÏËÇÄÂÀ¿¾¾¾¿ÀÂÅÈËÏÖİé}i^WQMJHFDBA@@ACDGILPW^mõâÙÒÍÊÈÆÅÄÃÃÃÄÅÇÉÌÎÓÚáîwg]WQNKIGFEDDEFGILNRY`nõäÛÔÏÌÊÈÇÆÅÅÅÆÇÉËÍĞÖÜæõqbZUOMJGFEDDEFGILOU[gzìߨÑÎËÉÈÇÆÆÇÇÈÊÌÍĞÖÚæùre\TMJGECA@@@ACEHLPX_qçİÕÎν¯­°¼ÓÓÀ¹»ÃÓl[\`xoZK?95466546:?HPbâÏÈÄÄ¿¼¹µ³³µ¸¸¶µ·»ÂĞõUF=7/+&"!$).:KtÔǾ¹´°¯±µ¸¹·´°¯®®¯±µ»ÇzB3+% /^½´³³°­ª©¬¶ÇØÍ»¯ª¨¨¨¨¨ª°ÆF.&-ɬ¨«¯¯¬«¯¾|O~¾®©¨¨¦¡Ÿ¨¼N6/+%/Ͳ®¬¬«®ºŞTnò­¬«§¡¢«¶ÄŞK3( +ì­°³°²ÅM?w´¨§ª«¤¡¬¸»¼ÌB,&$!F³´»°ª¬Ç7.U®¦ª¯«›Ÿ­¹¯©¯İ:7>8$(V³«¦¦´r93Cʳ«¤Ÿ¥«¬­²ÀÚäïH/#&ޱ°«¥¬l-*>¿®«¤›Ÿª²¯®µÄȽÁO/$ -ϯ¬¥¡¸1&,BȲ¦›™¥­¯²½À¸´»ÚB2&5έ£ «L)(-;Ã¥›™œ¡§±Äɹ¯¯·¼Î?( ,㳦£¥Ç("+5k«œ—™ §­ÄİÆ²«¯¸¼u.O¯¦£¤¹. #.Y­——§®ÌnŰ©ª²¹Ü1@¸¨¤¤¯5 +?³–—§¯ÎUϱ¨§­³Ò3! ?À¬£¢®3!+7ºœ–—¥­ÒFÓ¯¨¨«®É3!>«¢¥´3!+;²›–˜§±ÜNí¨¨¬´o-PÀ¬¡£½)%-:®˜•šŸ§´PFº©§¨©²I',Òº¦ «O#(.ò –˜œ¡«ÌCÕ¬¨¨¨«Î."Gȱ££¼-#*6³™•šŸ¥´PF¼©§¨¨¯N) +׸¦Ÿ©G!&,U¡•˜œŸ«ÍAy¯©©§ªÅ2"DȪŸ¤Á+#'5¯™–š¤ºFGºª©§¥¯E'/_º£Ÿ®;$$&*rŸ–™ «ØFÍ­ª¨¦«Ó1&<è°¡£¼2%%'0ºœ˜›¡°mT¼­¬©¨±M,#'JÌ« §ê*%'*=«š™œ£¶Qü´®¬©ª¸B, ,G½¥Ÿ«M*'&*P¥šš›œ¥¿Mѳ±®¨©½<)+G»¦¡«S-)(+V¦œœœ£·çÁ³³¯­­Ã>.#"5Ó¬£§Ç8-+->°œŸ«ÂÀ¶¸¶±®¸]9+'>º§£­á;/-0ô¨ œ¡®½´´º¹³´Ò?4')B»©¦°ßA74;Ê©¤ ¢­´°µ½½¹»è>5((:Ê®¨¯ÊYE>Aέ§¤ Ÿ¡«¯­¯¸¼¼¾î?7-  -FƯ­·Ëõz~Ù¹­ª¦¤£§««¬°¹ÀÅÜH;3+##+8VÄ·¼ÂÁÀ¾´®®­¬«¬¯¯®°¶¾ÆØSA:51,)$!#(+-1>XyÚÆ»µ´±¯±²´µ¶¸¸¶·º¿ÅÌİoXNKE<850-,---.5>Ks˽¹¸¶´´¶··¸º¼½¾ÀÆËÍÔáşm_OGA>;73321027<987678:<<;;<=?EJO[ræÚÒÍÉÇÅÃÃÃÄÇÈÊÌÑØİèúmc_][Z[\\\]_cgkoyı÷ïììêìïñûumhb]ZZZZ[[[\^bhkknxúîêëêçæééàçöøü~ÿkdbWåÃÓ^]]\V_õc[öŞ×ÔİßàùôğoåÍÓçï_QKIWdZiëâÚİŞĞÏÒËËÈÅÉÌÍÑÚnMC<62247:B]ÓĽ¸µµ¶···¹ºº¼ÁÍl=,!)3ᯢŸ¢¤®¿Èͽ°¯¬©­µÚ0 &O«›šœœ§¸_XÎȾ®¦£¦«®Ï( 'Ù –•–˜Ÿ°Ğ@7@c烈¢©À, $İŸ“’“•³t<14@ʯ§Ÿ¥µ?;¬–’—¤¾>,-1=í¤ §¾6 G¥“‘“˜§Ö7++.;É®¦œŸ§º; A§•‘“—§ï7*(-7Û®¦›¥¯w(  *·š’‘”—Ÿ¾9-((1Yº©Ÿ››Ÿª¾< +=¥–‘“–™¨M/+'+:Û®¤™š¡¬À4 + H¤–‘“˜¬M.*(-DÈ®¢œšœ¡¬Ç2 + +:¨—’”™ªR.++.>Ô¯¢š›Ÿ«¼@   (Å›“”™œ º5(*/:R¾¨œœ¥¯à. "1°™”–š¨Ï4(*5E^»¥œ¥·ş2 ',¿š”™§Ñ2*,9L`¿¦¢¯Ù9# &*J¢–—Ÿ¤º?-*2J^Ù®œŸŸ¨»^2 )*T –™Ÿ¢¨¾?.,6\ÛË®œ ¡¨¹ş6  )*;©˜˜£¨¶o7-3eÉÓ¼£›¡£¥®Ë>&#,.ŞŸ—›¢¨­¿R82=ÚÀÀ²¡œ£¥©µè7##+3È ™œ¢©®¼ı=7FÒÄÁ°¢Ÿ¢¥ªµÎ>&(,P¨›œ¡¦¬·Éb@?lĽ·ª Ÿ¡¤¨¯¿ş8""(-n§œ¢¨­³½ÙKHß¾»¸­¤¡¢¦«³¾Ù;#&-Q®Ÿ ¦¬°µ¾áSiË¿º±ª¦¥¦©®¹ÊS/ #'-_¬ŸŸ£©®¯°·Ìd~ʽ¹³®«©§¨®½ÒV7'#*,7ͪ¡¡§¯´¯¬°Äòèɼµ±°¯«¨ª³ÇlE5('-.7寥£§®³¯¬®ºÒ{⟲³´¯¬¬²¿èJ:.&#,/1<Ú²¨¦ª°µ°­®¸ÍşéÆ·°²¶¶²±µÀëH<5-%!*.16FͲ«ª®µ¶±®¯ºÍğÛ¾³°¶»¼º·ºÆvI@<3*"#+//1;n¼¯­¯·¹¶¯¯¶ÄİŞÆ¸²´»Á¿»º¾ÏkOID:/'"!$*.139KÓº³²·»º¶²´¼ÉÔ̽¶µ¹¿ÃÀ¾ÀÉÚlUOF:1+&$'+/139FîÁ¸¶¹½½¹µ´¸ÀÌʾ¸¶º¿ÈÉÄÂÇÏècYVM?4,'&)-/127Bwź¹½Â¿¹´³¹ÃÌȽ¸·¼ÃÉÇÁÀÅĞìklo]H:/*()-///2:NÖÀ¼¾ÁÀ¼¶³¶¾ÉÉÀº¸»ÂÈÇÂÀÃÌÙèîízVC8/+))+-.05=RÙý½¾½º·µ·½ÄÆ¿»º»¿ÄÄÂÁÅÌØãìîzVB7/*()+-./4=TÔÀ¼½¿¾º¶µ¸¿ÉȾ¸¸¼ÁÄÁ¾¿ÉØî|zhSD8.(#"&+/26>_²­¯·¾¿»·¸½ÇÍÁ´­¬¯¶½À¾¾Ë_A;>DD;.$)27;SÀ¬¡¢­»À¾¾ÅÙjzÄ®¥¤§«®±´¼ÙC418>;2+#-:Dj¾¬¡¥¶ËËÆËÜje̯¥¡¤©ª«®·Ò@0.372+#*>DJή¡œœ¤¸ÚοÉkNYͯ£Ÿ£ª©§©´ÒE406<7-(#8QDL½¥›š¯àå½¼ó?@௡¡ªª¤¥¯â=57>?4+)(!6æL@ɤ™˜°fk¾¾M3<Ê« £¨¥Ÿ£·M;=@>8/-.+ _î48²š•™§ÕNÇ·e-.ù®¦¢¡¤£¯P@Z[A:65>D, )U:+L¡”– ·ÙͼØ0(;¸©§¥¡ŸªÓIYjD88=GL22>2@¬™–¬ÁØÕó9,7Æ­«¨¢ŸŸ¡©¿VQkWHK[öÔÚ6*:1@«™–š£»l{û9*2޵«¢Ÿ¡ Ÿ¥¼ZHC?DG@Eõü/@;-M§š—›«é`ÄĞ9.;è·©¤§¨¢ ª½yHDXhG=Kãk3#<5.FµŸ˜š©ËØÆÍX>8C«§¨©¨¨ª³Ü>;HaeTKOaI/.846H¼¤¤´ÔéÍÀÄûMöº­ª®»Å¿ºÀŞZ[İÆÅ×i^`UA1'"'.56426M̾ÁÎçßȽ¾ÂÅľºº¾ÂÃÄÄÄÆÈÇÇÊÌÎÖåy^OIC>976656667<;<<<;989¾¤›˜œ¨Ï7,0M¼«¨¯Ò4!-ЪŸ¤ª¯°°¯³½æB79V»¨Ÿ§·İORݾµµ¾y:* 'Ï¥››Ÿª¸¿º¯ªª±Õ:-.D¸¡š™©ÂNBY𬮼[4)" 0­š–˜Ÿ¯ÄÅ´©¥ª½@*(4Æ£™—›¦ÃG>X¿®«®½e=4/*  İ••­Çǰ¤Ÿ¤º:%!-Ë¢˜–š¦½tnÆ´®²¾Ü_bíóF* -«š˜¨¶·©Ÿ¥À3$$/˦›§¯´³²µ¿ã^ïĵ°º]-  ,¯œ™œ¡©«¥¡¦³].(.J¹¥ŸŸ¡¥©«®ºĞaU伯®µÚ8'  1§——§®«¢Ÿ§È5&(>¾«¤¤¦¤¡ ¤¯Ù>8:_¯££¤¡ ¥®É?6KĞÇÀ·²¹u* +,GJ¿¡™˜µÕ¹´g/3Tó­«¥§½åWFBENض¯¾B$ +(?3E¬œšŸ±Í±ªÔ,/Ş·¹¼´¥››§ÄÍ¿ç7-1LÄÄS3( $Ç?)c£ ±VÈ£«/%_®¶Ğɬ™£Çΰ·=()7SN2'*()Íë?Ó®««´ßÒ¯³C5Ó²»Ã¸¬£ ©¾Ä·È;.1991("#2@Hæ·¯¶¹¼¿½¿ìHTĞÃÆ»­©©ª«±ºÀé?784-*'"8øD?¿«°¿Ãľ»Ø>@ĞÉOR·§¨­¯®®´ÒB?J=-*./) 5ÊÛ=Q°ª½ê͹´ÈNTÁ¶ÈnÀ«ªµ¼µ±¾jA=?:-()*%'<ğJAϲ¸Ï̽»ÀÜaßÁÃoWij¼êß¾¾óJYá}JALk_G=DVPB>DOPLQnÙĞÔÒÌÇÇËÎÊÄÂÅÈÈÈÊĞİêör^RLJHDA????ACGLUb~áÔÌÉÇÅÃÁ¿ÀÂÃÃÅÊÏÖÛés`XQMHDBAA??BFIMUawìŞÖĞÎÌËÊÉÉÊËÍÏÔÙßèôsg`]ZWUTSSSTVX[_enÿïèáŞÜÛÚÚÛÜİŞâæéíóú|vromkkkjjkllnopswyxz}|{|}|{{||{zzzyxwvwwwxwvxzzyy{|}ÿııüûúúúùùùúúûüüûüıüûûúøöõôóğğñğïïïñññòóóôôöøøøùûüüüış~|{zyyxxwusrqpoonnnmlmmlkllllmllmmllkkkkjkjjkkklllkmoüͺ¹ÈvZkvhh^_ã×ïoåÏËŞkúìwrõïèûao~o^Xhñx[_viéÚx\ZrÏÓMImgvÛ_JYĞÎkTfÚ×^Në×Z\äp]z~nryßöYdqÖĞ\ZáÔÛbWZôÒçoştíŞé÷éçmjĞÌu\lwôæóiaaêŞÛÑëfqæÚjXZ^ÜŞav{U^äílbkæáünåı^üb_İîa_eİßb^dnjpßî]ùËÎZGUäêd]^yÛÓî]ïæöŞõYdt_èÒkTvÕÜiçæx×Ûsenÿlu_Vy×Ù~]d÷ìÛßmrnûÚßza]nÛŞbY`ñììî_pàèïkfıõøqkôàû`fjıìòı^eò{ôïüz|pd|äêmhşzïàügoÿèìküökwnÿíoyjjáâ~üòekëîêlgàìnû÷zùûlıñ{ttøñêî|yo÷tgïåìiitiíío÷ÿiuéòiòàúş~lotü{mntxşúv÷İãkoì}q{vgfìíoıøòòj|înøëww}|ôñz÷îrs{lıêîviwu}ìtoò~úòxtxôòurpyôûuzòï{yøöø|y÷ôütyúwüñ|uyùù{øïúrqüû}ş|uşî÷v}ıuyò~lrÿñïğóyvõíüy{uxnvòqmøùûÿ{ıûözmtúúx{õ{nùò{÷ın~ïzníìinïùyïûhwøzşzxûxw÷õ÷ô÷stïó}wr~şvyüñøotôîõunyøö|üïûşùıurù}xòøöìñû}üíù{ğÿtû|{ulzøø|gxäğşodûõiszküîtptwúò÷ol|ò÷w~øviuæójty÷é~lt~ùplõïùn׿ÑNUoîôc[[esùêåæøõîkguíÛìgúînnk^hgwé_XR[¾¶ÏNHWİÒé\U[[]úŞÚŞ÷lfj{ø}igüï~}ìî|êæo]\cpîëqrïêçæôeeêèqıëú|}zşùùimãŞù]Y^sãâín]`|âÜßäç|j}ìçëu_X_vymoyxşßÏÍÓuON^æåge}úuyôñßÚş__hlimûğîäŞßàézşz_fpdgo||şàænng_oülbdfmyñŞß÷}ûóìéåæõşwqíívvoïİï~õjbrñw\\kikìêwxvhoğëîûşìäãäìğæßâàÛßõsqldfe`aadu}w}wg^\[\^dghuñçߨÒĞÎÍÏÛêõı{pemımdhia\ZXSOMKKMPZgmzäÖĞÍÌÍÍÎÏÑÑÏÍÎÏÔŞèèåîl^WTUQKD@DEBAEINZmåÏÆÂÁÁÁ¿¾¾¿ÁÃÂÀÂÆÌÓàşv^J>94.+(%$$'-=صª¤£¥ª²¼ÆËËÈÄÁ¼·²¯®¯µ½ÒI2(!5Å©œœ¡¬½íJ@DSåÈ»³®ª¨§¨«²¿x?4.,+*)'#!+F¼©¡Ÿ¢©±¿ÑÙÔÍÇÃÁ½¸²®««­³ÀşB6.*'%!,|­ œ›ŸªºÖ`eç×ÍÇÁ¼µ®ª§§ª¯À^<2-+*(% &I¯ œ›Ÿª¹ÌìõÙÏÑÔÕÏ¿±©£¡¤¬½_<530.,(!4¼£œœ¨µÁÆÆÄÈäRKWα¦Ÿ¡«¾cA;<=7.',ުŸŸ¦®¸¹¹½Ë`?;IÊ­¡¢­¾æ[OH>5-)&"+ͦ¡ª²¹º»Æb?9BÍ­¢Ÿ¦®¸¾ÁÌX7,)-7<1"0­›šŸª´²¬«µi/(/û¬Ÿ¡©¯¯¬«´è4((1KóG) ?®¡¢¨©¦¢¢®_-&+R±§¤¨¬ª¤ £®ú4,/JI@:97-! >«Ÿ£«¦œ¤Î* +Y·¯¶·©šœ©ÏMYôW:/1KÑâ4 '\³¨¤™›¨ß0+4IQl­Ÿšœ£«²»ÈX7/9VÙØW=0& +&Ê­«ª•–¨F*,?S:9Ê¥›šŸ©©§¯á6.7L^WgÛì=% %IÛµ£˜“š²QGD8-+D®¢¡ ŸŸ©ÈZVJ;6>ïÃÌM6* + >fª™‘—­×ØY2&&?³¬©ŸššŸ®¾¾×:,.BÓÌÑËÛ=$ + .?¹””«®¿;&%2iʹ¦œ› ¥¬ÃH845:CiÎÛL3% &+=¹•𢣧½:)-;AN¾¦Ÿ©¼_<3/4@Q\_b@)!.Ö£šœ ­z9:609ü³©¥›¢¬ºØ<./58;>HG2#%5梠œŸ­ÆØY:5>>?AFKQ[iúæİØÔĞÎÌÊÉÉÉÊËÌÎÏÑÔ×ÚÜßäèìğ÷ı{vomid`^\YWVUTUVWY\^afjnt{şøóòğîííìëììëêêèçèèééêëìíîïñô÷úıÿ}zxurqpopooqppstuvvxyyzyxyxxxvuuutuwwvttttvvvuutpunmshşjoÅÆÛÕåñõg_QLNT_ghsÿãêïÿàÛÊÍÚkclQMi~oöìØÏëûÚ÷XZ[\^TXeZQWZ^aX^m]`øîâÛáŞØŞäÛÕÓÓÔÑÑÚİÜáâín|òn]TPMGCEECCCGKNTnä×ËÆÃÀÀÀ½¾¿¿¿ÂÄÆÅÃÆÊÌÓãeM@82.+(&&'+/>ö÷®«©«®²¶½Ãþº¶²­«¬®´¿y=2+$36S±£¢ª¥ªÖHKKPKp±©¨Ÿœ ¨°»T11/*()-+"(,+K¹«§¬©£­ÈÆÉßìf϶µ®¤¢¥§¬¯»VAI;00031("&-+M»©¡©ª¡ªÆÔâmdH]º¶²§£¤¥¬°¶î@F?9749=.% *)7Ó¯£¦¬¢£¸ÕámjJB˵´«£¡¢§®¯ÂH??8524;5)$&**A쥪ª¡§¾ÑØïgGMÀ´°©£¡£ª¯´ÒB><4006:/'$(*/MÁ«¦«¨¢©ºÈÖßcCQ·°ª¥¢£ª¯¶ÍJ<72//160)$"*(/JÆ®«­¦¡ª¶½ÉÍçFPƺµ­©¥¥«±·ÉT?9763262*% ((-@ß·­­¨¢¦¯¶¾ÉØOHëż²­¨¦©¯·ÆüM=899664.)""*)+3Hȶ³®§¦ª°»ÁÈ{L[Ò¿¸µ°¬­µ¾ÇÎäUHJKG@=94-&#(,++/=|Ç¿¹¯¬¬±»ÀÄÏêéÒÆÁÀ¾»»¾ÃÇÊÍ×àâäïqaYOF<6332/-.29ANkÖÈÄÇËÊÈÈÈÅÄÃÀ¾½½½¾ÀÃÆÈËÎÓØŞêxaWNF?;8532126:?HSoİÏÉÅÁ¾½¼»»»¼½¾ÀÄÈËÎÓÙßêøxk`YRMHD?=<;:::;=@GMYnæÖÎÉÆÃÁ¿¾¾¿¿ÁÃÆÉÌÎÒÕÙİáéó{md]XSNKHECA??>?@CGMT_{ãØĞÍÊÈÇÅÅÅÆÇÈÊËÍÏÒÕØÛßåëô~qh`\WSOMKIGFEEFGILPX_nòåŞÙÕÓÏÎÍÍÍÍÍÍÎÎÏÑÔ×Ùİáèïúukf`]ZWURONMLLLLMORW]frøëâİÚ×ÔÒĞÏÏÏÏĞÑÓÕØÛİâèíö|pje`^[YWVTSSSTUWZ^cjtùîçáİÛØ×ÖÕÕÕÖרÙÚÜßâçìôştkd_\YWUSQPPPQRTWZ^ckuûïèâŞÜÚÙ××ÖÖרÙÙÚÜßâçìòıvmgb_][ZYXXXYZ\^`ekq|öíéåàŞÜÛÚÙÙÙÙÙÚÛÜİßáåéíóüzpkgca_]]\\\]^_adhlov~ü÷òïîíîîïğñô÷ü~yrmjgd`^\[YXVVTTTQWOXÏËÙȰ¯ÚMelkV`öıûÍwöÍÉØçôúèôbRKKMKIFBAGN[hilşãÖÑÒĞÌÆÃÃÅÇÈÇÅÄÅÇËÑßhPE<60-*(&)0FϹ³±±³·½ÌëvÜø±®®­­¯¶ÁşA1')´›Ÿ©®®¸b7,/Y½¯¬­ª¤¡£¬¿ÛàÚÙS90*  )¨”•­ÅÅÔ<,)5¿¨£¥­­¨¦©µæfÔÃÀc7+ º’•¤ÈNO4()6¸ŸŸª¶®ª­´Ï|¸¹Ì<.' 7—ŠÍ469**9º™Ÿ­Ğମ¹Ğ³¶ÄH0/%¤ŒŠ—¿2*2.(8¹–´z^·©­¸¿½®¯ÍD356  ňµ3)-4(/¸•›»EJÁ¨©¶»¼³¯ÈLB@H*  +.–ŠŒ£;*(,*,¼›•š¸7=ɪ¥®¶²³¶ÏDId~7 ŸŒ‹šT,%'**Í›•™±13Ø­£«´®²½è>NÆÄK §Œ–×,%"(-䜕š®5.İ®¥§±¯±ÆjDW¼»Q³Œ•Ã,&"'-\Ÿ”™¬:+Z±§¦­¯¯ÆXDYº¶\! ¶‹•Ì*%"&-\Ÿ”™­>.Z³«¨¬®°ÊPJ÷º¹Y$ +²‹–^(&%'+R¡•™¬@2^¶­¬­­±ÌMH×¶»M%  ÆŠ”Q$(()*@¥–˜¬C7z¸¯¯®¬°ÍMGܹÁD#²‹˜5$,++(?¡—›®FGȼ¹¹³ª¯ÕLHßÀ÷8$ «Ÿ1)4-*)P¡›Ÿ°éξĞﲪ²Ù[UóİG/!'‘–³.17,)-ÅŸŸ¨³ÄºÃÿʽ³®¿İßZaM7/%3•›Ã0==-*/¿¢¢§®¸¸ÕNêIJ®¼ÊàJ>3'!»š–¥L?B2*%:¯¦¬¸³©¬ÌHV½²½ŞİÄÂ[3,+)!È›©Q=R>.(4º©­´±©ªÃGGÕº¿àáÌÌT2+*'"+º¡¢¯jMS;.,<¿¯¯²®©¬Á[MçÈÕ~éĞÑM0)'$#*^«£©¾n[F4-0O¾·¸·¯¬²Â×ÙÏÔxkßÑŞN:2.,+.=Õ²®´¿Û^H96Ϻ¹¹¹¼ÊQ947>GXÒ»²²¹ÄÔ|QB>BVÓÅÄÇÎÔåXIEIWdóÑÅÁÉØæüZF<AOuÚÖØÓËÄÂÉÙwbyÖÉÅÄÿº¸ºÁÖ^G<5.**/;QòİÍ¿·²µ¿ßSKKJF?@JmÏÇÇÊËÉÇËÙjRNQVUOMP]şãáéíèŞÚßğmejwüylipóæáèíÚÍÉÈÏÚÜÛÖÛö_UV]df^[apïæéîíãÛ×ÖØÙÓËÈÉÍÕÜäzYF;3-++,/39D^Ğ¿¹··º½ÂÌßeRNOU^oëØËÄÀÀÁÃÄÇÊÎÕÙÙØÚŞãäâŞàívd]YSNLJJKLMOWgîÜÓÎÌÉÇÆÈÊÍĞÓÕØÜä÷fSF<5/+)),09AMq˼´³¶¼ÃÊĞákXWjŞÏÉÅ¿¼¹¹¼ÀÈÌÏÙï_ROPPLGCBEHJLNWläÔÎËÈÆÅÅÇÊÌÏÒ×İå÷pf]VNKHEB?<;:9:>974/368=@LæÍÆÆÈÁ½»º»¹¸³¯°²¸¿ÃÊÖë][mV>.%)篥¥¦¤¦³m2-6IsĞ»«¡Ÿ§¯½Ìu>5:TËÆh<3,$"Ϭ¬µ«¯E-6qc?JÀ§ ¨ª¬¯ÂE27LÜÚR@=2%H¸²³¬œ«U5=gU8=À§ ¤©¨¥«ÅA6>YWJNVI2$=À¹´ªœ«Z>QoC3?¹¦¥ª¨¡ ¬ÖC@HD:+  fÀ¿±¤Ÿ¶HPÔX76h¯§«¬£¤¶ïNMH;5¾­¯®¦ŸŸ©¼ÕïJ3-04-$)ÚÒ}²Ÿ¨¼ÎÄÀY4;¿¬°µ¨¨¸ÉÖO3*,/* .ÈÛW²¬ÁÍ¿¾a5>º«±µ§Ÿ©¸ÈÙT6*(*$$ëÈLË š¥¾Ë¾½î96Ô¬¬¸¬œ¥³½Æ^6)$$"+ÏÓIÀŸœ©Çͺ»v8;Ä«®º¬œ¦µ½Äb5(#!MÖA[¨›¡¹ËºµË?7n°­¹¶£œŸ®º»Í=*#Jİ=Q¨›¢¹Æ·´Ê?5a±®¼¸¤œŸ­¸ºÈH-"A\=\ª¥µ½¶´ÄJ;d·²¾¹§¢­·»ÇN.$ "$BO=Z¯¥ª¸¿¹¶ÀWBùº·Ã¾­¥¨±¼ÂÌb:-*,,&#*:E>@|À¼ÁÊËþÆİäɾÃÊú·»ÂÊÏÖíSEAB?<;=?CGJNXpííèÜÓÒÕÖÕÔÑÏÏĞĞĞÓÙàìüod[URTVUUX]ekrşïçâáâàߪßäåäåéïö÷ûxnkifb___`abbfkov}øïíìëëëêêíîîñöûÿ~~{xvsssssuxz|ÿüùöõóññğğôõö÷ööúúûş~|{ywwwuuvvvvwyyyz{}}~ÿÿ~ÿÿşşşşıûúûûûüüûıııÿÿ~~~|||{{{{{|{z||{{||}|}~ÿşşşıüúúúûúúúûüüüıÿ~~}{||||z{{|ÿ~~~~şı~ÿııüıüúúúûüüşışııÿş~}ÿ~}}}}{zy{}{{~~~~}}ÿ~~şşşşıışüıÿ~ÿ~~~~||}{{|{z{{z{{||{}ÿşşÿÿşüüüüûúúüüüüııııüşşıışııışÿşş~şÿ}~~~şş~}~~~~~ÿÿÿ~}~}}~}}}~~}~~~}|}~~|z~ı}zz~ı~}}}~~~}}~ış~}ÿşÿ}~}|~ÿÿ}|~~}||~||}z|sküîjnuşôSÄ·@Rª»3?¸Ç7BÆí=SÉdAZØÉÓCBÖÚD?On78¦¨*-®´12¾Ç4?ʪ¦s9ÖÉ@7kİ;C½Â^ξáIPÙmAbl\²°úɸì:@Úo?YÏzzËÔ|oZRNHOdZNRïĞ~NjìSRobShïnèzFNØùFNתMRÏéHº§ÁO¾¹O8^ß?LÃËÛ½»Ëßèk?æ¶~SÇSHÑUMÀÏWÖoMmVäÄjqÈælwfè__Ü[_äSw×KQÏßaXWêïM^ÉÙVne\ŞŞtãÊ¿ËNOÏÙöÊÌu^gíiVçåSHFi×ZZòF?~lIXffêÜãoyÔÎøî¿¾ĞëİÂÉYÜ¿ÒåĞÙ\O\]TJGH??SOǬ¶tY¼µG  ¢Šœ#ËœÕ!,¦”§3X•ª-<¡˜¥D8º¨µOV¹¿* + +ÃŒ”9=³*$»–^=ª–B1®™Î4髬ÙEÛÅ5 §š0סÃ*(°— æ\¥–£?=«™ŸÖ8ş®¬ÒA_[* *’’¸/¦­7%Lœš¶Lµ™˜º9Æ›®CE¸«¼HDW3 ™“«*/¬¬B'< š¬`½›—¬EÖ¢œ©fI¾¯¾J@G0 -——¸+I¨³6(霴h­™š²Z¸ŸŸ¯~ç·³Ö=:7& +¬—£B7¯©^)7¨›¦ßØ£ÆÆ¦§Ç{¾³Ç?42+  \›¢øC°¦Ï*3¬œ£ÏËŸ˜·¾¥¤ÀhÁ´Ë:./,  K¢­võ«¦æ+D§©Ñºš£²®Ÿ§¿Ñ¿½_4-,' ü©¹d§©Q.Ï£¡°Ê­œ¦®¦«ÂÊ¿Õ=,*,$ ÖÀïʪ¤·=X¬¥­»±¡£ª¥¥±½¿Ø=.)($ +:OCt­¢«aY­¦¯¿·¤¢©££­´ºÏ?.*)$ '23D¸§ª¿Ê®¨¯¼·¨¡¤§£¡©­µÇM5-($ )(/Ê«­º¼¬§¯¾¹«¦ª¬¥ŸŸ¤©¬°¿`?:5.)$!*AîíÚ»­«®¯«§§ª©¥¤¥§©ª­´¾Ñ]B6,%!*6Nıª§¤¢¡£¤¥¥§¨©ª«®²¸ÀØT>3+$$,9c½¯ª§£¢¢¤¤¥¦¨©ª«®±¶¼ÉìN>3+% %,9V˸®ª§¥¤¤¥¦§©ª«­°µ»ÄÓşO?80+'$!  #',3Aoɺ±­«©©¨¨©ª¬­¯´¹¿ÊÙ÷WE=840-,+*+,-/4:DVíÎû¶³±¯¯¯¯±´¶¹½ÃÉ×z^OGC>;987779;=?EJRaıâÔËÆÂ¿¾½½½½¿ÂÅÊÑÙævf[SNLKIHGHJJKMPYdpóçßÜÚ×ÕÔÒÓÓÓÕÚÜİßæïöúwkiic]\\]]\^ahlnyşıÿ~ñêìëêêíğóûwrqnjeeglmjijmqqsv|öóùøöõôóñò÷øûşş~|zvsrsqprozno}aédìºNı®Qñ½Jgau_Fõír^ÔÍiãÖŞXuàcOeÚLcù\ûJÊÍDÉÕYy÷ÏRpßYe^öX[zs}cÙŞnåÛuhÛloèaèş^Ñî^×qâõ[â|kfdc|\]û_yniôdoÙU|ÔVãàzÚ~û×`p×Tjâ_eéêmßïèÚzÚíb×qZÙi`ç[íj[ÖbeØåúôÛå{öà|\ã}Rıî\hşt~ùíòpñw]kwber÷ü`áÛ]èÖòyóÚ_TŞeNòéYaïøjúØ÷hÜøWòä_píö|xäï}á}nÛñ_ßáfìßôùáálîŞbcöaVZ_WP^y^oÙäíÒÖzÜÎun×ÿ`âêbîÜzúÜäöçãùhhlZQYVLU[O^ugñáåÛÔÛÛÔİİÚëîéäìväíföv^\_cOXlN^}P[vXUfhYlßşèËÏÓÃÇÌÂÉÏÉÏİİémd_TOOJIIECBBA?EIIUdøÓÌž»¹º··º¹¼¿¾ÇÉÊÙİó\MD?70.+'%%&',4;eÀµ«¦¢   £§«°¸¾ÌÔî[]K?:/'+8=½¬¨ŸŸ£«®µÇÈÉßÉÂú¹º¼Ên>, (/Y¶«¢œœœŸ£©¯¹ÂÍŞçÖÏȽ»¹¸ÂÙQ4&!-8Ë®©œœ›¢©­¶ÄÉÚ÷ÖÓÎÀ¾¾½ÅàR9+.2R±­¦œ¦§¬»½½ÚĞÀÏȹÂÅ»Ïj_6*"/5k³¯§ŸŸ¡¨¨®½¹¾ĞÁ¾Ë½¹Å¿½èiP/*!27~²®§Ÿ ¡ª¨¯¿¹¿ÓÁ½Ê¾¹ÆÁ¾ácM2* 67`°¯©Ÿ¡¢ª©¯¿»½ÎĻſ¶¾Â¼Ó]R4)  1<[´¬©Ÿ¢Ÿ¡«¬¯¿Á¿Ìʾ¿À¹º¿¾ÆåY=.&!%BDØ««§Ÿ£¥®­¶ÇÃÃËȾ½¾¸¹¿¿Ë_H4( 2T`³§© ¢¡¢¬¯µÅÈÊÏÄÁ¿¸·¹¶ºÄÎg>/(##/hÌ´§¤  ¡¤­²·ÍÕÊ×ĞÁ¾º¶¶¶¸¿Ìy@/&#&,\¸­¦ œŸ¡£«·¾ËóiöŞÎü·´³µºÄò?-#!*/X³¦ šœ¡¦ª²Â×xcnûßǼº·³¶½Ê|=+!!,6eµ¦Ÿ›› ¨¬²¿ÖaXøâéÍ»····»È\9,"!-=å·¨ŸŸ§®¶½ÉğXyÔÑÌ¿º¸¸»ÂĞc;+!!-<üº«¡ŸŸ¦®¶¼Ä×ktÓÊÉ»¸¸»ÄÔ[:* ".=ñºª¢ŸŸŸ ¦®¶¼ÂÏ÷}ÓÈÈžº¹½ÈÚ]<,!".=i½¬¢Ÿ ¡ŸŸ¦®·»½Çæ{ĞÄÅÇÁ¼¹½Ìï[>,!#/<`¾¬£Ÿ¡¢Ÿ §¯¶¹½ÊèïÍÄÈËÀºº¾Ìá_<+!%/:_ºª£¡¢¡Ÿ¡©¯³·¾ÏíÛÈÇÎɽº½ÃÍÛ[9* (/9vµ©£¢¡Ÿ¢«¯°·ÆÜŞÎÉÏĞÁº¼ÁÃÇÙK2(*/:Ğ®§¤¡ŸŸ¦¬­²ÀÑÓÓÕÕÏÆ½¼¾½¾ËyD/& +.?½«§£Ÿ ¦ª®ºÎÔÜhsÒÆ¿ºµ±³¹ÀĞK/% +ê¶­¢œ›œŸ§±¿ÛM?BL^Ğ»°«¨¨©­·Ì?,$'ûô·›œ˜˜Ÿ©¯½M5880?ÏÅ·§¤¥£¥­¹ä9+>XL¥› š•£¥°ÔE>;/6|úЬ§ª£¡©®·_5+">4ÀŸ¢•šŸ§¹ÒM>3/CJM¹­¯¥ §§ª½i=+#7.¾¡¨•œ¨´Â[C54D?Nº¶°¤¥©¥¬½Ö?-""4'㯕œ›©®¶bL;5@))c­»˜™™¥¤¬ÓÜF6>9?öÕº®¬§¦ª«·àM-"(8°Ê¤˜š˜ ¢¨»ÍU>;9@Mí¼µ­§¨¨¨´Îu/#$7»Ò¤›Ÿ™™ŸŸ§·ÂnB<<>EõÇ»®ªª¨ª±¾ä<)" "ÚŞ¶Ÿœ˜œ¡«¶ÇlE@A>RÖʸ®­«ª®¸ÆY1)HlàÄ·±­«­³½Ñ?.&)@H¸¦¤Ÿ›ŸŸ¨®³ÉßyMLZmß°³·Åß?0',6A¿®©¤Ÿ¡ §«®¹ÁÏåiiûğÒÉÁ»»»ÀÏî?6*%" -3>껵¯§©¨¦ª«­±µ¼¿ÍÕ×ëİÚÓÌÌÊÍÛí[D=5+/-&+*(-07AaÙͺ·¶¯±°¯²³·º¾ÄÆÍÎÎĞÍÏĞÎÚİèmdRK@<>5/1-,./39DOcÒËÆ½»»¸¸ººº»¼¼¿ÀÁÂÃÅÆÉÍÏØàîn[OF?>821.-./27>HPvÙÏÉÁ¿À½¼¼º¹º»»¼½½¾ÂÄÇÌÏÙáîpaSMH@>;6410126:?IQeéÚÖĞÊÊž¾¼»º»¼¼½¿¿ÄÉÇËÓÖİé}jcVMLF?><88768:=AIP[sğà×ÒÌÉÅÁ¿¾¿¿ÀÂÅÇÇËÍÎÒ×ßãíqm_WUMJGCC?>>=>?BGLT]gîäßÕÑÎÌÊÈÈÈÇÇÈÈÊÌÌÍĞÔÕ×ßçç~qr`ZZWQMMKHIIGGJLMOX\^qú÷æâŞÙÚÔÔÔÎÒĞÎÒĞÏÑÕÓÕİÛàëçzuşe_`[ZYSUVNTSPXRX`\ecdùk÷ßnâßíÏÚØÎÚĞÏŞØÖäåäèëzíçhmîd_h[f\QkWTmPZ~R^x]up{äoıÜíóÛãîßàíçØÚèİÖÚêïÜúëäcö_j}TïmSoaY__\e`ZûrZëı\İğXİydÍlrÍnàÚmÏäqÌår×ıãåÿïRßìMÙmWqYç]Nâ_Tôd_asé]oãr÷íâskÔolßõÜuÜÓkߨêğİæ[]êoZ÷jfbmßRmÚSgûZi\|êNŞÜPØëjÛkáåoÎâşÕëèãtê}iàïóİxwjZhphZ_k]arq\ZlaìÙxbaŞÕaæÌíàÏÑİXŞ×Né×ZcçÛi`ÏôLzüTQ`şKUÚX\ãjhlyğZhÜhxÓéä×âÙÙãתîÏßsÙü_}ìïgşâ[UñbLW\LHS[KUöbkİÚÚ×ÏÎÛÔÏèߨãİßÕÍõßÍùîßùûU]iINOFH@BHBNPOlcñÓßĞËÏÆÈÊÀÈÊÄÌÈÆÏÈÊØÍ×àâ_^O?@<5530027:>NyÓÁ¹´´³±µ¸¹»½¿¿¾À¿¾¿ÆÊÚ`MA90,($$()7ZÔ»°ª§««¬»ÃÃÛàÏÁ·³¬¨ª«­³¿zK:-*(!&%3]к³ª¨°­®ËÌÌçå翵¶ª¦©¨ª¯¹ÓöO753---(#%&$9\×»³©©¯«°ÇÆÌÛßÙ¼¶´«¨ª«­°¿ßîN;863/-*$#&$7mÉ»´©©°®³ÈÓÛÚÙ×¼²¯«¨¨«¯³½ŞiWA;996.*& &".Yż¹©§±²³¿ÔíÏÊÛ¿¯­«©§©°´ºÓkQG=566.)' &$.Eοî©°²´ºÀØÎÂÌö¯¬­«ª¯·ºÇßWKI;8;5/,( %'&/;_ÚÙ³®µ°±²¶ÆÁ¿Îƾ¹³·³¯¶¹¼¿ÇãõjMH??=43.())'),.6fÖ¿±§¡£§©¥¢¥¬°¯¬­µ¾½µ²·ÂÓÛöK8,%!.IæÊ½¯§¢¥«¬§¤¨®²®ª«±»»µ´»ÊßnO?0%%-(&/l¿Å˺ª¦«¹¸­ª¬±°«¨©¯»¾½¾Ìr[[P?1'6½ºÈ½°µÇ?2󬤩±¬§§¬·¸®ª¬¼Ú˽¸¾ÊÈÓZ:* °œ£¾ÙwZ6$.ºŸ›¡««ª¬ºÑ½¯ª­¿Î»³³¸ÂÔk@/% ²›Ÿ»K;>4(/¿˜œ§¯°°¼ÌÄ´ªª¶Ã¾²®´¿ÖhF5+  [Ÿ¬ßFE:**N¨šš «¯°¶Ã᪬µ½»´³ºÎZC:/$ /©¦½gJ?/*9¹Ÿš¥¬±´¸¿Æ½°¬®´ºº¶µ»×F6/( "¸¡±ÊëóB-.R¬œŸ¨®¯¯·ÁÏÁ³®®µ»º··ÁZ9.*# 1«Ÿ¨·ÍÊÉL67r«Ÿ¢ª®­¬®»ÌÍÁ·³¶»½»ºÅ[6+$ R¨¤«¹Àº½ÕOFܳ¨£¦¬®­«¬²¾ÏÏÁº¸¾ÄÆÅÊü@/$>»¯°¶³®¯µÁÎʽ²®®°²¯¬«­´½ÇÊÇÇÊÏ×İïaI8,#,BoÙ̺®ª¨ª­±µµ¶º½Á¿ºµ°¯³·»¼¾ÂÊÙoSKF>5+"#,6>LÒ¶ª¤£¤§¬¯µ¼ÅÓßÛ˽µ¯®¯²¶º¾ÉŞZLIID8-$ /OIJ«£ «¾hJMRSO]ɱ¨¤§­·½¿ÅÔZIKkĞØL.!5ϱ©£š›£¼@--7BOO󺨟¥³ÍæçäkKI[˺¼á1 %W¿¯©Ÿ˜—›­H+%,:I]ü¼©Ÿœ ¬ÄYIA=98B|ÀºÄP/  8ữ¨Ÿœ©Ò7+,7Gîɶ©¢Ÿ¢¬»ëL=5107BSU=+#.JæÍ¾³©§«¹a=78EPݼ¯¬¯¹ÃÊÍçQEKؼ·»ÉÎËÔ^;/-/1//8NË»¸¹ºº½ÌgJJbÙǾ·®«­µÉî\H9-%+AÏ»¯¨¤¨¸V8/-+*1Vº¬©ª«®¹ï;//6>Mæ¿´°·ÃåUE;7:HğÊÁ¾¼½ÇåQFDFJTúÎÄÂÇÎßeLA>AIUiâĞÊËÓär^TNOZxâÛØÖ×İõd[WWX[h}òó{sj^YVX^cmvëãçİoÕ¸¾ØfZĞüBEMÙÙ^ö¹ÄS\ıC94>mZ[éʽÎhvyşPHsÓÍÍÏÃÄÖ{[c_LMUdlURUMG?=?@L导º¹¸¼ÈÜùğëŞÊ¾¶¶¿Î]=+ #-3:s­£«µ¼ÉG*'.8Dõ¶¨©¯¸Ãl8.3>J󿱯¹ÄÚO915?Mÿƹ¸¾ÍìN>9IùÈ»´²´³µ»½¾ÄÊÈÂÆËİS<$ 7°0¨”š¢ÏÊI*&1à›¨£ d..*+-O¯±­¤¬¾óIF79fİÈ·´¶ÅfR;28=C[ÛÊËÍØaOFDNOaÌÃÿ¾ÇáÛÖpùÍÇÉÔÔÔR?>4+)(').GÁ·°«­µ¾ÇÉİÚ¼¶³­«¬±½Æá:.# +¸êB–“¨ÃÍ#(*$n¥œŸŸ—¥IÍÿ/8ê··¹¥©éü\-&&)('/6/7YȾ°®µ·µºÀ»´·¶¯±º¾ÂÜF8. N7u˜•›¤³È%)'+¸›š™™°İÈM3F¾½Ê¯¨¿LH0.Ö½˜›§ÁËE(5ØÏµ¢¡§¦¯lYbHIiÑa7) 3">˜˜œ¤¹/(H/+´¢¥Ÿœœ«¿´á4]àGğÓeD$4&I—•™§·3+>.:¯¥ «½·o" +*(Ü™—›¦À2.>.9­££œ«¸¸àCëâMõç?( *4£•˜›Ÿ¯H-870Ħ£Ÿ£³´¼JUÏVb|>, +/0÷˜”œ§Í3.<8@­ ¢œŸ©µºÉN`×QDH1 .?¥—š¢²B2>9;½§£ ¤®²ºğfŞ]KB5& /2Ò›— §É<D¾§¢¢ŸŸ¥°·¹ÎyÔÖV?4' +OR£”𦧷;0AHM¾¦ ££Ÿ¥±·ºÒ{ßçZD6( *IE¥“™¦¥¯:-?CAÂ¥Ÿ£ ¤²¸½á[öùOF;) (Q=¯“•¨¬ªG'5JEË¥Ÿ¢±ÈÖpMM_yT<) +.R?¨•«¯®=$/Uo½£››£¦­ÎG_ìEAûc/! erS™Æ¼·.!8ÌÂ­šœŸ¥¬¸u@[ŞIBõU' +8¿S««ëÃI&)N¼«¡œšœ¤®´ÅE;YxIHL/ -Ãü¯’¦Oà]*'?¼¨Ÿ›¯ÈÃß:<êÿ>:/ 8ÅÚ¨¬BöT)'F¶¥œœ›®ÌÓ÷>;S\=2( ëÍÒ•Ç7fZ-*Q¬ŸŸšŸ¶ëÍĞ=1@];% M¹a³’©2>Ñ?+9¹¢¡œ¥ÈgËİ:2?A* 5·ÒÆ™;-ìÚ2-Ô£œ¡ŸœŸ±c[Ğg3,43  .½ÈΗu(AÂK,?©››  ªÛBVàD,)-# 5Æ×Ñ™Ù+?Âd/<­›› ¢¥ÆELl=)%)# B¼ÚÍŸ’™Î*6ÅÆ<8¸›—§£ »=9VP.#  :¹ÁƤ–˜´20ë¿o@Ë¡˜š¡¥  «â9692&E±µ¹£—š¹00eÆãc¾¥›™œ¢§¨­È<-+)"(Ű·¯Ÿ™Ÿ¾;8Lß͵©šš§¯»×B.&/¾®®«¥¡¦³İGAT˶­©¥Ÿ¤®ÈL:2,$-Jѽ³­¬®´¼ÅÑÙ̾µ®«©©©«¯»ÙP@80,*('%%).6=JeÚËÁ»¹º¼½»¹¸·····¹¾ÇÏŞv[RLFA?=:7678:;=?EM_ïÜÔÍÉÆÃ¿½¼¼½¾¿ÂÆÊÏÙæüla[VQNKJHFEEFGHJMQY_nóäÜ×ÒÏÎÍÌÌÌÌÍÎÏÑÕØÜâëúrg^ZWTRPPQRTUWY[]_ejq~óìæáŞÜÚÙ×ÕÕÕÖØÛßåíùvlfb_]\[ZZZ[\\^adinvÿöîéåàŞİÜÜÜİŞßãæéëïöü{tomkigffffhikkmpsvy}şúööôóóòòòóôóóõöøøøùûûş~|{{{zz{||{{||{zyxyzzzz|~~~~~şÿÿııÿşıışıışüıÿşÿşÿ}~}}|z{{zyy{yx{zz|~şııüúûûúúúøø÷ö÷÷÷÷øùûüüüş~şşÿşşÿ~~}||||{{|||}|{{{}~~ÿÿ~~~}}|{zzzyzzyyz{{{{|}~şşşışşş~}~||~||}{}~}|~şşşşışşıüüüüüûûúúúùùûùúûüüüüııüüııüüıııûúûúúûûüûûüıışşıışşıışÿşşş~}|zxxvvvssutssqqrssqqqqppqrrspqqpyoëÎÔşblÕÎù`ahxmfeejntoyòëíuÁ­·QBObUGA@GRc~êàÖÎĞÛŞåohw||ynne`ik{j꾿ûU\oxd[W]põíêìéßßëùúohpy}~x{|tvş|onx~}ytnklqvyüõùûôõúğ~hnhmmi¿´ËK=JİÖiJJ[õßßêîáØŞóubZ_nóéóúûswøõòü~õ÷ùúû|nnxÿòíôûúùö÷ùÿy~şıúııúûüıûú{uttutvskjmqw}şüÿ|şüùôşstvx||yqooowûÿxö÷}ëê}ûóïïüşvrùøúñğúzûóõóôûxkkwsúv{¾¯·|??M^ZI@EYäÖÕØÓÎÏ×è^MGIQ]}æùjoÿ~yzkfun^XVfçãôêÖÏÔİâîksèèõşøéİÙÜğhşÛÖİú_Y[`iùénY^rùîììô}öşe]bøâèo`iûİÎÒëg]]amıkci][i}ãÙŞö_SX~ÛÜ|_\W\åÎÍÏİm^glkùím^dyæŞèíáàíôóojôêo\Zbrog_`uîëìîéåy_gñßİët{íàØÕßıo|íãİÜï_WV[glc]^disıùşk\[g|ïğxkoîÛĞÍÒßûkmé×ÔÙåp[WZ^fwıo_WROOSZanıòğüqnyêÛÔÕÙÜ×ÏÊÇÉÎØŞåâÜÙÛí`OJGEFGEBA@AEKWlîááßÚÖÎÈÄÀ¾¼»ºº»½¾¿ÃÇÊÌÑã^J?93.+(%!#-G¾«£¡¤©¯·¼¾¿ÂÈËɾ´¬¨¦¨®¿X6*$)Ú§›˜šŸ«½Úvk`NDCPÊ®¢œš› ­ÊD2,)&#!.ú¯¤Ÿ ¦¯½ËÎËÇËßf]ë¿­¤¡ª¼f>51/-*%!&=¾¨Ÿ §¯¼ÅÉÊÎåZKLş¾¬££¬¿\>7431.*&"#0{³¦¡¡¦¬¶¾ÆÊÎæXHCM×·©¡Ÿ §²ËT?;:850,(%" *C¾«£¡¤©°»ÃËÓóQC>Bb¿­¤ŸŸ¢«ºŞJ=:8741.,)% (=줡¤©°ºÁÉĞîRC>A^Á®¤ŸŸ£¬»èH>=>?>;62.+& $7ˬ¢Ÿ ¦®ºÈÙÿXH><>AB@=:5/+$'C¸¥Ÿ§±ÀØgOD<9;GÕ³§ŸŸ¥°ÉU@=?EJKHD@=7.%9·¡›š¥±ÅìYLB;67Aݳ¥¥±ÍP?=AJR[[VOI?5+ $S«™šŸªºÚXI@;64;V¾«¡¢«»âMDCHN\vëê}WA3(%s§›˜šŸ¬ÁiI@;734>쵦¦±ÈeLJMUeéÓÊÈÏe=-#"N©›—™¬ËJ;9988;IѲ¦Ÿ¢ª·Ñ_RVjãÑÈÀ¾ÂÑY?=;>XÀ¬£ ¢©µÇäñŞÖÓĞÊ¿¸¶»ÒD/($"&ü¥š˜«Ğ@:a¿¯¬­¯³´³µ¼Êçöϼ³¯µÂyD:63/+'#+¡©¸ÏnYQG>?Pϸ®­¯³¶·¸ºÂÕßĞ¿·³·¿ÍãiO>3,)()($#5먮½ÖÚËÌ~G>L˲«¬±¸»¹¸½ÎvkÖ¿¹¹¿ÊÌÇÆÔN7-,-.,($#&-?=;=Jdè×ÌÅÃÈÒİßåõî×ËÈÆÂÀÄËÑÚå~a\gwgZZbYHAB?7259:AzÊÊÊ¿¿Ï}ufMI[åÖɽ¹º¼¼ÂÑäği^~ÙÑÍÅ¿ÄÎÛñXHBA?=;:::;?[ÔØäÌÁÎh`yWEH_îèØÊÅÉĞÖÓØìóÛÑÕÚÑËÍ××ÏÕıclfRIHIGCBFJGGVéáèÔÊÍÙÖÏÚíäÜÛÕÍÉÈÉËÎÒØæú}ncac_YURKC?<::@SnğÓÅÄËĞÓç[OQW]nßÎÊÌÎÏÖía\\XW^rğäÖÏÒÙÚßòlb_`ejıæááİÜäêôrjgbbkqpıîïñîò{w|vnmtyttıòùyÿúoioohjmlqyuxış|}|y|ûûúóöøíëööï÷zvolqojqogokdzweqóıøéìõëêøïëüøíö÷îôûõø}ıú}|ı}{ş~|ÿÿ~şüşûøøø÷øøö÷÷÷öøø÷ùúùúúùüşşş~|}}{{|{yyxvvuuvusrssqpqooopprtsruwvxyz|{|~~~ÿÿıûûúùùøøøøöõ÷öõõööôóõôôôôôôóóõõôõ÷÷÷úûûışÿ}}{z{zzzxyzyxxzyxyyyxwvvwxxwxxxzyyz{{|||{|~ÿşıışıûûıüüıüıışşıııııüışşıüüûúúüıüışıÿÿş~ÿ~}}}~~}|}~~||}|{{||}}}~~şışşıışıüûûûûûüûüşıışşÿÿşşş~~~|}~}}}}~}|~~~~}}}|}~~}}|||{|}}|{|}}~~}|}~}|}~~şşÿşşşüûüışşııüüıüûüüüşşış~şşÿşşşşşşşş~~şşÿşşşş~ÿışÿ~~~~ÿÿ~~ÿ~~ÿ~~ÿÿÿ~}~ÿ~~}}~}|}}|~}|{|}~ÿÿ~ÿş~~}}}||}}}}||{{{zyxwwssronmmlkjjihhgfeedcccaca_f]ea[À¼cÕ¿p[dïèUèÚgcùÎét½¼ÇÅÒŞTMÌÎoİØkOXÖÖ_mÕíKaÑnYoézS[ßlLcw\SPo`NTãnMŞöZmWëpPóçZa÷ió`hÖclÜşèúìÚÿóëåîkäêğêüİõkåûì~|İkùâöÙòúÚyõïuèkûämßôsÜeğİcŞîiÛboèYèù^à_fêUmù[ı^]é^eêiyogêmfôs}xkèöhïóşòqwûlju}ÿÿöøùììîíğéówîõûömïênóíøë|ğéksùkoouûnvîòüÿñíuvïùzw{ıuzóôşüõù|{ıøôóòïüpqzz{õóylhnrioıolorşpqñwnûşûyrñşoôóø÷şğıtñòûöñêòzòùq}öó÷ÿóõqs~|zwÿşotúş{|öùu~úyxu~÷|öëôııúúzÿø{|ııö÷ôïüzü|uu~ú{yııwoszzz}ıxoqsvx{öõıüıÿzrz|v{ÿı|uÿ÷ş~üøısszto{óô~ûözrxøñ÷õîöywüöÿøêì÷ûúıxwúõúùöúzwÿü{{~şzw}~wv|~yyşşzy}ı|yşü~}ıúş}øôûşüı{wzÿ}{~ı}xy~}|ıû~ywyyx|ü~|~ış}}ış~şüü~~ı}z|}}}~ûûşüı~||şyr{ıüøø÷û~şşş}y~ş}û÷øøúùøııü|z{|}|{{{{}~|z{yyyz|||~şşşıışşşıüüûúûûûüûüıüııüüıııışşııÿ~~ÿ~~~~~~ÿş~}~ÿ~ÿÿ~ÿÿııÿşÿ~~~~~~~~}}~~}}~}~~~}}}~}~~~şşşıüüúûúúúûúùúûüüüüüııış~~}||}}|{{{zyyzzzz{{{{z|||}}}}}}}}}}ÿ~~ÿ~~ÿ~~~~}~şş~~ÿş~~~}~~}~}~ışşııÿÿÿşışşüüııüüüıüüış~şıııışşşşşıışşıııııııüışüûışşışışÿÿ~~~~}|{{zyzywxxxxxxyxxzyy{{|||~ÿşııııüûûúüûúûüúûüûüıışş~ÿşÿ~~~~}}}|}}}}|}}}}~}}}}~}}~~~~~ÿ~ÿş~ÿÿşşÿşııııüııüııüışüüıüüüüüûûüüüıışşşÿşÿ}}~}}}||||{zzyyzyyyyzzyzz{||}~~ÿşşşıüüüûûûûûúûûûüüıüüşşşÿÿ~~~}}~~|{||{||}}||}|{|}}}~}~~}~}}~~}}}}}}|{|}}}~ÿ~şşşüııúùùùùø÷ø÷õööõöööøøøùùûüüüşÿ~}}}{z{ywxxvvwwuuvwxxxxyyyzzz{{|~~~|}ÿ~~şıışşşÿÿ~~ÿşşÿşşşııııışışÿııüışıûüııüııış~~ÿşÿ~şşÿ~~~~ÿş~~ÿÿÿşşÿ~~ıışıüüûúúùúûúúûûûúúııüışÿ~}||{zyxxwwvvwxwwwwxxxzzxx{{{~~~şııüüıııüüüıüúúúûûûûûüüüüıışÿÿÿ~~~}}}|||||~}{}~}}}}}}~~~~ÿ}}~~ÿÿ~ÿ~~ÿşıışıııüûúúúùøùùøøø÷ùúúúúúûûûıış~~}{zzzxwxwvvvuvvuvwvwxwxzz{{{||~~~ıışıûûüûûüüüüııüıııışşÿ~~}}||||{{{{{|}zxyzzzz{}~şşşşıııûüüûûüüûúùùûúúûúûûûüüüıüüıüışşÿÿ~}}}~}||{{zzzyywwxxxwwxxxzz{|||}~~~şşşııııüüüüüûûúúûûüüüüûûûûüıüışışşışÿşşşÿ~~ÿÿ~şş~~~~~}}}}~}|}|{||{||||}}||}}~~~~~~~ÿşşşışşııüüııüıııışÿÿÿÿÿ~~~ÿÿ~~~~~~~}}}}}}}}}~~}~}~~~~~~~~~~~~~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿÿÿÿÿÿÿÿÿÿ~~~~}~~}}}}}}}}|}}}}}}}}}~~~~~~~~ÿşşÿÿÿÿşÿ~şşÿÿÿşşşşşşşşşşşÿÿşşşşşÿşşıış~şşÿşşşşşıışşÿ~~~~~~~~}}~~}}~}~~~}}}~}~~~şşşıüüúûúúúûúùúûüüüüüııış~~}||}}|{{{zyyzzzz{{{{z|||}}}}}}}}}}ÿ~~ÿ~~ÿ~~~~}~şş~~ÿş~~~}~~}~}~ışşııÿÿÿşışşüüııüüüıüüış~şıııışşşşşıışşıııııııüışüûışşışışÿÿ~~~~}|{{zyzywxxxxxxyxxzyy{{|||~ÿşııııüûûúüûúûüúûüûüıışş~ÿşÿ~~~~}}}|}}}}|}}}}~}}}}~}}~~~~~ÿ~ÿş~ÿÿşşÿşııııüııüııüışüüıüüüüüûûüüüıışşşÿşÿ}}~}}}||||{zzyyzyyyyzzyzz{||}~~ÿşşşıüüüûûûûûúûûûüüıüüşşşÿÿ~~~}}~~|{||{||}}||}|{|}}}~}~~}~}}~~}}}}}}|{|}}}~ÿ~şşşüııúùùùùø÷ø÷õööõöööøøøùùûüüüşÿ~}}}{z{ywxxvvwwuuvwxxxxyyyzzz{{|~~~|}ÿ~~şıışşşÿÿ~~ÿşşÿşşşııııışışÿııüışıûüııüııış~~ÿşÿ~şşÿ~~~~ÿş~~ÿÿÿşşÿ~~ıışıüüûúúùúûúúûûûúúııüışÿ~}||{zyxxwwvvwxwwwwxxxzzxx{{{~~~şııüüıııüüüıüúúúûûûûûüüüüıışÿÿÿ~~~}}}|||||~}{}~}}}}}}~~~~ÿ}}~~ÿÿ~ÿ~~ÿşıışıııüûúúúùøùùøøø÷ùúúúúúûûûıış~~}{zzzxwxwvvvuvvuvvvwwwxzÿüüüııüıııışşÿ~~}}||||{{{{{|}zxyzzzz{}~şşşşıııûüüûûüüûúùùûúúûúûûûüüüıüüıüışşÿÿ~}}}~}||{{zzzyywwxxxwwxxxzz{|||}~~~şşşııııüüüüüûûúúûûüüüüûûûûüıüışışşışÿşşşÿ~~ÿÿ~şş~~~~~}}}}~}|}|{||{||||}}||}}~~~~~~~ÿşşşışşııüüııüıııışÿÿÿÿÿ~~~ÿÿ~~~~~~~}}}}}}}}}~~}~}~~~~~~~~~~~~~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿ~~ÿ~ÿ~~ÿ~ÿ~~ÿ~ÿÿÿÿÿÿÿÿşşşşşşşşşşşşÿÿÿÿşşşşşşÿÿ~~~}~~}}}}}}}}||||}}}~~|}}|||{z{{{}}|~ş~ÿış|~üı~şüüıûúûúûûûûûûüışş~}ÿş~şüıÿ~şÿÿÿ|}ş~~ÿÿ~~ışÿşşşşş~}}|{||{}ÿ~ÿ~~}}~}||~~}~ş}~üş}}}ÿ}|~~~~~ÿşÿıÿ~~~~şşıııüüüüışıışışşıÿ}~ÿ|{~ÿÿ~|~~~ş~}~~ÿş~|}~~~}ÿ~z|~~}~~}}şÿ|~ışÿ~ııÿşşşşşış~}şüşüüşıÿ~ûüşüüşşış}}ş}z}|{~~|}|{}~|}}~şÿÿ~|}~~~ş~|ÿ~{~üüş~ış}~üû~}ıü~ÿû}{ûı{~ıÿ||ü|yüüÿ~}üş|~ıûÿ{ûı~úışşÿüş|ÿüûı|üú{|şş~}ıÿzy~şyÿş{}|~û|wşşw|ş||}x|ú{w~{}ı||y}ş{şıÿ÷~tıøııy~óù~ÿú÷üıøõõÿ}÷ûwvöòşşûû|z~}}rüîxuÿ~ùwtúz}wqükàÓa[ëïlcùßzjöşleìãuÏĞPToïÚxtámdmor_næw`criWlàyajüójawğú÷éì{_ZÜÃÄÎâ`X~Ô×çÚÕ|V\zkTrÑ~NX`WVaxú~_VgâãøöìtoáİááßÒÑ÷csêîkfdk[DKñnKCKVMMkÓÈÈÆÃÄÀ¼»»»¸¹ÁÍÎÍÎâsV=3/'Eš–²AOK.4®›²¶°Ê_´  ©®µİ?BEGJLNSZd{êŞ×ÒÏÎÎÎÍÍÎÎÏÑÔÖØÜáæëïúzunkkhedc`_^^`behkov{şøòîìëêèèççèéëììîğó÷úş|zxtrroonnoonnnooonnooooooqtvz}~şüùøøø÷öøùüıüş~~|xwtsspqsrsstuuxxy}~~şıüú÷õôòñğïîîïïïïïñòóõöøùùüış~~~|{|{{{zzzz|~~}~~~ÿşışşşş~ÿşÿÿ~~~ÿ~şş~ÿşışşışÿÿÿşÿş~|||zyyyyzyz|}}}ÿşÿ~şıııüışÿ}}{yz{zxxyxxxyxxzz{{|~~~şşşışşşşûûıüúúûüışıüıüşûüÿëêşÿüşûû|vwxy{xy{xy~}{|}~}|}}}~ÿ~|}ÿÿ~~~}|{|{zyvwxwxwxzxyyx{||ÿıû÷øùúùöôô÷ø÷úüûıı}z{}|y|}ıüşúşıø|ÿù~öôıøñõüúöú||şş~|z}~xyyuyu~÷{ıøıûü~ıûÿöòıış}z|{pvvsxntşqtuorpvzvûûs{şu~útzøıüıö|tÛÏ×àîxkjqcY]ffkyûûx~òwuğñğòïèìêãçêïzùöowÿsvpsylo|qlnswzúøüşùğòıùíú}ï÷ôğüöun~zsmvrdqzmroxÿuşùõù~ïö|óïğøûëëúõùzunÿ}vşoyşu}ux|xzx~z|÷üöíúûòùùöù~ü÷||ş{zrossqosw~üz|üúûûûş÷óõøòíğøøòùzxu|xwzszzwı{||oms}úşüùıûøôôûıûúıùğööö~ø{}óutvvxooq{}rqojfegfdd`bmrôæäŞÚÖÓÔĞÎÏÒÒÏÑ×ÚÜâïüuh\VSNKJHGFEFHIKOU\jïÜÕÎÉÆÃÂÀÀÁÂÄÆÇÊÏÔÜä~b]TNJGDCA?@?@BCFIMS]sæ×ĞÌÇÄÂÁÀÀÂÃÅÆÈÌĞÖŞğve[UQLIHGFEDEEFIKMPZalíŞÖÎËÉÆÄÄÄÃÄÇÈÊÍÑÙáörd[TQSQMKLJJHFIJJRWYeüãàÜÏÎÍÊÈÈÊÉÈÍÍÎÖÛáçúkie^XTPMLKKKKMNMOPV[]oéëå×ÒĞÍÊÈËËÈËÏĞÑØİØàûxh^\\VLNSOLLOOLMPRRYijmâÜáÕÏÏÎÍÊÍÏÍÊÌÙÎÎçÛÜymc\\XQMMONMNIIMLNQW_evøê×ÑÏÎËÆÈÆÃÆÆÌÍÊÛŞÔât^eZJQREEHJDALJAKPKO]|`cÏÍÕÅ¿ÀÁ¾»ÃżÄĞÊÊßmŞèMReJBGI=8=;59>==KfTlÉÉ˾º½¿ººÂ¿¼ÃÅ¿ÂÉÊÎÕÙånTQK>>;674465:?AMföŞÎÃÁ¿¹¼¾¹»¾»»¿ÄÀ¿ÊÌÈĞãîtSFHD9770/1..59=G[ÖÊÀ»¹¶¶¸¸º¼¿ÁÀǾÇÀ¾ÇÆÍ׺NQ@7:1-.,,+.63>^\ϼ»¶²°°µ³·¿¼ÀÉÂÂÃÁ¿½ÅÆÅÛê]D=6/,((''*+/:FcÍ»²°®«­¯±·¼ÀÉËÌÊÅÁ¼ºº·¼ÆÉyF>3,)%!#$#)-1Eh͸°¬ª«©¬¯³»ÀÉÑÑÓÉ¿¹···»ÃÏa>8.'$ "),äØZÄ­­®¦¤«±³¾V=;1*)*'$"*(&>ÅØÇ©¥®¬¥­ÄÃÀjD\ÕØÊ´¬«ª¨©¯ºÈ÷E60/-*)*('.&'W¸Ìɨ ¬²©«ÇïÍéGOÔŽ²¬©¨ª¯µ»ÚB;:/+,/+('"'1,+S³¸Å­¡¨¶³®½j^x]aÒÀ¸®ª««ª®½ÛòQ8/25/-//+"'/-*;¾±¹¶¨£ª·º¸ÂfGQŞÌ˾¯©ª®®®¶ÔQKC6/065/-,( !*0-/x±±º®¤¦±¾¼¿áLKbØÆ¼´­©©­±µ¾öC<9401441.*# '0.+=¹­¶¸©¢©»Å¾ÄdDLÜý¹¯©§«±¶ºÎJ:::405:7/,' )1./a®«¶²¥¢®ÉÌ¿ĞG>^ƽº²«§©®´ºÅk?99942693,'!$-.,?·ª¯³¨¢«¿ÏÈÕL?N×À¹²¬¨¦ª±º¿ÚD78<737>:/*%)/-0Ó««´®¤¦¶ÑÒÓ]DGnŶ°­©¥¨¯»¿ÍK78?=69ED5-)!+-+=³§­¯¦¢¬ÄÖİU@ANä¾°¬ª¦¤ª¶¾Ça;5;>;HHU¾«¨©¦£¨µÆÛU>:;AQa___J4'(-<¼¦¢¤¥§¯Ãd=6=KPݲ§¦¦£¥­½Ô_B;GʤœŸ©°½ØH1.DÎʬ¡£¨ª¬µÇiJNi`_ϾÅã^G6+"$Ję ª·Ì÷M6/G»º¬££©­±¸ÆrLZŞâíÌ¿ÇóM=/(!*Tê½¥£­Àá÷I25ò»¹´ª¤¤©°¶¹Ç`RæÏ××ÉÄĞW<3.&8ñÓ°¡Ÿ¦¶ßki>1?ǵ´¯¨¤¦­¶º½ÒZ`ÕËÎÎÈÆÙI70+"#H뿨Ÿ ©ÂWcO65V¾±¯­¨¤©±¹»ÂÙdoÏÅÉËÉÍwB4,(!4şr¸£Ÿ¤²oXàE2?Í·¯°®¦¤­·º½ÈèYîÅÄÏÎÉÓS;/,&$J`É©ŸŸ©Ä^éT67Q±¯¯©¤©°¹¾ÁÌpfĞÅÉÎÒØzC2,' 9qÔ±¤Ÿ¢µXZ~B6<ë´­°®§¦«´¿ÂÂÔ`ıËÄÆÊÓíT޳§¥§­´½ÖOBDWѾµ­¨¥¦ª¯¹ÈøLAAHMPSTNA3*!%,:j·ª¨ª­±·ÈcKJ]ÙȺ¯ª§§ª®´¿İN@>?@CFIH>5,$!%).9zº¯­­®¯¶ÃŞ^`ıèϾ³¬ªª«®´¾áNC>=;;?EB=70+''),.4DÛ¾·µ³°²¹ÄÎÏÏÓÑǺ³°¯¯¯²¼ÍïZKA==??>=<;6.,,..07Gûμ·´¶º¾ÀÂÅÈľ»¸¸¸¸º¾ÅÏáeOIDA??AB@=;975357;BM`ãÎÅÀ¿½¼½¿¿¿¾¿À¿ÀÁÃÇÊÏÜíj\WRUTMKIIJE@BBABABFJQUVcòà×ÏÊÆÅÃÀÁÂÅÊÌÏÖÕÖÖØŞäîôîfSVUNOQRQPRUW]\X\_`ZXihW\ïìñÜÓÏÍÏÒÏÒâèßİãöğç|`eğïcnòl÷áìşidombgf`_^congdflssrkıáæáİãæíòìïø÷ÿ~ñøıúun{ÿnm|yøí{şúkvxi{ûúïòéì÷îîü}ıòövóêóøö~ywnkfjjansmwusşxröôşü}||y~ğõ÷íğñø~xkqş|zvûííïûzüôğôqxïúqnv|úíşsúğéõsşooıyıôı|üúü{s|ÿyşöö~~ùú{xıúõøtvwnuyz|vøîô|{ï÷nvù|sqıõ{x}ïñ|~vuyoşïø}sıöqrøúur|~rwı|ı~úñzpy÷û}zp|}}ñü|y{óñòşz÷òõûy|}}öxyôûş|ù÷÷òú}ruz}öúıÿıü~øöüyzü|uzıûÿqv÷û{şõù|şû}yzıú|zü}wutÿ}yüû~}úûzyşşxÿú|zt|üşúw}úyü{yù}{÷ùşz{ı{şıxûü{üôşwú~~xvñ~ÿû|øxxøú~}ıûùüşıÿ{~~ù{röüü÷ùøw}}ûûy~vw}ÿù{yzwú|~üyıx|zxşyyy~xx÷~xò}sõı|yúÿr÷ıüû~öøüw~÷üıu÷ö~ğ{|úyşz}ğ~wû~øú~ú||w}û}ü}şşıöıù{qv{ü}wvwyûÿı|{ô|sşı~~qvüÿú÷üvu~ó~~ùxövvî~}z{øûúuxôõôyqüüò÷ıøvùşvñyvïxq~{õûúùyışûy~ıvşu}yqñúx}ytxïôgsï}wy÷ûo{ıûuuò÷ù{úóu}~ÿüş|z÷pıèûuuïópüü|õuqşü|qòîÿ|zğïxyúÿqw~ùı{íõp~ıù}m~÷|w}ïûwøø}pxóxzxzóp|ò|yo|öyv{õşoıø{üúso~öôvxùùğxqş}ô÷{wüï||ùûø}ü||öywññ÷yl}ñşı}oşú|üv}ùùüqúôuşûzûyw÷z{~{ızõùtış}{|ñùu{ı}vùğxsûûû|}öüøouéùsozğuvöxnrôóltîósnıòöroôønnòòsıüıül}ñuşôïşpïõ}onëî}vxöyxş|÷ù}ıúúüíî÷ìóıõøù}ns|qspnuûâíoïòookx|nûõzşîåçõmloeinlntìæğngû~nïy`doôumêògzíöøìç{i~çwcòïuzùğjsÕĞŞô|ocfşıhnèäôóíúikíî|ùéğilwşxişöhkïìüõîzÿìwblujitãæo~ïô{vëôgh|î{~éîììøılkma__hsm}èÜæo}ùxf_ùşn{}ëqhúfd__÷l}èğÜèïÛÜØİáÖãşwüòaezun\etgih|kX_hg_eçæë×ÍÍÎÌÈÅÆÊÊËÏ×àñgPD<72.--./1;]ͺ­§¦§¨©­²´¶¸¼¾¾Ë_8) *E¶œ‘—›¡²F4=FÛ±¢œ›š›§õ" -Åœ‹“›¦Ï+!)5Å£˜”“’–¡¼F- ?»®Ÿ”˜®ÙJ8**I¼« š–˜œ¢³_@7) ,ñ´¡“–­ÎG2)*_¶¨™˜›¦¹èeN3& +MÁª—’¥pA/)*H¯§—˜ ¡¤´ÅÀÄ}=+  +#Q®œ“²F/$#,¦¡˜•š¡§¥¬¿Â¼ÁêO9 !˧’°-&!'-½˜–œ¤®©§¸¾´²ÄG=% Ä¢š”©*$4¹œ™™—œ§°­©®·³°¸ÙO3 1§›˜–›N#:¾£™™›Ÿ­´±®¬¬­´ÃìH4! ¶ ™“•®&%*H¬™™ ¢ªÉ\ŧ¦®«­Í=25( Çœ—“™F,?Å¡•›ª®ÀM@ˤ¡ª©®Ú5+-+  @ ¡š“–¼/=Ч˜™©±¸jB੟¨««¿<-.-  +¦–“£),AO¸œ–¡³±½JK±¡¦¯­²X.,.% ¯Ÿ˜“›>'KFΠ–µµ°æI»¡ °µ±ş.*-+W£ ™•˜¼&A>\ª™›«¯«ÀQʨ¡®¸¯É6-., /©¡š–•©'&@;?¶œ™¨®¥²^İ®£®¿®º;-.- + *­¢™•–¥.)D79¼ ›¥¬£«Ïб§±Î·¸E.,, + (¶ª›–”Ÿ8/\40ܧœ¥ª¥ÁÌ·ª³}¿¹K.)*  +-Ó¯›–•Ÿh[ç/.y¯¥ª§£´µ®­½ZÑÎ:,-,"+HÁ¦›£¼»¹V?aÅ·¹¶ª¨®¯®°»ß_^H9244,&$-/:YÉ´±ºµ¯·¿ÉÌÁ¿Å¾¹¸¹º»½ÃÏÜvQKJC=;73.,089;AUÜÌÍÉÂÂÃÆÅ¿¿ÁÃÄÄÃÃÆÈËĞ×İëyg[SMHDB?==?ACEJQ\i~æÚÓÏÍËÈÇÆÆÅÆÈÊËÍĞ×İêwbWOKIFDCCDEGJLR\hüåÜÕĞÎÌÊÊÉÇÇÈÉËÌÎÓÚâòoaWPLIFECDDFHKOV^nòãÚÓÎÌËÊÉÈÈÈÈÉÊÌÎÓØßók^VNJFBA@@ACFJNU^oîáÙÒÏÍÌÊÉÈÇÆÆÇÈÉËÍĞÖŞòk^UMID@?>>??BGKQ[jğŞØÒÍËÉÇÇÅÃÃÃÃÄÅÇÊÍÑÚés\QJC>;9999;=CLVkå×ÏËÉÆÄÄÂÁÀ¿¾¾¾¾ÀÂÄÈÍÙíjSG?:40///03;GXúÖÈÀÂÅÃÀÀÂÃÀ½¼¼»»»¼¿ÂÈÒågOD<5.++-,,/8GbãË¿¼½¿Á¿¾¿Â¼¹¸¶´²³µ¹»¾ÈÙnOC9/+$!$%)/@Û¿¸°¬¬¯·½ÂËÕÖʼµ±®¬¬­´¼ÅâN<3.("!$)3^»µ²¬©ª¯¹º¼ÅÏ˽µ°­ª©«®¶¿ÔP=5/-($$'-?ǹ·¯©§¬¯¯²»Çޏ´®ª¨«¬­±¼Ù\D3+'##'-JÀ»»²¬«²´¯²ºÁ»²¯­©¦¦ª­®²¼ĞîY>3-+'" "$,>Zjθ¯¯±­¬¯¶¶²¯¯­«ª¬¯®®¯³¸¼Ê^>3,&"*1?Ûº°¬¦¡¢¥¦§¨ª«««¬®¯®®°´¹Ãm<.&%-9r»®ª¦¡Ÿ¢¥§§©««ªª«­¬¬®²¸Àê?.&"+6W½®ª¦¡Ÿ ¤¦§¨ª««ª«­­­¯´¼Ég<-%$.@Ü·«¥¡ŸŸ¡¥§©«­¯¯°´µµ¶»Ä×T:-'!"*7l½¯§¡Ÿ£§©«®²µ¸¼½½¾ÄĞnG7-'#")5YÁ°©¢Ÿ¢¦©«®³·º½ÀÀÂÈ×bG9/)%"(1Hζ«¥ŸŸ¡¥¨ª­²·»¿ÄÇÈÌÜcK=2,(#!(/?缯©£ŸŸŸŸ¢¥¨ª­°¶º¾ÃÇËÎÜ_L?7/+($ "'-6Iؽ±ª¥¢¡¡¢¥§ª¬®²¸½ÄÍÓÙàsUH=6/,*&#"""$(,2=VѾ´­©§§§§©«¬®±·¼ÀÇÎ×İågOH@:520-+***+-/39CYÙÅ»³¯­­­­®¯°´¸»¿ÄÈÍ×à|\PJD?<:975323468;=CN÷ÓÏËÀ»¹¹¹¹º¸¸»¾¿ÃÇÈÌÕİïkaYOJJMNHDEDDC@??AFIMUZgìŞŞÜÕÏÏÌÊÍÍÉÈÉÌ×ÛÖØáéíïñçßëôóurxeZWWYXWXY\_]ZZZ]bgmsûïìäàâİÙÛÛ×ÙÜÚØÛáçìîïva^ind^``^\ZZ^]Z^jllmoøîíêéäâàßߪàåáßåëíö~ûykoogkqiiicoxlnuplou}õûúòòğôïêëéëğííïğóîøx~şztsspw~qtûyz÷~rtxyyúô~{ÿûÿ{şşüüÿıúû~}ı{pt|üş{ıüş~{şıxx}ş|yşüşş~şş~~~üüÿüûûııüııüıışÿÿşÿşşÿıı~~şş~~~ş~~~}}}}{{||{{zy{|zzzxy||||{{{zy}ÿ||ÿÿ}şûüııışııüışıüşşüûûüıûùúûùùùøùúúùùúùøùøúüûûıüışşşış~}~~~~}|}{{||zz{|zxyywwvvwtsstwtuwvvuvxtqrtrsvtttstrqrprtroqunvxoê}Ö¼ÃĹÉdRPTFGYTO_òÛÒ×Üİíôòstmbkklyvöîz|ûşş{ooüsfmşóoiş}qnm~r_hwknux{sxwz{m|îÿ}îôôïîíıóïvğñrtnşşrñòïæøöé÷üöûèêûߪòòğûxtzmoìîùğükjvj_s|g~çï{ıõjkúfoéljşhwçìãÜÜÚãßÙïöí\V[UTV]\R_hVhğûïığêùçãéáŞÜŞİÙàëàæ|z}g[bnULSLGPTP]fdúİÒÊÊÈÅÇÆÃÃÅÆÆËÓÕØæ{h[LE?:754348:>Xé̼¶²¯¯±¶·¸¾¿¼¿¾»ÀÉÑY@6,#! 0¼µ¦œŸ¥­ÇúZC^Ì¿­¦£Ÿ£ª»L+ >Ã§š——š¦ÍC5&(3>Ȫ™—–˜ ®ä* ;²¥›˜˜¥«Ó53+)9d¼§˜—˜™Ÿ®Ì3 !g®¥›š›Ÿ§®î;;/3Sͯ¤™˜š›¤¶m, 'Ê®£ššœŸ§°r@;/8^̯£š™š©»I( ,¾®¡›œ¤ªµO?<1@éÀ«£™›œŸ¬ÂC'+¿¯¥Ÿ¤ª´dID6FÔ¾¬£›œ ­ÃB(+δ¨ŸŸ¡¥«´ßVG;MÙ¿­¥Ÿœ¡¬ÀK+!'N¸­¥¡¤©«´ÎpUEOÙ¿±¨¢ŸŸ £¬½j6' '5oŶ¬¬­¬°¼ÄÖóãϾ¸°©§¦¥¨­µÍN7+'"'*2I_É»º³´º¸¼ÈÇÉž½¶±±®­²µ¼ÎùF85/,-,*,048?QhrÚÊËÊÄÄÉÉÇÃÀ¿¼º»º»½¿ÇÎÛmVJCEB>@A???DKIO_WYmw~ìáÜÛØÏËÌÌÉÊËÌÎÎÕŞİë|úe_l^X_]Y]^]WUe_S`sd\bıpcz|nvíØßwàÖëyߨórãŞëıúäìm~êyjottüü`^kda÷ào^øêÿkhôõiræèokìàæÙÙzòáwÿëë{^ríl|æolây]nopnhø}gzôırfgqxïéohïzhîáq\uúpéãğúsiwäîküynztŞİdrî|zduìeföï{oïìóözöòıúôîûúìûöéñ|xîåyvèê}óáòóéuùçïzwíîlnìïxüşøóooqab`W[\WX]^^o}|xiïßnbííqôïy{úóïõóïóíéêêéèìïêéììííííîòõôôùùûşûûıûü~üı}~}||yxzxwvvxyxuuxxxxwvvvwtrtsssrtvustuuxxvvz{yz|zz}}}~şüûùùùúù÷÷öö÷÷öö÷ø÷ö÷÷øøøùùùúùúûúúûüşşıışşûüzzüú~z}ûûş}~şıı~}ÿş~||}}||{{|{z|zz{z{{{zyz{{|yy{zyzyx}~ts~ü{wzÿüü~~ıúúûúùùùûúøøúúùøøøø÷øùùúúúùúûúúûûûüüıÿÿışşıııÿÿışşş~}}|||{zzxwxwwwvvwwwwvuvwvvvuvtsustuuvustvxyy{|||}}~şüûûúøøøöööõõôóóóòòñğïïñğïòñğóòñòğïïïïïîïïïïñòñóõõ÷øúıüı~}||{xvusrponlljjjhgfedccbba``____^^^^]]]]]]\]^]b]fk[ÎÇ[È·í¼ªÃɺîByĞ@?;??>CJKLfğáÌÉ»º¹¶µ·¶·¹º½ÀÇĞ×ö\ND>:5/-,())(-.3>Hüȼ³¯««ª©¬«­°¯´¸º¾ÈÓçSG<2-'&$!$#%+-5L~É·²®©ª«¨«¬ª­­¬¯°±¹½¿ÒìcD:3)%%!"()1DWι´®«ªª©©««¬®®¯´¶»ÀÉÓôZL>7.)'$!"!"&)/:JßÀ¸°­¬ª©«©ª­¬®±±·¼½ÆÒØwTN>81**'$%$%)*/InÎÅ»¶µ±¯°¯¯±°²µ¶º¾ÀÉÓØøa\JC>520,,,+-.08?KnÑÆ½¸¶³±±°±²±´µ·¼¾ÃËÑİz`UJB<52/,-,+./2:@MòÑȼ¹·²²²¯±±±´µ¸¼¾ÅÍÔèl]OF@:34.-.,-0/6?EYÛÒÆ»»·²´²¯³±±µµ¸½ÀÆÑÜî[QI>;41/,,,+./4=FVãÌü·µ³±°°°°²³µ¹¼¿ÇÔÜmSM?<7//-+-,,/46BO\ĞÈÁ¸¶µ±°±¯¯³±´¹¹¾ÆÌÜiZQB?;32/.--..26:JNlËʽ¸¸³±²°¯±´²¸»¼ÈÎÓs_XH?=7320./0038;BQaŞÌŽº¹¶µµ´µ¶·º»½ÇÉÍòíiKMF<<:75886<</+,*&"%.+ 0qİ«ššŸœ›§½½¾S?޺·­¢Ÿ ¢«¿Q6'(ßÎ¶šœ¢³ººâJ꿼°¦¢¢¡¢«¼ì?-$ RËÕ©›Ÿ£œ®·®¿P׽ȼª§©¥¤«¹Çf7+'#!-ùcƤ ¦Ÿœ¦¯«±ÛÖÂØÏµ¯¯«§«°¹ÈX:1+&%$!%8D^²§¨£¡ª¨«¿ÈÂéñ¾¹º¯©«®­µŞXL1*,)$""$ ,BGÕ­©© §«§²Ë¿Ékλ¼¶¬ª­­¯¼ß^A/--(''!"! *7;ş²­ªŸŸ§¦¦´¼»ÒuËÁÁ¸­¬­¬­ºÇİG72.**)#"".2>ij®¤Ÿ¢¥¤ªµ¸Áå×Éɽ³¯¬«­°¸ÈïH83.++'"!"-3>Á±®¤¤¥£¬·¶ÆsÏÈͼ±¯­ª¬±¸¾áK?6/.-*'%"(+.kÀ·¨¡¡¢¢¦®²¹ßæÊà͸µ±««®¯´Àà[C53/**( %(5eۧ¢ ¡£¦®µ¼ÚèÒİ˺¶¯¬¬­¯µ½ĞdG:62./.)'!!%*,Iú«¡ ¢ ¤­¯µÚèËvâ¼½¸­­¯­±¼¿ÎUF>61/.(&!#)*D̼«£¡ ¡¤«¯·ÊİŞóÛǽ·¯­­­¯µ¼É~MA841.-*& %(+Oν©¤¢Ÿ¢¦ª±¸ÈâİúßÈ·°¯­­°²»ÉÛXE<73//-''#**.߯º¦¤¤ ¤©¬³¿ÑÜóoÑÊ´°¯¬­¯²»ÆİYF;63/.,($!!**8âɱ§¦¢¡§¨¬¹¾Ï}èíŞÈ¾¸±®¯®¯·¼Àî[N;9700/+*%#$'+*FÚÌ®¨¨¢¥©ª°ºÂßóîrØÇ¿¶°¯®®¯´»ÂÙZK=760/.*(#$" )+/UÖ¾¬¨§£¦ª«³½ÆáûçëÕý·°°¯®³¸¼Ìè\E=:532/,+% &# *+-OûÇ­«©¤§ª«±¾ÂÔgâáòž½±¯³®°·¹ÄÚxL@<763/.,)#$&!&+*9\踭«¦¦©ª®¶¿ÉßuŞãÙÀ¾¸°²°¯µ¸¾ÍâYH>98534/-+#&(!),*>Xû¶®­§¨ª«¯¸¿ÉŞëÜáĞ¿¸³µ±±·¸¾ÍØeHB<7630.,(#'&#+,.HZѳ¯¬§ª«¬²¹¾ÌÙÕÜÚÆÃ¾µ·¶°¶¹ºÈĞàNHA99732/,(%(&%,,0J[̳¯«¨ª«­³¹ÀÌÕÚÜÓÉü¸·³´··½ÉÎ|OL=9:221,*&&($)-->P÷¹³®©ª««°·»ÆÏÓÛÚÌÇ¿º¹·´¶¸»ÀËÚcNE=9640.,'&)%(-,6JYͱ¬ª¬¬®´ºÀÌÓÓÜĞÇǽ¹º¶¶º¹¿ÉÏüXK?<952.,)%)&%-,0KNÓµµ­©¬¬¬µ¹¼ÍĞÑåÖÊÊ¿º»·µºº¼ÉÎÜTOG;=:24/+))('+,.=Fl½¹±«­¬«±¶¹ÄËÎÚ×ÍËĽ¼¹·¹¹»ÂÇÕkXH><741-,((*&*.-:IUù¶¬­®¬°µ·ÁÈÉÖÖÌÍǾ¾¼¹»»¼ÃÉÏø_NA?:74/.*(+(*.-7GMͼ¹¯­¯­¯µ¸½ÈÊÎ×ÎËÊÀ¾½ºº¼»ÁÈÍêbQD?;73/-))*'+,.:A_Ⱦ´¯®­®°´¹¾ÇÌÏØÏÌËÁ¿¾º»½¼ÂÊÎè]SF>=952/,*,*+/.6CJ×Á¼²°°®²¶·¾ÆÆÏÕËÏËÀ¾º¾¼½ÅÇÎğoSFC<850.+++)-./>AXÅø¯³®¯µ´¹ÀÀÊÎÌÎËÆÄÀ¿¾¾ÀÂÉÎØt\MC?;64/,,,*-..9AJØÅ¾³²±¯²µ¶¼ÀÃÊÌËÌËÅÄÄÀÁÄÃÊÏÖü`TGB=850---+...:>HÛÎÀ¶¶³°´´¶¼¾ÁÉÉÊÌÉÇÇÄÂÄÄÅÌÎÕ÷rXIG=981..-,./19ALò̺¶¶³µ·¸¼¿ÁÆÉÉÊÊÇÆÆÃÅÈÈÍÒÙócTIB=84/-.,,//4>D^Ïɽ¶·³±¶µ¸¾½ÂÊÆÊÌÇÉÉÅÇÉÈÌÕÖî`ZI@=62/--,-/17>KgĞý·¶µ´¶¸º½¿ÂÇÈÈÉÈÇÈÆÇÊÊÎÙätWLC;92//,-/.3::410-./.4::531/0118;?VfâÈÄ¿º»»¹º¼»½¿¿ÀÄÄÇËËÏÙİík]OHB=9753555:=BR`ìÏÉÄ¿½¾½¼¾¾¿ÁÂÃÆÈÊÌĞÕÛçñn_YNIFA?=;<=>?BJOXoğŞÔĞÌËÊÈÊÉÈÌÌÍÑÓ×Üàåæzns`adZZ[ZZZ][Z`]Z_`_dgjnuùôîåäáߪİİŞßáâãçéêíïôùüş}yusqnlkjijjklmoqvy|~üøõóòñññğïîğñòõ÷úûıÿş}|{xwwsrsqppooqrssuustvz}~şıüü~~||}||||~ÿüúúùùúúúûüüıÿ}{zwwyz|~{z{|~şüúøöôôôôõõöøùøùúùøööøùı~}|}{zxuuvursutsrrttux|}~ıışşşÿÿşüûú÷÷øöøø÷øùúııışııüı~~ÿ~~~}{|}}}}~~~~}}}}|||}~~~~şııüüüûüüüúûûüüüüüııış~~}||}}|{{{zyyzzzz{{{{z|||}}}}}}}}}}ÿ~~ÿ~~ÿ~~~~}~şş~~ÿş~~~}~~}~}~ışşııÿÿÿşışşüüııüüüıüüış~şıııışşşşşıışşıııııııüışüûışşışışÿÿ~~~~}|{{zyzywxxxxxxyxxzyy{{|||~ÿşııııüûûúüûúûüúûüûüıışş~ÿşÿ~~~~}}}|}}}}|}}}}~}}}}~}}~~~~~ÿ~ÿş~ÿÿşşÿşııııüııüııüışüüıüüüüüûûüüüıışşşÿşÿ}}~}}}||||{zzyyzyyyyzzyzz{||}~~ÿşşşıüüüûûûûûúûûûüüıüüşşşÿÿ~~~}}~~|{||{||}}||}|{|}}}~}~~}~}}~~}}}}}}|{|}}}~ÿ~şşşüııúùùùùø÷ø÷õööõöööøøøùùûüüüşÿ~}}}{z{ywxxvvwwuuvwxxxxyyyzzz{{|~~~|}ÿ~~şıışşşÿÿ~~ÿşşÿşşşııııışışÿııüışıûüııüııış~~ÿşÿ~şşÿ~~~~ÿş~~ÿÿÿşşÿ~~ıışıüüûúúùúûúúûûûúúııüışÿ~}||{zyxxwwvvwxwwwwxxxzzxx{{{~~~şııüüıııüüüıüúúúûûûûûüüüüıışÿÿÿ~~~}}}|||||~}{}~}}}}}}~~~~ÿ}}~~ÿÿ~ÿ~~ÿşıışıııüûúúúùøùùøøø÷ùúúúúúûûûıış~~}{zzzxwxwvvvuvvuvwvwxwxzz{{{||~~~ıışıûûüûûüüûûûüıııışııııışşıışşııışşış~~~~~ÿşşşÿ~şş~~~}}~~}|}}|}~}}~~~~ıüüüııüıııışşÿ~~}}||||{{{{{|}zxyzzzz{}~şşşşıııûüüûûüüûúùùûúúûúûûûüüüıüüıüışşÿÿ~}}}~}||{{zzzyywwxxxwwxxxzz{|||}~~~şşşııııüüüüüûûúúûûüüüüûûûûüıüışışşışÿşşşÿ~~ÿÿ~şş~~~~~}}}}~}|}|{||{||||}}||}}~~~~~~~ÿşşşışşııüüıııışşşş~~~ÿ~~~~~~~~~~}}}}||||{||{||{{||z{|}}|}}}ş~}ÿıüüıüûúúúùøø÷øùøøùøø÷ùúùúûúúııüış~}|||{}}zy{yxzyyyxz{zzzyy{|}~|}~|}~}}~~~şışıüÿ~ış~ıııüışıüııÿ~şşış~şşıııüıÿ}~ÿ~ÿÿ~ş}{}||şşÿ~ÿÿ~şııüûûüüıüúúûûı~}ÿ~}}|}ÿ~şşÿ~~}{{}|{}}}~}|~~|zxxyxy{z|~}||}~~zxxz}z{ıüşşüûúúûúúúùøõõøùø÷÷ùüıış~~~~ş~~şÿ|||ÿşşÿ~}|}~şş~ş~|zy~~}~şüûıûúı~~|||yzxw|{z}|}~}}||{{}~~~~||}~ş~ş~z}~}ÿ~ıúııùõööö÷ö÷úøùÿ|~şÿ{wz}zwyxussx{z}ûùùûøö÷ùüıı~|~ûışù÷÷ü|||}{{||}}}~şış}}~|||}ş}y|ÿ}|~úøûÿÿüúışş~ııüûıış~~}|{wz|}|}ıûûüÿüızyzyxuvyzyzz||z{~ış{|ıûøü}úøûüúõõùûûùı}ş}}ÿÿıûûù÷ûÿûûzwxwz|xx~ıı~~üúı}~ûûşÿûøüıûùøûş}}|vstronotwvvxzzz}üüşşüııúúúùûùø÷óòööôó÷ûûûş|upsurorxz}ıÿ~üüüûı~ÿûøôñóõôõùş~~~ytqsw{{y||wvxş~soosvt{şşøòïîïîíìíôøòîîóöõú~{y{vnmmmlkkmomlnooooprw~úóîêåäååæçèìïóøızz}yplklhdggebdjkmqsy}øîìéäߪİÜÛÜÛÛßââçõwy|sjc^__][XX[]_^^bglovıùõëãàßİÛÛÚÙÙÙÙÙÙÛßáäíÿrlc\YVSONMKJJKKKLQX^kõãÛ×ÑÍÌÊÈÇÆÅÄÅÇÈÊÌÏÔÛáîwg\XSNLJGEB@????@EJNXdùãÛÔÎÌÉÇÅÃÁÁÁÂÄÆÈÊÎĞÕÛâğ|k_ZTOLJGCA@????CGKPYeşëß×ÒÍËÉÆÄÃÂÂÂÄÅÆÉÌÎÑÙŞæùpf]WPMJGDA@?>?@BGKOZhzîİ×ÔÎËÈÆÄÂÃÂÂÄÅÆÊËÎÒØßèöo_XTNJGD?>?>>>?CHLS^oïâÚÓÏËÉÇÄÂÂÁÂÃÁÃÇÈÉÎÒÖàìraYOMID@>==;;;:1--14/18AMQgÙÎÍÍÈÁÁÁ¾¼¹··µ´µ¶¹»½ÃÊÎØ|ULE;3.)),.06?]íÜËÅÅÌÒÏÔÛÖÏÈÄÁ½»»½ÀÅÈÍØÚÕÏĞoMG=4.3>>?IpÏ×íàÜån^wìöìßÔÍÎÎÊÈÇÌÎÍÏÖİæåîohYKD>9411004/! +)Cw»“Ÿ§¬¹.,8Cÿ¥˜™š›œ¡Ê=:3/,5ÏÇøN9, +=<=®Ÿ®©¡Ì.C?6º›šœŸ¯L;;=/)12! ,NÃ©š”šªºÎb4%*;s»«ŸŸ¤©¬¼şNFXjïÆËX5 ^®¥œ‘‘¼@L?%!=¶²¯£›˜«´¹ÅN37a½ÓXD+ 6¾­£––¥ÚQQ2"!H¹®«£™•š¥¹Ì×H2.:ؽÍP8* + Eµ³¬œ““¾KD>,*㬤 œ˜–š©Î@89625@nÏX/ :ÌŶ¤™•™§ÃK?6*$#,󬚙™š¨Ã<,)-5;?>:4(*Ü·¶µ¬Ÿš™Ÿ´H.*-137F¿¤™”–œ§¹Ó]@3*')/;=/"O¸±¸¾´¦š­\-'+6KhİÀ® š—™¡´^93441-)''%#7ί««««§££§´h3))0I﨣 ŸŸ£©¶å=.*))++)%&;ɯªª¬®­«¨§¬¹g7-,5W½¬¥¢¢¥ª¯¼Ï[@70-,+++)%" !'1MƳ¬ª©ª««­°¹Ê^@76]ʺ±­««¬¯´½ÊìTIFJWéɼµ°¯²¹ÄØ{^QIA=;9862/-,+-08Ewǹ±®­­¯´¼Êè_WZfõÜÎÅ¿¼»»½ÁÉÓêeTLGC@>=:740///3:D^ÔÁ¹µ³³·½ÈÕİŞÜİİÛÕÎÉÅÂÀÀÂÆËÑÛík[SNKHD?=:86557:?I\åÎÆÂÃÇËÍÍÍÏÑÒĞÍËÈÆÅÄÄÅÇÉÌÏÕÜåóte[TNKGC?=<;;;=@GNYg}íäŞÛØÖÔÑÎËÉÇÆÄÄÃÄÅÆÈËÍÑ×İåóug^ZUQNLIGECBABCFHLPW]gtôçŞØÓÏÍËÊÉÈÈÉÉÊËÍÎĞÕÙİãëõ{nhc^\ZXVSQONMMLLMNQUY]cjsüîèâŞÛØÖÕÔÔÔÔÔÕÖØÙÛÜŞãèíõ}slifb_^\[YXWVVVWYZ]_djoxüòëêãáÛØİ¿·ÍlåŞ×Õİîyõìïñ÷ïëwea^ZSOMKKMMNOPSUXZ\ajuüíäßÛÙÚØ×ÖÔÓÒÒĞĞÒÏÖÌ·¯¼_CIZl\I@>?CGLT\YQNOPQUZeğÛÒÑÏÌÈÅÃÃÃÂÁÀÀÀÁÃÅÈÌÑÜ~YI>92.*&$$'.>í½´°°³¶¸¹»ÂÓiOO~ñª¦¦ª®·¾ËêL9-)&&&$+|¬ Ÿ¤­¸º´¯µÔ:+)5ΪœŸ¤§©¯Ë9%!*.+" ˘œ­õ乩¥º8"1½¦¡«³­¡˜˜¢Ë+%/ZÀÚ5)&*, #©––Ÿ³¹ª¦­I!&\­ª¯µ¬˜›ªU3;kÉç@=WľJ" ,¹¤£¥›®1.ɳ½Å´Ÿ˜™¥ÆOÓ¶ºU29«¯`,')" ¯šœ®®›«,;µ­¾Å§šš¦Óùµ¬¶c?×°¯½jO~J+ .©Ÿ£¦›²,6V[º£œ­Àº²´ÁÔº¬¯½×Ϻ½Z:40% +M¥¬ª—7&56,AŸ•¹Í¯«Ø?ƨ¥±É·®¿SRÍÍ6$# 'ªº –›:+I,%Fœ“¥Ïµ©»4;«¡¯¾°¨¶C[³µV..1 +§©»œ•>.G"#Ëœ—¨¸©²F6רª½­£­Ô^·ÜTo@, + +tš½ª”—¿"i&QŸ˜¡¯¥±95á­­¹¨¡´ÎÊÂÀÓÆ¿>)$ $™²À””·!ù*HŸœ¢§Ÿ²3>Ì¿¹³¦¥¶¹¸ÒÎÀ¾ÇC3- ¨›N¡-C=)©ŸŸ¢©9=ÍæÀ°¨¦²±¯ÊÒ¾¼ÇO;0 ޘe¦4;?&ª§¤©?QÃEجª«¯©¬ŞË²½ÛZ?. 1•ğ·™8>S"«ª©›¨?ò¸=ó©«²µ¨«êî½êbN. (•iÁ—7"ZN#«´¯›™¬F»·0u§®¾¯¢¯m¶®ÚdÏO) Tœ8¤ŒŸ/,È+9¯Ñ¨—›¸Õ«ê-º©¿À¨£ÂÑ«¸bÓÍ8% ­­<•¯/JÍÛÎ̘Ÿ¿³ª<=®³Ì»¦ªÏ³©¾İÉV' 5¡9¤Œœ>;»(6Ág­™šµ¹¡Î0½®Öݨ¥É»¨¹úÉÑ- «<´—ÊS²6*äE»œš®² ¹;À­Îø«¨Ì¿ª²ÙÈÍ- (µ2§™ÉÌ­+/T?½œœ³©»I¶­hqª®ä»©·åÅg'Í>?–¥Í§¹ J=;­›ª¸ ĞÁ¦·E¼«ÕW¯­ÕıÜ0G2@›’¢»¡°"$B=5¶¯µ·´£±Q¿²gB¼²ã^÷/ +,)¿œš§¦È-7G9=°«¿¬¥®¦¢¶Ç¶¿JJÈĞ><7 "%ͤ¤ª¢ºL]Y@HºµÈ°¤§¬¥¡­¸²¼ZHûY60,  &Ϭ¯°¢¡¹Ö¿ÇWu¸¼Óµ©¬¯¨¥­µ±¹éOqX80-%$ &8FFnº´½¼±®°¯¬®±¯¯²µ´±°±°±³¸¾ÏO4'$-@ů­ª¤¡£¥¥¨­®®±µ´°®­¬­¯¹Çc8('8É®«§ Ÿ¡¢¥«­¬®´´¯®®¬¬¯¸Æt:(#2Ù°ª¦ŸŸ¢¨ªª­±²¯¯¯­­°ºÇk8'!0Ⲫ¤œœ ¥§¨¬¯¯®¯®­­´¾ÑL/#$9ȯ¨ œ››œŸ£¤§¬®®¯¯®­±»Éd8(,X¹¬£›šš›Ÿ¡¤©¬¬®±¯®²»Èm;*(B®¥œš™™›¡¦©«­°°¯´½Ëd:)&<̰¥œš˜™šœŸ¤§©­°±³¹ÄŞI1&+EÅ®¥Ÿœššš›œŸ¢¥¨«®²·¿ÔY;,"*=Ôµ©¡œ››œŸ¢¥§ª¬®´ºÄàO:-$'2OƲ¨¢œœŸ¡¤§ª­¯µ¼ÆÙ`G9.' ")2EÛ»®¨£ŸŸ ¢¥©¬¯¶½ÃÎòVG=5.*&"  !#&*.7El̽¶°­««¬««««ªªª¬®±¶ÂòE5*!$*0Y̸®©¦¦§§¦¥¦§©ª«­¯µ½ÍjF7.(""(-4>Oݾ±«§¦§©©¨¨©«¬­®±¶¼ÉîN=3-'#"&+0:Hiϼ°«¨§©«ªª«¬­®¯±µºÀÏnK<3-)&%$$&(+/6>LmÒÀ¶¯­¬­®¯¯¯¯±³µ·º¾ÆÕsOC;4.+)(()+.39>HWùÕǾ¹´±¯®®®¯¯±³¶¹¼ÀÉÔóXH=70-+))*,/5;?DL]êÒǾ¹µ°¯®®¯±³´¶¸º½ÀÈÑê\J>70-*))*,08>CCHWöÖÉ¿ºµ°®®¯°³µ·¸¹»½ÁÇÏæ^K?81-*((*-2:ELKKXíÒÈ¿ºµ°®®¯±´·¸¹¹»½ÀÆÎã^J>6.*'%%',4@YórXZîÍÁ»·´±¯®¯²¶º»»»º»¿ÈØvRB8.(# "(0BñÉÄÍçóÔ¿¶±¯±²²±±³´¶···¹¾ÈÛ^G:/'(>Ì·±´¼Çż²­­²º½º³®¬¬®¯°µ»¾ÍL5*#;¼¨£¥©®²¯¯±·ÆéqÖ¸ª£Ÿ¡¥¬³¸Ás8&(ʤ›› ¨®±°³ÃX;<|±¡œ› ¥©®½I($»˜š¦µºµ®²ô3+5¾¡™—›Ÿ££¢§¾5 " â—š²Xʤ¦F/§”’›©«Ÿ–—¥@ +@?)  !½¦©§ Ÿ¸1!";®ŸŸ›––·D;IS8&!! ¤—±¹¥™›_%ºŸ §¢™’¾Lé¹¾G+*;Q3 +¿œ¬¨–’E6ùß̬—‘™¥¬ª¹Q76QóV?3( ®œ¢³’­$,z;2Ë››¢ «?-BÈÉ=7Yé3 Æ­¬¥•—È0+4/)¨”—œ•“¡î/;åA-6ıf' 4±ª©š’®C43+&¬—–˜™“”¥Íoãl5-?Ğ÷8+ H·Â±——¹ØËB#2¥››“˜«º´Ë7-8QG3358MN­”­©°;!%P®¨¤™’•œ¢¥¯O16=717?5  1?¼•™Ÿ¡«æ/,>Ư¨˜˜™œŸªÉL<2,+,,'  -7ݨŸ¢¢¥°ÈĞÁ·²®©¤¢¢£¥«µÇZ:-&")5IÆ®©§§¥¥ª­­¯¯´¶³±¯¯®­°¸ÂõF1($" &/JÔ¾°ª¨¦§¦§«®³µ¸»º¸¶µ¶¶¸ÀØT<0-*$!"(-6J鯹°«©ªª«­³¹¼½Á¾½½¾¿¿ÈÙeLA963.+)***,09?J鯽¹¶²°³µµ·»¿ÁÁÂÅÆÄÅÌÑÏÑÜy]XLC=986424668;AKVlßËÆÆÂ¿¾¿À¿¿ÂÃÅÅÅÉÌËÊÎÔÕÙãïmecTLKHDBA@ACBFJMPYe|îèÛÕÔÒÏÎÍÎÏÎÏĞÑÒÒÖØÙÛİâéëïøşrljc`__^\]\\]]]\]][]_^_cbdlmns{}şòñïíğêèéäååáãèãáäãäãåéåãëêëõîúvùtmmilngjnikjhjlkknnonmquow~ovus}syùñõùóïèìëäêéåèçëîéïôïúóútø}nwwuomhipginhmqjr|lvurù~yrzrpôwû÷uğï~{îğüôøğòøö÷óííîé÷÷îüıÿ{ûìùvñsu|iú{jvk|ù|ùmñ|qùlíîıäåîõ|ìïwùìëóëıøîvÿk`ıfZ|a_kT^dYaf_lıoéãñŞåßÚèàßèéù|íùk{xt~mmwupprw{tyûøòğîíëéììéêëíğğòøş}yzyqrussrrsuvvwwyyyyywwvtstsstsrrtvxyz|}~ıûùøù÷öø÷÷÷÷ø÷öööõöøøùúûşşÿ~~|{{zz{ywwxy{|}~~şışıüıışşÿ~şşÿış~~ÿÿÿ~~ÿÿÿşışıûıüûıııışşş~~~}|{zyxxy{{}}{{||z~úûúùÿ|}~}~}}şşıı~şüüùùııüÿşışş~}}}{yxz|}~~şşş~~şıışşÿÿş~}~~||~ÿÿÿ~şşşşşışşıışıııüş~~~~~||}|}}|||{{{{|||}}}}}ÿıüıışşşÿşıÿşışşşÿ}}şÿ}şüüûûııúüşşış}}|{{|}|ÿş}}ÿşşşıüûúûüúûıúùûşşüûüüûüışışşı~}|zyyvvwwvvvwwxwxxx{zy}|ÿøıÿûıÿüıÿÿ~~ıışııÿ~ıüüùû~şüııış~}~~ÿ~||||}~~}}~ÿ~ÿ~~ÿ}şüüúúüıııûûüşÿşıııüüşıüüûüşş~~şş~~~ÿşÿ~ÿş~ÿşşşÿÿÿÿıışııüışışş}{}}zz||zzyxxvwwttttttusrrrsrsutuvvxzz{}~~ıûúùùø÷öõö÷õóôôóòòñññññïïğğğïïïïğòòñòóóòòõöõõöøùùüüüışÿ}||zyxwusrqonnnlkjihgfdbba`__^]^[][XcOõ¾ÒùĞŞë`VlYXff_ö¾¹Íçèé|]ULM^]ÖµµÉõïÔŞSKMkÔİhY_ÚÎÙùQKfåó_KJ_üşleùàæôtm{ÿu|üüîôıõwvyfkööp][dbcb`lh``]aoöğğåŞßæïèİİŞæèŞØÖİîûíâîeXXZUQOPY_dc`fvöñçŞØÏÌÊÈÆÄÂÄÄÂÅÊÎÖäñ|^QKF@<96322258:?O÷ÎÁº´¯­­­®¯²³µ¸º¾ÅÍîM=2+# &(*0Dɱ¬ªª©§¦©¯º¾º´¯²µ´³°±ºÏO8-%#$)3k´«¨©ª§¤¦«·ÄÀ¸¯®´¶´°¯¸ĞM5,$"%)0X¶ª¦§©¦¤¤¨±½¿º°®°³³¯­±¿[7,$#(.Iºª££¥¤¡¡¤­ºÃÀ·²²³µ±®±½o8*!!(2g±¥ŸŸ ¡ ¡¦°ÀÎɼµ²±²®­¯¼]2&#,<Ī¡Ÿ  ¡£«¸È×˼¶²°¯¬¬±ÄC,  )7Ü­¢Ÿ ¢¤©¶Ìîßù²¯­«ª­·q1#'5㬟œœŸ¡¥ª¸İZ_˸°­«©§ª´ï/ )<É§šš £¨®ÄUGNͶ­©§¤£¨´]+"/_°™—™£¨­¹l>;LÁ®§£¡Ÿ¡¨½5 -ï­›•”–œ¤«¶Í@//>Ǭ¢œœ¥¼1 + %;»£—‘’–Ÿ®¾ïG1*/K± ›™™šªd!  'A²•™©_4.-./A¶”‘•œ¦È*  ­–’‘“—Õ"=³¡›”‘±]:/% + 3§™›¥­¼2 N©œ™š™˜›¡³ÕßÈÄU) ¼œœ£©®D  O¨œœ›£²ÃÁº½h+  ¯—™¤®¼/ ÑŸ™™œœ¡¬ÃѺ¯±Ü, + "©”–œ¦µÙ'#»›–—œŸ¦¶Õ϶ª­Ñ- + ¤”«Áo$&­–”˜ ¡«ÁòÆ­¦«Î.  +$“¬ÉJ-£“”™Ÿ¢£¯Ùh¼¦¡ªÍ/ $œ’­ÌD0‘”𠣤µo_º£Ÿ«Ş. #›Œ’¢±ËB7”œ ¢¥¸P`± ªã. !š‹ ´Ü>2’›£¦¨·ik² §Ñ1 ¢Œ¯ÖC +¤‘’› ¤¤¯ğ_¹£§¿>' ´œ¬¿n*³”’™¡¡©ÏJȧ¡¶K- +8”Œ–§²Ë;L›‘–¡ £´Z~° «à4# «Ÿ¯Ãß- µ•“šŸ£Ÿ¤ºiÖ­Ÿ¢·D) +*™–¦µÅ["/¤”–œ¡Ÿ§ÈVʪ ¨Ê4!`”šª¿ÄG?•–£Ÿ¦¾^ά£ªß,Ó•“œ¬ÇÃL#=¡––¤¢Ÿ¢¯ÍÕ¶©¬ß)  ʘ–œªÁËE'9¨™—›¢¢Ÿ ©¾ÖIJ¯×+ [™›¤µÌB+##7°˜šŸ¤¤£¥­¸¾º¸Ì5  FŸ™œ¦»ÑK/%#1º——£¤££©µÄƾÃI% + +"ºœ¡¯ÁŞB/()E®œ˜™¡£¢£¨±¿ÉÔ^7" +'²¥µÅÙT;--F²˜˜œ¡¤£¡£«»æI-*'! + *±ŸŸ¬ÈãÏ¿ÃlADÌ©œ˜™£¥¢ ¤°|4+)(! ,´¢¢®ÆÌ¾·ºÛKIËªš›¢£¡ ¥³e4,,+% g¬§­»¼³¯²ÉNF诡œŸ¡¡ŸŸ¤°×=431,! "Xµ­¯±®«­ºyHV«¢  ¡  ª½iB>=8.%)鳬¬¬©«±Äc[Ö¶©¥££¢ Ÿ §´ÍZJF>6,$*Õ¯ª«ª¨©±ÌRQα©§§¥¡Ÿ¥®¼ÆÎôI;9:7+ #_µ°¯¨¢£²I/6ݯª­¯¬¤Ÿ¨¯µ²³ÅL9=]åI/# 2µ¨­®¦£«ñ,*:È®­®«§¤¥ª­¬«®¼mEEQW>3,! 9¹¯¼²ŸŸ²A,8oéζ§Ÿ£­®¨£¦±¾¾Âó?:GK:* 8×¼·©¤ÈF?QN?׫¡£¬­¤¡§¯²®´æ>>NI3)" -YfȬ¡ÊYÛî>1x©¤«­¥Ÿ¤­¬¨¬¾ïhZ?532'(4;¾©¡¨¿¼½K5;Í­®­¥£¥¦§§ª²ºÃ|F=:3,",.6»¨¤¯½¯¾>:Lŵ³¨¢§¦¢¤¦¬±¶ÌM?:3-( -'O­«®´®±^DZZȱ¬§¦¥¡£¦¦«´¾îI<2/))">²´°®­±ß]nGز¯«¦¤¡¡£¤ª°¸ÖJ=2-'& O·¿¯¬®µÔÕcCdz´ª¥¥¡Ÿ¢¤©®·İM>/+% #æÇÍ­­³·ÂÓUa½¹³¨§¦ŸŸ¢¤§­»ÙX9-)1Ødº¬³²¶Ãå_˾½®¨ª£ ¢¡¨°¼ÜA1+!&QDÓ¯·³¯¼ÈÔÏÅÀ¶®®©¢¢¡Ÿ¤¨¬·ÉV;,!-0?¾»µ¯²¹À½Ãʺ»¶«¨¤   ¤¨¯Áy3'#)OÛÀ®°¯±¶¸Ã¾¿Ä°¯«¢£¡Ÿ¦©¯ÅW1' -JT¾²·®°µ´¹»½º²°ª¦¦¢¤§¨²¾ï7, '6=Û¾¾²±³®²µ´·³¯­©¨¦¦¨©­·ÄT8+(,:Zâ¿·µ®­®­®®¬¬ª©¨§¨©«¯¶Å[;+!!'2Cü¿¶®©¨§¨©ªª«ªªª©ªª¬¯·ÉS7)$-?è¾²¬©§§¨«­®®®­¬«««¬®³¼×H3( ,Dȯ¨¥¢¡£§«¯´·¸¶³°®­¬¬®±ºÉ\;-$#3û´§¡ŸŸŸ£¨­¶»½½»¶²¯­¬­®²ºÉ^<.%!/\¹©£¡Ÿ £§¬²¹¼¼»¸³±¯­®¯²¹ÅïD2(!*CÅ­¤¡ŸŸ¢¦ª°¸¼½¼¹µ±¯®­®±¶¿ÙN8,$%6ﵨ£ Ÿ ¤§¬´º½½¼¹µ³±¯¯±´»ÉûE3*#*@ʯ¦¢ Ÿ¢¦«°¸½¿¾»¸µ²°¯¯²·¾Ï\>1)#!-IÅ®¦£¡¡¤¨¬²¹½¿¾¼¹¶´²±±´¹¿Ñ^B4+&  +>Õµª¥££¤¨¬°¸½¾¾¼¹·¶´³³µ¹¿ÍyJ;/)$ (7_睊§¨«­±·»½¼¹·µ²¶¯¨±¾¼ÈÍD11&,7n©¨§ ª²·ÉæéÉÆ¾­­¬¤ª­«·ÁÂ÷SRIC=6+%(Yh©Ÿ§¤§¹ÆÇÔî¹À³­°«©­®°¼Ïç`GLM:2,"1¶»¦œ¨¯±ÎQØÅÌ´­¶®¬¯¬­°³ºÁßdÿRhù<3*?§¨£©ÃÚcG\¾²¯­­°¶°®²±¯¹ÊÓæW`Ùp=3'!#8Ÿ§¡ªå9?xe¿§¨®®¯¼À®®º²±ÌváÛäÙÂa/+ .+­™¡§­Í9+K¿Ä«Ÿ§¶»¹Öά­¹°²Ê]îÃÕŞÀS,( P2Á–·¸z6(>«±¯£ÁÔÅÄÛ´¥±À¶ÆKR¿¹ÌÅÉ/""0¿=¦˜­ñJM6*¸Ÿ®¬ «fF½»Ê«¥µÉÃÅZ_µ´ÏÛQ,!;·>¬™«F7WH-¼œ©¹§«W9È­µ²¦¬ÎİÂÓb²¿`H4'# ²TÛœ¡Õ26İ9?Ÿ¶¸ª»7A®ªµ¯©³_{ºÇ㻳Ï8/.(" ~ª7¯™¬7'RÃ5ÊŸ±Ì±¶4Lª¨­¶¯¯eP¼¼ÇļÉ7),+#µ¸V¤Ÿ¼.&êÅC±Ÿ¦°É¿½Gi­¦¬½¸°ÓWö»ĞÔÜ6(,.%ª¶l£¡Ò)&ʺN°Ÿ§·Ó¿»M{­¦¬¿½°ÌLÊ´¹ÏİÚ>**5-!Í©u¯¡¯9!>¯Ğ˦¢¬ÍÙ¶ÊI½¥¨ÂÓ¶·pfµ®ÃköK,%.7&M¢ä»Ÿ¬= 1­½rª£ª½eº¹KÕª¦°Ø¾¯ÍT¿±¼yXo9'*2) ) ·Ê¥©Ø$#¹¬à²¥ÕI¼µn]­Ÿ®OÈ­ÀGÛ¯±ûLĞV'#46# ³¨m¬¡·3C«Éȧ¦«Ì\µ¼RĪ¥²ò½¯ÑW¿¯¸{JH2'+3) K»¾§«]'¬®Ï«¡«àL¼¶lÏ©¤µpįÃSʯ¸eOe;((3- #Ÿ®ç¨¨Í' ¨Ư ªÃ]εĞk¬¡°_ް¶Wø¯®ê>LE+%-. &Ÿ¬Æ«ªÁ%ê¼µ©¡®>ğ¯Äû»¦¥ËQ·³Õ÷½¯Ä=8<0*,,# +¡ªÅ¬¦´'î«·´©Ÿ«mĵ¯«¨¨ª­±¸ÄÓßëèÜɾº·´³¸¾ÅßQ<41,**)*,/78>QhÜÌÀ»º¸·º»¾Á¿ÆÉÆÄÄÄÂÀÄËÎ×ï]NLG@>>?=>DEGFFLKJNMWbhİÖÏÈÇÀÀÿÃÅÇÑĞ×âØëğèüöúw`kaU\TRPNSRRSVYXXX\^Y^lmwñâİÛÖÒÎÎÓÏÏÓÙáİàíí|znguicbcg\dqhünişkignùso|ğúu}ûûığïø|òèşüöêänl}ñùkşxjy{xpxõ}|~ùø{şıÿóûxøôïùrñ÷uşzuzö~zıøïızxswwmqyuúonútwıõ}xïôûşõñzú÷ıvnøñş÷~|÷úïöwñîwyøí÷o{û~zvzy~}p|õôøus|øşw÷úûûu}şwşşzøõúvoùûu~rvşwòúq{owışô|{zuúş|üú~ùñúõû{óõúóûùvkwrv~w|w}øûÿvıû|ÿ{uvpz÷xzıÿ}s|ú~ûø~ûõùöızyxywüóîóşõúÿş{ıum}}yòîğş{ş~÷{r~zzöîylôıwñşr{ü}zryú}ıüı{şıp|úpşòqşïvúöxış}}{~ü÷ùıüşu{ôqjùøûìíõÿsosxşúÿøûuúêøşêşqû}znoulúçêîÿtò{oí}hokrù{ùì|luşïıyòsktzûsjyúonüïêğóî}tşùõsoòõÿşúîürøíqníóolqîìÿüúzyxzôvpúklòòìëøştsgaüîğèğ|ïõoúürvimnmôğëğòãêüxôwamse]véúîñéídqíëèèæ~\^|û||äÚÿizûëzeumZrßrjçŞáşmïjbú^mğcîékşööîjÿènïösíchô`úÛgsìjäëöÛsjèluóe|{hôôsöş{êüzúntzu{|qöëóëó|ôı}ôùşüx~ø|üøûú~~û~zzxwxtw~{~ûşşÿ|}yvzwy~{z|y{|y{{z}{|ş}~ş{}ÿ~ışşûüûúûúûıúùıııüûııûışııÿ}~ş~}~~}~~~şşşşÿÿ~}}~~|~ş~}şıÿ|{|~~||~||~}}~şş~ÿşıûûıüüıüüüüşşşş~ÿüşşüş}~şşşşşşÿşş~~}}}}}}{|}{|}}}|{{{}~}{|}z{}}}||}||~şÿ}~şışşşıışşÿÿş~}~şış}şıÿÿıüüüıüışşşıı~ÿışşışşÿşşÿÿşşşÿşıüüûüıışÿ~şıııüııüüüûüşşııÿşÿ~ıÿ~ş~~~|}~|z{|{xxzywwuuuuutsrqrpopppnnonnnmllkkjiifheej]èÒcŞÂØ_WÇ­½ELÓÍkHGHXÆÄ^MλÓO[zn[RXVN[ıa\pïãèz~ííëëíæáàŞæîíğóvehf]\UU^VR_j^_è×ôñËÊØÎÇÊÕÓÊØmäàZKLPD:>B:8>FBHaòÙǽ¹¶²®®¯¯±³·¾ÇÙQ=4+###%%*8MѸ«¤¡Ÿ¡¥ª®µ¿ØN;.# ',:cƱ¨£ ŸŸ¢¥©­®²·¸¿ÅĞO:,('! %$-G÷¹µ®¦§§¥©«ª­®­°¶¸ÆmK4&)&%#)**>Mb¾µ´ª¨ª¨©¬ª«®¬®µ¸¿øM<*)+ #( &-)4HL޽ºµ¬¬­ª«­«¬­®²¸¾ÔZG9.//'+-(,/.6=ETl×ËĽ»¸´±®­¬¬­®°·¼ÅÖqOD;40.,,,-.159>GSoİÌÀ»·²¯®®®®¯²¶»ÁÍä^LA;7310/1258;?GPbëÕËþ»¸¶µ´´µ·º½ÃÌÛpVJA=9765568:=@FLVhìÙÎÉÄ¿¾¼»ººº»¼½¿ÃÈÏİ}[NF?<:8778:<>DJScî×Ìľ¼¹¸··¸¹»¾ÂÊÓèbOF?;8644468;?FN^îÖËþº¸¶µµ¶·¹»¾ÃÊÓæhTJD>;987789<>CKS_ïÙÎȾ¼º¹¹¹º¼½¿ÅÊÑŞş^PJC><:9889;=?DJP]qç×ÏÆÃÇÀ¿ÀÁ¿ÃƱ»K×ÊH[âL?CD?H?=îU9KUENaêæâË¿¼¼½¸µ¼»´¹½¾Á¼ÌY^K83.($"#&'+5Pͽ°©§©©¬±µ¼½··²¬¬«¬¯·Ñ?.$ ){¬›™–›©ºèN><Ñ®ª¢œ™šŸ§¯_) +$Q¥š”–˜™§l4-15H«œš–“•™¤³Ì6$ +)+?­œ™¡£œ©C2IÉ騠—šœš˜°À»N*#"#   )ÆŸ“™¤™›Ó-.oÌD³—–›œ˜–¤Ø¾¾9'%-, *9À™’Ÿ›¥õ*6¼Ôꦙ˜ ™›²ÏÂ×6$(5) #*.Ä—“›¡f&:¼å䩚—¡›œ±İĞË>',=1$  + +)#,­“”¢¡™¤<#>¹cK¨—˜¡£™œ¼NÏÅ:$-]=($) ""%[œ•Ÿ£œŸË*1ÅÚM·˜¨œªÈÖ¿Ó0,Jh:,-/ #aŸ›¡£¢Å2;Ñáe¸£ ¦Ÿ¨½È¾Í=6MoL859**zª¢¦¥¢©ÅEIÛÚÓ¸©¢¤§£¢«·¾¼ÄXGiÙnFCE3# *D¼®¬ªª®ºÑàÍÉÇ»¯©¨©¨¨«°¹¼¿Ïá×ĞãWQP?0(! #&,>İÇ¿¶¯°ºÁ¿¼½Â½³®¯¯­­®´¹¹»ÄÌËÊÜ^XYG8/,(" !$%&+9NsÓ¾¶¶º»º»¿¿ºµ³³±¯°²µ¸¹¾ÈÌÉÌÙîşaMG?71-(%%'*,.6BTqÒÄ¿¿Á¿¾½¼»¹¸·´´´µ¹»¼½¿ÅÊËÏßıklTC?=92-..../4:=EQháÖÎÊÉÉÉÅ¿¿Á¿½¿Â¾¾ÂÆÈÉÈÊÏÚİéyi\TNMMIFFCCA?FHELW[[WmÛß÷ãÖÖÙÕÍÑØÕëÙÊÚİÔØÜçÛàlãëXcû]SXYZ]T[wmnd`ùtoèßßïğÛØêÿëëùxèÛyauëêfeëı\}ßnvîpnfihmâùadfózcônjêfgçóöüõæicù{rjoëÿn{|íåólşßî~ùmfvéîúéìô{t}gûêoùı}ãÿlíïõÿqíønu~ŞÜcißòöìùwZlåíîfj÷şéşp|akëäïauî_xãbgøos|î}më{göıimÿygm÷onäíamòıúëéşiyöûëzmèôlõğylwŞëhçéko~çïzæz^õébié~öÛÛçjnåùıïoollïüwøşèògëêedntbbùzlêæf^zïó{qj\_|ôñunóıüé÷òïpúşirvşwjúúwôûğäìîêìêíñíóòìöú~q}ııïïòùüòôùú|xyyrquqrxsorsooolmsu~ôğøxokjkjfgq÷ìêìğøyxş~zÿûûôíîîíïìêõï÷uíö{ïòşgsújäı^ßí]o}ğíâİhhäshxownmxbdphmokxpm|vüğõñöõïõóğööóõ÷÷ø÷ùúø÷öö÷øøõõö÷÷÷øúûııÿ}|{{{yzzy{{z|}}ş|zxwwvwwtuxwwyz{~~şôõ~{|||}|{{zyz{|||zvw|}}|}~şüüııışşüüüûüüûúøúùñõüúùùùúûşıûıüúûúúùùûûûı~~ûø÷û~}}}}zvwz||{|}}~}{}}|{zzyyz{||{{zxxxyyy{y{û~z||}~}|{}ş~şüüûúúüşÿüûûúúüüışöùz{}|zy{xxzz}ı~şııüüşşıııüüüüüûüüüşüııõ÷ıûüıüışşÿÿşÿşışşşıüışş~}~~~}}}||||||{||||||||||||{{{}}}}~~~~şüışüûüüûüüûûûúùúûùùùùøúüùøûûûüüüûüÿıışı}~ı{}}zÿ}z}vu{xtsvtnusqupxvkounqw|ykxmdy^óÏøôßpobyñ_gòÒÙ}ÓÚ^eïûW`àmdäßèşëŞlgèülïçóro÷ugêé|îêåyoìlgmmö}twéçeèçXîê\woíûY×øMßuXédûğ[ãæ`óæxoşùè}fÜyYÚoWéeûì^ØğTÚê[äëõëiİàUáİVéèjëeèæTãßWxóxveâëbççûwtŞd]Ôu^à}îøeØvRÙîUïpû{VÙæSÔß^ÕvgÚ_ÿèZåúZßoeİbzæXøøZßù_İylànıêaõêZwáaiç{÷ş}ßögõße\İwWåw[ßúnáwòî_íô^äìræmëŞblİà\sÏwYÚ|Zîlbrñòn÷ñòì|k}ãoUİÚ[îrtÑ\XÕğYfŞîOîÕT^Úæm]ìÕ\PØĞOTÈÚJmËäKYÌåIhÎåTnÌÛPcÍäM_×pOòàT`ÓvSçáhsqíÙf_ÏØRsÌõOúÓoSpŞt[êâ^qÜëfjáêYgÚê_qØÜ]mÙøaïámjçq_ïïYXóùXYüîn`]øãlfóêäærçÑÜáÜßàÚÙêúŞŞhd÷^Wgb]\VU^_XWUUa|bWsÚŞwû×ÏÖßÚÏÎÏÖÖÏĞÔÙåéìî{]]hVMPOFBGHBBIQRTp×Ö×Ç¿ÀÄÁ¼½ÅÈÀ¿ÊÏÇÈÔ×ĞêRQN;0//,(*0549RÏÅÀ¹²°´·¸º¿ÆÇÆÂ¾½¾½·³ºÎÙÏò?0,)&$&),-3EâÈÁº²¯¯³¹½ÀÅÊÎÍ»ºº¸µ¶º¿Ëİ]E8/*%!!&+--2H̼º¸²­¬¯·¿ÆÆÅÊĞ˽··º¹¶·¿ĞñT>0*%! $*.2=黲°¯­¬­¯·ÄÙ×ÉÇÍÊ»²±µ¶µ¸ÄäXE5*$ !(-09^½°¯®­¬¬®´¿ÖàÒËËË¿¶±²´´¶½Ô[B3)"%+/;󸮬«ª©ª­´ÁânáÑÓĞ¿²®®°°²»ÏO9,$&,2GÁ¬¦§¨§¦¨­¹ÓdfæÜİͺ®¬¬®¯³½ÚC-" )/>È«£¢¤£¢¤«¸Ô\ZkhbÛ»­ª«««­¸Ü;(*0Iµ¡œŸŸŸ£­ÄWEKQMQͯ¨¨¨§¦«¼N.! )9½¡››œ››Ÿª¼}G?==Gϲ«¨¥¡¢©¹r3!$3¸™š™–˜Ÿ­¼å?439KȰª¥Ÿ ª·ã. $Aª›™˜””𣬾H1/27O¾®§Ÿœ£©·?" -ºŸš—“’—¤²e6/.0=ܵ© £®h+ 'Û§—’‘•šŸ¬Ö;1.-6e»¬£›¡ªÃ4  [­¡™’‘•˜œ¨ÍF:.*3YŲ¥œŸ¥¸:" Dº¨™‘’••™¦¾ç?,*5I÷¹¦¢´Q+ /a«š•“’’˜¡®ÁF--57H¼«¥Ÿœ¤®ã, *Q«œ—“‘’˜Ÿª½F2105T¾¯¦ŸŸ¢®l- %_ª—“’’˜Ÿ¦ºE=6.:bγ§¢Ÿ ¦´K- +Ù¬—•’“š¦ÂdF35BS˲ª¥£¥¬É?(;È©œ˜””—š ­½ô?=?Eí¾³¬§¨¬¼V..Q´¢œ˜–—šŸ¦°ËiLEIiʼ±««®¶ï7%':̪Ÿ›˜—™¡ªºË÷NNdİǹ±¯±ºâ<(%6m¯£š™š §³ÄÎdRrÜ̽µ³¶¼ğ:)&2g²§Ÿ›š›Ÿ§°»ÊøoùŞÌ¿¸·¸¿k:) '3h²§Ÿ›š›¡ª³¾Ñö÷ÜÎÄ»···ÄO3$,?É­¥››Ÿ¥®¸ÀÌÏÌĽ¸³²´¹ÏD+#1W¶§ œ››¢©¶ÀÈÙĞüµ¯­­¯¸å7%';ά¡ššœŸ¦¯½ËÖÚʼ³®ª¨ª¯¼S,-[¸¦›™›£¬¹ËåäÎÁµ¬©¦¥©¯É:$#<Á©›˜™ ¨¸ÍçmßÇ·¬§¤¡¤«·Y+-v®¢š™œ¡§¯ÄôgİÇ»®§¤££§°Ò7#'=ɬ¢œœŸ¥¬·ÅÕÛÉ»²¬§¥¥¨®»e1$'8r¼­§£¡£¨¬²¹½¾»¶±®¬¬¬®²»ÏL5*!$+4Aiɹ¯­«©¨¦¥¥¥¦§©«­±¶¾Íg@3+$#+4HØ»¯©¥¢ ŸŸ¡£¦©¬°¸¾ËéN<1*##+5IÕ¹­¨¤ Ÿ £¦©­²ºÂÎíO<1*##*3GÖ¹­§£ŸŸ¢¦©¬±¹ÁÌãT>2*#!)2Dܹ¬¦¢ŸŸ¡¥¨¬±¹ÁÍáW?4,$%-- !.>WĞ´¦ŸŸ›š›Ÿ¤§§¨¬µÄÛxO9*$2GzÅ®£ššœŸ¥¨¨©­¸Ëì`H5(#-:JÚµ¨¢ ŸŸ››œŸ¢¤¥¨¬²»ÇÜQ9+"(4JÕ¸«¥ œœ¡¥©«®´¾ÖQ:/((Jµ§¡Ÿ £¥©±Àȹ« œš›¡­Ñ3  $¾¡ ­ÎK?:10C·—˜¦©¥¢§¯¿ÈÁÆëG6.( +4©Ÿ«Ö^ØÊc8=¼ š¬¹­ ¤°º¹¼ÕE;FK4  #¹ ¤½\\cM0&9›–£E,™•ª5+1ÿ¨¡®Ù¼¦¦µÃµ«²ËǸ·ÀÑǼÌC2*%È—Á33K9/Ù©¤­É·¥©º¾µ­´Ìó·ÃÏɽÊJ8-&!2›š¯=/C=-N«¤ªÁÀ¨¨¹¿¶­¯ÄɶµÀÎξ¾_<0'"¦—§N/>J-6³£§½Ó¬¥´Çº¬¬ÀÔ¹´¾Ëǹºû=6,%Ö˜Ã14M4-Ϧ¤²æ¸¥¬Á¿°¬¹Ú½¯¶ÇÓÀ·ÆL<2(#Ÿ—©:+EI+<®¢©×󨣸ѽ¬¬Í趯¹ÌѸ¶ñ<4-( Eœµ9.D9/Ûª¥­Ï¾§ª»¾¶­´ÏÁ±³½ÏɺÃ\A6+%½™ŸÖ06E/1¾¥¤·å³¦®¿½¯­¾Ô»³¹Çο»ÓI;1*#©™¦K-?J.;¶¤¥Â쬦³Ä¿­­È϶±¸Ìѹ»s@:3*!"¢˜¨=,IO-8³Ÿ¤Èï­¦±Ê¾¬­Àɹ´»ÌÈ»¿îA6-&?œ›¶31Y;,J¬Ÿ¨ŞÈª©¶Ï»©­ÆĞ¾²·ÒÌ»¿h8.,(²šŸÌ/:H/3˧ ¯Ô·ª¬»Å°ª´Éͼ³½ÎľÉN3+)$-Ÿš©=.M@-9»Ÿ ¾Ú²§«ÇÉ­ª¶ÔÙ¶¯¾ÔÍ¿Ï;+()%¾š»3:W3.P¬§ÈÄ®¨°Êº«¬»êÏ´³¿ÚÜÈh0&%%M›š¯9:k<-6»Ÿ ¶Ç¶©¬¾¿¯«±Ğõ¿´¶ÄØÓj8*$%!%¤˜ [/NS4.J§§¼Æ¯§²Å¼­©¹ak¿°·ÓõlF.$" ½›œº1:^L77½ŸŸ­ÈÀ¬ª±¼¹­­Ágx½±ºÜI9/("¸›œº6GMF7@¶£ «¾¹­«®¹¹¯¯¼jT̸·Ó<.)&\ ›«nLZf?5X¯¡¡®¹´¬ª¯¸·²³ÃbXй¹Û9*%!"¹œ´hSìn;7~¬ ¤¯·°©©°»¼¶¹ÏTTλ¾W-$ 䜪ĞVŞÑK:G¹¤¢©³´«§ª´¾¾½ÃäPZÒÃŞ8'?¤¤¹åÕÏ_A?̬¤¥¬®«©©¯»ÄËÌİb[gæd;*P¨ ¥°¾ÁÍiHK˲ª¨ªª©©©®·ÅÛõ`YTSUF6)+Ǫ¦§¬¯¹ÕUGk´­¬ª¨§§ª¯ºÌñSHFEID:.%!:À­¨©¬¯»ÉçøÓƺ³¯«©©ª­³¾Ô]G@>>=82,%!.L˸²¯®°·¿ÊËɽ¹³¯­¬­°¸Äİ\LC><862-)&$%)3Dsɽ·³³µ¹½ÁÇÈÆÁ¼¹¶µµ¶¼ÃÏwUHA>9976743449BKPYrÔÅ¿À¿¾¿ÃÆÃÃÇÇÉËÌÓİä}bXQKHJIHGFFHMNOSWdróæéæäŞ×ÔĞÏĞĞÏÏÑÙáãâèî~quniecd^\_^`hhnkjxuspkghupmwûğìëîòïéíôíğîïüñôïèğñìíìïz÷ê~uttû~oklonjkomqpwzoztvıvõø~õûîîùñù~ğòö÷uşzoüwytmûxt{qwrszr~ıxş{öê÷öò~üüôíôùïíúøûzû~xuyı|{yy||}xutsw{|{ışxøò÷ñüzı|~÷ùş~úùüô÷vwşşşúùv}÷{ûışñúz{}ñıo}~yûøüşyÿûpşısürsyvùrmzüşxzor|||o~ûr}so~ø}w}~ü|v|ú÷ïùtúùúz{öûïõûïò÷õşzøıøîúğïzózûçûïîöëéíäëvëöêîoëtş}e{aew_`ffj^XZ`of[ezùëì÷ߪéâóìæòïwùï}ıq|ùoyşu|uk}÷w|úûîìûøïğïùÿùø÷÷øùø÷ùöô÷÷õıy}}}üüşş~ÿı}zzyyzxwyywutrqsrrssuvvwwxyzzz|}}ÿşıüûûûûûúúúûûúúûûüûùûüıûûüúúûúúûúøøùüıüúùûüûüüüışÿ~}||{zyyxxxwyxwxwwxwwy{|zz||}}}}}~ÿÿÿÿÿşşıüüşııııışııüûıÿşşşşııışşşşÿ~~~~~~~şşÿÿşüüüûúùúúúûûûûüüûüüışıÿÿ}|{z{zz|{{|{||zzzyyz{{{{|~}|~}|~~ÿÿ~~~ÿşııÿ~şışÿş~~şÿ~ÿ~~ÿşÿ~ÿÿşııış~ÿşşşııüüıışşşşşşş~~şşşÿşÿ~ş~}}~~~~~ÿÿ}}~~ÿ~}ÿ~~~~~ÿ~ÿş~~}|}~~}}}}ÿ~}~}}şÿ}ÿşşşüüıışşşÿşıÿ~şşÿşışşşşıış~ş~~ş~ÿş}}~}}ÿşşÿ~ÿ~}}}}|}~}|||}~||~|{}}{|||}}|||z|}}}}}|}~~~ÿşşşış~ÿıışıüûûûüıııışıüıüûûüüûûûúùúûûúúúúùøøùùúúùúùùûışşşşşş~~|z{yxxwvusrrqonnnmmlkkgmfgoZÚÅî_ıöçøomimzş}øıwõìòöõxolpwevdâ±´KBlóqNBEQfniîáåì뿼ğW`oÚæYS_úìîìîzğİÙÖì_XZôëddwïétaùi[ëp_ëèiV{Ùóe]dæíZ\{juæ|ek|ñíî`eÛïf~rğódîåüßÛçöxkmãîjçs]èèüåïs|vıé{ëÙ}yëmõÙİiXvİäe]óŞá}XW}Ùæ\X_júíxfuù`]nüëèybi÷zxì}aoñøéàôc_âÎÚsWKWÙÈÏ^MSôÌÎuRWüÚÛßæiS]İÑÖæbR^ĞÈèSNRrÕÓôWP]çÕØôZWtõ`üÔÛw`_şæùd_ftèİàóf^k}kfgcmşùìİÛtTXdj|ìwUMYéÓÓäbZsÜÑ׺^^|ÙÑÖßëôğäßëydfôìïæîn}ÛÙ~bdvåâòi_}ÙÏÓä}ma^qŞÚïgcjnjc^XUXZ\ed^]\]_^`möøeYZfïÖÍĞèpq|øõzjd`ZROOUcnd^aqìçëëßÔÌÆÂÃÈËÈÄÂÇÏØÖÑÔÛèdMD@@@?>==EZâĞÌÌÉþ¼¼¿ÆÊǽ¸·½ÉİlSC7.*'$" "*?͸³µ¸¼¾¿ÁËÚÖµ®¬«­®°µÁY4)#!$6Ͱ¬®µ¼ÁÆÎïSNú¾®¨¦¦¨©©«³ÌG4.+'!%<˶µº¿ÀÀÊşKEV˵­«ªª¨¨¨­ºåC7/)"*S½´µ·¶·½×L>Dû½°¬«ª¦££§¯ÀoF;3*")P¼´µ¶´³ºÕG;Bİ·­¬¬ª¦££¨°ÄjI?6+"%=˹¶´±±¸ËP>Bﻯ­®«§£¤©¯¼Ò]F:.%/²°°´¿x@ÿ¾´°­¨¤¥ª¯°°·ÍPBC?0$$BÁ¸´¬©°Ù?hų¨£¦«¬¬®µ·¹ÄŞ~hN<, /À³±¨£®W34>^̸§Ÿ£®°«­¸¼·¹ÆİiXJ3" ä­¬©¦¬Ğ6,1RÄ·©Ÿ ¬²¯²¹¸´¹ÂÍåcR=*<´­ª¥¨º=),MË¸²­²¼¾¸µÂ\[Ìã3!ä©£§ª®Ş-&1f¾¯£¡¯»¶³¸¼¶±¹Ó`ñÚK--¯¦¨©ª¹>&'?õ¬Ÿœ¦¾Á³³»¼µ°»ëiËĞ='D¥¡©ª¬Ë-"*b¸±ªœ­ÜÁ¯²½½²®¿VòÁÕ7$õ¤£§©°è*-Ú¹¯¥®ÚƱ¶Á¹¯±ÇkÚÀÜ6([¤¡¥©³U( /ض¬¥Ÿ¯äDz·¾¹±°ÀsÙ¿Ï<)3¦¡©µç,(nµ«¥ Ÿª×ä¶³½¼µ°»òç½ÀP/$¹Ÿ¥®Ğ5"!<¹¬§¢ ¦½bÁ¯·¼·²·Í~ȾÚ>,+¨œ©ÇH.!(÷¯§¥¦¤«×û¶°º¼¹´¹ëﺻf7).§›Ÿ¯ÌI,"+Ü«¥§ª§­Óû»°´¾¿·¼âÕ¸¹æ8) $­›¬Õ?/%(a¬¥§«ª«¿u¿°µ½À¼ºÂÉ»¹Û<,"Ï›œ«ÎH9(#A¬¥©®­¨³\Ï®²ÁĽ¸¿×¼¯ÀF.',¦› ³Y<."+¾¦¦¬¯ª«ÕXº®¸ÊÈ´²ËظµÕ:,) 6Ÿš¤ÃA;."0´¤¦­°©­æd¸¯¹Ìɳ³ÈÆ·½_4*']›šªc6:.%<¬¢¨¶¸¨­tc¹±ºÎ̲¯ÄÇ»Á]4+(!Hœš©}::-%<¬¢©·¸©­í_¹®ºÖƯ°Çͼ»æ6++%+¢™¡Ä337(/¸¤¤®Â±ªÉX¾²´¾Ô¾±½Ë¼¼×@/-+Ášœ®G28,)j¨£ª¼¼«²{Ùµ°¹Õв¯¾ÇÀÇv://*¹š·:6?,)í¨¥­À»ª³fä·¯·ÒĞ´³ÀÁÀÅæ:..(µ˜œ»45G-'}¦¡¬Òé²Xë¶®¶í貯¾Á½¿z4.5.$Hœš«G2?6(:¯¢¦½Ğ¯¬Ïl¾¯±Îp»±¼Ä¾ÆC/64) ¯—»1.H2)i¨Ÿ¨Öެ¯îy½®¯êX¶­¶ÅÖÆÄ@-16/$°™¾52@0+n¨¡«ÏÏ®³êܸ¯µày¸°¼ÅÅÃÖ>4<=1*"*Ÿ—¥Y-7+ +˜§_.9L00½¥¥¸hÁª²ÜÙº®³äm¹¯¸ÂÌÆÎ@18:6.$'£˜£é0=`2+ã§¢¯úÊ«®ß\ů®ËZ¿°¶¿ÈÇÉU78A>3(<™§M-H_/1Ğ«£¯×º¬¸×æÅ¯¯ÉÛÀ¹¶ºÆÉÏN>>><6-&!ª™ŸÀ9Hã8*;¹¥¦·½°³Æuıº¬³ÎİÅ·´½ÉÊàK=9984+!GšªY>ïk/)I­¡©º¼°²ÊVö¹®µËм´¸ÈİØ×`?7686-"5¡š¤ËHìü1)7¼¤¢­¶´·ÇeUƯ®¼Í;·»ÇÏÛvM;2033*¾®klÈ].*<´¢£­¶¹»È]Yİ®¶ÈϾ¸»ÉñdlS=2.//'$´¬ùhÜK2,7¼£¡§±¿¿ÁÛoÙÀ´±¼ËȽ¹»Ï\POJHʵ³½éTñþÏI2,,*!1­œ›¤½p×ÀÊI.)3Ȩ¤«¾üض¬¯ÅK=O³µÄïlÒ¿¿ë=0./,#-¯œ¦¾ãÅ·ÀF,(5Å©§¯ÉãÄ®©¯ÏE?h¾¶¾İmØ¿¹¿_8024-!2­ŸŸª½Ä´¯É7()=»ª¬¼Ïǵ«¬ºlJ_˽½Ï~Ù¿º¾ÕM<;=6)/µ¥¦«¯²®¯Ó2).FòµÄÈ·­«¯½êeÓÄÉÙçÛŹ¹ÇúWOI>2(#ì«§ª¬®¯°Â=,/DݽÂͬ«±»ÄÎÍË×o{;º»ÄÜwiO;/( 7²§©¬««®»Q.,?ÜÑÖɾµ¬ª°½¿¼ÀĞénrϽ¼ÇÏÊËŞV>2,(!$ެ¬±®¨§®Ö7.<éßORȱ«¬±º¹±´ÊSSÜÆÁÅÎÓÆ½ÉO:74,"7¼°´®¥£«ÃL;A]\@Bϱ®³¶²®­²É\wÈÆŞrÛŽ¾ÔVJJ<,"#Lºµ°¨¢¥°ÎLEPO<9\º±µ´­ªª®¼ÛëÏĞhTßÀ¾ÇØwXG6*!"Y¶¸·¨Ÿ£²Ô^Z[I99x¶°¸µª¥©³¿ÌÎÏáUPİÀÄßdfQ9*!$QÀ¿³¢¤µÉĞæL94?ѹ¹¹­¥¥¬µº¾ÊzMKfÓÏãîŞp?-$>ØÚ¼¤œ ¯½½ÅV50>ÛÄĹª£¥«¯°¸ÏUIMX^aræòI1'!4FO¿¥¤¬¯°½V86CcüÒµ¨¤¦¨©¬¸ÙUMHBAK\UB7.("./6Ϫ¥©«©ªµŞHCLOMì·«©¨¦¤©´ÆİY?79?@:63.' *,-?½®¯®©§¬»ÏŞsNKrĸ°«¦¥¨­²»ØH;983.,,,'*/+.W¼»½±ªª´¾½ÀÕmâļ¹³¬©«­¯µÅiIC=71/.,("$+/7F}̾µ°°·¿ÂÃÅÈËÆ»³¯­­¯²µ»ËrQLIHJG?;6/*&#"'1>GPêȼ·¹ÀÍÌÅÅÇÆÀ»´¯®°µ¸º¿Íèd`fqgOMSMC90.//.-.7COdçĞÈÄÄÊÎÍÍÈÀ¼»»½»·¸¼ÁÌÑĞÙpZiéıc[OMNE=::;:<>\a^ʲ®µ»¸³±²´´¯¬¬¯²¯°¼èB2)  &ªŸ®²¤£·P=>_ÉÏß±šœ¢­¿ëéŞG.(% ®¦ÆÌª¥µJ/5à¼åH¾¡›œŸŸŸ¨ÁXêÅÑN?>8+ »©¸±££­Ë=8ì¾mD¿£œœŸ Ÿ¦¾\øÏmA:72* ¯¦º¶¥¡¨¼@8ݽc@ĦœŸŸŸ¨ÃWhßoMC>:0& ";ȶ¨¡¤³Şâ¾½áş»¨ŸŸŸŸ«¿åêçV=641,% !@IR¼¨¡¤­»½´µÆÑ¸©¡ŸŸŸ¨¹ÎİiG9331,'" 059Ü­£ ¦±¶®®¾Úů§£¢ ¤¯¿ÍãO;2/.-*&)*,A¿¬¦¦¬®ªª³Â÷­¨¦¤£¡£ª²¼ÃÎoH;4.,)#%#&4d¾··±©¥§«­«¨¦¦§¨§§©¬­¯²¹ÄöC4,'!%9׸²¬¢œœ£¦¦¥§«­­«©ª¬®±µ¼ÓI3)"*Aİ®ªŸœ ¥¨§§ª®®­ª©«­®¯´¼ÏJ5,%':×µ®¬¤¢¦¨©©«®°¯­­¯±°±¶¼ÈwC6-&%3MÑ»°ª¤¢¥¨ªª«®±²²¯®°´´³´·¿ÍìO=2+% (2FiÑ»¯ª¨ª¬¬¬­®±±¯¯®¯²´µ·ºÁÔlK;0*$ %,:Sçȹ¯«ª¬®®­®¯±±¯®®°´¶·º¿ÏmK=3,' !""&,8Nè˽µ®¬­¯±°¯¯±²±¯®¯²¶¸»¿ÎhG:1+&  #$&*1?hк´¯®¯´¶¶µ´³´´±¯°²µ¹½ÄÖ^C6.)%! #$&*/:OÜÆ¼·´±±µ¸º»º¸·¶µ´²³´·»ÁÍøL=3-(%#$')+/9HùË¿»¸µ´µ¹¼¾¾½»¹¸¶¶µ¶¸¹¼ËxP@2*$""#&,6MÒÁ·¯®°¸¿ÉşKKR_áÄ´­¬©©¬²¼ÑO90,&&(&)/6GäʽºººÀÇÎk[ZM[áÑ¿¶¯­­­¯¸¿ÔOA8/,+)*,.4@`ãÆ¼¿½¾ÉÑç\PNPWxÒÈ¿·³´±µ¼¾ÊëmPDA>===<<>@AHNTgãÜÏÈÇÄÁÂÂÂÅÆÄÿ¾¿ÁÇÒxM=2.+(*,.:Jtȼ¹·¸½ÆØ`MGDHRmׯ¾º¹º½ÃÎíWH@=<JmÖÆ½º¸·¹¹ººº¹¸·¶µ·º¿ÒZ<0*$"!!%)/=OÒ¿¹´´·ºÂÌØûyôìÖÍÈÀ¾¼»»»¾ÁÆÏØş\WLKIFGEFGHJKMQX`oìİÔÌÉÅÃÃÂÂÅÆÉÌÎÔÛâycVLH@<941/.//28>Ní˼µ¯«ª©©ª«­¯±¸»ÀÔûD8,!"!",+KİÉ­¯­¨°±¶ÏÅÎéÀÉÁ´¹¯®±­°¶·ÇÜa>:4.-+*+)+./7@MÛÁ¸®«¨¥¦¦¨¬¯·¿Éßt[IC8/)))@ÚŬª¨¢§¨©±¯°¸®²³­²¯¯·´»ÈËZC:,)$ &.5U̼­©¦££¤¤¨ª¬±µºÁÂÈÎÌÖÜêZF8.$%*1oжªª¤¡¥¢¦«¨®°®»·ºÉ¼ÆÎÄàìe?7-$!+/Lͼ¬¨¥¡££¥©«­´´ºÀ½ÄÄ¿ÊÅÉÙãN=1*#!'03{ú©§¦ ¤¥¤«¬­»µ¼È»ÉɾÒÇÆîâN:5+$! &.0OÌ¿¬©¨¡¤¦¤¬­®¼·»Ê¼È̽ÍÈÃãÛ^>;.)%!%!)24õǺ©ª¦¡¦¥§¯®´¼·ÁžÉ¿ÊÄÉŞİX@=0+)!""$$%25Iƾ®©¨¤¥¨ª®±´¹¼½ÁÀÀÃÂÄÆÆËÓïUD;3-)$""#%&08DȽ²©©§¦ª«­²µº¿¿ÄÄÄÆÃÄÃÁÄÉ×üWC;2,)#!" #'(1=L̼²«ª¨¨ª«®²·½¿ÃÅÅÅÂÁÀ¾¾ÀÆÏã[H=5.+(%$%$'*-5BWλ´®««««®³¶¼ÃÅÉÎÉÅÆ¿½¿¾½ÆÓÙiKA930-+,,*,/.2?=EİÖͺ¶·´±¶·µ¼Á¼ÁÉÁ¿ÄÁ½¿Â¾ÅÏÌŞZZM=:?92::18:49;:?FLOjרËÁü¼¾»¿Ã¿ÆÈÄÅÃÂÄÅÈÌÏÒÙ|míWL[PEBCC??CACLICLTQQZk\^÷şê×ÏÎÍÈÈÍÎÆÈÏÇÆÜØÊ×íÏÌndÚxZöçfPXfOJRSPacWccUXf_W\bZkã{hèóeçÜslãëıØÓßÔÑôèÛ}ëÜñıäãíéåïşøüêïgùïbjò{a\vlPXoa\có~`ïákgôğe]úú]nå|jòæ}mãŞìììçğõáçÿøî}uêãşpíúhùëõöşôın{nemnpzp~ğxpwışxõzlõñz{ü÷usğíùt÷øjşîzwığ{nöóxx}óótúòjmùüutììyûøõüyõwmsuôôûóûıõûúınwõ~óósxûüyw}yu~üú÷ûùûtqy}õımıô{ôñ{uÿötjığ|{øò}sıÿsvüöşxøõvx~or÷ı~ùıû~|ıwvúşvù~wøşşüıòğúmpşq÷îü÷ıîìnxñyt}şvoïësu÷ıqo÷ïvvìîøıwşzuü{nmyúwuöğıoúõou|{vx÷uoöóûöôûxş|mz~ùëñììızx{yxş~qmyıööüëït~{owöûnmûø{ïëòxmüwfnu}ú÷ğ}yñîôspû{{ıı}oxş}üüõğü~ûxtûövoûñùöîò{u{wmly÷xwùşüíçîy}ü{{u{qhnw~ùñú}ñëï|úõı~pqxx~ú{wúÿy|üú~÷ùzvq{ı{x~{vıöøşşûzyö÷~ûùû~}ıü{vúúq|~|÷xûúwûÿyyşü{x{}}~yüúwùüwùûüı{şü~ş|yû}ü÷w÷øwû}züıı~|şı~ûûzşøş}üúüûúúùüıúüÿüü~üşıü|şı}|{~|z}zz|zzz{{|||}~}}~~ÿşıışşıııııüıışşşÿşşşışşş~~~şşÿ~~~~ÿ~~~}|}}}}}}|||zzz{{{z{zz{zz|||}}}}~~~ÿışşşıüüûúûúúúøøùùúúøùøùúûúûüüıÿş~}}}||zzzyyzzzz{{z{|{{{||{|||}}~ÿÿşşşıüııûûüüûûûûüûûüüışşşşÿ~~~~~||{{{z{zzzzyyyyyzzz{{{||||}}}~şşüııüüúùùùúúùùøøøøøùùøøùùùúûüıışÿÿ~}}|{|{zzzxyyyzzxxyyyz{{{||{}}|}}|~}}ÿÿşışşışşüııûııüııüıüııışıııüşşşÿşÿ~~~~|{|{{{||||}}~~~~~~şışşışıüıüüüûüûûüûüüûüûüüüıüüıışÿş~~ÿ~}}}||{{{{{zyzzyzzyyyyy{{{{{|~}}ÿ~~~ÿÿşşşşşıışşüııışÿşş~~~~~ÿ}~ÿ~~~~~~~}}ÿşÿşııııüûúúúùù÷öùôğõöôõõõõ÷øøøùøùúûüış~ÿ~}|{zxxwvvvtrqponmmllkkkkjjiiihihgjejid}[â½Ç×ÙìãxõëU[è|lëçÜÜ|ߪizc`õ[bìigyşzurğØÙØÛî~Z_÷X_ùnû}ìÙîwß{^o`_dYnûlìíõëyñìgt{dymfìqnâ}ıéiùëfõôd÷üpéşüèxõğuï|oîıyìøùî~öønüüp}yşï{÷é|}ôv{}s|usùüûõõöz{ó|tûzvü}üùu|úy|xwüı÷ñüüûvuvt|ûü~y|}zıú~}}}{{ûşv|úş}zvur{ùøùü÷ô}x{yusyúşşôöúùûøısrvrxúøùışô÷z}{w~ÿşüÿ~}~üùø÷û}|{zz{~úö÷õğğõ÷û~xopxv|ööóöüø}rwtpvxşù~øïõı~zumltuxııüşy~ÿ}ıüüüzz|x{şüöúü÷ûıüÿşş|şü~}}şùúøöùı}yxuu{~ÿıüùû}~ş}z{~~~üøõøşüÿvw||}~şüşşûı|{{{xvy}}~üüüııü}|ÿ}}~şúûıúüıúı~şÿ}}}ÿ~|}~}~ÿş~{}~|{{|}}}şş~~}||{}}{~ÿ}~şıııış~ÿşışşüûüüüşşşşş~~şşşıışşşışşÿÿÿ~~şışÿııÿşşşşÿııÿş~~~}~~~~~}}~~}}~}~~~}}}~}~~~şşşıüüúûúúúûúùúûüüüüüııış~~}||}}|{{{zyyzzzz{{{{z|||}}}}}}}}}}ÿ~~ÿ~~ÿ~~~~}~şş~~ÿş~~~}~~}~}~ışşııÿÿÿşışşüüııüüüıüüış~şıııışşşşşıışşıııııııüışüûışşışışÿÿ~~~~}|{{zyzywxxxxxxyxxzyy{{|||~ÿşııııüûûúüûúûüúûüûüıışş~ÿşÿ~~~~}}}|}}}}|}}}}~}}}}~}}~~~~~ÿ~ÿş~ÿÿşşÿşııııüııüııüışüüıüüüüüûûüüüıışşşÿşÿ}}~}}}||||{zzyyzyyyyzzyzz{||}~~ÿşşşıüüüûûûûûúûûûüüıüüşşşÿÿ~~~}}~~|{||{||}}||}|{|}}}~}~~}~}}~~}}}}}}|{|}}}~ÿ~şşşüııúùùùùø÷ø÷õööõöööøøøùùûüüüşÿ~}}}{z{ywxxvvwwuuvwxxxxyyyzzz{{|~~~|}ÿ~~şıışşşÿÿ~~ÿşşÿşşşııııışışÿııüışıûüııüııış~~ÿşÿ~şşÿ~~~~ÿş~~ÿÿÿşşÿ~~ıışıüüûúúùúûúúûûûúúııüışÿ~}||{zyxxwwvvwxwwwwxxxzzxx{{{~~~şııüüıııüüüıüúúúûûûûûüüüüıışÿÿÿ~~~}}}|||||~}{}~}}}}}}~~~~ÿ}}~~ÿÿ~ÿ~~ÿşıışıııüûúúúùøùùøøø÷ùúúúúúûûûıış~~}{zzzxwxwvvvuvvuvwvwxwxzz{{{||~~~ıışıûûüûûüüûûûüıııışıüıüüııüıııışşÿ~~}}||||{{{{{|}zxyzzzz{}~şşşşıııûüüûûüüûúùùûúúûúûûûüüüıüüıüışşÿÿ~}}}~}||{{zzzyywwxxxwwxxxzz{|||}~~~şşşııııüüüüüûûúúûûüüüüûûûûüıüışışşışÿşşşÿ~~ÿÿ~şş~~~~~}}}}~}|}|{||{||||}}||}}~~~~~~~ÿşşşışşııüüııüıııışÿÿÿÿÿ~~~ÿÿ~~~~~~~}}}}}}}}}~~}~}~~~~~~~~~~~~~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿÿÿÿÿÿÿÿÿÿ~~~~}~~}}}}}}}}|}}}}}}}}}~~~~~~~~ÿşşÿÿÿÿşÿ~şşÿÿÿşşşşşşşşşşşÿÿşşşşşÿşşıış~şşÿşşşşşıışşÿ~~~~~~~~}}~~}}~}~~~}}}~}~~~şşşıüüúûúúúûúùúûüüüüüııış~~}||}}|{{{zyyzzzz{{{{z|||}}}}}}}}}}ÿ~~ÿ~~ÿ~~~~}~şş~~ÿş~~~}~~}~}~ışşııÿÿÿşışşüüııüüüıüüış~şıııışşşşşıışşıııııııüışüûışşışışÿÿ~~~~}|{{zyzywxxxxxxyxxzyy{{|||~ÿşııııüûûúüûúûüúûüûüıışş~ÿşÿ~~~~}}}|}}}}|}}}}~}}}}~}}~~~~~ÿ~ÿş~ÿÿşşÿşııııüııüııüışüüıüüüüüûûüüüıışşşÿşÿ}}~}}}||||{zzyyzyyyyzzyzz{||}~~ÿşşşıüüüûûûûûúûûûüüıüüşşşÿÿ~~~}}~~|{||{||}}||}|{|}}}~}~~}~}}~~}}}}}}|{|}}}~ÿ~şşşüııúùùùùø÷ø÷õööõöööøøøùùûüüüşÿ~}}}{z{ywxxvvwwuuvwxxxxyyyzzz{{|~~~|}ÿ~~şıışşşÿÿ~~ÿşşÿşşşııııışışÿııüışıûüııüııış~~ÿşÿ~şşÿ~~~~ÿş~~ÿÿÿşşÿ~~ıışıüüûúúùúûúúûûûúúııüışÿ~}||{zyxxwwvvwxwwwwxxxzzxx{{{~~~şııüüıııüüüıüúúúûûûûûüüüüıışÿÿÿ~~~}}}|||||~}{}~}}}}}}~~~~ÿ}}~~ÿÿ~ÿ~~ÿşıışıııüûúúúùøùùøøø÷ùúúúúúûûûıış~~}{zzzxwxwvvvuvvuvvvwwwxzÿüüüııüıııışşÿ~~}}||||{{{{{|}zxyzzzz{}~şşşşıııûüüûûüüûúùùûúúûúûûûüüüıüüıüışşÿÿ~}}}~}||{{zzzyywwxxxwwxxxzz{|||}~~~şşşııııüüüüüûûúúûûüüüüûûûûüıüışışşışÿşşşÿ~~ÿÿ~şş~~~~~}}}}~}|}|{||{||||}}||}}~~~~~~~ÿşşşışşııüüııüıııışÿÿÿÿÿ~~~ÿÿ~~~~~~~}}}}}}}}}~~}~}~~~~~~~~~~~~~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿ~~ÿ~ÿ~~ÿ~ÿ~~ÿ~ÿ~~~~~~~~~~~~~ÿ~~~ÿ~~~~~~~ÿÿÿ~~~~ÿşşÿÿ~~~ÿşşşÿşÿÿÿ~şşÿşşşşşşıışııüüüûışıüüüüüûúúüşüûüııüûüşşüış~}~ÿ}|||zyyzyvwxyxvwzyxxzz{{{||||~ÿÿ~~ÿÿşş~~~şşşÿ~şış~}}~ÿşşşüüıüúûüüüüúúûûûúùùùùùúııüı~~şışşş~~~|{}~~~~şş~~}}~~~}|}}}|}~~}~~}}}|{{||||{|~ÿ~ÿ~~}|}~~}|||}}|}~şş~}ÿşşşşşıüüûûûúûüüüşşüııûüüüûûıüı}}~~~|{}~|z{yvvuutrttssqqsspoopqopsqoooonnonmnnmmmnmyîëêèéæßİÜÜÜÜÚÙ×ÓÑĞÏÏÏÏÏĞÑÔÙâùcTJB=97668<@J\æÍþ»º¹ºº¼¾ÂÊÔî[J?:631025:BPöÍ¿¹´±¯¯¯±³¶º¿ÇÏç]J>82.,***,/6@]Í»³®¬«««¬®°µ¸»¾ÄÍâ\E9/)&$" !&-:QØÁ·¯¬ª©©¨¨¨©«­®°³¸½ÆÖkI9.'"!")1>UßÄ·¯­¬«©¨¦§¨ª¬­¯²¸¾ÇÒıM<1+&"!  %+3=RÕ½µ°®¬ª©©©©©©«­°´¹¾ÊİjPB92-*('&%$&)-2;KíȽ¸´°¯®®®­¬¬­¯²µ¹¾ÆÏŞnQE>94/--,*))+.4:E^×Ç¿¼¹·µ´²¯®®¯±´¶º¾ÆÍØõ]NF@<610/-*)*.39@ZÑÀ¼»º¸··¹¸¶´³µ¶¶·¹½ÂÈÍÕìcXOLGA<4/.,)&&)-4=KŞÀº·¹º¹º»¼¼º¸¶¶··¸¸º½¿ÃÊÏÙïrudPH>4.--+'&)-3:A\ÏÅ¿½½½½»·¶¶¶·¶¶·¹»¼¾ÄËÏÔŞşcRI@:2...,*(+/5:ARãÑÌÇÿ¾¾½¼¸··µ¶¶¶¸¹»½¾ÂÇËÑÙçÿ]NI?95/./.,+-28851154314=AEVuØĞÑÈÉÆÁʹ¯²ª¨´ÈÆÃé{ÊÖıké»¶¾ÃİP>21.)%"-247LËÓÓ¼µ·¾¿½ÃÆÄ½¹»¶®®®«§ª²¶¶ÅìûT:,(#"%%6»¥¬¬¡£®ËÓ×<>ïÅ·²¤œ¥¯´¿YC:4)  %=«ššœ™œ­o;85333479=@HOXdtıïèàÚÓÍÉÅ¿¿¿¿ÀÁÃÄÆÉÌÏÔÚåşeZRNLKKKKLMNOPQQQSVZ^epûîêçææçéìííîîîîïîîîïğñóö÷úş{vqnllov{ıõïìéåäãáàààáãåçêíñ÷û|yxvuuvtqrspomlkiiihhjkmnry|ş÷óñïíìììíîğòõøûş}zwwvvxwvusppnnoonoptvvy|zz}~~ÿıúøöõôñóõõõôõ÷ôóôôôôôöùüış~~~~~}|~~~~}}~ÿ}}}}~}{|zz{zyyyz|||ÿÿÿşÿÿşşşşşÿ~|}~~}ÿÿşşşıüûûûúûüış~~|yxyxxyxy{|}{|}}~~~şş~~~~ÿ~ÿÿıüşüüüûııüüûûıûúüùúüüşüüıüûışşÿ~ÿÿ~}}~ÿ~~}}~~||}}|{{||z{|||}}|}}}~}~ÿ}}~~~ÿ~}}~|zz||{}}|}}}}}ÿ}~şıüüıışşış~~şüışüüşşışııııııüúùùøùùúûúùùùùúúùûûúüûùúùúüüüıüüüüÿ~ÿ|z{{zyyzyxzzwvxxxvtuutttuustsstrqrstussttuvwvuvyyy|{z}~~şıüüúøøööõóóññğïïïîîîîîíííìììëëëêêëêêëëëëìììíïğòóôöö÷ùúûıÿ~|zyvtuqoonnmllkjihgffeddcba`___^^_\b\wÒgMWYZWúÛ]PVR]\NÌÀæøjbfjVHT^ĞÊg~Ù×ÔÖlNìĞã÷ÏÀÍØÅ¾ÂÇÅÙQsß\TôÕóìÆÉèÙÍìRfkEFYTIOş_\Şx^tibUS`UMZmZ_å]ToVYllêtnøoj_óuWıón÷éènç×øíÜàæ|ğäôôŞÑîğÍæ÷Øàã|åáeææïë~èxØÎrèèvúoñdjy^ínfë]my]îl_pdñq^sfwêúçìlnjc`héìğrdû\dí]ïárıüıXhòS}íiêlnhjåvàîgÖú[õ~éæzüîæßÙïxßøkdkåşòçzz~ßıbÜßunnjdßæôÔf_ØmXşì÷~qøêkjò^_Ùê\ìÜnfÙáSôßNNmëV]ÓhaÙèiRîÚfybàåVÔò]Óî×ÜmÔq`uZ|ZZğYyÑÙñkìlcıOåÌMsÏNtábÙ_lËkî×\ôŞhVäÌivæ^_ZßİYïårahûUîÔnr\âçJòzgÎ~îêdú\q]íÈ^ÙÎNŞâpàfÚuSİßöVéÌOXúN\Y_éíãQJ^Xa]oÏïñãZhîÉÇØ¿ÌfÖØÚÚÚÌÚåùîhDmqD^TNK<^W=MHOOF×áäÀÎÎÄɾ¼½ÄÆÂÅÊÃÀÛcoI;>=:/.(!#06^²´º¾ÛiC?Ƶ¼²ª¯»¶¯¸»¯±½ÆÈÎa[Z:,*&(?V°§¬¹îO6/GÄ®­©£°ÂÁÉľ±¬¶¸ºÚaWH;.)!#ÕЬ¦¸S94+8·©¬£Ÿ®ÖßÕéÒ²ª¯µ´¿MAN9,(*®¶¥›¢¿..0';¬¥©¡¯FCØ¿¾±§­ÁÂÇ[?FH2#4£ª™¢å#'/'A£›¢¦¤¸;8Ô¹¿°¥¬ÅÑÎoCE?,¯¡›­.*.-Àœ™¤©¨Î2:¿¯¹¯¥®ÏèĞßC<9)  šŸ¼#,0:«™š¦¬¯m3G¶­³®©´èîÉÛC83& 2Ÿ™¥u03I¦˜›§¯µd5W°«¯¯¬³ÛõÆÔI6-%-›Ÿœ¥Í1>]¦››¥»»Ò=_³¨©³²°ÍP]Ùİ7' 噟Ÿ¦f9EÒ¥œ›§¼¼ËOݳ§©·µ´ÉicÖã3% +º—¡¢Ÿ£Ğ<íº¬¡™£ÁÈĞž½ª§³º¿ÀÊNTi5$ +¬š¡¨¤Ñ/Æ©°ªœŸ­Ï]µ®ºµ°¬®ÈÚÊ×ü:)" $¤ŸŸ¦¨¢ü""/¼¬¼®Ÿ¤Áú³¬¯»Æ²¬¼ïSqŞ8#%® ¡®­¥±G+-Ü´¹»²¦ ©º½³¬¯ÆŞÍÅÌcHKG7*#;lÏÜÓ¼·¹ÄÛÓý¿ÇÊÀº·´´³³µ¹¾ÅËÎÒÚõWG>93.*)+-,,,/;OıÜ̾¶³µ·¸¸µ´µ¶¸¸¸º¼¿Ã¿¼ÀÍáhPB6.*%&(&$&+4GgßǸ°¯¯°¯®®°³´´´µ¸¸¸¹¼ÁÍà^H;/)""  %/DoÖµ¬©ª«««««­¯±±²´µ¶¸»¿ÊŞZD6,% !(5Mìͽ±«©©ª««ª¬®°³³´µ·¹¼½ÃÌæTB7-'! ! "'1CcÓÀ¶®«««¬¬¬­¯²µ¶·¸¹»¾¿ÄËÚiM?6.*%#$%$%',5D]İǺ±®­­­­­­¯³¶·¹º¼¿ÃÆÉÎÚwUI?82.+*+++,-1:ESyÕÆ¼¸µ´´´µµ·º½¿ÀÁÃÇÌĞÚŞên\PKIE?><:998778;@JWgğØËÅ¿¿¿¾¾¿ÁÁÄÄÀÅÅÇÏÌÔÙØåæón\XVJGD?><;;:;<>BHNXmèÖËÇÄÂÁÀ¿¿¿¿ÁÁÂÄÆÈËÍÏÔŞüi]RMHB@><;;:;<742.'?ñAJ®®Ã·¯¿I<`¼²´µ­¤¡©¸¿»ÁZ=HàÕfOOG8-%'MüñµŸ§ÂäÎÓL9@È­©«¬¨¤¨¸ÙÜÊÖNF{¿»ÆÛöZ?/&.ÖÄÄ®ŸŸ¯ê^Ûw>9_¶«ª¬ª§§®¾ĞÌÉçShɾÂÊÍçG5-(6×Ñ©£¼bæÔN8>ବ¬©¦©³ÅÊÃËp]ÖÂÃÇÃÅëA4.)"+ñÌÌ®Ÿ µlÿÑ_<=Ú²¬¬­ª§ª´¿À¾ÌpüÉ¿ÇÊÂÁâ@75/'6ËÙΪ¦Â~ÍÏI8F¿®®°¬§¨±»¹¸ÅŞÓÆÊÒʾ¿ÔR?7/+%"Kßå² ¡´ÒËÎO=í¹µ¶¬¦«´³°¸ÈÉ¿¾ÇÎŽ¿ÎÚõF50.*% ,I^Æ«¤¬¿ÌË{B?h¿¸¶®©«³³¯¶À¿½¿ÆÈþ¿Ë×éJ610,&!$;KÛ®¥«¹ÁÈöFA[ι®«­¯­­µ½¿¾ÆÙØÆÅÑÒËàK<82,&"#:Nı¯¡¥®®®ÀK>HH>HÍ·³°«¥¦­´´ºŞJRwO@JlW?::3*#"6N]¹¢¥©¦©ÅD?C6/8÷¿¸¯¦¡¤ª­±ÆUIMD@騢§¢£³lID5-/DŞÄ¶ª¢£¨©ª¶ï[sL;B\SHPP>DJE=70) "+*6¾¬«¦Ÿ¦­µÊF41117Wö­¦¢¤¦ª°¾ŞXE;9;;;??971*%!*+,Eɼ´ª¥§ª­±½áWMDAKkÛÇ»µ²±²·¼ÄØkUJFA>??=>@>;:89;=?FPdñÚËÆÅÂÁÄÆÈËÌÍÎÍÎÎÎÏÑÔØÜáëöule_][XWTSROOPPPQSUWZ]`foÿóìæàŞÜÚÙØÖÖרÙÙÛİŞßäéëğû~xnnkcef^_`^___``ceejmlsxwıú÷ññïííììíëííëíîíïñòòğñõõöùúıÿş~~}~ıışúùüûúş~~~zxztqrommmmmnopqsuyxw}}}ıÿüüûöööõõõôğóõîñõóùúúıûûÿ~ÿ}|}zyzxzzw|xr~yr~xs{st|uzûuyûzùûxôû{õü|úüıùıùùşïûşíúşïüşïü~öüüÿÿúx}ùzıúzûşwıÿ|~{}yw|ywx{ww~zzş|~şwüöt|üvş}x{u|şvwÿ{y}w}şxz}~|şş{|{ôzyírûíqñ÷vï{~ò{øùyóøtîúqî~ûôrí~wërıûoîuuñmşükú~myynsrlxojtlotfm{_ól`¿hI¶ÍRŞimPİì@îàZßüxÉifÓSÇÕÿÄkÓîßİ?İ~MÕnÛ½ãÑÃHŞÍ?kSDâPSásrkôfaZvuJäSTÎFõÔCÑßHÕğJâÜNŞ~SÒZjÔYmÌsXÏaäëdÓWä}óïqëgÒ\Èj]ÇL½J^»:ÇÛCÌèjnÌIï¾EÉgP¾JæåN×VïÒ`^Ì÷BÈ[D¾KZÉ=ìÊJşÎOTûKÎáGÍÿMêskØiIÏéKÂİCÕ×Nwô]ÍVG¾øLÑlÒmIÊuAÛÙdÓRİÂ>}¾I_ËlÜ×JÜÈKşÍM[ßkÚÜXÚËNYÌ]PİeYÛ}ëÖ^zİj[ëş^éoßáfßbõ×YnŞWWyS^æ\wßú÷`ïØuzĞóNßbNÔijÎa[ĞwVËæRéñm`é{c×ıhŞŞgrêXbÿ_góızøiŞÖjÚÔZyß[şÑ]mØT^âukjéŞ[êÎYbİ\XêpQŞáO}×mhÏãNÛÌQXÍtRÓèRãĞb\Şïşğôázhÿö}gxçhVrîddxùj[_öésşë÷myÚşZáÚø~éÚõuÜæyáßåÛvSrà_LSudLOewi[iİäaèÊİ_âÑç~æİÜèğßÚØİùúâête[VQLILVSLNU^qğãÜÜÜÚ×ÓÍÉÉÇÆÃÃÂÁÄÌÍÉÏğ^ULA822/,*+.15=XÊ·¯®¬ªª­±µ¸»½¾¿½¹¶¶¼ÍúS;*.BLʬŸšœ£­­®Æ?39UÄ·±¨šœ¡«ºİ<'(LÊ»°¦œ¡®½ÆÍõH;<_½®§£ Ÿ ¥®ÄL4,)%" $7qÉÄÁ¶«¥¥©¯·½¿ÃĞğ{×¾°«ª«®³ºÇwC6.+***)'$!!'3MÚÆ¿¼´¬¨¨«²¿ÏØÖÕÕÕÍ¿µ®¬­²¼ËñQA81-+*)'%&)-6HêÆ»µ±¯¯°´ºÂÌÙàÛÎż¶±¯°´»ÈãZH>83.,)&$%(.8Jèȼ¶²°¯±µ»ÄÏßíâÒÆ½¸µ²±³¸ÀÏ|NB;72.,(&&'+1>VÙÄ»·´²±³·½ÇÕæéÛÌÀ»·´²³·¼ÇÜ`K?:73/,)'&(,3?XÙŽ¸¶´´µ·¼ÄÍÕÓ˼¹·¶·¹½ÃÍâdRJE?<6/+&##&+4Du˾º¹¸¹¹¸¸º½ÂËÌż¶±°²¶»ÁÈÏİnUKD?:4-& );â¼²¯±´¶···¹¾ÈÙèÖÀ´¬¨¨«±¼ËÚì_J=60-+'0Ğ®¨§ª°·¸·¶¸ÁŞVMe說¡¤ª±¿Ú[E:3.,*& &V­¡¡¦®º½¸¶ºÆiGMܹ«¤£¥§ª¬¯¹Ü?/+-24,!(ÀŸš­ÄâÏ»¹ÎJ:A¿¥œ ¬¹º°«¬»O2/9Pg>&-¹¢Ÿ©®®±ºà:.4Wµ¥ £¦¥¢ŸŸ§ºY97?HA2%'Ш Ÿ¢¤¤¦¯ÎB57C]Ñ»¬ ™––›¤³ÎaI=1*'# +ᣠ¥¢§á,'/_¿Âʸ¢–’›­ÂÆÁÓ>-*1C;"  +*Å­©Ÿ™•˜©G*+@Z?3?®˜‘™ŸŸ ©Ö-'0Sk:&  Ï¡ ¢—•¡L$#:ßL6@¬–“šŸŸ®H*-KâH1+'  ϯ¯¢“”¯/*7?0$,¼•–˜•”™¨~;>C>77IK*  6¼ª›™¯H91)%)B´¢š•’‘—Ÿ®ÊM6/7HWO?- + /_¸š«Âè7" ,Bϯ“’—›Ÿ´B26<<6;M7  "9â’™ «¼D*(-1=¿ —”•”•œ¬ÎO?1,-39+ +%.Y§•“šŸ¢­l3/2/4Цœ™—“”›¦´ÈH/,-..( +)5µ›–š¢¸T>9..T¯¥™““˜¥°}4,)%$" $/É£Ÿ›¨·Åà>9Uĵ­¢›™šœ¦¶ê?.&""*P­¢ ›šŸª¯¸ØLOÙǾ®£¡«À[9*!':ů«£›¢¤©²ÁÎÊÌÒ¿±ª¨§¥¥¬º×K5,&")<şÇ³¥ŸŸŸ¥­µ¹ÀÕÑ¿¸µ³®¬°»É}E4,(&  '1995/+&#%&$$&+/5Eß½±¬¨§¨¬¯±´¸¹¹¸·¸·¸¾ÉÓÜñ\TTLA?<4-*,-)'),.0:OİÆº±®°±°°µ¸·´µ¸¹º¼ÂÉÈÊÙò|øgTSRG?;73//.,,-/48@UæÊ¿»¸······¸·¹¹»½¿ÄÈËÑÙäøzmi]ROLG@<954433479?ACGJQ]pîäÚÑÌÊÊÈÇÇÄÃÄÄÈÈÈËÍÏÕÚáäëşnhea\[[VUWVTRTUQPUTTZ[\_goqyúôêæçãàááßŞâææâèïêìîìôïôÿóû}öşzùúı÷øùûşüûöøÿ~şüy}şxy}|tuuvzw}ş}ûùüşûıy~÷öı|úùışıúıû}wÿz|ùşıı|şyyûusûtuø|z}w}üzúöw}ÿ{ø}}øüv|õyıó~úüux~wşû{~z|ùúyşÿr~|rüşt|öõúı{şôpuùo÷ïyûşüóş{{|şyy|ıõ|ûöwõôÿ}óïvõzvòpòõ{ï~yûìõù~lômfí{zùwïxoüùssçrrósëikïeó~jèusçqk÷kôî`ë}kígïnkßw}tfùòsï}eópòâ_~ã^yæeâÚbÜã_ÚîwØ{hédkòmú÷ywğp{íûãtvödumrætzìmnûûu}wmúşöõnwrmøï÷ıúwşti{junoëoüõô|iì~~ı÷èk~øtøg}íkõèïıqúíå}yã|oşíúeùıtòn|ø{èé÷ñòeeöüxv{uükjÜğkæúopjõõg|ïk|ø{æxhëõuwlü÷mv}uuoøíøıyîäsmîzrïvvëzoìòpóõıä}cyıryzküıh|~qùíòéélmúü÷úòüdxìoûşné{gìèlbpujwõõìtqàìxçèxzïìyrğ{lúíö{tyüjdıx^uävmòtsïxÿğoÿï~éàıñÜêøåókqj_^^tòoğßoeèíormydZmjcupwêêêߨÔÙâßék^_`[gõoşæêéíşïxg|pcoûsxêøoüv{ò÷n^lïøsyçè~ñáßîjkymkhnàü^ìğfìèuëu`ïk]èö_éâüíhhäs_éğ`}ëï÷ıäëkìècf~~tşåãjlâp]~yûìjä×o÷ßyò|\usX{èoçélìğvçxgéınôpo~nuûywvmn~ÿöïøøtvîõúï{vpi~r_fe_`\amexêîߨÜÚÓÕÛÙØŞêëì{l|z[WcWKMOLHMZUWìÚáÓÆÆÈ¾ÁÄÀÁÈËËÏÛîoYI?;50.,+-.5C_Ê·¯«©¨¨ª­°µº¿ÄÄÊã]H9+ %Kɲ¥œŸ ¡²ÙÑS8?ß½´ª¡¡¥¦¯Ğ>+)ä´¨Ÿ››£¦©ÍDOC:K¿­©¢œ¤©µO-! /À­¢œ™›¤¥¬^>K;8_¸ª¥šœŸ¤·N." %\±¥œ› ª«½HLRFn½«£Ÿœ›Ÿ¦±o4&,ͯ¦Ÿ¥«¬ÄRîp[Ë´©£Ÿœ¤ªºJ/&)|µª¢ŸŸ¤«¬¸æÚ×îÉ·«¤¢¥«¸V7+! "8Á²¨£  ©¬¬¿áÉÎÏ¿±¨¤¢Ÿ¢ª´ÓC/&" %JȺ©§¥¤¬¬¬ÂǽËǺ°©§¥¡¦®¸Ú@0'%!!'"?ËÖµ¬«©±°¬À˵½Ä´­ª©©¦ª·½Ö?4.)'$" &)+?Ḳªª²°°¿ÊÄ¿¿¾²¬®­ª®·ÂØW901-*,+('&*/1=nÒÆ½·³¸»º¿ÅÇÆ¿¾¼·¶¸·»ÁÇÑê_IFI@>ED<9;<77>@?HRaíáÙÑÍÈÈÌÊÈÍÍÌÌÉÉÍÉÎÕĞ××ÙïûurkX[e^]d_ZXONNJMMMTSV\iüdußéçßâÜÚÛÚÓĞרÔÚæÜÕÜàŞçõpqsc`b^]\[[YY^e]Yek`buìûwèæìëêåèßİæÜÜãáéæëyíòyíyd~ímbq÷i_mtomnnuòof÷ôtwóìunğğşxöõoúzjûù~zo}|opzóù{|}÷ú~÷øşwş÷mxéó{ÿğë}}ìñú~|î~jùørûzyùsşúyût{ùw{}÷øozñş{øı~ôùr{ğ}zõíómtñ|nwüvt}~ûşo{÷xonşôzuxüÿxÿ~zúùouïÿvõøúõıü~~şr}öüú|y÷ù~ø÷úùıı~úüzïøsïôzğöxòóyùıÿòxüêş~ñøøöşu}ıy{llsihd]]]ZZ]itvèÜÚÚÜŞåõüzqlilt{~ùùúññòïôğìñóñ÷ûùüüşzy{zwy}|z{}ı~~ûışûı}~ÿ~~}zyyz{zy{}~ÿ~~ÿÿÿ~}~~~~~ÿÿÿÿ~~ÿşÿşııüüüüüüüıüûüûûüüıııışÿşşÿÿ~~}|||}|||{z{|}}{{||~~~~~~ÿş~ÿış~~ÿÿ~ÿşşÿ~~ÿşÿÿÿ~~~ÿ}}}||||||||~~~~~ÿşşııışıüüıııııııııûııüüûüüûüüışııışşÿÿışÿşÿ~~~~ÿ~~~~~|}~~}}~~|}~}{zzyyyzyxxxyzxxwwyyxxxxyyzz{}~}}}ÿşşşıışşüüüûùùù÷öö÷ø÷ö÷÷÷ööõôõööõõôôõõõôôôõöö÷÷÷øùúúüıış~}{|{y{zwwwwxwwvsrqqoonmmmllkkiihgggffffeedeeeddgbjfdü\Ѽİ{ÓgXıìØĞξÂîr×ÓWıÅ|vÆ×iøòpXoêZ|ëUgpTg}][dbW^ı^_íkfõy|ñôõïóÿíøff`^\[ZSUSQ[\\jltşõíåßßÙÛÜÒÔÓÏÒÑÏĞÖÚÛãêío][UMLJFHIHJNRZp÷åÒÏËÄÅÀ½¾¼¼½½¾ÀÃÆÍØå_OH=960.,+--/6;JúϽµ°­­¬¬®¯³¸»ÁÇÑßmSI<6.*+&')(-5:YØÆ¸³±¯­¯¯¯¶µ·½»½Ã¿ÅËÊÏßïVD:/.+&(&'-.8Lh˽µ°®¬­¬­°°´¹º¿ÆÉÏÜçtTI>2.-''(%*-/>Püú¶¯¬­­¬¯¯¯·¶¹ÁÀÈÖÕçg]J>7/.*()')-/:5//,,,,05;510../16>?BEINWfxêÛÓÎÌËÊÉÈÈÉÊËÌÏÕÚßìüo`\[WUSSSSUXZ]dnwúìçåãââãääåèéëíñ÷ú~woljhgfdbcefikntzıöôñîîîîïñôøıÿ}yzzxz}~şıüúüûùûù÷÷öôóóñïîîñôõøûü}xwusqpqssrruvwyxy{{|}~ıûúùø÷ø÷÷øøúüÿ|||zzyxyz{}|{}}}|||{{}}~ıüüûûù÷øøøùùûıış~ÿş~~}{}~}}~}}|{{|{{}||}~şşıüıııüüşÿÿ~~}}~~ÿÿ~~~~~~}||}~}}ÿÿ~şıııüşşşş~~~~~}~~}ÿşÿÿşış~ÿ~~~}}}|||}~}~ş~şış~ÿşşşşışşşÿÿşışışşışıışÿşşşşııışşıışşÿ}}~}|||||}}|}||}}}}~~}}}||}}}|}~~~ÿÿÿşşşıışşşşııışşÿÿşÿ~~ÿ~ÿ~}}}~~~ÿÿşııış~~~~~}~ş~~~~ÿÿ~ÿÿ~}~ÿ~~ÿÿÿşşşşşşıÿÿÿÿş}}ÿÿ~~ÿışÿş~~ÿ~ÿ~~ş~ÿÿ}~ÿ~şş~~}}ÿ~~~ÿşşıış~~şıışş~ÿş~}}|}~||~~}ÿ~~şÿşış~ÿ}}~|~}{ÿ||ş}|ÿ~|~~{|ÿ}}ÿ~~ıı}~ş}ıı~şşüúıüşşüüúü~üıÿ~~ş~ıı}ÿıÿ}~}~ışı~|ı~{}{||{}{{|ÿ|zû{v÷ø|şúş}şışúõı}ü~~ışöõ}~şyy}üum~øvy{züüúvo÷û{|uøï÷~q{ï÷ww|üõüwûû}ôöúrwërlìôqru~ò~mmnúön~ùotüø}uüòòymyöë÷ijıæìo~õş÷ôéÜÛémmó~iisëéû{osñìîj`mjajñõt~{kn~÷éõmrjkíäï{vôèím^jùòñtuëİàmanïäò|÷rnı{v÷ótuõvl|ñùkbeq~u}ìæèó|unltıû~ğäñãÏÓänXTOLMReæØÔÔÏÏÔÜìroqkuá×ÖáZIGKSTJFIP^ajÜÈÀÆÓÙËÀ½¾ÂÇÉÊÏãr`SH>95478776?â»°®°±²·»¼º³¯°¶ÅU5! §ˆ’º;+),*S£šš¦¾¼¯­®¾ÕÓo=" ¯Œ™¼TE2"B¡—œ·Mܱ¬²½¶®¹P' ‹‹ G,'( %¸™•Ÿk9Ç«¦¬µ¬«È:' ¥‰†š1*'&™“œ[+O¬Ÿ£²´³Ï@/)  +NŒ„<)/%;‘—¼$-±¬½²´æ:/.  ª†ƒš68(Ù—5@ ™ºÉ°·o:6: £ƒƒŸ I?+É–¢(K›•ŸÍë³°Ù9&¤“˜¯m»¬ºK<ÙÉ œ…«&WE.¿”‘¬ _—‘ÇX¸±ÈøÓ²Ø’€ˆÉ)M@5­’•ɵ’‘ ÿS··Ğ×¹§Æ ›‚†ª!®“•¼Ê”›¾J;ËÁ°§µއƒ” *Id¾š”©+1›–«DJÅÀ·«§ª2 ™„ˆ¬8o}¬–™Ïº’œÍ7l½»­¤¡® –†Š±1Û¦—\ "°’œÒ4Kò§Ÿ ¶! ¯‹Š"-н°¸.%Ú˜šº3< ®2 +¨Œ£7µ²®¡£¾2+º—‘œĞ.=»¦Ÿ ¨Ç'  §©G³·³££º6.¶—“a-H°¢¡ªÙ& 6™˜:/ʾª ªd/l•›¹8E·§¢¥«¸< ;˜›/8¹º¿§ ¬_1Ïœ—Å9q¯¦£¨®½5  ¡‘Î*òºªŸ§â.J¡—œ²>E»«¥¦¯È7# ®‘©%$7ͯ¢œ¦^/D¬œ¬ËUPà·¥Ÿ©i( ^‹›. 8@X«˜—®+(ĬÉËÇ^K¿¤«?#FŠ™56=R¬™–¬,'Ï ªÃÌĞOOº¤Ÿ«D(!%•Š”Õ.6>¯š—¤7'c¨ §¹ÆÆ_Iè¡©ÿ,&"ŸŠ®!'17½œ•M'A­¢¥¯¼ËH?Ǩ ¨Í8,!ÏŒ‹,'0)F¢•˜¼*8·©¨®²²à7N±¤¤µM5+  ŸŠ¯$-*(Çš”E*j°­¬­®¹H8Ò«¤§¹K-""$ ˜Š”Ä''- $±•”§;7Á¹¿°§¨¾<@¿®ª«µm+!!;Œ¡C*.)/Ÿ“›»>òºÎĪ¥°çBí¸´¯ª·@( !½Œ¨L+*"Oš–Ÿ»YÏÊ^½¦§·êQ˸·®«¼:&ª”«x4)×›™¡³ÄËRI·¦¬»ÆÈÃÌÇ®©À6(#˜­Ş:(»›œ£¬µÈFK¶ª°¹·»ÎÚ½­¯ï6.$*—›­Ê@ %¯Ÿ¢¥«Ô:X¶³·°¯·Íí¾±¿ZD0 Û‘“Ÿ©¿73ª¥¢Ÿ­e=кɹª¬»×Ö¸´İOM,’œŸ¤È&ø´®Ÿ› µlßÅ}ê°ª´¿¼¸¾ï`|6 Ä—›œ¨E1kÕª›œ¦·½¾`EÆ®´¼µ±¹Îjc=% :›œŸš¿&+>>»œ ©®²ß>޶½È·¬¯ÄáÚG& +Ÿ ˜™­-,2,s¤ ¤£¨ÇDéÃá꺬¯¿ËÎ=& /¢¥ •—«6&/.&C©¢£ ¢¹^Ì¿WLÀ²·ÁÄÄC' N«ª›’–«<38'#@³ª§ŸœŸ¯¼¹ÊFBşÇÇÕÊÉ@& k¼©š”™­j]=))=Ʊ¬¤Ÿ©­°ÅUEKbXISS7'.AÔ«Ÿ£³½ÃZ;?=6-%'3;FpÁ²²»¼º½ÅÕÚÉÄž¸¶´¶»¾ÆÔß}[UPKD<5/+*/88;FYÜÊÉÇÂÁÂÄÈÆÁÿ¿¿¿ÄÈÊĞÛİãö}iXNG?<869===>CPm}ïÚÑÍÊÉÇÄÄÅÆÇÈÇÈËÌÌÎÑ×áîxaWOKHDA?@BA@ACIOWbıáØĞÌÊÉÈÇÆÆÆÆÅÇÉËÍÑÕİêıld\UOMKIGEEEEFHKPYanõãÚÕÒÏÍËÊÉÉÉÊÌÍÎÓØÜàì{mf_ZSONMKJIJJKMOSX^i|ñæÜØÔĞÏÎÍÍÍÍÎÏÑÕ×ÚŞèò~mb]ZUPPPNOOOPSVZ_iqşæàŞØÖÔÑÑĞÑÓÒÓÕ×ÛŞéòö|j]XXWVROOPUTSZ_bo~z|òèäãáääŞÛİߪİİßååäåíöòòÿsnlf`bb_^\\``_egepÿ{ûğìæãåâßßâãâàßäçêìèçêòz~}ooigle```bda_dknljn}÷õöñëêëééëçæéêëëëïúü}wtpmjggfbdhfehhhlqy|ÿúõíìëéèåãæçççèêìííïöûş}ywupnmmmmlmmorrtwzÿûù÷õóğïğïïïğñòôööøûûüş~|zxvtssqqroopqqsstvxyyy{{{||{|}|}~~ÿ~}~~~~şııışşıüüüıüûıüşşşşşÿşıüüûúúùøø÷ö÷ööõôôõö÷÷÷øøøøøùúúûûüıışşşşşÿşş~~~}~~|{{{{{yxwxwvvutssrqppopqoooopppqpqrrsrsttvvxzzz{|~şşıüş~ıúûşş~}ş~|yyzzzvuzş÷ôöôïìççççâߪßààߪßßßáããæéëìíò÷ù}vqljhd_\ZYXXWWWY\^bfkwúïêèåàßßŞŞŞßáåæçìòõü}ytokgghdc^__ZhShÇûàÄÛİ]eiAWúRGd½ËöÊÛPNáØPQŞÊŞqÂÑYÕ÷ßmHÒáFôºËÓ¹ÕìOQã4>8.-+$ "'"/Y|dz«¦ª¬¥ª½»¼ÔésÚÃÌﯴ®¯³¶¿ÅÆ_GG6.+#$+Sş¿²© §«¤ª¹¾ÎÓÙJh¾ÆÂ°¬«­°­®ÀÆÃŞQA:5-% -JÊ·±¥¥¨¦¬²ÂnÒŞJsËÆ¹¶²«­³¯³»½ÍÚßJ=:/)# &:Ï·²©Ÿ ¤§«­¸âñädl}Ôºµ¶¯®®­´¹ºÂÑ|H?8.)#!!&2éµ°¬¤¡ ¥­¯³ÀÓhWà×ÜÆ»´®±³¯±¶¼ËÕçK<3-)$$%(1l¹±­©¥¡£ª¯¶º¾Ú[káÍÈÌù·¶¹½¼¼ÅÕdNL@7/+'!"&(+-7R̺²¯¬ªª¬±º½ÁËÒßİÍËËËËÇÂÄÆÈÊÊÎÛífULA:4.+,,,--09EdØËÁ»¹·¸»½¾¿¿ÀÁ¿ÁÂÃÆÈÈÉÉÉÊÌÎÕÜêkZNGA<74200//15;DOeäÒÉ¿¾¼¼º¹¹¹¹º¼¾ÁÄÈËÍĞÓÖÜäïtdZRLHB=:75321138>GRhåÒÊÅÁ¿½¼º¹¹¹º»½¿ÃÇÌÏÒÖÙÜãìùoe]VOKF@<:7532248=EO_îØÍÈÄÀ¾¼º¹¹¹¹º¼¾ÂÆÊÍÏÔØÛßéõsf]WOKF@=:7532236;BL[|ŞĞÊÅÁ¾¼»º¹¹¹º¼¾ÁÆÉÍÏÔ×Úßèñ|lb[TNJE@=:864446:?GP`òÛÏÊÅÁ¾½»»ºº»¼¾ÀÄÈËÎÒÖÙŞåî~ng_YSNKGB><:87679>>?AEJOXfùâ×ÏÌÈÆÄÃÃÄÄÅÆÈÊÍÏÒÕØÚŞãéíñú}vmhb]YUPMJGEDCCDFHKOW_lıéŞÙÕÑÏÎÎÍÍÎÏĞÒÓÕ×ÙÜßâçìïö{olhc_[XUSSSPLHGKN[æáWMåÁ¼ÈO=Gߺ®±¿üO_ÛÍÌß^`èÏÉÎéf^_gcYPLJHC?==?CHKLMSdêÙÓÑÏÍËÉÉÊÉÇÅÅÆÈÊËÊËÌÍĞ×İçíïz_QLJIGC><<<<<=>BFKQ\yÛÎÊÈÇÄÁÁÃÃÂÀ¿ÁÁÁÀ¿ÂÆÈÊÊÌÕõd_ZPIA<951/../26:?M|Ğý»¹·¶¶¸»½¾¿¿¾½¾½¼¾¿ÁÄÇÎİfME>83.+'#"&*,.2<]É»¶²®«©«®²µ¸»ÀÅý¹¹º¹·¹»¿ËİgG80,(#$(*.?ϵ®¬ª¦¢¢§­³·¹½ÆÎɽ¸·¶¶µ²´»ÌwN@3(!#)/>ͯª¨¦£ŸŸ¥¬±¶¼ÁÉÊÁº·¶³¯¯±·ÀÈÓT:.' !&.J»«©¨¤Ÿ §¯¶¸½ÇÍÌ¿¶±°°®­¯¶½ÍõM5*#!$'/[³§¦§£¡«¶º¶»ÎŞÉ¸¯­¯¯¬«®¹ÅÓhA.$!$-Jº©¦§¤œŸ©²¹¹¼Óe×»°¯°¯«©¬µ¿ÊİR9*""#$/g·«¨¨¥£­²´¹Â×ìɵ¯²²­ª«®·ÂÌÛI1)$$"$6ʰ«¨§¢§³´²»ØøÕÀµ°±°«¨¬´¹½Ëd@1)$$"&;ò®ª¦¢ŸŸ¨²´±¼îqǺ¹·±®«ª®·¹¸ÄP94.&# &B½¶µ«£¡¡£©®°³ÀğßÀ¼¿¹¯¬­­®³¸½Ì^A6,%!"& $Bº·»®¤ ¢¥«¯®±ÇgÓ¼¾È¼®­°¯®²º¾ËY?7,##$*ú»Ã»¨¡¤§¦¨®³¹ÉÓĿɱ­²´­¬¶ÀÁÊY;1+% $!/ÍÀѵ¤¢ª©£§³¹·¿ÓÎÿ»´³³®­³»¼¿åI=3*$!##>Ìë׬¢©®¤¡­º²²Êëüÿ³¯²±¯³¹¾ÌwL;/)% ".VVX¶§«¯¦¡ªµ®®ÀİÀ»Êɶ°¶¶¯°¹¾ÀËjF;2+%!! !.HJe´ª®­¤£­°«°ÈÉ»ÀÏ¿³¶»³®´½¼½ÕTI=/(%""#7H?Ù­­²©¢¨¯¬«ºË½¼Îθµ¼·®±º¸·ÄìnP8.,'  %69>ůµ¯¥¦¬«ª°»¼¾ÆËûº»´°µ·´ºÊÏÜK:7.'$!"-7:mºµ²ª§ªªª­µº¼ÂÉÆ¿¾¼·µ¶¶µ¹¾ÄÎkH<4+'$ '11@ƺ¸¬§©©¨¬°µ»ÀÇÈÃÁ¿º¶¶µ³¶º½ÆÛaJ:1,(" (.1Eʼ·¬§ª©§¬°³¸ÂÈÃÆÉ¾º¼¹´·º¸»ÆĞßS>8/(&  #,-:íǺ®ª©¨§«®°¸ÀÃÇÌÉ¿½¹¶··¶º¿ÅÕ_K=3-)%"*,-KÖɶ¬««§¨®®¯»¿½ÈÍÃÀ½¸¹¹µ¸½¾ÅÜkN=5/+'! &+,=kÑ»¯¬«¨¨¬­¯¹½¿ËÌÉÊÆ¿¼º¸·¸¹»ÃÌİSE<3.*'""!)-,GîÛ¸®®«¨ª­¬¯»º¾ÍÇÇ˾½¹···¸¼ÀÈÙdL?72-*(" $"#,-2Nyθ²¯¬«­®®µº¼ÄÉÇËÇÁ¿½º¹¹¸º½ÁÌècL>;6/.+($#&#'.-8QYɹ·¯¬­­­°µ¸½ÆÅÈÍÆÁý¹¼¹¸½¾¿ÍÛ÷QE?953/,,(%)('/15PeÖº¸³®®®®±¶¸½ÄÆÉÌÉÅÿ¼¼»¹¼½¾ÊÒäXLD=:7420.-+*,+-47>U~ξº´²°°´´·¾¾ÃÌÈËËÆÆÁ¿¿½¾¿ÃÉÏátWIF>;;7440/-+-.-59=YõÔ½¹¶°°±±´·»¾ÂÈÈÉÌÈÅÅÀ¾¿¿¿ÂÈÊÕölPGE><;886430//.137=CUòÕÁ½º´¶¶µ¹º¼ÁÄÈËÊÌÉÅÆÂ¿Ã¿¿ÆÇÎŞê\OKA@>:;9797575588;?ENbçÓÈ¿¾»¹º¹º½½¿ÁÄÆÅÈÇÄÈÃÂÆÁÆÊÉÕŞê]VNFDA>=;:876443368;AI[ëÕÆÀ½¹¹¹¸»¼¾ÃÆÉËÍËÉÊÅÃÃÀÁÁÄÆÉÒÙë_YMFC?=<:997776788<=APRqÔÖÆ¿Â¼½¾¼ÀÃÂÉÉÉÍÊÊÊÆÅÃÀÂÀÁÅÇËÒÙìf[NGE?<<9885664779@AMhmÓÊȾ¾½¼¾¾ÁÆÇÌÍÏÑÎÎËÈÇÃÂÂÁÂÄÇËĞÛél]RKHC?><;::887698;?@M[dÕÏÈ¿À½½¿¾ÃÅÈÌÌÑÎÎÏÈÉÆÁÃÀÀÄÂÇÌÏÜïu`TOJEB?=<9987889;;8:75988?>EYZñÏÎÅ¿À¾¾¿ÁÄÈÌÌÑÔÎÓÏÊËÆÄÄÀÃÃÃÊËÏßãwZWMGG@>>;;:88989;=?GMWùÜÒÈÅÿ¿ÀÁÃÆÉËÎĞÎÑÏËÌÇÄÅÁÁÃÂÇÉÍÛàu\WLIF@?><<9987899=?EN_ıÚÌÈÿÀ¿¿ÂÄÇËÍÏÓÑÑÑÎÌÊÆÆÄÂÅÄÅÊÌÒâçmZWLIF??<:;88978:;?DKXqßÑÉÆÂÀÁ¿ÂÆÆËÍÎÒĞÓĞÎÎÉÈÇÂÄÄÂÇÇÊĞ×çy_RNHCA==;998899:=?GM^ößÍÊÆÀÃÁÀÆÆÊÎÎÔÕÓÖĞÏÍÊÈÆÅÃÄÅÅÉÌÏÜæz^YNKHA@>;:977767;>BN[üÔÌÅ¿¿½½ÀÁÅËÌÔÙØÜÙÔÑÍÉÆÅÃÁÅÅÆÍÏØñûcUQKGD@><;988779;?DP\úÏÍÅ¿À½¾ÀÀÇÊÍÔÓÛÛÖÙÏÎÌÇÈÆÄÇÇÊÍĞÚçxeYONIDC><;98888:=@IRháÓÊÅÿ¿ÁÂÆÉÌÒÕÙŞİÜÛØÑÏÍÊËÊÉÍÎÏÚŞélg]RQNJIGC@?>=>>?BFJVeÿÜÑÎÈÆÇÅÇÉËÎÒÕØÚÚØÙÖÑÑÎÌÎÍÍĞÒÖİèîx_[WNLJDBA>=>>>?CFLWbøİÒÍÊÇÈÉÉÍÏĞÙÛÜŞŞİÚÙÔÑÒÎÎÑÏÔÚÜçôpf_WWTNROLNMLLLKJMMNVY^tùéİ×ÓĞÍÎÎÌÏÑÏÓÔĞÒÓÏÎĞÏÎÑÕÕÜéïo_[TNNJFEB@@?@BCHKO\mîİÖÏÍËÊÊËÍÎÑÕÙÚİâŞáâŞßŞßßÛáàÜèêêÿpjh_\a\Z_\^_^^Z^^Y``]dksqÿéõñäééêêèíéèêãçåàäâãáŞåâßééëïudlc[^\XVV[[Z^^_bbkgcptuïëîñæİåáÛààÛİââßèîàâíæãçæåæêêìù}ykfda^Z]]Y^b]_agngt~nyûøøøìñøêîøîìôõëíúéåóíêíïwôé}öëıpxñxhqvjjşsarölj~}feöx^wæogèæioŞïaíİomİßmğ×îlŞİo{âübzöek÷mhşsdrùoqîûkûínsîÿnzôxrîôrùõw}}uwxxqtùzzôıûúúğúıø}~ş~ı|şôøúúşú~xûşwı~şıyş~yşÿüù}øö|ÿ}vy||ıüıùùÿ~ü|~û|||xvrqtuvx{üúüı|üøùõ÷üúùÿı÷õóüıøÿşı{{}{ûıy}xsrt}tpş}w{y}}y~ûüş~şöùøôüıøùü|}şx{ö|ÿî{øòoõşnïwvöm}øqøşwüuøïu|ş{øÿşöxuùıûüuóösú|}ùp}ûtüşÿò{şùo{ûyû~xúø÷ôÿ|ı{}şz{û}}ÿ}û|~ş|ıvv{vvw{zxwu|şÿúş|ışıı}ış}úı~öõùıüùıúùÿıÿ~ù{xõûv~{üøxûüw~{û}uôüzşûñııù{ôúsıÿzóôwsüóôü}û~şúwş÷{v~øÿûüy~vq÷ø|snü}vşúùt}ûqqzù|vu|÷şùùzuxúıtuüÿ}üx}üw}{uxùôx}üşø}ıôúûşõôöïş~}wöôôü|öòö~ñôitïrşïuóïz{şıw÷õxok|}ÿöt~}ÿñ}ÿyuxozxişònøîwùurûrvuı|só|÷ïyüîóvúzkó÷w~|~uùğûò|tø}w÷ót{ztìñ~ñørtòïwtrzìnzînë÷që}tpøî{éø~úiøùwñrolnëp|ögïzyölíliüiù~|îvwğàydûvîèózjî~üçmøìjûzwŞønë{nwşûiqøkl{w}ïşksşú{wîy{ßøóßvöékùå~npz|jsóúùşûòxsôïxjnyrvü{øõyxsms{xzwmşózûşnv|üõşöõyy|şø÷÷ı÷îúôîyşùşízløyúî}íÿiûù}ûúøxvyxóùxû÷yltıu|øzş}uòïúÿúövyøvş÷~íülô}rìqmívq|oû}oïñnrùöyvûxuynxõsuîôşıüôyn|{z|rùùlıõrôğ}óò|wşô~x÷ñözqúõu}ö}|ıüû~||ûïøqşøvòëöíîwtü|pz~wvtıö÷îúÿútzö~xyxztvóü~ïxxùrÿ÷nmnorr~øù}yı}u}óşzüzt|ùúızyô}yüozûuúyrùumwmjûöln~qpşyòÖÏÜwn{xóßßêàÔÖáéîúqfb[QT[]mïö}zusidgekv|ôñíêêãèëçõ~xuüuwúuxyrzxuqmsuv|vxù}tşóòïîô÷üşóòúúùıÿû÷ûùúwûïÿx|yz~şúö|zöú}{zü~zûõòüy~yqpwüqnûù}ş}ÿıtrşø}u~ñüxöíòzy÷úwqwü}tvzxooşû~ùõ÷øù÷øı{utvyzÿ÷ô÷ùûûı}{}~{z|yzşúôñõùûşzw{~~üûúùûş~}~~~şıüı~|yvwz||z{şş{z|~ÿşüúûûüüışüúùüıûş}|}şııúù}tpoooszş~{ş÷øş|}|xux~ş}üôõûü÷÷ııøú}xx}şşû÷öú~}{wutvyy{ıûø÷øùı~~~şùöôôøúøùúùü}yvvy{|yz|}}zz|{}{z~üüûøõøúûÿ|yxz|zxy|zyz{{wuusuxyz|şşşşşûüşúøùøö÷ûûûüûıÿış}}şıışüüıışşşÿÿıúüış~ÿş~~şşşşşıûüûúùûış~}||}~}}}{{}}|||||}}|{||}}~~şşşııüûûûúûûúùúûüüüüüııış~~}||}}|{{{zyyzzzz{{{{z|||}}}}}}}}}}ÿ~~ÿ~~ÿ~~~~}~şş~~ÿş~~~}~~}~}~ışşııÿÿÿşışşüüııüüüıüüış~şıııışşşşşıışşıııııııüışüûışşışışÿÿ~~~~}|{{zyzywxxxxxxyxxzyy{{|||~ÿşııııüûûúüûúûüúûüûüıışş~ÿşÿ~~~~}}}|}}}}|}}}}~}}}}~}}~~~~~ÿ~ÿş~ÿÿşşÿşııııüııüııüışüüıüüüüüûûüüüıışşşÿşÿ}}~}}}||||{zzyyzyyyyzzyzz{||}~~ÿşşşıüüüûûûûûúûûûüüıüüşşşÿÿ~~~}}~~|{||{||}}||}|{|}}}~}~~}~}}~~}}}}}}|{|}}}~ÿ~şşşüııúùùùùø÷ø÷õööõöööøøøùùûüüüşÿ~}}}{z{ywxxvvwwuuvwxxxxyyyzzz{{|~~~|}ÿ~~şıışşşÿÿ~~ÿşşÿşşşııııışışÿııüışıûüııüııış~~ÿşÿ~şşÿ~~~~ÿş~~ÿÿÿşşÿ~~ıışıüüûúúùúûúúûûûúúııüışÿ~}||{zyxxwwvvwxwwwwxxxzzxx{{{~~~şııüüıııüüüıüúúúûûûûûüüüüıışÿÿÿ~~~}}}|||||~}{}~}}}}}}~~~~ÿ}}~~ÿÿ~ÿ~~ÿşıışıııüûúúúùøùùøøø÷ùúúúúúûûûıış~~}{zzzxwxwvvvuvvuvwvwxwxzz{{{||~~~ıışıûûüûûüüûûûüıııışııııışşıışşııışşış~~~~~ÿşşşÿ~ıüüüııüıııışşÿ~~}}||||{{{{{|}zxyzzzz{}~şşşşıııûüüûûüüûúùùûúúûúûûûüüüıüüıüışşÿÿ~}}}~}||{{zzzyywwxxxwwxxxzz{|||}~~~şşşııııüüüüüûûúúûûüüüüûûûûüıüışışşışÿşşşÿ~~ÿÿ~şş~~~~~}}}}~}|}|{||{||||}}||}}~~~~~~~ÿşşşışşııüüıüüüüııışşşşşÿ~~ÿ~~~~~~}}}||}}{|||}}||||}|}~~}~~~ÿÿÿÿÿÿşııııüüıııüıışşÿ~~~~~~~~~~}}~}}}}}}}~}}~~~~~~ÿÿşÿÿşşÿşıÿşşÿşşÿşşÿşş~ÿşÿ~~ÿÿşş~ÿ~~~}}~~~~~~~ÿşşş~ÿşşşÿÿÿÿÿ~}~şÿ~şş~ÿ~~~}~~}~ÿÿ~~~ÿÿ~~~}}~~~ÿşÿ~~~ÿÿ~}ÿşşÿ~şş~~ÿÿÿÿşş~ÿ~~~~}}}}}~}|}}}~~ÿşşş~ıışşıışıııışüüııüıışÿşÿÿşÿÿÿ~~~~~~~}~~}|}}}||}||||}}|}}~}~ÿÿÿ~ÿ~}ÿş~ÿşşşşşşÿ~şşşşşÿÿıışıııışıüııııışşşÿÿşşşÿş~}}||{{{{zz{|{||}~ÿ~~ÿ~şışşışşıüüşşışşşşşş~~ÿ~}}~~~ÿ~}}}}~ÿ~~}~~~~~~~~şşşÿ~~şÿ~ÿÿ~~~~~ÿş~~ÿ~şş~şışşşÿÿÿÿÿÿÿşşşüıııııışÿÿ~ÿÿ~~~~ÿÿş~ÿşÿşşÿÿşş~~~}}}}||}~}}}}}}}||}||}}}}}ÿüışşüüıüûüûúúûüüüÿ~ışşşÿş~}şşÿ~}ÿ~~ı~|}~}z|ş~~~}}}ÿşşı~~ı~}şş~~~~}~şÿ}}~ıü~ıû}|üşÿşÿşÿ{|||~}}ış}||şı}|ÿ|z}~~ı}xyüıuüö|ÿxwşwşıxûuwóy{úy}ÿúùşúüûú|{ùûw{ı~{tv{}÷øığõy÷ìêíüîënvêçéğíóoqüzjsôwjpyedûytùwniqıoıô|úihìóùèìlfâïfäîpofôhiôfûymêcgßïqìíşçá~òçlşälğãóô_ñüUÜçeÑæhi[øk^ßâvıñi\cliÿØÜöyX[x_^lhjóäëXN}i\ÓÏâñoüîêÖÍÌËÉÇÌÎÇÆÏËÊÕÍĞ^M?:-(,9¡?"S?+.¼­SϯÀÑ»®¯º³©¬®©ª´º¸»ËÎÜA.(!¯»®¯N%0íOÇ©©®¯«®¶¯©©ª§§®µ»Íl_O5)")½¹­¦±C/>GT·¨¦©ª©¯±¬ª©¨¨«±»ÏòQ?:.&",Á¼©¢®L;PAS·­¬ª¥¨­«©©¨¥§°¸½×_ZL7+&!4ß½¥ °NXS9Yº±°¬¦¦§¤¢¤¤£©°µ¹ÅáWF8*" )XË©¤®ÚìÑIX¾·¶¯¦¥¤ŸŸ ¨±¹¾ÊİkF6-$ +';c§¬Í¼È@RÃÃᦤ œ›œ¥®µ¼ÖcE:/#(.+'¾¨\Y³´óÍ­¶Ê·ª¬¬™œœœ ®´´Àã}M0*% -#A›©b¬¥ÃG¯«bÊ«©®¥š››šŸ«¨®ÒRH3&$!!#4¹ÜÁ¬²¾°©¯¾²¬°¯¦ ¢¡Ÿ¥¨©¯¾ÎèK:4-'!'+*3^Òۧ¦¨¦£¥¥¢¡££¢¡¡ ŸŸ¤«¸ÙC/&!+IÉ·¨›œŸ    ŸŸŸ£¬»~9) $3v¿¯£œœœœŸŸŸ ¡¡ ¡¦­¼{8(  .^½­¡›™™™™›Ÿ¡¥§§§§§¨­¹ÛB/% )O»¬ ™–———™›Ÿ£ª­«¬­¬«®¼ÚK6) 'E¯¢š—˜˜—™›Ÿ¥«­­®¯­¬¯ºËl?.% 2깩˜˜˜—˜šœ¢ª®­¯´±­®¶ÂÖR8+$'=Óµ¥œ™™˜˜™›Ÿ¥¬®¯µ¹³¯µ¾ËëJ6-&'=产››š™šœŸ¥¬­¯·º¶´¹ÃÏñI7.)'9_¬ œš›œ£©«®¶¼¹¸¾ÉÕüJ91,$$0G⹨¡ Ÿœœ£©¬®¶¿ÀÀÈÕâõXC<80*%%%!!%)*-5DWéǹ´³±®®¯±±³¹¾ÀÆÏÙÙÛè|pmc[ZYSNKJKKJLPRTZclxùöõøşş~y}ı|}}{üú}ÿûù~zÿ~}ÿ~üı}üù~ÿû{|ûşıøş}~ÿşûü~ıışüıúù||ş|z}{z~}~ı}xy}ı~||{}ş|{y}û|yşys{}{ş~{şıø÷ÿùıvúúxÿ|vüú}ışúõ~wz|şşùúûğzqóñü{úñ{{úotîüqyşøxzô~ùûpşóı{~üõíóıûìèuqş{øı|vo~ws|qûülqmpôş{óóùyovxtşykpsruvöykûrhûzq{xòõóğuÖÑwíü`ùfráúãŞÚÜ]tì]ghfk]ræßŞòs}zkhwûwvèŞí}ünl|prıu}÷íåîòø|øtgjihhk~slüûpfkvixûmşğîğõØÍÑ×ÙÜía^aXTW^lsm~îøn]WXQPW]nôóàÚØĞÏÏÍĞÙÚØÚâäÙÚéçãòıdWZUMLKMMHGKNSTT_owñßÎÇÈľ¾¿¿¿¿ÁÄÆÇÉËÎÔØÜüR@82-($!"):黫£ Ÿ¡¦«µÄÖèØÄ¹®¨¥¥§­¾Y5& *9=µ”˜¢Ÿ Ê/%$*'+£˜•“– ®¶].'(//,;tK/#!!3ĦŸš¡µñ=4-*9Ä®¦š™¦¬¹M1,++),;H:,!!)#)K·¨¦¤©¹ÙL?3/EǸ­¦  ¨¬´á?85338ENC7,!!$"(=Ä­¨¦¢¡§³ËúaMEPθ¯­«ª¬±¼Ìë]RRV^øã~VC7-% $(+.9S˺¶·¸¸º¾ÇÏÏÊÅÁ¾»¹º½ÄËĞÖØÕĞÌÈÅÄÇËÓìZJ?940///026;?DJNU\iößÔËľº¸µ´µ¶¸º½¿ÃÈÌÏÖİêvbYRNKIHGGGGGGGGGFFFGILOW`zåÙĞÌÉÇÇÇÇÇÈÊÌÎÒ×Üäğwkc][[Z[^aglpw~ıüşztmid`__^_beimtyşöğîêçåäääæéìğø}xtonoorvz~üù÷ööøûüü~~ÿ~şıüûúûııüúúûúùùö÷úúúüş~|z{{|||}|{|yxxvuuutstuxz|~ıûúùùøöööö÷ùúúıÿ~}~}{|}şıüüûúúùùûıÿ~}zxxvstsssssuwxz||}~}ÿş~şşşüüıüúûüüûúûûúùùùøøùùùûûüışşşÿ~~}|{{zzzzzzzz}ÿ~şüııûışşşşşÿ}~~~}}~}ÿııûûúùûùøûüûüışÿ}|{zzzz||{}~~~ÿşş}}||{zyzzyxyywxzyz|~}}~~ÿÿşıııüüüûûûúúûúúùúüûüüûııüüüûüüüüüş~ş~}}}|}||{{|}}}}~ÿş~}~ÿ~}}|{|||{{|||}~~}}~~}}||}|}|{}}}~~ÿÿşışÿÿÿÿıışııııııüüüüııûüüûüıııüûûüüúúûùúùùùùúùùúúûııııÿÿÿÿ~}}}||{{yxxwxwvutttttrrrpqrsrrrrtttttuvwxyz{~şùóğîïñöûÿ{x{||}}}ÿıú÷óğïïïíííííîîîïïîïïïïïğïïïğğññóôóôôõöõ÷øùúüış~}}{yyxvuuuutsrsrqqqooooopoprmun|Øàavâğsqrw{{~}~~}}}}~~ÿÿ~~~~}||{zzzyxxxwwvuuvvutttsststtttttvvvwwwyzz|{}~~ÿşşşşışşıışşşıüüüûûüûúúùùúüúøùù÷ùøö÷õöõóóòòõôôóóôôóõöö÷øùúøùüúøùúùøùùûüùùüûüıüüışşışşşş~}ÿ~|zyyvstrpqonnomnnmnopqorrkeb`acccefgkjgkjhjknohklyık~_ݹËbÅÔUq_[\NÔ»ÅîaİÍØğOܶÊCKÛÊØQK[ıÒÖkROëĞɺÏ==ZáàI9@şÉËğ[ReĞÏóNCZ×lJOiåàëŞİølZN\ÚÎîNMUwÖç]hßÕámgzÜ×|Z[enyàÓİuûÙÎÎİkZjÚÍÏàmeõìkXbÑÆĞfKHPmÖÖdT_êÕÙïjYNVp]M^ĞÍeGLãÆËùjèõYVúØãuñÚÕÜçlYXVLJ[åÚİên[Z^WS^îùWYêÔÓÑÏÙñßÍÏİÏÄÌûáÁ¾Ôe÷Úİô[KIRXG>COF8:KF56NØèxÌ»¼Â¾¶³¸¾½µ´¼Ä¾¹¾ÉÎßQ=60,% ?ËÀ³§¤®ÈÏÆÎõ̲ª¨§¤¢£ª²´µÇRHM>.+-+*ÎÙs­¤å?оI5થ«©Ÿ¦´µ¯¸ßWçÖL8:6'&À±¶©Ÿ§î7IÖY?Ϩ¢©¬¥¡ª¹·®°ÁÖÉÆtF>5(!*L¦œ¨¿ÆÕE5<髺´¤£¯¸©£­È͹¹áFLG* Ğ–Àº«Ä,$?ª¨Ô_«Ÿ«¾® £·Ú¾°¿LOÑH" «“¢Ï¶¬k&%ñ£©kÔ¥¡²½ª ¦½êÄ´¾{{Ü@#³“Ê´­T%#T£¤ÍÍ¥£ºÈ« ¥¸áµÍO׿N$̔¸­ù'"N¤¦ØĞ¦¢¶Ã«¡¨¿Ú¼¶ÍnÈÄE&.›˜®¼³Í/#6¬£¼Ì¬¦°º­¤¥¶íÒ¼ÊÒ·¸M*¨•¤¿°´9)³ ¯Í±¦¬½¹¦¡®ÕνÌä½µÜ1 \˜·¯­R%#ù¤«Ìµ¤¨»º¨£­Â»Â×ͽÈ=%&œ®®«É-!<¨©Ä¸©«µ·ª¡§ºËÅĞìÅ´»O)±›¦²¬²9!/±©¼½«§®¸­£§¸ÃÁËÖÀ´¾G,!Å©°¨®F%.µ¬Ì駯´© ¦µº½Úyμ½í6'<¡¦°©ªÒ+-Â±ËÆ­§«¯ª¡§³¹»Ïùѽ¿Y/'$5ª¯°¥©Ê66É»óÊ­©¬«¥¡¨³·¾ØÚÊÆÏR7,&!,µµ²¦¦½??ÌÂõÔ±ªª¨¢ ¨¯´ÁçáÍÉ×M:.'#!%ß¾³ª¦¯P?İ×wȵ­¨¥¢¢¨®µ¾ÖîÕÏãY?5/*%+@Ü»¬§±ÖÑäLYÔ²¤¥¦¢§®±½ÈÈÖÓÕYKD71.)$)8E浯ĞbÁ¼¾½Æ¹­¯«¤¦©­»ÄÎİÑÖñbF;71.,(# +20>Ç»ÅÀ´²ÌTγ®¯¬§©·¼³·ÄÇÏîP?FXC=C4+($+:..IG?âÔȰ¹Á·¾¼¶Á¼°°¯³»¸Æ_ÍÊXXN=<:9<97636524:DKÒ¸ÄÀµ¿¾»ÍĽ˽¸ÂÂÃÂÆìÙ×XLDEE?BBEL@CTJF?AÛ×IOìá\r½ºÄÌÔÊÌâÆ»ĞúÍÍêîçæZJWXQ^tŞïKK\NJNnÜd]_VeqjèÕçyÚØåØËÒáÒÖÜúSìÖc[únWeìÚvR_]TVoøiW]ÔmSÏïSd\âvhËúTİİòÌÊáğ[Xİù\ÍÍ|ævk[MæØW\øXiÿîØZedU÷]ÕÍNö×[ænqÌciÍı÷àüÜj_ôlwSmÓ]ïØcp^bå_Yñncì^ÿŞrêfpâhbçÚ{ïk[âYòÇbdÖşlóìâ{dŞæ`ôyfímñæe]nİvúÔfôùOäìmğèi[ÒXkÏLçãLâŞøşoè\yænßZî÷OÒùZâqbjonååtãìhÛì{ßVúŞUîãgåòiİg\ØnbÙhrèS÷ìxéxìjhkòîşíjtnÿngßpïÙeiöùoçë{ÚZeÜfwàû^ûüvñzìvhèêdìçjóñyqıuuë|oğxoò÷ılwë}kí{fêhuíbîösånÿqwß_ßweÙWíé[öpÿz}úsıséórêhöâ]ñŞe{ëioìhßçYåkkëiæwxçplîç]òã\Ûs[ßméñpõáñ]Ûgbçlêÿjÿàekİ[ÚñOÏW^Ö\íëù^wùóş]ßspÿÛáZîvvûÿfİã[Ûdoá\mĞcTÍPïÙQà~îWßåYÕkìsoÜQuÖJèÏMÜß^ékå×]ìâaqomuìxæOØ×JÌø`fŞİNÎgRÛsLÖÌ=ËÉ>ÍÓLğÆFZ½?dÉUqÙçMÛo]ÍpofÛ^NÇheİlêrd]ÌqQÍboåUøÖnWÔuOÒblÛaîaaïåeßÑKİÑGêËMLÈgGÁvLÆlğkNÇR]¾HPÅNMÇüAÒÉH}ÎUêÔ[àqWÍbIÚûmÙTúÓNÜÒSÍıRÌU\ØR÷ÛcçİUfèşÕøeò[ZÔeP½bCÀSLÀPUÂHRÆH~ÅNsÛwa`ÇXHÀiNÊYUÏtYËgGÇiJÅzEËÜ>äÔIÜæyÆLU¾PI¿k=ÍÖAçÈUgÁaKÆîHÙÜPÙÛHÑÕ?âÅZUÎÒFYÌK[ÃKWÄNIÆzSÁIVºGW¿QVÅPMÂYJÒôUßÜm~VÖİJÌ|NÄ^_ÆFaÈGvĞOëÊ\GÃÎ8Õ¾?ŞÉGÏæDÉßIî^YédTÜĞKOÇå?ËÂ=ğ¾HTºmK¶ş8Éå;ÜàLÈiPÂ`Y¾oAË}>ÊÛ=ÛÈRÛÄV^ÈJEÉQLÑN^ÖWàÎ_îàélOçálhÜËXgÍkóÔPQÔÕTEÏÉ<<98<==Fgëì˹¶»»¶µº¿½»¼¾À¾¾Êß^?0)"7J<ËŸ›¡¥Ÿ¢µàô[Ge¸®¤Ÿ¡¤¨»1 +3@­™—££©Á;,,5>L¦œ›œ›œ¨Ö9( 2AÇŸ•™¥©¦±?*.9;FƪŸœššœ¢°{/ '5Zª™—¦¦«Î5,1;Dq¸¥œ›››¥Á;( %5E¸˜«°°Æ;.5Oμ­¡›š¡¨¶H&*Ü®¥š©¹ñع«Ÿ—”•šŸ«½?" +;Æ«Ÿš–—Ÿ±ÒK8.))6ޱ¦š–•˜Ÿ®Ö7% 3Ï®¢œ˜—œªÁT<5.+.BÁªŸ›˜—˜œ¦¼A*  E¹©¢š˜œ¨ÂG98733>Ëªš™™›§¸J* 0À©¤£Ÿœ›ªÏ<36=DGRÊ­Ÿ™—š ªµÌG-)w­£¢£££¢¦¯ÏA46Cnθ­£›¥³×F7.'+M¼®«ª©§¥¦ª²ÄxOMWïÎÀ·¯ª§§«±½ÓV>3+%!+=ëÁ¸±®¬©§¨ª¯¹Ëôb~ξ¸µµ¸»½¾ÃÌîH7.)%" !%*3E÷Ǻ´°®¬«¬­±ºÈÙÖȾ»»¼¾ÂÅÆÉÏá[E:2.+(&%%'+2>YÓ»¶³¯®®¯³¹ÁÇÄ¿½¾¾ÀÁÃÅÇËÒâdMA:51-+)(')-4?\ØÇ¾¹¶²°±³¸½¿½½¼½¾¿¿¿ÁÃÆÌÕê_ME>:61.+))),09GaÛÉ¿º¶´´µ¸»¼»º¼½¾¿¿¿ÁÃÆÊĞİwZMF?<72.,+*+-19DYâÌÁ»¸¶¶¹»»º¹º»¼½½¾¿ÁÄÇÌÔâx^RKF@<83/.-,-/5:620/./16;7421126:AMdâÓÎÌÈ¿¾¾½¼»ºº»¼¾¿ÂÆÊÎÕİêwcYPKE@<96310137;BM[qìÜÏÉþ¼º¸·¶·¸¹»½¾ÁÅÉÍÓÜêr^UMHC>;74211359=ENZnéØÍÇÁ½»¹¸···¹º¼¾ÁÅÊÎÔÛãôiZPKE?<95322358;7410/025:@NißÑÌÇ¿»¹¸··¸¸¸¹º»½½¿ÃÈÏßücULB;61.+)''*.7IãÄ»¹º¼¾½¹´±°²¶·¶¶´²³´ºÄÑïYL@4+$(=Ƭ¤¡¤«¶ÇÚ×Ƚ¸¶´°­©¤  ¤­ÇA-'%%&$6¬š”—ŸºA4?É­¥¨²Ër̬–•š§Ø/%$'*,& + Å”‹‹”´*"K«Ÿ¢³T>à§–˜­?)(/=C9-%  D–‹Œ–Â$)̤ ¬ÑBd«š’’š©ÈNMXE7/0?\= /ƒ‡˜=M®­å.3¶š‘“ ·»ª Ä)&Ë Ÿ¼$ ª‹…Œ =*/6L·’“œ°×¸£Ÿ­H)3¾¦£²H/(€‚—.#2A*=–ŠŒŸNI­¢Ö.9¸¦®W3N·¹3  4—Œœ«J0º£š—š£´Ï»ÚD:W¹µÀİbR0 +®•——’›Û&áÇ˸›•¦ÂÇ®¸:,9¿­Á^hh> È›‘”‘e'HQή˜™¨µ³¬Ú/7ïµ·oÚ¹½> ­––›•‘;@Y,-6:8=E9'"/Σ™–›¡®o6::93/-+)&&&(+.9IîÆ¼²®¯³¹¹¶¸¸¸µ°±³µ¶»ÇÍÓèxVNLF=762-,,,,+-3:APØÀ½¼º··º»»¹··¸·¹¼¿ÀÂÉØîxu_NJIFC?;<;85479;>DQayÙÍÊÈÇ¿½¿¼º¼¼½¿ÀÄÇÌÒÚåïg^\PMJIIGFBAFCA?BIHJQ^~øæÔÍÌÉÆÄÆÃÁÄÃÇÊÈËÏ×İÜåp_]a_XXUOOPRQNPSUY[[_jqomx÷øú÷øóğğéëíí{~}u{p|ö{{vøèëíëçæãŞààߪܪßàãéîîòzheb[[]^\WX][]`_^^djiklpzs~ìíîêèåáßİİİİŞŞŞäâàèíïóüwuqlhehg_cjfbgiiknsxtv{wpxòöş}}óõöìïòğòğïğíîóìêêîüüóğøôùkkpt|ü|utlkuupmwızş~vwu~÷ızx~üúûzı÷÷õö÷ı~ô÷wzÿu|~vxy~üüùunutz}{ıõîø}ù~şòûx÷ğõùÿüùùó|n}÷şyw~yu}ztxş{w}~|{ywwy~|{|pmoyûûñîø~ığïøûøõôõòììôóíóöñ}wyt~ùzrrvvzş~zxwxttxyz}zw{|v|ş}ş}z|ûüst~yw|ıııúı~ûùúüıú÷÷úıøùşûúş|z{|{xomqzÿ}~şzzşşüúşz{|xxywurrrry~ışÿûúùõôööôô÷úùùşşı~~||ÿ~şıüııúúûúúúúüüûııışıüışüııı~~şÿ~~}}}~ÿ}}{z|}}|{{{{|zzzyzz{|{|}|~~~~~ÿ~ÿışşışışşş~}}}~~~~ÿş~ÿşşşşÿ~ÿÿ~~~}}~}~ÿ~ÿÿşüşÿıııışÿÿşşÿ}||}~}~~~ş~~ÿşşşşıüşşşÿşşşşııüûışıüşşüıüşıııüııüışııÿşÿ~~~}}{{zz{{{{{{{||}{z|||||{zzz{{z{{z{|||~}~şÿşıııüüüüüııışışıüıÿ~~~}}||~ÿ~~~~ÿşÿşüüÿşüûüıüûûüııüûışÿ~~~~~|||{|||||||{{||}}{}~{z|}}}{|||~~|{|}|{zz|~}}~}|ÿÿ~şşÿşşşıışıûûûúúúùùûúúúùùøùúøûııüüüüııûûııüııışüışıüııışşşş}}ş~}ÿış~~}|{zzzzyz{zwvvvvuuwutvtrrrsttvvvvuuwxwxwwxyz{||}~şıüüüúøùùøø÷õôôóòğğïïîîïîíïîííííííííííîîîïïïïğñòôõöøùúış~||zvuusponlkjihgeddb`__^^^]\\[[ZYYYYZV[WZeX¼®ŞDæ¿ÆE=ND@RüãOÚª³Å­¯¸ÊAI>2HNJÜͶ½Ã»ÕWeDK|FJcHQeVÛßVåâ\jVNcNIa_fäòßÕìéäd^XLTTLY]Zş|sæjWc[Xkk}ÜâİÏÏÏÎØÛÚäßÖØÕĞ×ÕÑß|ZLMNJIHKYWTjÿ}àÛÕËÍÌÄÅÆ¿¾¿¿ÄÆÆÏŞÛŞôiTLH?94/.--.16?[Ô¸±¯°²²´¸»»¹·¸·´¶½Èl>2*"/A߯£Ÿ¬¬«Ô¨­»®¦¬º¾Å_A=5,,.) FÉA<¬›¦ì¼¢°/4¶¶>E­¦¸»§¤³Å½ÈE681)()%!MÌ?A«œ©×¸¤µ14¼¸BC¯¥³½©¢®ÍÊÃT2/3.'#$ #LÎDO«Ÿ­Ë²¨Ã4>¾ÂG\¯¨±¶ª¦®ÇÛÙQ3,-.(!  /dbK½¤¦ººª°H8òÆ]M¿­®²­¨ª¶ÉÜh>.,.+$!!",HiPÍ«¨µº­¯r>[ãOQƶµ¯ªª­¯·ÎTB7-**(#!#.IUMʬ«¸¹­²wDkd=A̼¿¶ª¨¬®³½ÚL80.,(')((6êûQÁ«¯Åº®½KLßS9FËÃɸ««°±¯ºæLB9/+,.,*.;I]İÆ»¸¹»¼ÀÒk\TKNvØÌ¿µ±²´µºÉnM?6/-,+,08@bÎǾ¶µ»¿ÀÎgPNIDKlİÓź¶·¸·¼ÌâÿO>::62273+&"'-8N̶®ª¦¤¦©¬±¹ÁËÏÒÕÏÉÄÁ¿½½¾¿ÃÌÜù]ND<:70,+,---/6>I[äË¿½½¾¿ÁÅÈÉÊËÊÉËÍÍÍÎÏÍËÈÇÆÅÅÈÌÒŞú`RJEA?===>?ADHKOV^kşëâŞÛÚØ××ÖÕÓÒÑĞÏÏÏÏĞÒÓÖÚİäì÷tkgeddefgikkjjigfdb`_^]][[[\\]_dinwşöïìêèèèèççççççææææçèèèéëìïô÷ı}ytpmlkjjijlmosx|~şúúûúúúùùûùøùùööøöõöõóóôö÷÷øøûşÿ~|zwvvvwvvwwvwxwvvwxwvuuwwvvwxy{}~~şşüùúûûüıûúûûúüüúúúùúúúûıÿ}|zvtttrrtuuwyz~ûûúøøøöö÷÷øúúúııüüıüûûúùúùøø÷ôóòññòóòğñòññññ÷üş{wtpnnmllkkkkllnprsvy{}}~şÿÿÿ~|zyzyywwwxwuuuwxx{|}}ÿûùùùøöööôööö÷øøùùùùùûûùùûûúøø÷óññğïîíîîìííììííîïïğòóõùûüıı}{zywtrponnnnmllkjihgfddcccbbaa`_`^b]_e[˼àU[aĞÍéZJWşzvu¾²Ø?WȺ®±^4==<<=?ELYùÖÌÈÄÁ¿¿¾¾½¼¼»º¼½¾¿ÂÇÑë[I=731/.-,++,09Iéźµ²±±²±±±°°¯¯¯¯±´¹¿ĞaB5,'!!.Z¸ª¥¥¨®¹ÃËËż´­§£ŸŸŸ£©µÎH2)%!';в«ª®µ½ÄÅ¿¼·²­ª¥¢ŸŸ£ª´ËP9.*'%!$<¿ª£¤ª³¿ÊÉ¿¹³¯¬ª¦¢Ÿ¡¨±ËJ5,(&$""C³£Ÿ ©¸ÍáϽ´¯­¬«¨£ŸŸ§±ÎE3,*('%C¯  «¾èú˸®­®¯¯«¤››¥²Ø@3.,+)% #n©¢²ØUú¾¯«­³º·¬¡›˜˜œ§½R95784.& "V¬¡Ÿ§µÌØÂ²«¬¶ÈÕÁ¬˜–˜«ÇSEGKE8-%*Í©¡¢ªºËÆ·­«±ÅìÓ´¢š–˜¨ºØîàß\;,%! ,¹¡¤´Ùß¼«¥©½K?Ø©š”–œ©¸¿ºµºê8)&)03( + 5¬Ÿ¦¸ïç²¢¤¾:.D®œ—𢬬¤Ÿ£³I,+6Tc<(:¼­«­¯¯¬ª­ºèL]»¨Ÿ £¡ŸŸ§¹a??LO>1+(' "q³¶Å¾­£ ©¿^Y˶¯¯¯ª œ›¨´¿ÅÌd@:787/) ;ÖÅų§£¥¯ÁÉÅÂÄÆ¹­¥ŸŸŸ£©²Ç}UKG=4/.,$ 9TeÚ¯¡£­¼½³´ÍU÷µ§¦§¤ŸœŸ¬º¿¿ÎJ;?D=2,( &;F_»¤ «¶´®³ÚI캯¯®¤¡¨¬®»ãRMYL9342(*.?«¤©®««µÏ^İÆÉ¿°¦ ¡¢¡¤¬¶ÃÓıONM@951)%'=»¬¨ª¨¦®¾ÆÕãzá¼°¬¥¡¡¢¨¬°ÄêvdeVJNH:0&)c¿®¤¢£©¯´Ó?IhnÒº«¤£¡ ¦®¶ÀÌÜ^fìú}gM<+!<¿ª¥§¡ ²ÜwE:=Kνµ¥¢¤¨¯·Æ×ÒlZæßÚòL=+ -¿¾¯¤¡¡¬¹¸cDÚmg¿¶¬¥¥¤¨²´ºÒçlMHG@<3)" 5ër¶§ª¬¬¶ÈÜâÛÙʺ°«§¥¨ª¯ºÂÙXJA964,( ".>Bʲ±­«³ÀÄÎêØÉÀ¸®ª©©ª®´»ÄÜ`PB<;3-)#"$"'-04,'#!!$)0=TÖÁºµ±¯¯°°°°¯¯°±±²´µ·»¿ÆÓnJ;0*%" "%+5Dj̽¸³°¯°±±²³´·»½¿ÁÃÃÄÅÆÇËÔèaMC=840.-,,-/39AUàǼ¶±®­¬¬¬¬­®¯³¸½ÇØcH;1+'$"!"#&+2=PãÉ¿º¶µ´²±±±±²´µ¶¶··¸¹¼¿ÈÛ]G<5/,*)))+-/5=KmÓŽ¹·µ³³²±°°°±´·º¾ÆÎßfNC<71-+)()*+.4=KjØÊÁ¼¹·µ´³²²³´¶¸º¼¾ÀÆÍÛû]OG?<97654324680++4ݯ£œ˜—™Ÿ°I# #\¨œœœŸ¬Ï;/049_±¡œš™š«m) 5µ¡¢«½N3/7@cº¥œš™š¥»9 (R¬œŸ§µÓ?/.;dǯ¡š˜™›Ÿ¬Î2 )õ¨Ÿ¡ª¾_;/0@齪™˜™›Ÿ­İ1 +Q¯Ÿ›¥­¼yBúU6*" +,ÀÀ­™•µIGı:(=©¡¡œ ¬ÂÒÀĞCHÎÏP>.# 0·¯¥š—œ¸45V9)AªŸ  ¤´_]Îß^Õ¾»¾Ü;) +<­¢œš›¡Ì..8/0Ö¨œ£§­ÅV[êÙÆºµ´·ÉM4& Ѥ¡¡Ÿ¥X'+<>>Χœ›£­­®ÂU\ɹµ¹»´´ÊG2*$ .²§¨¤ »1*9J?H¹¡¡­°¬¯Ä}Öº²µ¼»·¼é<2/) +nÀµªŸŸ²E, >ªŸŸ¥«¬¯½ÿ?Eߺ¬¨§¦¤¡¢©·åMMT]SJIG?/ B« Ÿ¥ªª®ºê?Bn½¬¨¦¥£¡¢§±ÔK@BLONLF?2$,º¤ £¨ª«®»øHI﹫¦££££¥ª¹óA9;@HG=0$%Ù©  ¦ª¬¯¶ÊjOYǰ¨¢¡¡£¦©±ÅU:45;A?4&!M¯¤¡¤§ª­±½ÓcVÙº¬¤¡ ¡¤¨¯¾}>3/177/#)׬££¦¨ª«®ºÍ^Sܺª£  £¦ª±¾j;/+-//)<¸§£¥¨ª««®¸Ì]YÔ¶¨¢Ÿ¡¥ª¯¸ÊR8-*))& 4À©£¤¨¬­¬­°¼Ü^ᆲ¤ ¡¥«±ºÉ_@@@DLRZ_gşéàØÏÌËÉËËÈÇÄÅÌÏÒÎÎäıånRfà\LQSOGHPNOQOV^vs_lëØ×åßÜÔËÏÚÜÒÌÔÙ׿ynøîk_^__WNN\cVVZZiogüıpîz{ÙÓäyßÖØÒèvÜßäÚô[cÙİ[WeìbQïüOYuırgmëäiiåߪs^İäiÚÛoeyØê]şá_YÜÛñtVmİêj[sç~pmnôö^VíÍåV[nßáíåd[}İßZkßPXØëùl\í~}ÙßüyßâsôgıÛ^câk}İwXeİŞh\a|Şìfcnâåùğ|øòèë_cæÛõ_}ë|éşWaèßzZmcMşÎmTëßûëí÷õtlmğòiæŞik}óãæs_ùêuü}ùæ|dfaçÖlyÛmoàimÜv^{÷ôúïlcÜ|aça}öPxãqëûíèiwvàÖYU~èØøbhgÛŞcb`iõéîaeëïßÚn[_òènçêYiãâáæ÷fqßèyilä~_kboãéukk{äİğ]bëíd_ߪa}é~ğgcíó}ûe]}éøqlñâüôèlkùîës`wäøoÿruçænnîxmî÷lóékcûæïloñôõ÷÷}mïígnõóunşnşêú|}ôîôıjh}~òôhkpïŞ~tîzoovx~úyùìúp}ûwr}øoxë}n}óìôxy÷êìwwõşÿtgûíşueoì{ntuö÷tvzıóìïqùíûïúmuxyèîhrù}tgnóæãziïî{î~püt}øwsúõıïseşêöm{tsìoqípîÛûcn}ôìpjşúwoóíxijïçøxwouéïimosêí~ooñznôòóôkoêõïèrmzğçveúçÿkxóxi÷íojrõìôyjıëw~rmï}øïrwzïímıèrzïk~óvğuoùúóogùèïs}ê÷xş}ır}äzhwóØïX}ğoúf`|ğêçj_èÿ_áÛv^^hvãÜûabwåãükuèëmiüãòd|õhïİrcçã|úùóøgbùêjoôóâ~jyoñş`q~ğçvmn}âÿ]c÷á}]tßßø]^îÚæ`]îÚèd\máÚæieørnòtmõãßöxşnzêéúfgy{üwkÿèãåë}hfmu÷îîøliu{óèìëëîæînaY\emïæêóh\_jìÙÚåq[\nîäëııùö{cZ^hkd^ao÷êèêéçŞÖÚñmlèÕÙåşxáÚâíhSNIEHM[qo_X]îÒÊÈÈÄÀ¿ÂÉÎÏÏÌÍÖŞzVH<7421/08E|¹µ¶½ÁÁ¾¹·¶µµ³´»ÉU3%å—Œ‘¯/ &#"+-@³ œ¢¿ü᧪³¿ŞT?.% ´Š™G&.9¿¦›¶duº¥¤¬µÌïU>6)  ŠŠ£'-9Cµ¡› ç>Ù¬£´ÁÖÏÎZA.·Œˆš(,QJ»¢¡e-n¨›²ĞÕ×ÇìTK+ ™‰Ê!@GK«².2°™¤ÄÎĞÑÛYØk),’ˆ=&HDq¦œŸÅ*8ª™˜§ÌİİÕßğ¾Ñ)-‘‡7'NF룜£ê&A£˜™ªæççÛÊñ·/Ÿ‹‹«0KM¯µ/+´™•ÄKZ÷ɹ¬¨ËŒ´6_ꪥÇ,3§–•¡îBTߺ®¨ªU +d–›6*WÔ¼¥¢°N3À›–œ¸>A§§½+ P—›6,aÛ»¤£±N9³™–Í7E㩦§À)È–¢&=¿Î´¢¤´E@¨˜™©@4í´ªª¬°T$ D–) AÃạ ­K;¬™™©H:Ö·¯¯­­Ò* " ¹©$_¿È¬¢»7A¥—š±:;ɱ­®­±P$,, ,™Œ—78Öß·ŸªL3»™¥k:]À´¯¬«Á1+:.  ’Ä)LÊ®¬H/Ï™ŸÆ;AÙ¸®«ª»9$ +@8" n“œ.6ͺ¦£Ã16­š›­D:~À·°«©À/!5zG#*œ–Û-]»«ŸŸº:4¿œ¨ĞE]ËÁ·¬©µ>&%.C@* ®©#%FÍ»¥¦ú.B¨› ¿BYÁ½½³§©Ñ+!+OéE( ½ $!B»ª¤Ì/7®Ÿ¸GUÁ½¿·ª¦¹5%';toA( ‘×.`̹¡œ¬<*V¢œ§Ë[ÏÁÊ~,'1MVE/ M“œ-$4QÙ­›Â/-½Ÿ¡°ÏÚÂĞô»¨¡­B*+8aê]<" &™•W/Cß¶›±5)\¢ª¿åÈË}½ª¢ªZ--8_şQI+ +ªª)6MÍ¢—£>%4¨œ§½ŞÇ½îİ®¡¢Á/,6NÜïnK$ “»*.E¶œ˜°-(`¢­½Á¾ÎTƨ ¨ñ02>IPWr< D’œ6'*,X§–›](0¶Ÿ©»¹´º\H´ ¡·<5C?4%Aœ¦±»I@º®¯«¤®ÇÄÄËͽ®®¹·¯²ËwÍÅw>?H7* § ¨¥¬À*2Ûʸ¬£¨»¸¶Ôãij°º²«°ÂÍÆÎRFM>0) ¬¨§ ¦»,#5:M¹­¤¨¯ªµsØÄ¾ºº®ª³¼½ÉÙcKB;6."ײ¯¢¡¬H+5:;󺬩«¨«»ÇÄÆÇÀ´­²¹·¾×çûI92*ѵ¬ ¡­N0:76m¸«©¨£ª¿ÆÂÍÕÆ¶²¹º·Æò}Q<3-'¿¼¶¡¡©Î7PE-D¿°©¨¡¢ºÃ¹ÚiÙźÁ·ÀÛåP=0(&#¹Ã½¢¡§Â?ŞN,=Í·­¬¡Ÿ³¹²Ìa]ùÇÎÕº¼ÎËŞM:-'&Òj¾£¡¦¸àÆP/8WȺµ¨£¬¯®¹Íp\ò_LïÍÑÎ×ö]?2+$"9BBÜ·­¯¿½¹Ê_TòÊËͽ·¶µ¸º¼ÇØÚıZ[böèkfbL@:2-*,6==GgÎÁÅÉÂÀÆÏÖÌÇËÌÇ¿½¾ÁÁÄÍ×ßéõz{tbXNG?;538==>COmğêØÏÎÓÔÍÉÊÊÉÆÃÃÅÆÈËÎÔÛßéÿoi_WOMIEBABCCDFIMSZfüçÜÔÏÍÊÇÇÇÇÇÈËÌÎÒ×İßæ÷vlc^XTSQNLLLLLMNQUZdnüäßÖÆÆÔÔËÎĞÎÑÚÜÙתú{{ld]TOSURTTQPRVXVX]fqõäŞÛØÕÒÏÏÏÏĞÓÖ×Ûàåóxnd_[XVVSRTUUWZ]_fltûîæàİÙ×ÖÔÓÔÖ×ÙÜßèïzlg^ZXVURRSTWZ]do{ğæáÜØÖÓÓÔÓÕØÛİßíütg_YVSQQOPUVYdoüèßÚÓÏÎÍÍÎÍÏÕÙİíraWOKGFEDFKOXnêÙÎÊÆÁÀÀ¿ÁÄÉÏÖì]OG>9438==CVqéÕËÇÈÍÌÌת×ÛÜÉÃÇÀ½½½ÃÈÉèX\J;:84/-;K;MÁÎ×»ºÀÇÌÆÜPêÜOnÍÚÕÄ¿¿Â¿¿ÓïİR<<6.+(/>3H½ÒÇ®´¹¸¾ÁŞXİXDëèoÊÀ¿¾»¹ÃÏË~ID;3/.++;C>ɻǴ¯¹º¿ËèKSN>SøjÎÁ¿¾¿»¿ÌÇÚUXI<<<6554>ONİÂÊ¿ºÀÄËÜîWU[SoŞØÈÃÃÂÄÁÅÓÓçPOE<>853/>JBĞÂÓ»¹ÃÀÊÚwSZOOôîØÃÄ¿½ÄÀ¿ÍÒØt\TOHBF=981;H=hÎşÅ½ÈÂÆÏÚ{ïpgÛİÔÄŽ¼½¿¿ÈêïR=:0-)&053ŞÉÒ´´¼ºÄÜYIE<@NOàÅÁº·¸»ÀÆÒ_}ÙSnËòÒÀÍËÌâhMB91/.-3>NÕ¼³­««­°·¿Íz]SGLI??8/--+*19-*! $$7Qo»°°±µ½ÚaMDKhͽ²¬«©©®°¹ÎäS=::4152./--49>QgÜÉ¿»¸®­®©«¬ª®¯°·ºÌy>(8;ü§¥¦¤©»áj82>@s»®§¦¡¡¨©¯ÊáU::;59A<:=635018Gߪ¨ª©«¸¿¾ÎϽµ³ª£¥¢ ¥§ª²ÁâM;4-& !IFÛ³²²°®¸¸°·´­­®ª¨©¨§ª®®¶ËÙM4*-Bɯ©©ª«³·¶ºº°®¬¦££¡£¥¨­´ÃuC4+! 2y±««­°²·º¶´²¯«¨§¤£¥¦§¬´¼ÔJ8+/\ʺ°®±µ±´·³°°¯«¨¨¤¢¤¤¥©®³¾ÛM6('9Pȳ°®­¬­±¯³¶±¯­«§££¡¢¦ª¯¹Ì[?/&!(9a¿±¬«¨©®®¯²µ°­­¨¥¥¥¦©¯µ¹ÊíU<.(!$.lÀ¯©¤ ŸŸŸ ¢¥§©¬®°³µ¸¼ÄÚX?4,'#%.<[È´«§£ Ÿ  ¡£¥§©¬®±´¸»¾Éİ[C8/+'"%+6Há½°«§¤¢¢¢¢£¥§©¬®²·»¾ÃÉÕtOA:3.+($! "$',3=PÙ¿µ®«©§¦¦§§©«­¯´¸»¾ÃÊÓçaNC<9630.,++++,-/29@Mw;¹´°¯®®®¯±³·º¼¾ÂÇÌÒÛën\OJGE@=<<;:;;;=>>BFHM]òÛÏËÊÊÆÄÅÄÃÅÆÆÉËÊËÎĞÔİîïívfhdYSSQOQTTNV\UØÚ^ÛÓçèäéİîYõkWæşbìçpqê~kkìíböë{bsîbnw÷g_ë÷{ôyßúcÚÚßÛÈÛlÓYõà]ßyb`tmfÙ]MÒWSÍNÏkLÃI÷ëZÒUñûîkjî^ãdeãü_åèUÛßVŞêTşùpøöôoyæ\íÚVá_{ÎXj×÷JÔÛNÔg{ÏYhÎTqÔRÎf^Ö_ö^ŞõlÍWeËK÷ĞTàkßyd×iéÜúyÿXwØVaægaİÕ`iOì×IÌeUĞHËß@ÊÙMçÛ]YènéúVÔ~\áñgX|zOwÏf`ÕŞYêä_ëuÜßW^Ëj]ÊOİŞMÑv_Îeaá[ësçÈWZ×jXëÔ[ZØk\İxßoKĞiN×pêõjÔh\øïÿfäyO^Ôù^îìtşÍîæagÎGîÓLõëİíOØñA}Òe\ÖÏZmÛñıXïØFߨIĞgQÊıRÒçåÊloÜÿ\yêb^d[bëíòØæ^ğPkæMß{~ÖeĞvQÎ^mÑ]êUlÙJÉèN¾LjÅ@ÇãAÁ[MiHÕõWÏßj[ßùQÏûòÖOÒnUÄbíßPÊn]ÈLQØKߪCäoMØÿ`ê[[ßäZØÎKİÉV×ô_ÌOnÈOåØRò÷åí_ågQndùâaÜãNÜäOËwRÒOëĞJÌâFÀtMÑL|ú_Ìe~ÜRëşcÙcÚæLñj\jlÍübÍgZèóÛtïÒ_\|bm}àÙlìÚNRíZW{úøgñÑozÈŞuÎÕòszåZLáøKyòV[]aVQv|VzÚrîĞÔØØÔÑèßÒòivn^Q`dLPQNUIOcN`ñdÑÎÙÁÂÈÁÃÂÅÊÅËßãuRHJH<=@:<>@MLUÓ×Ѽ»¹³³±²·¶ºÁÅÓxP;4-'&!%'3NѺ®§¥¤ ¡¤¦©­³¸»ÉoN9)!(3O´ª£ŸŸ¤©¯¾ÅÃËĹ»ÂÖ>,&+G̰¦¤›Ÿ¡¤®½ĞÙêù¹¾º½P/&,NÉ®£¢œš ¥°Ät`hUË·¼··[5),MÈ«¡¤œ˜Ÿ¥¥±âUcVQDZµµ°Ì9#%+?Я¢¡š¦¨°ÔQXfcͲ®±®½B'")=ݲ¢ š¤©°ÍMN__Õ³­°®´\,(1g¸¦ Ÿ››¢¨­ÂSL]^㸭¯®¯Ê8$,AÈ«¡Ÿš§«´ßLWquʯ¬¯­µP+&2fº¥ Ÿ›œ¡©®¼]Lkgè¼®­®®Á># )9z²¤¡Ÿ›¤ª®ÂZYíãи­®¯²Ê9!*8m¯¤¤Ÿ›¥©­¿mxÙßĞ·®°²²Í8"(5M¼¨¥¡¢¨¬¶ĞêÒÎ˼°°¶¸Ê@(&.<Ğ®ª§Ÿ¡¦¨¬»ÍÈÆÎÆ·³¸º¿g4#"'/>Òµ¯© Ÿ£¥¦¬·½½¿ÆÀ¹¹¾¿ÈU6(!'-6NÄ·¯§£¤¥¥©®¶¸»ÀÄ¿½¿ÄÆãF7*""! "'*-=ïǵ©¤£¤¤¥ª¯²·½À¾½¾¿¿ÇæJ8*! '.Bɱ©£ Ÿ £§¬±¸¼¼¼º··¹½Ë];*'.BÁ®¨£ Ÿ¢¦ª®´¹¶±²²°±·¿ÖO9+"&-7Uĵ­©§¦¨ª¬­®¯­­®¯³·¾ÓbG8.'#"! #(-1=dɺ³®«¬¬««¬­®­¯³µ¶¼ÌûYF8/+('&'((*-5>LøÊ½¸³¯®­­®®®¯²³µ¼ÁÇÚcOB:5/.-,-,.149?H\İ˼·µ³²±±³´µ¸¼¾ÀÉÑ÷VSK@<98877:<=?ELT^{ßÒÎÌÇÅÄÄÅÄÅËÊËĞÖÜàîpe_[XTPTUQSXYZ^cfkxüøïëëéèìëììëøóóuyşúÿs{ûıvxòúvşğòxûîıw|îìwqóõouú}~|ÿôxyú~ÿyzôõroıxy÷ıøşlşë|sı~ùutïxnyyquöòüjmïÿnzz}zqíãæãìõşimûpoş||{~ëé{~ìóôüñëninrxtyzsmşìşyõôôşox~uoÿé}mú÷üunùîywïó|ÿöîôo}÷v|zzykwümopiusgx÷wyşú~zïìñîôóîöô÷v}û{ûtjplfkklxwöçæŞÙÙÔÕÚÖ×áæé}i_\WOLJIHFHO]|ßͽ¼º¹»¿ÇÎŞcME=50257:MÜËû´´¼ÇÏkB8679748>J^Ö¿ºº¼¿ËõM?::=BNúÍÀ¼»¼ÃÔoN@<=CL\ŞÇ¿¾¿ÅÑmL?<<@HXâÊ¿½¾ÂÏÿPB=>BK_ÛÇ¿¾ÀÇÚ]H><>DO~ÎÁ½¾ÁËíQC=::;=BGKMIFPéÏÏÑÍÎåVJKKJWܸ´±¬¬¶¾ÅÎu@85.%#8JSÈ­¦­Çåo<+'-;CV_lÔÁÂÚ^TSL@a»¼ÈÁ¾¾ÏMZ×äÙ¿±¬²¿ÅÌg?68:2----6BNXoË¿ÎõteWGDRí¿±°¯­­®²¸ºÃĞÙ÷UB9.#2ѹ¯§ §Ó:2-(%,[¹¯­©§¬À^MMNQî½­¬µ¾ËtG:=O\şÙØÖûH:1.//9_ǹ±¯¯³¿Ñà|ljëɼ¹¼ÁÉÓrE942,"&`Á±©¥¤¯cB<3/4İ©¢¥¦¦¨µù]ʾÀĺ°µ×G:."*²ª¤Ÿ½/,-,5Y´¤ £¦ª³ÃïX}Îľ¹¶¹ÍO940/145448@OdïÚÌÄÄÉÈÅÅÅÈÊÉÅÀ¾ÁÄÂÁÇÈ¿ÁÈÏÜÖÓßüXONJIF?;888877:>CKYpãÕÑÏÍÍÌËËÉÇÃÂÄÄÄÄÃÃÄÆÈÉËÎÑÖİèükb[TOKFB?>=<::;<>@EKUgõäÜÔÏÌÊÉÇÄÄÅÂÁÂÂÄÅÂÈÎÎÏÖÜŞäùk_YOLLIEB?>???>AINUe{êÚÔÑÓÏÊÉÉÄÄÈÇÅÈÍÌÌÓØßıúåö_\ZZWMKMNLHFGHJLMOT\h}óêİÚØÑÏÏÌËËËËÊÊÌÍÏÖ×ÖÜäì{ncXQNLKHFFGHJKMOU]dm|ôãÙÔÑÏÎÌËÌÌÌÍÍÎÏÒÓ×Úßêôth`\WPNMLKJJJLMORVZ^dq~áÎĞáßÑÏÔÔÑÒÖÔÏÒÚÙÕÙßåí|jbcaZSPOOQOXêàaQSXYZ]`h}çáãÛÑÎÍÏÖÜŞÚÔĞÏĞÔÚŞàãéøla[RLIHIKLJGHMQOMP\htôèŞÓËÇÇÈÇÆÅÆÆÆÇÉÈÈÏßãá|]WOKJG@>??@??ADGLQ\sçÙÏËÉÆÃÀ¾¼¼½½½¾¿ÂÇÊËÒö[WQKH@:776423589;?IZäÎÇÀ¼¹¶µ´²²³´³³µ¸¼ÁÄËã\MF>70-,*))))*-29C[ÚÆ»´¯­«©¨¨¨©ª¬­¯³¸¼ÄÔ{UD91,(# !$)/=UÒ½³­¨¥£¡  ¡¢¤§©­°·¾ÊÚkJ;1+%#,;Z˹¯©¤¡ŸŸ¡£¦ª­±¹ÅÛV>2*"&0EÚ»¯ª¤ŸœœŸ £¦ª­³»ÅŞL7,$".EÖº®¨¢œ››œœŸ ¢¦ª­³»ÆŞN9,$ -FÒ·­§¡œ›››œŸ ¢¦©­´½ËêK6+""0Mȳ«¥Ÿ›šš››Ÿ¡£§«®¶ÀĞkB2)%6aÀ±ª¤Ÿœ›šš›œŸ¡¤§«¯¹ÆÜW=.&)=ä¼®¨£œ›šš›œŸ¢¥©­³¼ÌôL9,$ -H笧¡›šš›œŸ ¢¦ª®¶ÃÚ`C3) %6dÁ°ª¥Ÿœ››ššœŸ¢¥¨¬±»ÌmJ:-$-Jϸ¬§¢›››š›Ÿ ¤§ª®¹ÆäP>2(':Ἧ¨£Ÿœ›šš›œ ¢¥©­µÂŞXB4+"#2`Á²ª¤¡›š››› ¢¥©­²½ÚWC6+#".OƵ«¥¡œ››››Ÿ¡¤¨¬¯¹ÊxMº¯Ø|¬š››™—™¢À:.+! #Ë¿QΟ–Ú5a´ºG9ˤœ›œš—–›©Ú:1*  0ÀæG³™–¨E=À±Ø7>¸¡œœ›™—˜¯S5/& + @×R×£—œ»Aê²¹F5íªŸ™––š¤¼K3)  ,ìMG®˜—©TW¶±]/<¶¡›—”—®ó;, &M@>²˜•¤è}³°\-6½¥ŸŸœ—”•œ«ÏD1  39C±š˜¤Åů²O.9¾©¥¡›–“–œ¨»\1 //7²™—¦Â·§¯@+<º«ª¥œ•“–œ¦³Û2 + +'+>­š›¨³ª¦¸;/Nº²±§›””™¤­Ï. +&&3°œ«­¢¢º=;Û¼¼·¦›–—š ªÍ0 +.´ ª§ŸµLLÌÀÌ¿©™š›œ¦Å4# )»£¨­¢›Ÿ¶ŞÈ¾ÓiÆ«¡œœ§½L/!!D¶²µ©Ÿ¬»¸´¿Ü˳ª¨¥¡Ÿ §°ÄY4$ (6Qκ¯¬­®¯´»¾¼º¹¶°¬«¬­®³¿èI9/*'%$&*,-2>MXuÏ¿¿½»»½¼¹·¸¸¸¹¼¿ÅÌÙzTJD>;;;<=?BFKNS\htóàØÓĞÎËÉÇÆÈÊÎÔÛäıiceha[WVUVY\\Z\boøêáŞİÜİßßàêôğôoa\W^úí}y}~÷íîxjröø}üîêçŞÛßçëòşzske_\[[ZXX\^`i|ïæßßàáãåéìîìßÜãèßÜŞãìıqlona\]^^aa]\_bhwòìéçæäåêíğóëåèëèéêääíûtkijgeb_befikklort|öôòìêêéêìïğîğ÷÷ôõ÷öóõû|vrroiinooqoko}ùı}ş|zùîğôñîîğõøøøøõ÷ış~~ú÷ùşxtqprsqoqvzyyÿúıûôöıı÷ö÷ö÷ù÷öõõøùõòóö÷øùøû}|{xwvsssoqnsqjüdìÏKNÈ]SÔX^İ\{ç]ùíjüü}öüìøqèí}èôzéïşîîôîïóïîôñïöôòùô÷ü÷ûşùş~ú~|ı~|~{zzwwvtuvutrrrrttrtuttvwwvxwuzzy|zxzzz|}~~~şşşûüüúûûûüúúûùùù÷÷÷öö÷õõ÷÷÷øøûúùıûøşÿııüş~ışşışışÿ~}~ÿ}~~}}}{{{{zxzzxxyxxzzyxxyy{{{{{z{|~}{}||~}}}|}~}~ÿşıııüüüüûûúùùùøö÷ùù÷÷ùúùùûıııııışşşÿÿ~|ÿÿ}}}~~~~|{}~}}}||{{|{z{z{|{yz{zz{{|}{|}{{|}~}}}~}}~ÿÿÿşşÿşşşıışıüüüııüıııııışşÿ~ş}|||||~}}ş{y~zxıux~kíf|ÉzlñXÓo]êRuccö\ğô|şóléÂïZŞSïÇâïûiİáâßøçîozxoû}nÿy}î~ouonu}ôxrxim{lmlejmgiphhlhjhjoms|sy~s|}ùeüÒëåãzİñëòiáõzíıôôîïíîûùvşüz{}øoyğúûøîúñéw~øzzkowwöùóèòüïıÿşgnm`jci}húürçûôîwüoqkdlhejsmy|tymü}|ój|söĞØİâúàëêèø÷yóëëìèìõîpkkkj\`_^gcwnpïóêîéâíëõ}ÿrku||ëìçŞââàáæìwlf[\[ZZW^`Z_b[[eddw~ıŞÜŞÕÓÔÑÒÖ×ÚŞçòìõôêùêæìâîúr^aXMNMJLLNOQXZfyşëãÜİØÒÒÎÎÎÍÌÌÏÌÍØĞÓãÜáùöscZUQKJICBC??BABHJL_úíÓÇÆÁ»¼¾º»¾½¼ÁÿÂÈÆÈÏÓâeZL@=70.,)(((+/6?d˾´­­¬«®³¶»ÄÇÆÆÀ»¶²°¯¯´¼ÉìI:1+(% %&,>P껯®¬ª«°¸½ÄÚmÚÏÓ¾±¯­©©­®²¿Û_G:4231.//*&%()(,9AVŶ²­ª¬¯´¹Çßïrgçɽ¸°¬­­­±»ÃÓ]G=965320-*&#&**-;WwDz®¯­¬±»ÁËßmuÙ˸¯­¬«¬¯µ»ÊtNF>88:9642.(##'()/Dcİ»®¬­¬­´¾È×qayØÆ¼´®««¬­°¼ÊÚ]B==:7:<854/*%%(++0Fà̽¯«­¯¯²ÁÚŞèciÓ¼¶¯­¬®¯µ½ËíTG@=;<==;960,'$&+./;õÄ¿·­«¯µ¸¾ÕoiioİǼµ¯¬¬­¯´½Ìå]KFEB@DHEA>9/+(&&).3<^Æ»¶¯­¯¶¼ÃÕm_fwÚÄ»¶°­¬®±µ½Îï^LCCEDCFIE>:5.)&&*.18N˼ºµ¯®´½ÇĞè^VeÜÉÀº³®­¯³´¹ÈènaNDEKMKKKE=94-)')-15=h»»·¯°ºÈÌÏõX_äĞǼµ°®®¯µ¹¾ÉíYTSLFGNPLHC=81,)(),18Bkȼ¹¶´¶¼ÆÑäj]iåĞúµ²¯®¯µ»¿Éä]WUOMSZXQNI?94.+((+/5873,)),-0:MxÔļ¹º½ÀÇÎİspÜÍËź³³´²±¶¾ÃÆÔh[daWZnjWTTG:660+*,..4D^í;º¼¼½ÃÎ×İò{ÜËÇÀºµµ´²´ºÀÂÊàpxlYW_[QPNC;:7/,,,+,394/,***,19C]ÒÆÀ»¸¼ÀÄÉØïëÚÓͺ¶µ²¯±¶»¾Å×özjXU_aXZ^PE?<5/,*))+/9?VĞÄÀº¶»ÀÁÇÛıìßİÏ»¸µ°°²µ·¾ÉÏßgah_`{~fd_L?<7/-,))+.4=Pá̼º»¿ÃÈÖêäááĞľºµ²±±´¸»ÃÎ׿kirik~o_[PE=93.++*),38>bÓÍ¿¹¼½¼ÅÎÑßõä×Íý¹µ³²²µ¹½ÄĞŞïg_junp~oZPJ>850-+++,39=WÚÔÅ»½¿½ÅÎÑÜæáÜÎÅÁ»¶µ¶³µ¼½ÀÏÙÚûkö}síóolZLC;85/-.,,/39GViÒÆÈÀ½ÆÉÇÒİÓÖÕÈ¿»¸·¶µ¸º½ÃÌÒÜèêëîëæ÷olYKF=750-.-,.38ARöÔÉ¿¿ÂÆÍÕÚåìÙÏÌüº·´µ·¸»ÂÆËÛàáøøçîö~fZMC>931/-,--09?IkØÊÄÁ¿ÁÆÉÏİİÜİÓɾº¶¶µ´¸¼½ÄÍĞÜíïíìú{ğjWXK=<90//--./4=BQæÕÉÀÂÁÁÇÌĞÚŞİÙÏÉýº¹·¶¸º¼ÁÉÎ×áíììîççîûh[NC=930/-.//3;@N~ØÌÄÀÂÅÄËÕÕáìÙÓÍÅ¿¼º¸·¸¹ºÀÇÈÕßİğùæïíë|lXMH>:720/.//3;?IñÛÔÃÃÇÂÇÏĞÚëèàÛÏÈÁ½º¸¸¹º¼ÁÆËÓÙŞæßàßÙİéòfSKB;850//./47:74110058=GSkÜÏÌÈÇÊËÍÔÙÙÛØÏËÆÀ¾½»»¼½¾ÄÉÌÕİßéêçìëëyk^PKC=;7343267:CGVììÔÊÎÊÉĞÏĞÛÙÓÔÏÉÅÿ½¾½½ÀÂÄÌÎÒİŞáèæêïğvc\QID>;9755568;AIRzçÙÌÌÌÊÍÏÒ×Ú×ÔÑÌÇÄÀ¾¾¾¾ÀÂÆËÍÔÚŞåéíîòıve[RLGA><977569:>GM^ïßÓÍÍÌÌÏĞÕØÕÖÑÌÊÅÁ¿½½¾¾ÁÅÇÍÑ×áçìøı|vh^[QKG@==:8988==AMQcèáÔÍÎÍÌÏÓÓÕÚÓÏÏÉÆÅ¿ÀÀ¿ÂÄÆÌÎÓİßèïğı}oc^VNKDA>;;:8::<@DKWcïáØÏÑÎÌÔĞÑÙÓÒÒÌÊÉÅÄÃÂÄÆÈËÍÓÙŞèîø||slf_YTNIGC>?>GIK\gzߨÕÒÍÍÎÊËÎÇÉÉÂÃÿÀÁÀÄÈÊÍÖÜépaZSNKIFCA>=<:9:9;>@FQcü×ÎÌÆÆÈÈËÏÑØÙØÖÑÍËÈÇÇÆÈÊÌÒÚŞìüüz{óïîëî|qgXTOHGFACDBGJINVV]nmúæëáİŞÖÕÒÌÍÊÇÈÆÄÆÆÆÊÌÎÖÜŞïwr_ZZRONJIGDCBABBDGIMTZgùéŞØÕÓÏÏÏÍÎÎÌÍÍÊËËÉËËËÎÏÒØİãìüuka^YVSONLJIGGGGIJJMPU[esóãİÙÕÔÒÏĞĞÏĞĞÎÏÏÍÍÎÍÏÑÓØŞåñujc]ZXUSRONMLKLKLNMQVT[caròõãİŞØÖ×ÓÑÔĞÏÓÏÏÓĞÑÔÒÔÚÛİèêìz{xhgd[YXSOOMLMNNQTV]_eqryö}ùğöìèæŞÛÚ×ÕÔÓÕÖÖÙÜÜßâääæééì÷ütie^[ZWTTTSUZ[^hkwöÿø÷w|ypxsu÷ôëàßÜÙÜÜÜßäæëíìîííììîíîğôıwoifcabccddbb_^_biotıøôîòõø{xqowyıîëæŞŞŞÜßæéï~}{t}ûşöïğïëïûüshe_\^^^cfgoy~öòğöøö}~ø~øíîêåéçåìììõùüzsookkoowşıøóõøøÿtvpkqsrÿúöíîóòø|}ysvqmooszÿøùúøş~{z{yşûüóô÷òõüûı~~ÿş~ıùùğïôø~wpmonntu{ş~şûøôöùú}vrootzüôîíîïöş|xsw{}øö÷ñóö÷~xvpnoppv{~úùùõøıûıy{{ruxqwş{ıõûùö}{ÿwv||~ışıù÷ôòòóøüÿ||xy~~ûùú÷øùõøışzwxrsyzÿúùøøøü{|yvyxy|ıúúö÷ışzrppotwxıûşúûÿıü{xyyx|~~ûıüùüıııüş~{z}|}ùúşûü~şı}z|zvy{w~÷úöòúùøışıış~~ÿ~üúúõôùùü}}z{}|ıø÷÷÷ûşş{vxwuy}ÿúùü}{zsrwuz}vxxrvyzıùı|yrrwz~øööóóöôñøúøı~ÿ{{|ywtoostv}üøòñóôõöôõöõùş~ywyy{}~ÿÿüûışşÿÿ~~~~şşşış~ÿ~z{zy}~ÿûø÷ø÷øıı~||zz||~üûùùøøúûùûış~~~}}~şıııÿ}{xyz|||}zyz{{{{zz|{yyzz}~şüş~ÿ~{|}~~şşş~şışüúüı~~ÿÿşÿüúıüûıûúûûüııüışşışşşÿşş~}|~ÿ}|}}|||{şıwu|ÿ{yz~~|ış|şüşÿ}ÿş}şışûúù÷ùúüıüı~~~}{z{{z{{yz{|ÿ}|~||}{|ÿ~~şşÿÿ~}~ÿÿşşÿÿÿ~şıışÿşüıÿşıışşıüıÿÿıışııÿışÿış~ÿşıış~~~ÿş~}~ÿ}~şÿ~ÿş~~~}|||{y{|||}}}~ÿ~~ÿşşışÿÿÿş~~ÿÿÿşşşşşıış~}~ÿÿÿ~|zzzy{||||~ÿ~şışşÿÿışÿşşışşşÿÿıüşşşşıııüışıüüüüışııııışÿşüışÿÿ~}}}}|}~}}}||~}{|z{|zz{{||}}||}}~~}şışşş~~şşÿşşşÿşıışıışşııııışşşÿ~~~~ÿzyıü}{}ş~}şÿ}~ÿış~ış|}şÿ~}}}|}}~~~~~ÿÿş~~ş~ÿşıûüüúúûúúûûüüş~şı~~~}ş~|}}|}||}|zz{{xxzzzzz||}~~~~~ÿ~ÿşıüüışşşııııışşışşşşşşÿÿşÿ~ÿÿşÿÿÿÿşşşışÿışÿşşşşşııÿşÿ~~~~~~~~}}~~}}~}~~~}}}~}~~~şşşıüüúûúúúûúùúûüüüüüııış~~}||}}|{{{zyyzzzz{{{{z|||}}}}}}}}}}ÿ~~ÿ~~ÿ~~~~}~şş~~ÿş~~~}~~}~}~ışşııÿÿÿşışşüüııüüüıüüış~şıııışşşşşıışşıııııııüışüûışşışışÿÿ~~~~}|{{zyzywxxxxxxyxxzyy{{|||~ÿşııııüûûúüûúûüúûüûüıışş~ÿşÿ~~~~}}}|}}}}|}}}}~}}}}~}}~~~~~ÿ~ÿş~ÿÿşşÿşııııüııüııüışüüıüüüüüûûüüüıışşşÿşÿ}}~}}}||||{zzyyzyyyyzzyzz{||}~~ÿşşşıüüüûûûûûúûûûüüıüüşşşÿÿ~~~}}~~|{||{||}}||}|{|}}}~}~~}~}}~~}}}}}}|{|}}}~ÿ~şşşüııúùùùùø÷ø÷õööõöööøøøùùûüüüşÿ~}}}{z{ywxxvvwwuuvwxxxxyyyzzz{{|~~~|}ÿ~~şıışşşÿÿ~~ÿşşÿşşşııııışışÿııüışıûüııüııış~~ÿşÿ~şşÿ~~~~ÿş~~ÿÿÿşşÿ~~ıışıüüûúúùúûúúûûûúúııüışÿ~}||{zyxxwwvvwxwwwwxxxzzxx{{{~~~şııüüıııüüüıüúúúûûûûûüüüüıışÿÿÿ~~~}}}|||||~}{}~}}}}}}~~~~ÿ}}~~ÿÿ~ÿ~~ÿşıışıııüûúúúùøùùøøø÷ùúúúúúûûûıış~~}{zzzxwxwvvvuvvuvwvwxwxzz{{{||~~~ıışıûûüûûüüûûûüıüüüııüıııışşÿ~~}}||||{{{{{|}zxyzzzz{}~şşşşıııûüüûûüüûúùùûúúûúûûûüüüıüüıüışşÿÿ~}}}~}||{{zzzyywwxxxwwxxxzz{|||}~~~şşşııııüüüüüûûúúûûüüüüûûûûüıüışışşışÿşşşÿ~~ÿÿ~şş~~~~~}}}}~}|}|{||{||||}}||}}~~~~~~~ÿşşşışşııüüııüıııışÿÿÿÿÿ~~~ÿÿ~~~~~~~}}}}}}}}}~~}~}~~~~~~~~~~~~~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿÿÿÿÿÿÿÿÿÿ~~~~}~~}}}}}}}}|}}}}}}}}}~~~~~~~~ÿşşÿÿÿÿşÿ~şşÿÿÿşşşşşşşşşşşÿÿşşşşşÿşşıış~şşÿşşşşşıışşÿ~~~~~~~~}}~~}}~}~~~}}}~}~~~şşşıüüúûúúúûúùúûüüüüüııış~~}||}}|{{{zyyzzzz{{{{z|||}}}}}}}}}}ÿ~~ÿ~~ÿ~~~~}~şş~~ÿş~~~}~~}~}~ışşııÿÿÿşışşüüııüüüıüüış~şıııışşşşşıışşıııııııüışüûışşışışÿÿ~~~~}|{{zyzywxxxxxxyxxzyy{{|||~ÿşııııüûûúüûúûüúûüûüıışş~ÿşÿ~~~~}}}|}}}}|}}}}~}}}}~}}~~~~~ÿ~ÿş~ÿÿşşÿşııııüııüııüışüüıüüüüüûûüüüıışşşÿşÿ}}~}}}||||{zzyyzyyyyzzyzz{||}~~ÿşşşıüüüûûûûûúûûûüüıüüşşşÿÿ~~~}}~~|{||{||}}||}|{|}}}~}~~}~}}~~}}}}}}|{|}}}~ÿ~şşşüııúùùùùø÷ø÷õööõöööøøøùùûüüüşÿ~}}}{z{ywxxvvwwuuvwxxxxyyyzzz{{|~~~|}ÿ~~şıışşşÿÿ~~ÿşşÿşşşııııışışÿııüışıûüııüııış~~ÿşÿ~şşÿ~~~~ÿş~~ÿÿÿşşÿ~~ıışıüüûúúùúûúúûûûúúııüışÿ~}||{zyxxwwvvwxwwwwxxxzzxx{{{~~~şııüüıııüüüıüúúúûûûûûüüüüıışÿÿÿ~~~}}}|||||~}{}~}}}}}}~~~~ÿ}}~~ÿÿ~ÿ~~ÿşıışıııüûúúúùøùùøøø÷ùúúúúúûûûıış~~}{zzzxwxwvvvuvvuvvvwwwxzÿüüüııüıııışşÿ~~}}||||{{{{{|}zxyzzzz{}~şşşşıııûüüûûüüûúùùûúúûúûûûüüüıüüıüışşÿÿ~}}}~}||{{zzzyywwxxxwwxxxzz{|||}~~~şşşııııüüüüüûûúúûûüüüüûûûûüıüışışşışÿşşşÿ~~ÿÿ~şş~~~~~}}}}~}|}|{||{||||}}||}}~~~~~~~ÿşşşışşııüüııüıııışÿÿÿÿÿ~~~ÿÿ~~~~~~~}}}}}}}}}~~}~}~~~~~~~~~~~~~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿ~ÿÿ~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ÿ~~ÿ~ÿ~~ÿ~ÿ~~ÿ~ÿ~~~~~~~~~~~~~ÿ~~~ÿ~~~~~~~ÿÿÿ~~~~ÿşşÿÿ~~~ÿşşşÿşÿÿÿ~şşÿşşşşşşıışııüüüûışıüüüüüûúúüşüûüııüûüşşüış~}~ÿ}|||zyyzyvwxyxvwzyxxzz{{{||||~ÿÿ~~ÿÿşş~~~şşşÿ~şış~}}~ÿşşşüüıüúûüüüüúúûûûúùùùùùúııüı~~şışşş~~~|{}~~~~şş~~}}~~~}|}}}|}~~}~~}}}|{{||||{|~ÿ~ÿ~~}|}~}||{|}}||}ÿ~||}~}}}}~şÿşşşüüşşşşşşşşııışıüüûüüüüüúüıûüüûüüüüüşşşşÿ~~~ÿşÿÿıı~~}||{{{z||{{z{|{{||{{{y{{wïçóûûöîöxmjotmnvzıû}}|~{pnmmonmmnw~}~üùõóöûüıûõû~øñîìíïëêàÏÉÌÍÊÆÆÊÑßğoYKC?>=<<=@FMTaëÓÊÅÄÃÃÃÅÉÌĞתín]VOJFB?>>?BFLWkäÓÉÀ½½½»»»½¿ÂÄÇÌÒÛæüdTKD?;8544469=DQ{Òļ·³°¯¯¯°²µ·º½ÃÌŞbK>5-'%$" "(.7B`˺²¯®¬©§§¦§§¨©¬®±¶ºÂÏíVE;2+'$""&+1:61/.,*((),/4:F]áÍž¹¶³°®­¬¬­®¯²¶º¾ÄÌÙş\OG@<741.,))*+-06>MiŞÎƾº·³°®­­­®¯±´¸¼ÀÇÏßx\OIC>:630.,**,.06=HZô×ÊÁ¼¹µ²¯®®®¯¯²µ¸¼¿ÇÎÛñfWNJE?<9640.,,-/16BFG>EàçaöƳ¯°±¹¿ÈÍÃÃÇ»´®«²º¹ÀÛTHA3-.*$ !'(.?Ê´µ­¤£¨­¯±¿Ôǽ¹´¬¤¢¥¤¥ª¹ç?." %&:¬™•›™“›¶oJ7'&C¿²¢–”•™«h0  '~誗‘“œœ´4-,'&4·¢”–›§K&  qݽœ’‘™ ¥F*+'$+m©Ÿ™Œ“˜ ¿-  %Ìi¹œ““¢œ¨?./)'0İ§š•š¤Á. 8¶]³˜’–Ÿ¥®1).(&5̧œ™‘‘˜œ§İ- <²]¿š’—¡¦¡«=&+-(.c®Ÿš•–œ£½8& )½ÜÍ’™¡§¶;$%-./T®Ÿ™”‘”˜œ§Ü.% 9Qe«—’”—š «¹O+%*19j±¡š–•˜œ¢¯o/$ %28Ö¡–•˜šœ¢«»O.)/:EÜ® ›™™œ£­½P.#.:@¼——šœŸ¨°¾U0+4JëÀ­£¡«ºÎY5("*3?ŧ››¢ª°¸Ï?16KÚ½¯©¤¢ £­¿ÓöA,&#*1;ß®£ŸŸ¤«²·¿|>;Mλ´¯ª§§ª®ºÎhK<0)#)/3@˯¨¦¥¨­´¹ºÂéO\Ͼ·±¯¯®®°ºÉÜeSG8.*& #+/19V󮬭±¸ºº¼ÉàÛȾ¹µ³³µ·¹¼ÄÓævZK?91+%!#).007HÜ¿¸´´·¼¿¾¼¿ÊÍŽ¹¸·¸¹¼½ÁÊÏÕídYMB:5.(&(,/028GïÊ¿»»¾ÀÀÀ¿¿ÁÃÀ½¼¼¼¼¿ÃÄÆÊÎ×áûfYK?93.,-/257;DZßÌÆÆÆÅÄÃÁÁÃÅÄÀ¿¿ÁÅÉËÌÍÏÒÔÖÚŞê|cVMHA=96579<>@FM\ï×ÎËÊÉÇÆÆÅÆÇÇÆÆÇÈÉËÎÒÓÓÖÚÜâğzk\RMJE?<:::<>ADIOZ{ÜÒÎÍÌÊÉÈÆÇÈÈÇÆÆÈÉËÎÏĞÒÔÛŞâéıbVOLF?=:878;?DINYwİÎÈÉÊÉÆÄÄÄÄÅÆÄ¿¿ÀÃÆÈÊÌÑØß~dYKA=951.,,/8?HRgÜɾºº½ÆÇÁ½½¾Áþ·³´ºÄÆÀ¿ÆŞUC?A;/)$!'5MvŞÇ¸®««°½ÑÛÎÆÅÈż²«§¨¬³ºÀÍñJ8/..*"7¾Àqİ®›®R8O½»n:B¿¥¥­¬¦ªÉ5*-35-$=¯ºUÄŸ–™¨İ88cÉ\6?·¢Ÿ¡¢£¥¦¬Õ1,:I8,.:4" (©«74¡“°67`Ğ\4.棨¯¢šŸº]TF8799Aß×3 ´ªBFšŒ–å/QU,%3Ê«¡¡¦¡›Ã7NÇG*1̶Áİl;" żRšŠ‘e%79 1³ŸœŸ£Ÿœ¨G3zÆ@/Y±°Åôc=! 5­­¨•–¼1-%#å©£Ÿ›œ¥¯»ÜO[l[޹³ÁÜú; Æœ™•“«2 D¼¸¦—˜©º²·Ü\mrÇ´¼åÒÃI& +,«›”‘\ +Ñ­¢™–ŸºÊÁÖNPÏ·°¸ÉÈ¿ú. + +EŸ˜“•ª.=²£›•™«ãZ]VZÙ¸««¹ÇÇİ>* +¶œ™‘™Ä!'Sªœ–•¼B?MUş¼ª¦¬¾ĞÕ`7( + +­››“›ê/饘•—¢{7?JZƯ§¥®ÆßîM8+# +Á›œ–‘š½!0Ş¦š—— e.9M࿳§¢¬ÎohT?-$ 2™™•˜ª,+Ù§›˜–Ñ,.?Ô¹³¨ ªÆ^MVP6+& +³™š•– Â>´š˜—©4)3_º¶¯¢£µõGNl?,(  + N™™˜—›ª%2½ œ™”G'*F¹¶²¤ ¬Í<=oN2+' ¥—™˜›ÌN§›œ˜—®2$+Ì®µ®¤¤®[5DkD-&" + [˜––šª$-³œ›š—¢j)$C²®®ª¦¨Ç88Nd;(#  ””™ ¡çLŸš›™œ®;!)Ò­ª¬¬©¯m86GW5' +½˜““£·(­š˜˜›§Ø)$;¼ª©¬«­½[97>6*  .Ÿ–•¥«?!×¥ŸŸŸ¢½>>Í®¯Ãɸ¯¸[80,$ Òš¦§®K# 2¿­¯­¡™š§Æ×¹²ÍFM½­µô:/) "µ¦¬«±Q'$5ů¯­£œœ§¿İĸ»ÏŞÄ¸¹ÍJ6* iŸš¦©¬¿5!.Ï­¨¥¡Ÿ §·Ôäʼ¼ÃÇÁ¼½ÍO4$ (®››Ÿ¥§«Ø+"<¼¬¬©¢¨»ÒÒ½»ÆÜñ̾¿Û;' Û££¦¸8 -ç´®¬¦Ÿ¡­¾ĞÇ¿ÈíSjË¿ËD*i¤Ÿ¢¢£¯N&(M¹¯¯ª¢§´ÄÇÂÌûMPâÊÏD)$Ó§ŸŸ  ¤µ@''F¼­«©¢Ÿ¦²¾ÆÈÓ]MVÙÈÕI+ E·¨¡Ÿ£°d-&*<͵­§¢Ÿ¡©µÊØÙÔÚéİĞÉĞJ.Y¤Ÿ¢¥§¼5# 2­¨¦¡£¯ÕXíÏÉÕÒ¾¸¹ÓB0$ v ££ £Ä+%E¿»°¥œœ¨¾ÜÉÀÓ]e³·Ë[J;& 멦¤œ¦W((0EX䮜¢¯¶³¸ÕM_¸¼ÉÈÁÏ?' /·¨§š»2,168?¾£¢ª«ª²ÙNlÊÈÕ˹µÁQ3& B¼±¤™™¨h:A6*-[­¤§§¢¡«ÁÒÈÊvWйºÅĞç?&2Ó±£š›§ÆYE/)/Y¸¬©¤Ÿ¢«·¼ÀßU[ÕÁÂÁ¿ÊM+(HÈ«›š¢³ÅÙ7)->Ò½°¥ ¡§«¬¸Û[_ñei˾Å]6) ,;½Ÿ›Ÿª¬³X..\¼®¬§¢¡¦®´½êHEOTQ\øS2&")8¿¨¥¦¥¥¯ÜNKD>Kͺ²«¤¡¤©¬´ÊTHE?=@KB4*#'2ܳ®¬¦¤«¼ÅÌhKRŞÎƶ¬¨©ªª¯¼ÑzO?<>BA>;3)$'*(*/>Wìµ°³¸¸¼ÈÓİŞáâÏÇÄÃÅÄÆËÏÖØÛŞÚ×ÔÔØİïdRHA=:8778:=AHOZiøäÚÑÍÉÅÂÁÀÀÀÂÄÆÈÊÍÎĞÓÖÙÜßçïÿl`YSNKIGDCCCDDFIKNSZbnùçİ×ÒÎÍÌËËÌÍÍÎÏÒÔÖÙÜàèïúyojfb`^]\\\\\\\]]]^^`adimpyúòîêæäâáßŞŞŞİŞŞßáäèìïõıytoligecbbbbcdfghikmnrwz|şú÷õòïíëéçåãâßááÚá|{wpqomjowzÿvu{ut{~}{ş~z||yutwxwwxywwxy{|~şşÿÿ~||}}}~ıûûúùùùûüş~|{zzyyyyyz||{}şıûùøùùø÷øùùúûúùøøøù÷öõôõõõõõöøùùüşÿ}}|{zyyywwwwwwxyyyxyzzyzzzzzz{yxyyyyxyzyyzyyzyvtrpnmlkjiiklow~ùñìéæâߪİÜÛÛÛÛÜİßâåéìñøızsmjhda_][YWUTSRRSVY^fqóçŞÚÖÒĞÏÏÏÎÏÑÒ×ØÙŞŞîïŞygmce^ZWUQNX\SOIDEHJJLU]oè×ÏÎÍÌÌÌÌÊÈÈÆÃÆÈÉÍÒÙİãîòú{ofcZOIE@=;99:JTNMTaìäæİÚÎÇÇÃÁÃÁÂÄÅÉÍÌÇÉÒÖÚäèùe\WMHIKHCB@?ACFHHNYX`õäŞÚÓÏÌÈÉÈÈÈÆÆÈÉÌÌËĞÛŞæêwZ]dXRPPNJLOKKKKOOOYW[xşÿïç×ÒÙ×ÒÎËÎÓÒÖÖÖÙÓÔŞççèk`íó`b[Y]Y_aVXZ\_WZ\WZ^_agşğëïùêèèçéäİİçÔÀÂçwÙùVXliMRù{êìxïgircuvi_jù{åìjxy}nhwn}ïrìâù}m~ç÷ôæèøwş~øvllhúqdqñífòäûìpùmlŞyşr`cN_z_r^gl^kʸÀËÎXLZYN\ßÏĞÌ¿ÊæÍÌcM_ZJhÛmiâèo|é}TUkSMlzZ]zô÷äãgTNPgsåÖù}âïwQVænëİ]YUöï|ÅÏù{pôIYÕfíæàÕ^xåZßÄØ\ÚÑQJ[ÛÏnrágLTÛííÔÛÓàéßZdñlcbŞëdû{ØÕìîefk^PUğd^ëßì[ìİ_ûİrLLMYÇÕÚÆìëmfÙ[c]WåöìUvÌdZOs_FÅÊìËZSmı}iû\ÖwAéÎÿU_ØîßßjßĞÈĞ]ReénÔÊ]kkQ\WÍÅcàÓNIÕÏrÌÏaVO^[ZtÙÜRb]J[NxÏëÎÒÙóH]LEîæÉÎoÉsÆÀEHÕÙìoÎÈ5/ÕÒ?=Í´E-«m9ܵß)J²/ήÖ44¯ª,%À¼/3ÄÙ-+N¾÷3½Ì#9®¯<7§£3-¤T&h¯>'i°N'/`:2KEVÁı[º±ÁÕ½·Ïã°§ÅCºªË9RÊ9#'54'&480?Í»¹¼·­¯»µª«¸¼±°½ÍÆÀê?95-(%#%$%,6<]Æ»°¬«©¨«¬«°µ±¹¾½ÌÛßQC:/+)&%&%).1>lç¾±µ®¨¬«¨®®®µµ¹ÅÁÓjjC;8,+,'&*(+26CgÙ¿·°®¬ªª¬¬­°´¸½ÇÒåbLC;61-,+)++,06?Lıɽ·°­­«ª­¬®µ´¼ÊËëbXD?=642...-013=Nh}ÇÁº´´¯¯¯®´´¸¾ÁÑãnRNCB=8<868578:?AIXkÚÍŽ»¹¸¶¶¸·º¾¾ÅĞÔã[YMDD>==<:<>:>CAKO^yâÏÍÄÁ¾»½¹»½¼ÅÄÈÙÜöm\TJHJ?BC>AABDHMJU\hèâĞÍÊÄÄ¿À¾¾ÁÀÅÊÊÖÜähbSNMHHCCF@DECGJMM]d]ÚäÜÉÑÉÇÇÁÅÃÄÈÈÌÒØßël\cTTTIXLITFOIIYG\YTê]áÜêÍÕÊÈÌÃÊÇÈÊÆÕÎÑğÛf_hMSMHJEKHINHSUO\XggbçtòÚßÑÏÎÊÊÄÉÈÁËÉÇÒÑØßéqlNOTFHEDHCMMIUSW]hslïxèİïØÕØÎÊÊËÈÊÊÊÒÎÔãŞéîkcqSRWMMJLJHLFLOLWX]l{áìÛÎÖÌÊÎÉÍÌÇËÍÌÍÑÛ×áìŞlnhWmTNXKKJFHEHGFNLP`^wèçÜÕÏÏÌÉÉÅÇÇÃÌÊÊÏÌÕÒÛèØm}pP^MILBDC>B?@EBJONZ_|íâÍÏÊÃÇ¿¿¿½¿¾¿¿ÃÈÅÍÔÖéqe\RMHFC>><::99:9<>?HO^èÕÇ¿¼·¶µ²³´³¶¸º½ÀÇÇ×êàUMM>;832/.-,../67=N_âû¶¯­«ª«ª«¬­°³·¾ÂÊÜ}`OE>71.,(&&$#'()/9CnÊ»³­ª©§¦§§§ª¬¬¯¶¸¼ÇÎÓlRL?81-'$$ !!),2M{ɰ®¬¤¥¥¡¤¦¥¨¬­°¶¸½ÄÊÕï`L>7/)#! %+8NÒº­ª§¡¡¢ ¢¥¤§«¬®´µ¹ÀÁÈÜzU@5.&&)6àÆ·§¥¥ŸŸ¢Ÿ ¥¦§¬®¯³·¹»¿ÇÍãUC6+$%+9Ù»¯¦¢¡ Ÿ¡¤¥¨«­±´µº½½ÅÎÙ]G8,% -8g¸­¦¡Ÿ Ÿ ¥¦¨¬­®³´·»¼ÁÌÜXD:-&(7Y¿¯§¡ Ÿ¡¡£¦©«¬®²²´º»¼ÇØmJ;.'!&1NÄ´¬£Ÿ¡Ÿ¡£¤¥§«­¬®³²³¸¼¿ÅÖR?7-%!)3Lô­§¢¡¡¡¢£¥¦§©¬­­¯±¶¸º¿ÌãT@7.)$")0@ܹ¯¬¨¥¤¤¦§§¨¨©«¬­®°´¸»¿Íì[LC<3-+&  &,7Gû÷°®­¬«ª«¬¬«¬­®¯¯³·»¿ÆÌØîãÑØZB8/+'!!%).8KîÎĽ¹¶´³±¯­¬«ªª©ª«¬­¯²·¼ÄÎàeOD;4.*%! #(/;NÜŹ°¬©¦¥¤¢¢¢¢¤¦¨©«­±¸½ÈÛdJ=6/+'"!'.;QÚ·®ª§¥¤¢¡  ¡£¤¦©«­±·½ÇØeJ>7/,)%  $+6Ciʽ´­ª¨¦¥¤¢¢£¤¥§©ª­¯´¹¾ÇÙeJ>70-)%!!&,7Ek̾µ®«©§¦¤££¤¤¦§©«­¯³¹½ÆÕrN@:5/,($  $)/82.+'# !$).9Hn;·¯­«©¨§¦¦§¨©ª«¬®±´·¼ÀÊÛjOD=71-*'#  "&*/;Mîʽ¶°­«ª©¨§§¨©ª«¬­¯±µ¸¼ÀÉÚmRF>93.+($!!#&*/;Mîʽ¶°­¬ª©¨¨¨¨©ª«­®¯³¶¹¼ÁÊÙtUH>93.+($! "%*/:Mëɼµ¯¬«ª©¨¨§¨ª«¬­¯°´·¹¼ÁÉÕüWJ@:5/,)&#  #%).7H}˾·±­«ªª©©¨©ª«­®¯±´·º¼¿ÆÎßfOG?:5/-*'$" !"$'+0:Lïʽ·²®­¬«ªªª«¬­®°²´·¹¼¿ÃÊÖï^ME=85/,)$ "%,;PÚ½±¬¬­­®±·¸µ´³°­¬«««¬°¶»ÇîYQH=::5/,'#)/=Û»±¬©©¬­²¼ÁÄÍÏ»»²¬­«©­¯²¹ÅÛsM?<6.+' &9@Ì­©¥¤£¥¯³¹èvîJLãÏȹ¯¯®ª¬°²´ÀÓÓdBA>3-+$.@T¶©¦£¢¢©¯´ÆønTIWÛÌ¿³®­«ª­¯²ºÅÓ{NC=8/+'  $=HĞ®¨¥¦£¥¯³¹ÜlkRJqÊɺ¯®¬ª«®±¶¿ÎæYB:80+)# "3LS»¬¨¨§£«´¯¼ŞÔÙ][ÏÆÍº¯³¯¬®²µ·ÃåïS=<:0-+& &!(8;Sõ®®ª§¯²¯¼ÊËÔëôÔÉÎË¿ÄÌËÍÚëİÛîçÕÓ×תú]OH>978635679<@EJXpùàÓÍÉÄ¿¼»¹¸¸¸¹º¼¾ÀÃÇËÎÓÛãïve[UNJE@>;9754458;>EM\zàÒÊÄ¿½º¸¸·¸¹»½ÀÅÊÎÕİèøog_[YVSQOMJHEB?><<<=>BGMUazæÙĞËÇÃÀ¾¾½½¾¿ÁÄÇÊÍÏÕÚŞäìúyog`\WSOLIFDA????AEIMU^nğàÙÒÎËÉÈÆÆÆÆÈÉËÍÎÑÕØÜáèïırkc]ZWROMKJIHGGHIKMPV]iüéŞÙÔĞÎÌËÊÊÊÊËÌÍÏÑÔØÛßåíùvkd_[XVSPONMLKKKLMOSX^fsóçßÛÙ××ØÛŞèîíñúöíâİØÏÍÌËÊËÒרÛİàÚתÛÖŞãæùuZTQE?<73/3979FVmÜÄ»¼»·¹¼ÄÁ¾ÇÇ¿¾¿¿»½ÈÇÌÛ}TKA8/-*%).-/;KoÚÁ´¶¹²¶¿¾¾ÃÅÆ½»Á¼¸¾ÁÃÉÓneW>95.*&)/-.=J^ÛÀ´¸¹²·ÂÉ¿Êʼ»¾½¹ºÃÉÄÎ_X^G951-'(2/-:N`{ɶ·¾·´¿ÎÈ¿ÇÏ¿¸¾Â»¹¿ÎÇÅuQ]S=45/(*31/8KneÏ·º¿¹¸ÀÑÌÅÒØÁ¼ÀÀ¼ºÁÌÆËt[YN?9:3-/864>N^_Ó½Áƽ¾ÈÔÎÈÔàÉÁÄÅ¿¼ÃÌËÍè\ZRE>=9558=:=LT^òÒÈËËÆÉÏÏÏÒ×ĞËÊÇÅÅÅÊÍÎİî{WQJDA>>?@AGKP^oéÛÖÔÑÒÑÍÎÎÌÊÈÆÆÇÈËÎÑÚãúeZOJFCBB@?BEHLP[dlôéãİÚÖÖÔĞĞÒÔÔ×ÜŞáæêïòõşşü~şÿxzwpqnmmmostx}}şııûûûø÷öõöö÷ûş}zvsponmnoosx}ıùñêéêçäåæèéîüwnha^^^]^_bfkr}÷îèäáàߪßáäèíõ}qjd_^]\]^_bgls}õìçäàŞŞŞİŞßãçëñúzrmjgfeddegikov|ûõğíëêéèèéêìîñõøı}xurponmlmmllnprtv{ÿÿıúùöôóïïïïïğñóöùüış{wtrrononnopsvw{~ıúùöôóóôôóôö÷÷øúışÿ}{z{ywwwxxy|ÿşşüúøùøùùøúûøùûûûıÿ}}}{zzxwxwvutvuuwxz|}ÿÿ~~ıüşşııüüıışÿııÿ~~}~~şüüûüüüüüüüıüûüûúûûúúûúúúúûûûûüşÿş~{{ywwwvwvutuwwwyzz|||~~}~~~~şÿşüüüúúùøùúùùûúúüø÷ûı~şÿ{z{|}~||}||}~~~}zz}zwzwvyvstusrvuqsstur{nş|eØÛkønyüvöwiùäşÌÈúï~exlokbró{uïômtöïúûíüş÷üùzûõsòíxôõı~vîıoõltì}{jqçonîyp~ùnkïwhôíokìxcï|fşÿwv~òn{íjjèêfôÔ}nØj_ÚıWnè_^Üğeàßëöóåeeèn^påxh×Üb÷ÚiUÚŞN~ÓYeÔn^áê_øØõ`pîÿyóxjeùêalù]^{ıc{Üurİík~w^iëm`æçnêàğ÷åæo{ç{Z_äeQŞàOîË`YÎîOãŞOnÑe^ÚødãánñÛwlìõççøæívïåübãÖhpİ_SïsN_yXgãõfŞÔgyÏyWÑgFÏáHŞØHcÆPOÃ\LÉå^ÍâKâßAxÙBñËZæÍü`×ìLĞØJÕÙUíÒoFÖğ>ÔëKàãĞlŞÇOèØgÚkİÚéoUÅS?½N<ÊûEXÑXOÅcáÄNÉÇNÕÓ_XlfOõ_XŞaîÚ^ùå]Xñõ]ãæ^âßgwé{oyuçógÚŞ^áØfîÚmoâm^ñaRaTP]SZe_}óÿæİààÖÖÙÍĞÙÍĞÚÕÛçñ|hZXMJLDEHBFIJPUxèãÌÉÆ½¼»¹¸¸º¹½ÀÂÍÛéWJ@:40.,*+*+.28.( "+)DÍÇ­¦¥ŸŸ ¥§ª±¸¼Ğãì[OJ>2-&#-1Lƶ¬¦ ŸŸ¡¢¥«®´½É×ìdUQK=3-& $,9]Ë´©¥¢ ¡£¨­°·ÂÍÜïmZVN@6.(  &,6Y´«¥¡ŸŸ¢¥©­²¹ÄÏŞùzcWSJ=2+%"*3C༭¦£ ŸŸ¢¦¨¬°¹ÄÎØétb]^VH;1+%  $+8T̺®¨£ Ÿ¡¢¤§ª®µ¼ÆÒŞöqibd]MA8/)$!!!"#%*3FÛ¾³­¨¥£¢£¥©¬¯µ»ÂÏåmenzzgUJA:3,'$"#%'*.5BnÇ·®«¨§§§¨«®³¸¼ÂË×èóóíêøiXKB;5.+('()+.3:E_оµ¯¬««¬­¯²´·»ÂÌÕÙØØÙŞïk\SLD=70-,+,-.26FTıÒĽ¹··¸¸··¹»½¿ÁÃÆÈÌÏÖİæôo_TLF@<96321258;@IWzÛÍÇ¿½¼»º»»¼½¾¿ÁÃÆÉÌÏתê}h\SLGA=;876679<:8888::741../14:@IPcèÑÆ¾º¸··¶µµµ´´µ·º¼½ÀÇĞägUJA;60,($ "'.;TÚŽ¸´±¯¯°²´´²¯­¬¬¬®°µ¼ÈâWF?<84/*#$7Ú·­««¬­­­¯´¸¸µ®©¥£¤§¬±¹ÃÜO<4//.+%,i¶«¨¨­·ÈâÖĸ­¨¦¨ªª¨¦§¬µÃÏĞÚı^]øîP4"'Å—œ¹,%K¬Ÿ¡«Âܹ§Ÿ¡­¾Í¾²¶¿ÈÀµ¶Í:#¼“œ;)¹  ­ÁÖ¿¬¦§­¶·µµ¹Ê˹®­¿?*"## #Ÿ²Ú««¶½¯­¯³·¯ª©­¼Î˲­°¾\=7,%(¡“º"!ï´·µ¯§©¼Ë½«£§´Òá½µ±±¸½ÓI5'!$Ÿ“É)ʼܽ¨Ÿ§İN½¤ªÌü®¯½¼¹¸ÈC1)%" ¥’•µ-.d»ç4K®¥°Qn¦™›­×ɯ¯ÚCÿ´®ÅD<<0 + +´—“›Ÿ©["1ËÇöœ“š¨¶¶­Î39ï´¶uÚ¹½> ­––›•‘;@YG0(/ݧ¡¤Ÿ››¥¸¾Ãm92NËİNDG3 +/Ê­“”œ¬µºG-+=½µ±¤œšŸ§©¯È=0;>526<5%'5e«›™¢ £ºC9UÎõÚ¯ ¡  ®rB>/&#).' +.8Ȩ¡¤¤Ÿ¬Áö»Ò䨨«§¤©ºéZG2*-/*##'-CƯ«§ Ÿ¤¬´·½ÎÔŸ±°®«©®¼Ï_E>::93/-+)&&&(+.9IîÆ¼²®¯³¹¹¶¸¸¸µ°±³µ¶»ÇÍÓèxVNLF=762-,,,,+-3:APØÀ½¼º··º»»¹··¸·¹¼¿ÀÂÉØîxu_NJIFC?;<;85479;>DQayÙÍÊÈÇ¿½¿¼º¼¼½¿ÀÄÇÌÒÚåïg^\PMJIIGFBAFCA?BIHJQ^~øæÔÍÌÉÆÄÆÃÁÄÃÇÊÈËÏ×İÜåp_]_]VTPLLLMLIKMNPUUZgsyyíߪÜÚÚÙ×ÖÒÓÒÖßİßêìsÿïokhowji``ijllikkgoúoxøyüóïïûöîèêùñíõõôû~ÿşuoyy~|nüøv~zwznnxÿxt{ûı|ú{pşú{ooş~zvtüòøú{ozş|}ÿşz|ÿzwïí÷÷w~şxòôynsñòüuvóúùîxkx÷ú{}óñ÷ôóü~öı~öşwÿïò}øîÿwÿop{vyyzøô|soyôü|øı}{}òôôüúımşôÿıüù{~ôï÷ûñtikwî}kml{ş{~r{}s~voxuq|y~ü|ïï~vuöşpıı|ş}ğôt}øòñ|su~ïíúuwÿxüìüüíúúóïîü{~ulmnw÷îğ|{ü~|yñèşsüroıûû{nsòørÿíîürnsşíìz|ó÷ùöñ~mÿíôñûppluÿsüô{~ğíøib|ôomxpløùus|ñsk}}rrôòyru~~vnrzıïwlû{{ïôéäïñöğñ|ñòvúíîûqú÷wìèvdoóo{ïıús||cmüüğøzpnöøxõş{õïêût{rüúıêïüÿrw|unwõòëéêò{ùö}omzikûxøroñflîkorlómk|i{şqùøïş}ënnğ~îéùôùõúv{jj~prttútqîéîõêßìøåâëõğı_X[^Z[lrk{îíşsûütu}öñèİÜÙÖÔÙŞàèóxibZUPMQQOUY]kşéèŞÕÚßÛÖÕÓÌÊÊÈÆÈÎÓÚø]SLGA>=;:=>BKYíÒǾ¹´³²²µ·»¿ÅÍ×âò]I<2) !&6¾¦œ˜š¢ª³İ:9OYÔ¯¥£¥¦¹/ V˜•‘­½8&);³Ÿ›—”™£®é+ +"wŸ™š——¨ÅÉ6#'3~®¤šš£­Ä=.' >­ ›š¨¸»A-19AΫ¤š›£­ÇC1( 3³£š™¤±¶H125>Ö­§Ÿ™›¡¬ÌG2& +²¥Ÿš™¤¯³L/859ήªŸ™›©Æm:(# N¯¥šœª­¼:;:5S¼­¥š£²ÍK.& (¾¬ŸššŸ«®k9=1=Ó¸ª ›œª»×:)' *¶­ šš¢ª­W>F1>ȹ­Ÿœ¬¸Ó8*( -¹­šš ©­]BA/DÔ½« œœœª·è6)$ .º«Ÿšš¢§­[N?0H×¾¬ œŸ©´ä:,' Ùæ«œœ¡«»ÄJB_Qä¶­© Ÿ¢¡ª¶Ì7' 7â°™˜–”š ª¿M;14Dü¶©£œœ ¶Z! +79£š™”™›ª¹ß4589Õ»¯ ŸŸ®Å. /*³Ÿ“–™™¥®¹BBB8àǼ§¦¤Ÿ®¼L ,%T£ª™—œ˜¡««ëX÷;oÆÏ®ª­¥«ÁÌ'!-(¯­¦˜›œª§´ëÅ]TÃ×¼®³­®ÄÙ2"+)в­ŸŸ§¨®ÁÀÏçÇÇ´·¶²Ğï:' /'ß»¸ ¦¢Ÿª§­½·Ç̽ʾ¸¾º¼ä_4"*$ 1)çÀ¾¤ª§¢­©­¾´¿Ê¹È¿¸Æ½ÃZZ/$,'(2-ÏÉ»§®¨¦¯ª°½²ÂÁ¸Ë¼¼Î¾ïSG&,*("7+?Äã®­±§®¯¬½·¸É¹ÀÆ»ËÊÏ\O>/*-'%-(/B;̾¼«¯­«´¯µÀ¸ÇÍÁåÕÕUVA3..*)-+2=AÛɼ±³®¯´±º½¼ÇÄÇÖÏí_W?=2.4-062EL_ÆÅº¶·³¸¹º¿¿ÂÇÇÌ×èdK>;1/3-286MU{ÁÇ»·½·¼¿»ÅľÉÁÃÏÌõTG;7/0/.88@daÊÀÁ¸¼¼ºÂ¿ÂÊÂÅÇÁÉÎÒbNF:641359?JgØËÀ½¼»¼¾¾ÁÃÁÅÄÃËÍİVJ;35--2.9BEÔÎĸ½»¼ÉÊØmş`Z~píÔØÎÉÎËÍרéhgTNPKMRP[eiïæâÙÙÛ×İààòûzhheadegkrw}òğíçêêêíñ÷}nh`[YUTTSVZauíÜÓÎÊÇÇÆÈËĞÛíeSLIDABBCHLQ_úä×ÎËÈÆÇÈÉÌĞתêûnb\XURQOOPPRVY_hxïåİÙÖÓÑĞÏÏÏĞÒÖÙßè÷oc\XUQPOPRUY]dnüìãİÚØ×ÖרÚİãë÷xkc^[ZYYZ[]`ejpyıõïíëëêëëìíîïğöøûşıış~}}zywsponmmnoqtyÿúôïîìêéèçèéêëîğõûş{xvsqrrqsux{}ıûúøø÷õ÷öõ÷ùúúûıÿ~|yxtsrponmmnnooprtvx{}şıüúø÷÷øøùúúûşÿ~|{yz|zyyz}}|~şşüúùøöõöõõöõö÷÷úûüış}||zyyy{zz{|}}}}~şııûúúùøø÷øùùúûüüûü~ÿşşÿ~~~ÿşşşş~~~ÿÿ}||{{zxxyxwwwvuuvvvwwwxyzz{|{{||zz}~şşşüûûúúúùùúùøùúúùùûûûüıüııüışÿşşüüıûüÿüûüûúúùúùúüûûıışş~}}|||{|}{|}}~ÿ~~~~ÿşÿ}}{yxxxwvvwwwyxxyxy{yy{{z{}}|}~şşÿşıûûıüüıışşşÿıüııüüüüûúúúùúùøúúúúúùûûûûûııışşşıÿ}}}}~||}}}}}|{|||}}}}~~~ÿşşşışÿ~~~ÿÿ}}~}~~|}}zzz{{z{{{|}zz{{{}}||~}|}}~~}~~ÿÿÿşşıüüüúııüıışÿüüşıüşıûúùùø÷÷ö÷÷õôõ÷÷÷÷ö÷ùùúûûûııışıış~|zvuvtprooqljiiiigfedcdcb`_^^^]\\\[[Z[[X]W\aRÆ»g[sOZçdITãénº¬·¶¯¿É¹Í2('"!!)+:cÊ´«©§¤¨¨ª±¯´»¸½¿½¿ÂÃÎãX<.'#$)8P͵«§¦£¥§§¬®¯··»¾½¾ÂÂÊÚiC4)$ #&/JỬ¨¦¢£¥¥ª­®´¶º¿¿ÃÈÇËÛêP=0'% &(4PÖ¸¬¨¦£¤¦¦«­®³·º¿ÁÃÊÉÍçëN=4(%"&(/Mê¼­ª§£¥¦¦«­®µ·»ÃÃÇÏÌÑêèVA:+()  $),=lζ««¦¥©¦ª¯¬³¹¶ÂÄÀÑÌËçİşKE8-*'!!# &+.Ajγ­¬¦§ª¥¬®¬¸¸¸ÊÃÆİÌÒûØbNK82+('!$##/04TÖ¹±®¨©ª¨¬­®¶¸ºÇÆÇÒÎÓÜØü^P>:/)+%#(%)/3A~ǹ¯¬¬©ª¬­°µ¸½ÄÅËĞÌÖÔÑîõ`I?9/,+')*'/35MüË»³¯®«®®®¶¶ºÃÀÉÍÆÏÔÍŞàçNTE78.-/)-.-9:A÷ŞÅº·´²°´´¶¼»¿ÉÂÇËÈÎÏÏŞqu^DD?682/4/496CIMêÛÊ¿½ºº¸º¼»¾ÂÀÈËÄÍ×ÇÖxÔwT`JGI???=;JDKb\ëÔÔÉÅÃÁÁÁÅÀÂÍÅË×ËÙŞÍâüëi\[RLVPFNRFJSHJWJJbVWúoñØŞÕÊÎÏÇÊÕÊÈÚÕÌçxÛë]hëa\û][lWZdVVX\UOn[OæiSßïjåİÛíÖÑîĞÑâÏ×ëÜæväé`sñ\_ù^ZêrTíßPcãUZùvb_åiYİğ`ñåurÙíeØß`ŞÚ[òÚ_íÛfwäxgáûTßîQáäU÷âW]ÙwVÛèUâŞ]râj^Ûç[Şåcßà~qíçkëí_ëélëÿu~\donşıétrèwúîolûõjrírıäòñïüıoöğnú|k|hoíòóoúş^{ëùôsni~éeñê^âßfèõ_÷ñu{üõlsèzz÷léáşïürsr~htïtõòtyxüuyâ}dğ÷tõúïşrësnîyù}}énmóunıëìvÿïmşînvu|}uì÷yşq|wxûrwÿöù{òómmûz}ñùÿzú|zíÿyşsú|xız}tyòı{ğùvÿ~~x}ğ|yú|şøøú|y~~yùûuûûûşvúzpú~y÷vyôwøùwğ}zùsy~şúvıõzÿ}wş{}õ{uş}yyûûzöı|øúöù|şôıxõş}úsıúu}}øxuòw}ùw~{~|rsÿşyúz~úrü÷}øûıüÿş~ü~}ûüöô÷ú~ôûv}yøøw|wûøwş}z}~÷û|õüq|şşü|ú~vıû{zzz~|ıú{~ù}zúÿzwx~ruÿtıştûxzîı{~}úş|y|şöúy{üöùö÷÷ùr~üuûù}t|òşı÷ş}yøùsüğ}tıø}{}|ûzrüwsõørr÷ôxnıóyúüs}ûøöxt|vsyş}wıùúskéåşğüyóùz{pÿì|túóuxğqnyòğvúùñìyşórnıúüüüxlş}múøúùtøîvrûşoúéovîkjúõto÷ñøüúûlrïpnûvtşŞáuôñjcjnf`iëğsááoúãıdsîmgymo}ïæïòúüõrîéjxømùù~ìíêïøóru~nyøîëíëìïöøóykuxhltrzzùöqûõn{øzypş{m÷õ~}yörnò|wvrn\`k^fitşgz÷ûèêáâóåáäçèŞæïãèëñşòt_`gidguk`][XTUUQXen÷ŞÍÇÆÄÁÁÇËËÎÕÚØÖåêàødULF<983//16:Iåɼ´¯¯±´¶¼¿¿¾¼»·µ·ºÀÛB0(/Hµ ™œ§©»@0/<:L¯¥¤¢Ÿ©´´ÁeCEA-$#6X´¯®¦¨¹vQY--'.£¥œ¡±%-+6¹˜ ¨¨É:8ú°³°¥©¹öMS6,,Ù¥£ŸÎ!%.,;´œ›¤¥©Æ=:Dzº¯§©¹\VQ1,) ¾§¢Ÿç!',+@³›£¤©ÅB>Í·¼±¨©·gON3)$ µª¥Ÿİ%./+: ¤£¦·o?ç¼Ä¹­¬²æLS:,'?­«§¤¨>-64:K¿¥¢¨ª®¶ÊbÒ¿ÆÊÈÀÄnMUL<1,+)!,Muçå˸½áíàÑÄÆÁº¼¿ÄÌÇÂÆÂÀÅÄÈÓÛ÷]_ZU[SOMA;529<;<=FhíâÑÊÂÀÉĞÏÑÖßİÍÉÉÇÄÄÉÏÎÎÚåÛÜééé~bXNF?<>?FNSZbmòéæÜØ×ÔÑĞÎËËËÊÆÆËËÇËÎÍÎĞÔÜétaYOJE@?>==>?AFJP]lòàÚÑÌËÉÇÅÂÀÁÀÀÁÄÈËÎÛéx\PJE@>=<<<>@DINWhøçÛÒÌÈÆÄÂÁ¿¿¿¿ÁÃÆËÏÚínZOJD@><;:;=?DIOYjîŞ×ÏËÈÅÃÁÀ¿¾¾¿¿¿ÃÆÌÓŞ}^PID?=;:99:<:75668;=@IVlîá×ÏÌÊÉÄ¿¾¿·«§­²°µ½¿ÊùUI?91,)(,-,,.5?VİÉÄÂÃÆÁ¿¾¸´²®¬««¬­­±ºÊoJ8,$#*5XÓ¿±®°µ»¿ÃÍÌ»°¬©¥¢£¦©¬´Åb>0%!+>Í¿¹¬¬°¶¾ÀÈàʶ­¨¤ŸŸ£¦«¶ÏR<-!+=ɼ½¬©±¸»½Éüȳ­¨¢œŸ ¢«¸ÍW9*"$8øÂ¯§®µ°³¼Ç¿·µ­¦¢Ÿ ¦ª¯ÉL>2&,7Hׯ§ª¬©§¬ºÅ¾¼¼¸¯§¢£££§°Æä`;-*($"%/O¼±´­¥£¨³¹¸¿È¾±©§§¥¦ª±»½Ê]D<3*" (1:Jȯª«­©¥¥¦¤¢¢¥§¨ª®µº»ÀÓgG7* (/F¾¬§¤ ŸŸŸ ¤¨ª­±¸¼½ÃÔY=/%"*7Ù¯¦¡››ŸŸ¡¦©¬¯µ¼½¾ÆÜP:,!#+<Æ«¤Ÿœš›Ÿ¢§ª¬°·½¾¾ÈêK7*&-A¼©£Ÿ›š›Ÿ£¨ª­²º¿¾ÂĞiD4)'/M·¨£Ÿ›šœŸŸŸ¤¨ª­±·ºº½ÆÚQ:,!")8ص«¥¡ŸŸŸ¡¤¦¦¨«¬®®±ºÈg;+$-@ε«¥¢¡ Ÿ¡¢££¢£¤¦¦§ª®·ÇW5''2RÁ°©¤£¡  ¢£¤£¢£¥¦§¨«±½ÙB-!",=Ø·¬¦£¡  ¡£¤£££¥¦¦§ª­¶ÄY5'(4Z¾¯¨¤¢¡  ¢¤£¢£¤¥¦§¨¬³¾è=+$.Bϵ«¥£¡  ¡£¤£££¤¦§¨ª¯ºÍK0$ )8s¼®§£¢   ¢££¢¢¤¥¦§©­´Âi9)%/Kdzª¥£¡ ¡¢££££¤¥¦§¨«¯»×B.""+<޸¬¥£¢  ¢¤¥¥¤¥§¨¨©«¯¸ÉQ3&#.Jů¦¡Ÿ Ÿ ¢¥§©ªª«­­­®±¶¾ÙI2&%7İ´¨ ŸŸ£§«­¯¯°³´±±µ¹½ÎW9) /Â§š—˜§¯¸ÇïŞ½®¨¢£®ÀS1$",ü¨Ÿ £¤§±ÆË½´µ²©£¡¢¢£©³ÃåL6.,*&(D­ŸŸ ¡¤¬½Ä¿ººº®¨¥¤¢¡¦®¸ËP5-,("!-aª ¢¤§±ÈÌÀºº·«¥¤¤¢¢©´¾ÙG3.-)#,\«ŸŸ ¡¥®ÁÉÄÀÀ»­§¤£  §¯»ÕF2,*& !.ü¬¢¡ ¡¤®¾¿¾Áú¬¨¦£Ÿ ¨¯·ÎG3-*%*J³§¤¡Ÿ¢¬¶¸»ÂĹ­©§¢Ÿ §­³ÉI3-*$ "/ñ¶®§¡¢¨­®±¹»¶®­«§£¤¨¬°¿Y9/,&"! +8W·ª¥¨¬©­·¿»²¸¸¯¬ª«©¨­¹ÍöF1/0/./5621/-,+-/3´»8=«¬;2߸ÃLH_UWb]jîÛØsuİoXS_ÛX?SİìYgÙëaınVeñ_P^ígUğÙt^wäél`kêİòoßÜwoûóïmnßäkíÛãïwüz\ayrk_öÛwiãÙëcoïobmòïğ×ÎÚŞÕØÜãòïtevzngYTXOGNj[NdåêéİÌÉÖĞÆËÔÖÑËÒÜÍÌÛñl]M?<:534238SÊ¥˜œ«¯«¨¯¼¬¤©°¸±µF' +ıŸ¤¨¨Y/i¼¬š¡°µ®«³µ©¦ª³½´¿6$  \šœ§®ªİ/¿­ª£œ ±¼±©«´®ª«°·µ¿>& +¤—œ¬µ¸-"[ª¡¤¢£¬¶·­©®¯¬­±¸¸¸l,! +8˜–¡·¹Ø",¶ ¢ª¦¥®½¼«¦¯¶¯¬¬µ½ÅG* '—‘ ¾ÃÇ''¯Ÿ¬ª¤­Â¾¬¥®½´­­´»ÁX.#  ¯•¨İèAL¤šŸ°°«®¼½«¦­»¼°¬²Âc<.% ¡•¬DE/%Ř£¼¸°°³±©©¶¿»°¬¯¿Z6,&! £•¬>>7"É—£Ğɱ®²µª¦¯Ëγ¨­ÄX<1'  ɧ>8?#O•Ğ_µª®¹¯§¬Ã产§»P=9.#Œ•¹-27!'¶™—¨I`¯ª°³ª¨¶ŞÎ¯§¬¿k?0*&'" ¤Œ’±0.-$¹—“§<@¿¹½²£®Zm¹¯²»º¿<$!(,& + ˜™½:/.£“–±=N]O¨¯yìɽ²°µÛ/&&'($ .’ŸË?3<–›±øÚE;»¤ ¡­¿ÍnÚ±­»ù4('$#& +>ªŞÌBI™ ®·Ç89³£¤¤¨±ÍGè°´Éç@-"$& +¶—­µ¾.Ë£©­È3<µ©¨££­ÛBåµ¹ÄÈN, ! ¨™ª®»)㢟 ©Ö2H¸¶® Ÿ«ÄøÇ½ÓÙÎJ-'%  ¨”𡦷'欣  ¤Å=jÊǯ¤¡¦¸Æ½Ñ_×Ín:(%" 蘚Ÿ ¨D5¿®¥Ÿ¬üh×öÁ«£¤­µ¶É]îÌİ=**) §¬)%<Ö¯§Ÿ³ÂÃeﺮ§§««²àjêT>0,+ ×¢¤Ÿ›Ì 1±ª¤›•šµ8/;<,)D®¡¢¨¥¨ÀİȽÌMHçÊş<,# + `°®ª–˜©[:@@0*/Ü«¢¡Ÿ›§¿XD?<736>D6$.QìѰŸšœ§¼ÏÚb>0/?É®¦¡ŸŸ©¿H5//.,,,+$$<àŞ÷Ä­¡£®¿ØİãXC>MĬ¤ ¡£¦ª´ÏC2../0.)!&:[eo˲¦ £«ºÖÿog\Unį§¢£§¬¶ÃäJ:3//0/)'GËÀ¼µ«¢Ÿ¢¬ÅNBImÓÌ÷¬¤ ¢©·×O@:60./471%3z¹¶¯¨¡ «ÅI:@oȼ¹·¯ª¦¥ª·ä?66887310.( +?࿸³®©¥¤¨³ÎMDPÜ¿¸´²±¯­­±½òC::>BA=94.("#+9W̼´®«¨¨¬´ÇkOWèȼ¸µ³±¯¯´½ØSEBFHFA=82,%  &.@èÀ¶¯­«ª«°¼Ö]SeÓ¿¸³±°°°³¹ÄæOEBDGFA;5/*#!(4O˺±­«ªª®¸ËbNTêŹ³°¯®®®²¼ØN?>AEE?:4.)"$/OÄ´­«©§¨«µÍN?CbÇ·¯¬«©©ª®»éB759?D?:4.+$ .W¾¯«©§¥¦ª¶ãB;Au¶¯¬©¦¤§­¿S;67<><9862,! 6Í´®«§¢Ÿ£®Ú;4=aȼ·¯¨¡Ÿ¡«¼qE=:757;BH?2'$=Ç´¬¤Ÿ¬ÏC:=Mhܾ­¤ŸŸ¥­¶ÂàG4/5DdcF;6/&)b¹¯ªŸšœ©Ê@=KIDUÁªŸ£¨«­µ×@:BTcXNON>.",yµ«¦Ÿ£µÛaM?9>ض®ª¦¥¦©®ºÌ~[VJBDD?5,& &0c½¶¬¦£¤«´¹ÄûUUûÏǺ¯¬«¬­¯¹ÌŞgL?;;;:8.(%"$'(,1<;??BKOZkräâìØÓ×ÖØØÕÙ×ÓÔÓ×ÑËÍÎËÍÒÔÕÚñqøøvc]jnjmnlehtneglkrngtwkberhgvqidhwÿunuı{}÷÷ûø÷ùştûóıù÷óôÿùó÷ü|ûü|ùóòö~zyxty÷ü{{şø}üóüyûîøuüíõ~x~ö~ywûùtşï÷÷íôwsü}vúxqûôõõöüwr|öú}}tjozptıyrzôø}~rqx}úşü|tü~rúüoşòüy~÷~uzûù{z}{öøxùïınuóùxx}ùöúzşôùşõôştpyşöîÿuìïuíìsmvşúürúîtsöêëslêìp÷ííùbjéívvêåmjîönnõøbnâxcuïñ_fì{hdõßdXøß}]oâ|_^øä]fêv~vîÛw]kâŞ]SíÏÛUWÍÍULîÔmSlßÚãøßÖÜõçÕïcyíëôlhãİ}{ííwiûïefâÖôMYÛíh^^ùòëó_U\ğvTQ[mêçh_æØïchêä{mdfíçpbnéáów÷îğòó÷ü÷ñööôõöğëòsoöåësnöéìıqxøöùøóğùy{öñûtr~óô|wıùûıı|ieõÛŞlW]ıåîg^yÜÙù[\üãõ`[nééôü|tnnwüısms~ışztw}ÿ}z{}||}~ÿşüşıùøüşúøùøøù÷ö÷úú÷÷÷ùûúùùùüüüıüûûüıÿşüÿ~}|}}}ÿ|{|{{{y|ÿ~~~~}~ş~||~~~}}}}}}~}{{{{}}|~~}~}|}}}~~~~şÿ~}~ÿ~~ÿ~şÿ~şışÿşıÿşıı~}ÿ}}ÿ~~şş~şııÿÿüúûûüııüı~ÿ~|~~}ÿ~||zyzy{~}{{ıû~|~üışşüüşıüıûûÿşııÿ}}~şş}|}~~}}ÿ~|~~}ÿş}ÿış~~şııÿ~şşş~~şşış~ıüışııış~~şş~~~~şş|{~~}|||}{yz{{zyz{zz}~}~}||{{}~}}~~şıÿşÿşüııüüúüüüıüııúúûûûúúûûúùùùüüûüûüıûüşşşşıışÿ~~ÿÿ}}}||}}{{|||{z{{{{||{|}|{{{|}}}|||}}~~~~~~şşşşşşşÿÿ~şşşÿşıÿ~ş~~şÿÿÿÿşııÿşşşüüüışı~}şıışşşşÿ~~~~ÿ}}~ş~~ş~ıû{{ùøúü~şùøùüş~şúúş}|~~|}|zzz||xxzxyzxvvvwvtssrtoptn~hï½¼[8:VËÅŞzàxOXÛÍÁ»Í@6?ë¿Âl@?^ÉÅÜPJWoô]UʸÃS>EoÒØbFLͺ¹ÈO;8O½»Y55VľÕGCʬ­Ö2/G˹¼a:;m¿½ÏVHN[ahnxóîw^X[bòŞìcONâÀÀäJIXlàÌÉ×^RfÛĞÛdOPcåŞíyûããeT[ûáãv_føéórõéôõøkgvnmïèÛÖïköâİèe]lêàğ÷oY_èØß^NQdæÛßúgekîŞvRWñİßu[dõÖĞvYlİÓëXOZîçëëüpîàóìñ\^wc_ïãy_pèğåê_]ïâmesşîozÎÇÜUXÖÍÚhPPdÛÙqbÿÜÙhOZlowqebvêp]zêöwozwõñgxçùìâşkjjéÖá^Uoãߪ}\_ïØİïóòöù}nuö~omd_n÷piksíôfad÷ØÒÏÑÓÚ}__ccb_déßííöxrllom^\cbc}èÿùïcei_acxìëçèäåîûíİç{ïŞãmvåz`huiY^y{õçæëíîwpóüitëêôêØÙèäâïpjzlZZe^RYmcY_{jZnîooâ×ߪÎÍÕÖÏÒâçÛêtùÿ_UXYNMRNIIKLKR^cyà×ÕÎÅÄÅÀ¿ÂÃÂÇÍÌÏßìqZOHC>::8679:?GNfÚÊÀ»¶´±°°°²²´¸º½ÅÍéQ?6-&!'.=ğ½­§¢ŸŸŸ ¥§¬¯²¶¶º»¾ØuI2)%1=Úµ¨¤ ¡¡£«­¯´µ´²³°±·½ÚI8) )/h½®¦ŸŸŸ£§¦¯®®µ¯¯±²³ºÏù<-$$(:Û¸«¤Ÿ¤¢§­ª¯¯­±²³·ÂÏR5/!$(9ß¹¬£ŸŸœ¡Ÿ§ªª¯¯¯µ·¹¿ÍÙJ61$#&4hů¦¡Ÿ Ÿ¥©©®±°¸º»ÅÌ×Q=4*  $+Kí¸ª¥ ŸŸ¢§¨­¯°·¹½ÄÊ×lG91($&3QÓ²ª¥ ŸŸ ¥§ª®¯´¸¼ÀÇÏà^F82( $&4OÔ³ª¦¡ŸŸŸ¢¦§«®°¶¹½ÂÈĞßfJ;4+"!$&/Kí¹¬¨£ŸŸ ¡¥§ª®¯´¹¼ÂÊĞálN>7.%! #&,A`¿¯©¥¡Ÿ ¡¤§©­¯³¸¼ÁÆÏØè[K=5,#"%'1Iõ¹­¨£¡  £¥¨¬®²·º¿ÅÊÑÜì[G<4+#"&'8Lß³­¨¢¡  ¤¦©­¯´¹¼ÀÆÊÏÖßoN?8-$#&'3Oö·­©¢¡¡ ¤§©®±µ»½ÁÇÈÌĞÒãZH;1(!!!(+@j®ª¤¡ ¡£¦ª­°·º¾ÂÃÅÈÇËĞŞWD9.& #)/Lß¹¬§¢¡ ¢¤§¬¯µ»¼ÁÃÁÄÂÂÆÈÏcK;/)*,@Ú¿­§¤¡ ¢¤§­¯´½¼¿Ä¿¿¿¾¿ÄÈØSF6-&!-/Iǹ«¤£¡Ÿ¤§©²µ¹Å¿¿Å½¼½º»ÁÅÓNE7+(,2?ɺ­¦££¡£©©¯º·Ãƽ¼·¹¸·¼ÀÆëLA2,( -4=Ä»­¥¥££¤©«°¼¹ÄÈ»Àº³·´´º½ÆßWC7.+$ !16L¼¸«¤¤£¤§¬®·Â½ÉÇ»½·²³²´¸¿ÆİTI:3.)#"%2:_¿²©¦£¥¥§®¯¹Ã¾Ë»»³²±±´¸¿Æ×^N@:5.*%#$.=NÀ±¬¥¤¦¦¨®³»ÈÉÉÆ½¸³±®¯³´»ÂÊëVJ>74-(%$$0Eb¼­©¦¢¥¨¨°¸ºÍËÂĺ²±®¬®°²»ÂÊvTJ>960,(# &'7Nà¶­©¥¦§ª®µ¾ÅĞÑÇÀ¹²®­¬®°µ½ÅÏqOF>;95/-(" %+:UÍ´¬©¥¥§ª®µ¼ÅËËÄ»¶¯­««¬¯´½ÈÚaOG@><:73.)%  (.7gǹ­«ª©¬°·½ËØÏĞĸ³­ªªª¬°·¾Îö]KDCAA?><5.*$  $*4EÛ½²¬ªª«¯µ¼ÇÒÜÕɽµ®«ªª«®µ¼ÌïbNHKJIONGE=4-(!"')>úé¶­°¬«³ººÈíÓÖܽ¶³¬©ªª¬±ºÀÎùkf^oózìíZJ?5-(#%,4MØÂµ²³²¶½ÅËÔŞÎÆÀµ¯­ªª«­±¹¿ÍÜæîáÕÏĞÓÔòOD9.)%!*/7õÄǵ°º¹¸ÅÏËÎÙȽ¼´­¬¬«¬²·»ÉİÒÖäËÃÉÇÈÛnP>5.*%"  $)0=OÑÿº»ÁÂÄÍÏÊÉÆ¾º¶±®­®¯²¸¼ÁÌÌÈÊÄ¿ÁÁÅ×qRD:3/+(&%##(*,9GMÕÆÌÃÀÈÉÆÉËÅÂü··²¯°²±¶»½¿ÇÄ¿À¿½¾ÄÍŞ^I?80.+(&%%&),/=LMãÆÏÎÀÅÏÄÀÊû¼½µ³¶³¯µ¹·»Â¿¿Â¾¼½¾ÁÈÓwSI>83/-+)'''',/4@OZÙÉÉÈÅÅÊËÈÇÄÀ½¹¸¶²²µµ¶»¾¾¿À¿¼»¾ÁÁÌû_O?:70.,*('')*-6995/.-*))+-/4>HOâÍÏÌÉÉËÎÎÆÃÅ¿ºº¹µ´¶·¸¹½À¾½¾¾¼¼ÀÉÏíTMH>:84/-,*(),-/3@STíÊÌÎÈÉÏÌÈÅÀÁ¾··º´²¸º·¹¾¿¼»½¾¼¼ÂÈĞ{RKF@:663-*)))+./4?MSíÌÊÊËÍÏĞËÅÃÁ»¸¹¹µµ¸º¹º¾¾»¼¾½¼¼ÂËÒçXIF?9871.-++))-05=HYæ×ÙÍÇÍÍÄÆÉÄ¿¾¼¹¸¶¶¶¸º»½¾¾¾½¼¼¾ÀÇ×öcKEF>863/.,**-..4=AFlÑ×ÜÌÈÏÔÊÆÆÄ¿»º»¸³¸½·µ½À»»¾¾¾¿¿ÇĞ×yNMK?:961..,+,-/37;D\ğãØÌÈÍÔÌÅÇÉþ¼¹¶··¶¹»»¼¾½¼¼½½¿ÆÎäi]VK@<:62/-,,**/67:IlíëİÑÎÓÒÌÊÈ¿¿½º·¶¸¹¸¹½À¿½¾¾¼»½ÄÎŞoVNLG?=:50/.-+,/349CRbüŞÕÔÙÔËËÍž¿À¼¹¸¹¹¸¹»¼¾¿½¼½¾¾ÁÊÓæjVMGA><841/.-,-387EUüÜÒĞÕĞÎ×ÔÆÁÁ½º»¹¸»¼¹º½½¼½¾¿ÁÂÃÉÏÜ{YOKD>=:532/-./138>CHVi÷ÙÕÖËÇÎÎÁ¿Å¼ººº»»º»¿¾¼¼¾¿ÀÄÈÏİòkXOMG><;8420//136:=?KbloÚÌÑÖÍÉÈÈǽ¼¼¹·¹¼»¼½¿¿¾¾ÀÅÆÇÏël`WMGB?<96420/0359=?AJbooÜÍÌÌËÌÉ¿¿¼º¹ºº»»¼½¾¾¾ÁÃÃÇÎÙãy^XRJEB=9863112359<=COZoÜØÛÒËÊÈÆÅ¿¼¾¾º¸»¾¾¼½ÀÃÂÁÄËÍÌÒïfbXNMIB?=96555448>??HS]ioí×Ò××ÎÉÅÂÁ¾¼½¾¼¼¿ÂÀ¿ÄÆÃÂÄÉÎÓÛı[WWPKGEB>;998668:<=?HRZhèØÙàŞÑÊËÌž¿ÂÁ¾½¾ÀÁ¿¿ÅÈÄÄÉÌÍÏÕãp_[RLIGDA?><:9::9;@DCGNT\}íèÕÌÏÔÎÉÉÊÅ¿¿ÀÀ¿ÀÄÇÇÄÄÇÉÉÌÒÛßçşd[XSLIHD@>>>><FPaìÛÖÑÏÍËËÈÃÁ¿¾¼¼¼½¿ÀÃÈÍÑÚåÿcWMG@;8754459>CM]òİÛÔÎÍËÊÈÃÁ¿¾½¼¼½¾ÁÃÆËÎÖßîl\PIC=87643578453135;?DRyß×ÓËÈÉÈÆÃÀ¿½¼»º»¼½¿ÁÆËÑİêoYMD>;3/1/.15;AH]âÕÍËÈÅÈÇÄ¿¾¼º¹¹¹º¼¿ÁÇÍÔçnZLC<6.+--+.2:DL~ĞÊÄÅÃÁÅÂÁÁ½»¸·µ´µ¶¸»½ÂÇÎïfTC:4-&&)().5GZìĽº»¿½¿ÅÆÆ¾»ºµ²¯°²²·¼ÀÍèWH?5-)  #$)/KÏÉ»²¯²½¾¾ËÓÑû¹²­««­­¯¸¿ËåK;7-& !*B¸®¯¨¢¥°¿¹Ä`^Ğ»·¯¥¡¢¤¥§±ÌçL4+'!"E©Ÿ¤¡šœ®ÓÍİ9/KÀ¸® šœŸŸ£´O7.$  ,¯™š š—¡Ö?Z>*0Í­¨Ÿ–“˜œ¨é,'" ()eŸ––—¦R5V8)=¸¤¡œ’’™Ÿ¦µ3 $!2ª”‘œš–¢ì.6;(/À¦›’•¤±A (%> ‘›š–¦H,1;*5² ›˜‘–¦¹9 ($9¢›š•¤I*2;*6°š˜—Ÿ©½4  (%Ι“˜š¹/(64*i¦š–‘œ¥¯~( "'(º˜˜ ˜œÅ/-F;/̤›˜’•Ÿ©³i+ +"$'¾š“š ™œ¾:9\A3Ψ¡Ÿœ–˜ ©±Ú0"! # %Ï—¢šœµJJÛL7÷°©¦ šš¡¨¯É?*&$##8´ŸŸ§ œ¦ÃïÊÌFH°¬©¢ ª®·Ü:,+'""&>µ¤¨« ©¿È¼ËKW¾°¯¬£¡§­°ºæ?4/*"$$'9À«¬­¥¢¨·ÂÀÌsmÍ·¯«¦¤¤¨­¶ÇY9,&"!&(7À¬¬­¨£©¸ÇÁÀİoű­«§£¤«²»ÓC0+'#"$$'6æËÈ·«§ª®¯®³Âɽ¶´³°«ªµÂ¿Èk>420+$"',+)+3AJ^н´±±±±µ¼¿¼¸¸¸¶´¶¼¿ÁÍî[RJ@:62/.//../5=GZçͽ»¼¾¿¾¼º»º¸º¼½ÀÅÌÛîkUMG?<:7777789=BHO]uäØÏÌÌÉÅÃÀ¾¾½½¾¾ÀÂÄÇÊÌÎĞÓÚàäî~nb\XOLJGA><;<=;;=?BEJRZ^køãÜÜØÔÒÎËÊÇÆÅÄÄÄÄÆÈÉÊËÌÍÏÑÔÖÛàäì{k_YRLHEA>>?>=>?CEGNW\gúèßÜÙÕÓĞÍÌÌÊÈÈÈÉÉÈÉÊËËÍÎÏÒÒÙÜİâæøkbXSNGDA==>=>?@DHKQ\múğãÛÚÙÒĞĞÎÍËÊÊÈÉÉÈËËÉÊÍÍËÎÓÔÖÚßäïwd[TJGC=<;;===@EJMWtîçÚÕÔÏÎÏÎÎÌÌÌÊÈÈÈÈÈÉËÌÍÑÒÓÛİáëói[YNHF?><9:;;>DINZlíáÛÕĞÎÍËÈÈÆÅÄÃÄÆÅÅÉËÌÍÎÑ×ÛİãôwdZUKEB=:;:889<@DIVlûâ×ÏËÊÈÆÆÄÁÁ¿¿ÀÀÁÃÅÇÈÊÌĞÓÔÛáíoaTJE>93/32.279>FRğİÔËÈÆÆÆÄÂÃÁ¿¿½½¾¼¾¶®¶¯©´ÁÅÔU:>A222-& '+!%07>cÀ²µµ­¯»º¸½ÊË¿Â˽¸»ºµ°´½·µÂÆÈæhOB:-' &5Hï·§¦©¥¦®¸ºÁüYàÙåɶ±°¬©¬¯¯³¼ÊÕfH?:1( *;l»¨Ÿ £­¶Ç~C=OL\¿³¬¨¥ ¥ª«´Ê`A̰­§ŸŸ¥§®ÌW=/+'$Dd¼¥œšª·½V928D=Û®«¥œ£§¬ÎK:+'$ (íίŸ™™œŸ°¿ÚC2.=DD»ª§ œ›§¨µS:.'"Lĸ¥›™ŸŸ­ÊÖN5.9MLÊ«¦¢›¥©¯ß>5,&##(}˯¡››ŸŸ¢¶Ët@4/@Va¶¨£›¨«»M9,'#&ã·¯¡™šŸ¡¤°ïIJ4-BúÒ¶¦›Ÿ«´ÅM.'(!6»®ª—œ¥¤©¾H?N2/f˽®£œŸŸ¤°¿î?)%)  !;»­ªŸ™¦§§½CNO79a¾¸°¢ ¡ ¥µØ{;($$.ä¶­£œ› £¤¯ĞqwJUÓ¾¸°¬¬­®±´¹¼½½¾¿¿½¼ÀÈĞß_QSMB=<:41430/378;E^â×ɽººº¸µ¹¼»º»¾ÀÀÄËÓ×Ùü]^[PKJKGA???=;<==>@HOUeé×ÏÌÈÄÃÂÂÁÁÃÅÆÈËÍĞ×Ûâèósjaa_YVSPOOONMMNOPQU[^fuúëäßÛÚ×ÕÔÓÓÒÖØØÚİáâæğñştulhfghabc]^`ca]biglonvuúôùóùìèíçãéõïçç÷{ìßèyüğëöuøwfguwbdopg_lü}oisynxú{qoùçó|ôúğîñââéíëâï}íğüúÿqko~vmqv|xnzuep}ifsôoes~úx{êï{êßìëäñïîûæèuşñ÷|~çõjojdbamogix}njpÿüzvt}şnıêóïçäêùçÛßîìâàïtxzna_ppju{ndjoegjkmhgr{zv|ùpüéğßâóŞŞäßİÜñüåêæùoøln~ddg_aZZ]\lg]hfnøuuûïëâÔÕŞ×רÓİààîæèÿúvqnefXU[RLMOTRT]__gvèäèÚÓÖÙ×ÎÍÎËÌÍÌÒÒÕÛÛàåìf[ZNHD?><:;;>BDOrÜÍÆ¾¼»º»»»¾½¿ÄÃÅÁÀÇÊÎÜoL@92-'$!#).;Y¿®ª¦¢£¦­±¹ÍízÛÉŹ®««­±¼_;.#!/Å©¥Ÿšš¨¬¶U97:?BÆ©£Ÿšœ§´É>)"&@¹¡Ÿ¡š›¡¬¸¸i2;EHTʧŸ ›¦¹À[,  !#8¶Ÿ›™—©³¾]/.;=DÑ«ŸŸš›£²Áö1""(Y­—™ «¸ºW-4<951.,+,.28?Nu×ʾ½½½½¼»»º»»¼¾¿ÂÆÉÌÏÑÓÖÚŞæóiWKC=731/../28>HW|ÛÏÍÌËÊÈÅ¿½»º¹¹¹º»½¿ÃÇÊÎÔÜês^TLGA<976532369=BJUjç×ÎÉÄ¿½»¹¸¸¸¹»¼¾ÂÆÊÏÖİéüma[UPMJGDA?=<;;:;=?EJQ]uåØĞËÇÄÀ¿¾¾¾¾¿ÁÃÆÉÌÏÕÜäî}ne^[XUSPNLJHFDBAAACGKOW_qíߨÒÎËÈÆÄÄÄÄÅÆÈÊÍÏÔÚßçò{mf`]ZYWUSQONMLKKJKKMOSX^j|îäÜØÔĞÎÍÌËËÌÌÍÎĞÓ×ÛŞäíøymgb_\ZXWUTSRQQPQRTVY\ajuùìåßÛØÕÓÑÏÏÏÏÏÑÓÕØÚŞâéñütke_]ZXUTRQPOOOOPRTWZ^dlyöêâİÙÕÒĞÏÎÎÎÎÎÏĞÓÕÙÜßåìõznga]ZXVUSRRQOPPQSTVY\_gnzñèáÜÙÖÔÒÑĞÏÏĞÑÓÕ×Úİàçïûwmha^][YXWVVVUVWWY[]^bhmvûïèâŞÜÙ×ÖÕÔÔÔÕÖÙÛÜßäéğúyojfb_^][[[ZZ[[[]]^`cgjms|ùïìèãáŞİÜÜÛÛÜİİßáäèëïö~xqmjgecbaa```abbcegjkmrw{ûõñíêéçåãáàߪŞİİİŞßàáåçéíòõşyplie`^\ZWUSQOOOOPRVY^fp÷êáÜØÔÑÏÎÍÌÍÌÌÍÍÎÏÑÔ×ÛŞäîåèj][[XNKIFDCBAABCFILPX`ríߨÑÎËÉÈÇÆÅÅÅÆÇÈÉËÌÎÑÖÛáìünd\WRNLIGECBBBBCEHKNT\iÿêŞ×ÑÎÌÊÈÇÇÆÆÆÇÇÈÉËÍÏÒ×Ûãî{ka[UOMJHFDCBABCEGJMQYapğáÚÕĞÎÌÊÉÈÇÇÆÆÇÈÈÉËÍÏÓØİåñwh^XTOMJHFEEDDEGHKMRY_lûéŞÙÔĞÎÍËËÊÊÊÊËËÌÍÎÑÔØÜâìıne^YTPNLJIHGGGGIKMPTZamıíâÜØÕÒÏÎÍÌÌËËÌÌÍÎÏĞÔÖÚŞãíÿne^ZVRONMLLLLMNPUY_grøêáİÙÕÓĞÏÎÎÎÎÎÎÏÑÓÕØÛßçïÿme_ZUROMLKJJJJKLLNORVY^`fokïyóİ^ºªÀuÕêwTh±¯WDrÔyD¶¥Ó;HHD99[G/6F]éMTØNe¶´¶¹äàÎNvÂÇÁǺ«¶¼®¶Å×]qF//.&#!!&',:E[Ë¿¸³µ²²¹¸º¾ºº¸°­ª§¦¦¨­·ÌN4) =¶¥¦£˜š¨ª°ì9+4?/[ª ›–’—¤½6# +,/ͤ˜š¦œœº|I7.".õN½Ÿ™””’‘›§³F' !59·–¨›£òP<0)$IÍ婚•••‘—¥­Ê/ 2,5Gµ—§ «ş<36//Õ±­£š–˜›› ±|;.  $8_­œ—¨£²T7/849Á­¨¡›–™¦¹I0,! -9檚™¥¨¦»I27C7F¸©¥¡›—›Ÿ£©¼?-(" X°£¡Ÿš—›¤ª®Ğ/&&" )NƲ˜Ÿ­±¶É5-ErúÈ­¡Ÿœ›¨²¾V/%"!1ñ¸§›œ¥­µºc15QØÈ¶¨Ÿœ¡¬»Ş<)! ,FË¯š£­µµÆ:/BÑÅÀ¯£ŸŸ¦´ÖK4'!/\🤯¾¹¿F6BÌ··°§Ÿ ¢¤§°Ú=0+% =ÎÀ­Ÿ¤´Ã»ÅJ5@Æ´³³©Ÿ¦¨©²ÿ6.-)$-aËÁ¬¢¢¬¿ÂºÃYAv¸®±´ª¡Ÿ£«­®¸Y1,-+$%<ÔÁ±¨¥§²¿ÄÉéLVÌ·±´®§¡ ¦«®³ÅH2-..)# 0h˽¯«¨­º¿ÂÅÙqÛ·µµ¯ª¥¥©­²¹ÏE3.,)#.MÜ¿¯©§¬·¿ÄÆÖpìÈ»¸¶°ª¥¤§¬±¸ËO8//.,*&#(>hı̹­¬³¼¾¹ºÆÕÖ¿¸¹º¶¬§¦ª®²¹ËN7/.,')8Oѹ°¬­²º¿¿ÆÓŞŞÊÁ¼µ¯ª§§©¬°»ÒN:521/.,)"!.BM[Ѹ­­³·µ²¸ÆááËÆÃ¿¸­¨§©­¯¹ÍM:433/,)&%2FNnɶ®¯´·µ´»ÊİØÊÆÂ½³«§§ª­°ºÎR?:862/-)"(8?I彯°¶¶³°·ÅÓÏÀ¾Ãż¯ªª¬¯¯¯¶ÇeIB=6.+)'""?½´¹¸°«®ÆN?Wż½Â½°««°»»·¶»Ê˽´¯µ¾ÉéG/'$##H®§¬®¨§°Q//?İÎÌ»®©ª¯³´¸ÂÛÚÆ¼ºº´®®´ËS=2,'#!M­©¯«£¤´B3:GRLÖ°ªª¯¯ª­½îüÄ¿Èɺ¬«²½Ëè?-'&'##Z´¯°¦ §¾JFH=:Eᝰ­¨§¯¿ÇÂÅöfʵ®±´³ºŞ;-,)#!U·±¯¢¨¿[ZI34IÄ·»°§¤¨³¸¶ÁîQëÁ¾º±¬®½İR:-%"!;ÛÀ³¤Ÿ¨¶ÀÆ[57JàÓ㩨©««®½ÌÖÛİ×½³±³¹¿ø;/*% .S˺§Ÿ¥­³¹×<8BMW~¼­«©§¦ªµ½ÆÜ`b̽¾½º¼ÖG;1)!'7T¾¨ £¦¨­¿RCB==M͹¯©¤£¦ª®¹ÏrcıäÚÈ¿ÁÎïX>/)#&+0L¾«¬¬¦§®¾ÍÉ\CHRéİij±±²µ»ÕgXJGDJ^lôÛÔØŞá÷_ULGFEHKJIIGFDDEGJNT]hûäÛÓÎÊÇÅÃÁÁÁÂÄÅÇÊËÍÎĞÔØİåëíó|plc\WROLJIHHGHIJKLNQVY^fnÿóìèèçæçèééççäáßßßİÛÚØ×ÖÖרØÙÚÜŞàãçíôûzsnkjhgfdcbbcbbcefgjmoqw{|zz}}zzyyyzz|ÿüúøööôññòòóöùûı|{ywywuvuuttuvxwwzzz{xvututsssvxz~ıú÷ôñïïîîïğñóôõ÷÷÷ø÷öø÷ôòğğïîîïïñòòôøúûıÿ~|ywwvuussuvvxxwxyyxwxxvvwwxxwwxyyyxxvvwuuwwwwvwwwzzzzzyyyyyxxzzxxyzz|}~şşşûúúùø÷øöôóóóòïïğïîîïîííííîíìîíîğğòññôöõ÷øö÷øúûúûüıÿ}{{|zywtsroponmlllkkkjiigffedccbaa``_`___]`]^mYȳÕJlfYkcLJ[[_èòßɽ¯±ÅÎ×àu\^JJ`ıñêÕÕáÜÕÛwhjTZm^nmlçciê\jqe{h}ui{lıvrîuryuszìñøôû~}ü~|ş{||zywvussspoolmljshwwj¿´ÂÈÃçeÚ_CKL=HmN]lfdNúhG[UEO[MKZZTU[iOUÈïZÓMLæfÇ»ÓÁ¶¿¶¯Íâ´Çê¼ÇÙÚËÖ`ÁßLÜVJZWHFXIBTPJ_OMXMUZKIVIJjLRğSøßN÷Ò\QØëUÊß^ÌùïÒîjùÑWcÃhüÈ\ïÎîãêØ÷mÜUåÏ[àÙíçæÛúçrşËsoÜkÙæîÔxcrÜãoŞm\ş]]ëêoïøYç|OuZZñQZmfnFğÔCØíKÍcê×_ÙRìöLÌPLÛNßçõËYÒØMÏYPòLó[rÎTÕÏİÌfØÜeÔ[dßmtZŞäfËìëËaéÌo^×ßNëŞMX_mNRËfnË\lÙwk`ßgMÑ}OÒäX`àgS×XOÕhnÒİıŞß\ÜpMÕjQİdoŞ÷kuâefømß}nâkòğoßütëphlvkhp}n^îécíâ{ığ}oíñiíáüïãêêæŞäéÛëòÙïèÖpqédYb]LXcIWtObê]kòkûxjìîçÜÙÒÚÏÉ×ÎËÜ×Ûopu]S[YK^_LhZKYLIQJLMKWU]íuŞÎ×Éž¼½»º»½¼¾ÃÂÈÒÎŞk|SHG<750.,*(''),0;Nİ¿²«§£¢¢¡¥¨©®³´¼¿¾ÇËÍë[F4+"%6U¾«¤ Ÿ¡¦«´»ÄÎÌÎÆ½¹±¯¯­²¹ÅX;,!!.HŬ£Ÿœ¤©®¼ÆÒtóáÙÆ¾¸²²²´»Çş?1(!+:ܶ«¢ŸŸŸ¤©¬¸ÈÍoUyoëÆ¾»³±´³¸ÇÑX90(%2<Ş´®§¡£¡¡©¬®¾ÇËmfáúÖÁ¿¹³´³µº¿ĞdE3,$",4Oµ«¦¥££§ª­·ÁÅÚûÜæÚÅÁ»µ´²³¶ºÅÖ_?5,$#+6Mǵ«§¤£¤§©®¶¼ÊØæpéÛнº¶´´¸»¿ĞvK<0*%#&-=^IJ«¨¦¤¦©«±¹ÀÎØí}ÜÙÏ¿½»µ´·¸¼ÄÕmM;2-' ")-8SÊ·®©¦¦§¨«°¸¿ËÛèùòÜÏŽº·´´¸»¿ËîWE:0+(#""%*1?Uʵ®«©¨¨¬¯³ºÅÓßàîóÙÌþ»·¶¶¸¼ÁËã]H=70,(%!!$&),3Eûʺ°«©ª¬­¯µ½ÈÏ×á÷ïÖɾ»¸µ¶º¾ÅÍâVF=72.*($"#&*.1;Uͺ´¯¬««­±¶»ÀËÜğíßÔÍǾº·¶·¹¼ÂÍç[J?:51.,)&%'*.38A]̺²¯®®¯°´¹ÀÌÛæéáÛÓËĽ¹··¸¼ÀÉØvUJA<9641.,))*-18>IbϽµ°¯°²¶¹½ÂË×äìäØÎÇÁ¾»ºº¼¾ÄÍİnVKE?<9752/,*+-19AOmÖżµ±°±µ»¿ÇÌÏÒÓÓÑÎÊþ»º¼¿ÆÎÛîm_ULE@>=<:50-,-/5;86579=CM\ıİÏÊÅÃÂÃÆÉÌÎÏĞÏÎÍËÈÆÄÄÅÈÌĞתçïşoic^ZVQMKGB>;9889FMWîÒÌÈÅ¿½¼»º¹¹»½¿ÃÄÆÈÊÍÏĞÓ×İõ^MC<62.,+,.3=Uν¸¶¹½ÅÏåfRKIMa×Á¸±¯®°µ»ÃÒ÷YMKN]ëÒÊËØaE8/+'#!"&.Dɰ©§©®¸ÈîPC=;=Ghɸ¯­¬®±·½ÅÏäo`bö×ÉÂÃÌëM<4.*'$""%,=Ò³«©¬³¿×`ME?>@Lë÷°¯±¶»¿ÁÂÄÆÉÉÇÿ¿ÃÍéYI@<82-*'%%'-:v¼¯­®·ÇîRJHGLWü;¸µ¶¹½¿ÁÀÀ¿¾¾½½½¾ÂÌß_ME>;851.*'$$)5e¹­¬¯»ĞbKEB@G_Ó¾··»ÃÎÏËÇÃÄÅÀ¼¸¶¹½ÄÍÒÕÚãlVOKE>6.($!!&0W»­«¯¼áL?;61-+++-/6NÉ»ºÁÜeWPV^ıÏÃÀÃÎèñàÖÍËǾº¹¼ÁÆÆÈÍÖØÏÊËÔàëõxfYNB6.**+/38Cå¾·¿ùKJY~vwÖüÂá]tÒÆÆÇ¿¹¶ºÁËÊÅÆÍÕÓÍÍÖî|ììhN>61//14322;aËÃÄÎÚáiX^ûÒÇÊÍÎÑÒÒÚÛÎĽ»¾ÁÂÂÂÈÎĞÎÍĞİêèåèmTMG=2,)+078;Q˾Ãá_jti_iÓÂÂÌŞé×ÒàæÑü»¿À¿¿ÃÊÒÏÍÏÑרÑ×ïk_SF<853//1247CñżÀÒåq\WSmÍÄÃÈÒØÙèæÔÊ¿¼½¿ÂÅÅÆÉËÎÏĞÙâáÛÜìgZNC:410../27FáÿÉÛö^TXo×ÉÅÈÏÕÔÖÚÙĞÇ¿½¾¿¾¿ÁÆÌÎĞÒÑØâæäæ÷aQE;6443/--2;T˽»ÂäYQNXûÔÄÀÉÕétéÚÏľ½¼¿Á¿ÁÃÃÇÊÌÕÚÙ×ÓÚvg\KB<4/-.2446>yÆÅÍØåø_R`İÍÊÏ×ÓÖàßÓÇ¿¿À¿ÂÁÀÂÂÂÈÎ×ßİßìïûot_JA<631/10/5@ݼ¾ÉÏİvOEUÏÃÅËÎÌÓúkàȾÀÿ¼¾ÃËËÆÆÓëçÚÖÛߨÔíZI<751022321>Ò½¿ÈÓÔæMG_ÒÅÅÍÍÊÔô|ßÊ¿¿Á¿¿¿ÅÌËÇÊÏÚéäİèüóâäU>9961../03>Í·¼È×îvLBZοÆÌËÜ^\çÆ¼¾Â¿¾ÃÍÔËÂÆÓßÙÚö^]ëÓÛfOH>5.-./.2=ົÄËİlL@PÑÃÁÄÇÇĞiWö̾¼»¼ÀÌØ×ÓÏÒßÛ×ğcläİı]QF;42/..06AóÀ¼ÁÍÜıTJWİÈÂÆËÍ×ïzãÌ¿¾¾ÀÄÉÎĞÒÕİãßú]dæÔÛgWNC<720/./5Dʹº½ÉŞfFB\ÔÆÁÃÂÅÙc]êÍÆ¿¼¼¾ÇÒ×ÚßİÜİÚàwja]ccYK?;61//48[̾¾ÄĞoTRY÷ÒÈÃÃÄÊÓÙÚÏÇÄÀ¾¿ÄÏßèî{lgo|f\`_RHCA<65667:HæËÈÄÂÇÚbX^m÷İÍÅÃÇËÍÑÖÓÌÈÆÅÄÄÊÒİêúkccamôo\YUL@:;<868>FRéÍÆÅÉÑám^\iäÔÌÈÇÆÊÏÏÏÎÌÊÆÄÈÊÍÒÜôme\\eigaWLD>;62247>PÛÆÁÁÂÈÙeUY`oæÏÆÄÅÄÄÈËÌÍÍÍÍÍÎÏÒÙàìt`Z[\YYYOHGF@=<===?K]õÜÏÉÉÎÔÜéøûéÜÓËÈÆÅÆÆÉÏÏÍÎÑÓÎÍÔßèéz^WTRNJJG@<96217BOpĞ¿»¾ÆÌÕïYR\nîÛÌÄÂÂÂÄÊÑÛÜİääİØ×ÜßãúcTMNLHGIKMJKOORSXhnÿçŞÕÕÙÕ×ÚÜàİİŞÕÏËÊÊÆÅÈÊÌÍÒáõıwg[WWTNIEA=97459>H[àÉÀ¿¿ÃÉÔğe[ZbtâĞÉÃÁÂÃÇÍÖãîúzöìäİİßéşk[QLJHGGHKNSW^mwõííéèçäææáŞÜİÚÔÔÖÕÒĞÓÖÖ×ÙÜÜÜãîúrbYTSQOMMNMMMMMLLNRW\f÷âÜØÕÑĞÕØÙÚÚİİÙ×ÖÖÔÑÒÔÖØÛäğıtmffihhghgb_]YTPOOMNOQUZdtöéáÜÚÜŞŞâçééåàŞÚÖÓÑÒÓÕ×Ûàéïúyronkgeec_^^\ZYWURRTTUW\hnxìàİŞßİİãêëçååâßÜÜİÜÜİßããåëîóúşwpmjhfcba_\YZXVUVZ^coùïëçááåæçèèëìëêèéçáßߪŞßáäæéïüxqic`^^^]]__]]`ddfjnpruyı÷ïèãáߪŞàáâçíñóõ÷ø÷ğíìéååéîõ}ogccedcjkjhegfabcglko|ûôğíêìîîîğüüğêéìêæèêëìêïıùöış{xzrljkmlklotwş÷ù}xwmiifflrıñíèçèäåéíïóüxuvtsw|{~øøøòóòğ÷úıvqrqrtwy}ıü~wvrlnuxyûôôô÷÷ö~xxuzyswrpoks}ûïìéèëíõÿvonmntv~õïìîîîğğôøõöş|}|~}|}{w{~zvuxzwxux|zyy|ıøü}|xvru}|~øù~üı{}~yx}ş|xşşz~|~ü|{~ıúöıüõùüzv}~|ÿüúüü÷öışúûòùzù÷óı~óüøûyúûøıwúö}üûu{}{{t~~{üÿ{|şzyvputty}}zÿüÿztsy{tyüwwıtwûzşúzú÷{ÿüøóüúñõôö~üı~ü|ûö~~~~ıÿõõúõ||ûw|{{úy|şıòşyñöu}y|øvuıúùûÿşşşzzş{wv}üwz|z}tvşùşu}ı{zqwú{}z{ùq{ïöôvvöüxvúúşızóôûût~ûxü}ùë~zğ÷ö}uòùzüwöøløùsúruøÿ|{îõpş|ş~myÿıüu}üû{o~ùy~ıûûrzøv{}uñôtóõ~~rx}zy}ôøvıû}øış}{ıx~ü÷÷zı{ıõv|||ğíéò{ôıv~uwúşóîÿüú|ü}nhnspÿvrûıöøzÿııüz|||û}şü{~vv}y}}yşú||}wı{u|xüú{ùûıôûıü}úüıöÿzùù~ûõúüõü{û}zı}}}{õùú÷~úûıyröüvûzûùu÷şw÷y{ó{}~võı{şrıús{y|üwı}vû|wz||z}~ÿüşşwxşx{{~úx{ı{ÿüøûşùxz÷{x~}şúü}}şış}{y~}üü|û}yşyúòz{ù}|ûúøù~şı~ü}z}|ûûúüyÿ~~ü}üüz|~x|ı~úúû÷ùz~ı|û|ıûzü}}ù}{ÿ|~yzşxxy{şz{ıÿÿş|~ûıüşz}ş}~ıüúòõ~ùüûó|y}zıı|şù÷şy|û}z~vzıwÿşuzÿ~z|ÿ||{x~ıüÿw|}{|ÿûû~{ûüúûÿùyxü{üûr{ıyöúzúz~ıxş|şñÿÿõı}xs|øòöûş~ùùüûı{ü÷z~ú|úùyı÷ıøşuûş{üx~öşú}uúzu{r~~v{wÿvsüzşüyÿzrv~şÿúüışy}|xÿûü{ÿ~~û{|x~ıx{yûú}û~ıüÿışúı~ıüú~şøşû÷û÷ùşöÿ}ûşùıÿûşõùû÷üùø~{şı}úûû÷~{|v{zyü}~ú}|wu}xqwyw|ztuwsswvtsuz|y|üıı}}û}~üıûúøööùùõ÷ø÷ùúûıÿ|{şúúÿûùıüüüõù}ı}wÿüıı}üøûııÿ~~}şşz|üış|zşızyÿ~}{x{~|~xu}|zzx|||ÿ{yxy|{~|z~ıûüıûı{z~~ş~ÿùùüùû~ış}~|ıü}ıüûúúùøûûøüúúşûş~üúıııÿûş~úü~~}}}vuzxv{ş|~ü|~|y~|xyxy|}zy}~}}|}ş{|ş}|{ÿı~ÿÿıüııüıüşÿı~ÿÿ}şş{}ÿ~ııÿ}}}~~~ııûøúüıış}}ıü~~şúøüúøüúû~ùû~üıüúıúöùüüû÷û}ıı~şÿşûş~ş}|}|{xwyyxwvwxvttttssppqtsqrrrtrpqqtsqrrwwuurğÛáşìæğğéæèßÚÜŞİßááç}fc`_afjnvzrrokloomlu|ùîîîîğñùüü|}|wwsorrturtvxzxx{||~şûú÷ô÷÷öùûııû~|ışıı~üû~}|{zy|şÿ}şûúüşûûş~|}|{~üûıúú~}}ÿ}|ÿış}ÿûúıüøøúşÿùùş~ıûı}}şş{xy{{yw{ÿ}}}{zyxwxz}üøø÷øûü~zxxyz|~üúùùø÷ü|{|{{z{şş~~şûüş~~şş~~şış}||}~~{{}}}}|{}şş|z|}~şşşüüÿ~ûúüıüûúøøüûûûúûş}|~ııüü~}~şÿ~~}{{{||zyxwxyzz{yy{|}ÿÿÿ~~ÿÿıúüüüı~}{{}ıûúûıÿ}}}}~ÿÿÿşşüüûùùûûüııüüûúûüüüışÿ~~~ÿşşşş~~}zz{{zz|}}|{||{yxwwxyz{{zzz{{z{||}~~ÿÿÿşıüûûûúùùûúúûûùúüüıÿ~ÿÿ~~~ÿÿşüûûûûûûûúúùöö÷÷÷ùûııışş~}~~zxvuttsuvvvvwxwwwvvvwxz{{|||}||}~~şşşıüûúù÷ööõôóôõôöööõõöö÷úûıÿş~}}}{{zzyyyyxwwwwxyzyyyz{||}~~~~~~şışşşşşıışıııııııışşıışşşşÿÿşşşşşÿşşıış~şşÿşşşşşıışşÿ~~~~~~~~}}~~}}~}~~~}}}~}~~~şşşıüüúûúúúûúùúûüüüüüııış~~}||}}|{{{zyyzzzz{{{{z|||}}}}}}}}}}ÿ~~ÿ~~ÿ~~~~}~şş~~ÿş~~~}~~}~}~ışşııÿÿÿşışşüüııüüüıüüış~şıııışşşşşıışşıııııııüışüûışşışışÿÿ~~~~}|{{zyzywxxxxxxyxxzyy{{|||~ÿşııııüûûúüûúûüúûüûüıışş~ÿşÿ~~~~}}}|}}}}|}}}}~}}}}~}}~~~~~ÿ~ÿş~ÿÿşşÿşııııüııüııüışüüıüüüüüûûüüüıışşşÿşÿ}}~}}}||||{zzyyzyyyyzzyzz{||}~~ÿşşşıüüüûûûûûúûûûüüıüüşşşÿÿ~~~}}~~|{||{||}}||}|{|}}}~}~~}~}}~~}}}}}}|{|}}}~ÿ~şşşüııúùùùùø÷ø÷õööõöööøøøùùûüüüşÿ~}}}{z{ywxxvvwwuuvwxxxxyyyzzz{{|~~~|}ÿ~~şıışşşÿÿ~~ÿşşÿşşşııııışışÿııüışıûüııüııış~~ÿşÿ~şşÿ~~~~ÿş~~ÿÿÿşşÿ~~ıışıüüûúúùúûúúûûûúúııüışÿ~}||{zyxxwwvvwxwwwwxxxzzxx{{{~~~şııüüıııüüüıüúúúûûûûûüüüüıışÿÿÿ~~~}}}|||||~}{}~}}}}}}~~~~ÿ}}~~ÿÿ~ÿ~~ÿşıışıııüûúúúùøùùøøø÷ùúúúúúûûûıış~~}{zzzxwxwvvvuvvuvvvwwwxz \ No newline at end of file diff --git a/time b/time new file mode 100644 index 0000000..708d977 --- /dev/null +++ b/time @@ -0,0 +1,9 @@ +#/bin/bash +# + +HOUR=$(date +%H) +HOURS=$((HOUR+1)) +echo $HOURS + +announcement="This is the W eight R N L Dee Star Repeater. The time is $HOURS, For more information please contact K B eight P M Y or K C eight O C" +echo $announcement diff --git a/voice/ARNcontinue b/voice/ARNcontinue new file mode 100755 index 0000000..a579aed --- /dev/null +++ b/voice/ARNcontinue @@ -0,0 +1 @@ +,,,, Amateur Radio Newsline will continue in 20 seconds diff --git a/voice/ARNcontinue.dvtool b/voice/ARNcontinue.dvtool new file mode 100755 index 0000000..57a5c97 Binary files /dev/null and b/voice/ARNcontinue.dvtool differ diff --git a/voice/ARNcontinue.wav b/voice/ARNcontinue.wav new file mode 100755 index 0000000..59c9e60 Binary files /dev/null and b/voice/ARNcontinue.wav differ diff --git a/voice/ARNcontinue1.wav b/voice/ARNcontinue1.wav new file mode 100755 index 0000000..8d15310 Binary files /dev/null and b/voice/ARNcontinue1.wav differ diff --git a/voice/ARNstart b/voice/ARNstart new file mode 100755 index 0000000..f483581 --- /dev/null +++ b/voice/ARNstart @@ -0,0 +1 @@ +,,,, Amateur Radio Newsline will start now diff --git a/voice/ARNstart.dvtool b/voice/ARNstart.dvtool new file mode 100755 index 0000000..2eb9a50 Binary files /dev/null and b/voice/ARNstart.dvtool differ diff --git a/voice/ARNstart10 b/voice/ARNstart10 new file mode 100755 index 0000000..fe78bda --- /dev/null +++ b/voice/ARNstart10 @@ -0,0 +1 @@ +,,,, Attention, The Amateur Radio Newsline broadcast will start in 10 minutes, diff --git a/voice/ARNstart10.dvtool b/voice/ARNstart10.dvtool new file mode 100755 index 0000000..e696850 Binary files /dev/null and b/voice/ARNstart10.dvtool differ diff --git a/voice/ARNstart5 b/voice/ARNstart5 new file mode 100755 index 0000000..f57096b --- /dev/null +++ b/voice/ARNstart5 @@ -0,0 +1 @@ +,,,, Attention, The Amateur Radio Newsline broadcast will start in 5 minutes, diff --git a/voice/ARNstart5.dvtool b/voice/ARNstart5.dvtool new file mode 100755 index 0000000..4838b68 Binary files /dev/null and b/voice/ARNstart5.dvtool differ diff --git a/voice/ARNstop b/voice/ARNstop new file mode 100755 index 0000000..6138592 --- /dev/null +++ b/voice/ARNstop @@ -0,0 +1 @@ +,,,, This concludes Amateur Radio Newsline. The frequency is available for use. diff --git a/voice/ARNstop.dvtool b/voice/ARNstop.dvtool new file mode 100755 index 0000000..cc302db Binary files /dev/null and b/voice/ARNstop.dvtool differ diff --git a/voice/ARRLcontinue b/voice/ARRLcontinue new file mode 100755 index 0000000..f10e802 --- /dev/null +++ b/voice/ARRLcontinue @@ -0,0 +1 @@ + American Radio Relay League news will continue in 20 seconds. diff --git a/voice/ARRLcontinue.dvtool b/voice/ARRLcontinue.dvtool new file mode 100755 index 0000000..7ccc666 Binary files /dev/null and b/voice/ARRLcontinue.dvtool differ diff --git a/voice/ARRLstart b/voice/ARRLstart new file mode 100755 index 0000000..1a78766 --- /dev/null +++ b/voice/ARRLstart @@ -0,0 +1 @@ + The American Radio Relay League News will start now. diff --git a/voice/ARRLstart.dvtool b/voice/ARRLstart.dvtool new file mode 100755 index 0000000..205e7d6 Binary files /dev/null and b/voice/ARRLstart.dvtool differ diff --git a/voice/ARRLstart10 b/voice/ARRLstart10 new file mode 100755 index 0000000..e7e94cc --- /dev/null +++ b/voice/ARRLstart10 @@ -0,0 +1 @@ + Attention The American Radio Relay League news will start in 10 minutes. diff --git a/voice/ARRLstart10.dvtool b/voice/ARRLstart10.dvtool new file mode 100755 index 0000000..d6cf41e Binary files /dev/null and b/voice/ARRLstart10.dvtool differ diff --git a/voice/ARRLstart5 b/voice/ARRLstart5 new file mode 100755 index 0000000..cb92b37 --- /dev/null +++ b/voice/ARRLstart5 @@ -0,0 +1 @@ + Attention The American Radio Relay League news will start in 5 minutes. diff --git a/voice/ARRLstart5.dvtool b/voice/ARRLstart5.dvtool new file mode 100755 index 0000000..6ccc4b3 Binary files /dev/null and b/voice/ARRLstart5.dvtool differ diff --git a/voice/ARRLstop b/voice/ARRLstop new file mode 100755 index 0000000..02317b2 --- /dev/null +++ b/voice/ARRLstop @@ -0,0 +1 @@ + This completes the American Radio Relay League news transmission. The system is now available for use. diff --git a/voice/ARRLstop.dvtool b/voice/ARRLstop.dvtool new file mode 100755 index 0000000..9ce4f37 Binary files /dev/null and b/voice/ARRLstop.dvtool differ diff --git a/voice/silence1.ul b/voice/silence1.ul new file mode 100755 index 0000000..0ddd74a --- /dev/null +++ b/voice/silence1.ul @@ -0,0 +1 @@ +şşÿşşşışşıışıüıııııııııııııüııııııııııışıüıııııııııüıııüıııııııüııııııııııııııışıııııüııııııııııüııüııııüıııııııııııüıışüııüııııııııııııııııüıüııııııııüııüıııışıüüıııııııııııüıııııııüııııııııüıüııüıışüıüıüıııııııüıııüıüıııııııııııııııııııışııııııııüıüııııııııüııııüıııııııııııııışıııııüıııııüıüııııüıııııııııııııüıııııışııııııııııüüııııüıııııüıııııııııııııııışııııııııüıııııııüıııüıııııııııüııııııııııııııııııııüıııııüıüııııüııüııııııııııışüüııııüıııııııııııııüıııııııııııııııııışııüııüıııüııııııııııüııııııııüııüııııüışıüııııüııııııııııııüıııııııııııüııııüıııııııüıııııııııııüııüııüıııııııııııııııışıııııııııııııııüıııııııüıüıııııııüııııışııııııüıııüüııüıııııııııüıııüıııııııııışıııııııııııııüııııııüıııııııııııııııııüşııüıııııııııııııııııııüııııııııııııüıüııııııııüüııüıııııııüüüııııııııııııüıüııışıııııüüıııııııııüıııııııüıııüıııııııııışıııııııııııııııııııüıüüıııüııüııııııüıışııııııüııııııüıııııııııııııııııııııüııışııııııııııüııııııııüııııııııııııııııııışııııııııııüıııııııııüııııııüııüıııııüıışııııııııııııüııııüııııııüııııüüıııııııüşıııııııüıııııııııııııüüıııııııııııııııışıııııüıııııüıüııııııııııııııııııııııüıışüııııııııııııııııüüııııııııııüııüıııııüşüııııüıııııüıüııüıııııııııııııııııııııışüııııüüıüıııııııııııüııııüıııııııüııüıışıııııüıııııııüııüıııııüıüüüııııüııııııışüıııüııııııııüııııüııııııııııııııüııııışııııııüııııüııüııııııııııüıııüıııııüıüüşııııüüıııııııııüıııııııüüııııııııüüıııışııııııııııııııüıııııııııııııüıııüıııııııüııüıüüüıııııııııııııüıııııııııııüııııüşıüüıııüıüıııııııııııııııııııııııııııııışüüıııııııııııııııüıııııııııııııııııüııüşıııüııııııııııııııııııııııııııııüıııııışııııııııııüüüüıııııııııüüıııııııııüıııııııııııüıüıııııııüıııııııııııııııııııııışıııııııııııııüıııııııüüıııııııüıııııııışııııııııııııııııüııııııııııııııııüııııışıüııııııııııııüııııııııııüııııııııüıııışıüüıııııııııııüııııııııııııııııüııııııışııııüıııııııııııııüııııüıııııüııııııııışıııııııııııüııüıııııııııüıııııüıııüüııüşıııııııııııüııüııüııııüıııııııüüııııııışııııüıııııııııııııüıııüııııııüıııııııııııııııııüııııııüıııııııııııııııııııııııışııüıüıııııııüııüıııııııııüııııııııııııışııııııııııııııııııııııııııüüıüıııüıüııışııııııııııüııııııııııııııııııüııııııııışıııııııııııüııüıııııüıüııüııııııııııııışııııııııııııüııüııııııııııüııııııııüııııııııüıüıüııııııııııııııüıııüüıııııııüıüşıüüüüüüıııııüııııııııııııııııııııüıüııışııııııııüııııııııııııııııııııııııııüııışüüüıüıüııııııüüüııüüüıııüııııüıııııııüıııııııııııüıııüıııııııııııııüıııııüıııüışıüıııüıııııııııüııüüııııııııııııüıııııışııııııııııııüıııııııüııııııııııııııüııışüıııııııııııııııııııııııııüüıııııııııııııııııııııııüüıııııııııııııııüüıııııüııışıııııııııüıııııııüııüıııııııııııııüııııııııııııııııııııııııııııııııııüııııııııışıııüıııııııııüüıııııııııııııııııııüüııışııııııüıüıııııııııııııııııııüııüııııııışııııııııüıııııüıııııııııııııııüııııııııııııııüııııııııııııııııüıııııııııııııııışıııııııüıııııııııııııüııııııüııüııııııışııüıııüıüıııııııııüıııııııııııııııııııışııüııııııüüıııııııııüııııüııııüıııııııışıüııııııııııüııüııüıııııııııııııııııııışıüıııııüııııııüıüııııııııüıııııııııüııışııııüııııüııııııııııüııııııııııııııüıııııııııııüüıııııüıüıüııııııııüııııııııııışııııııııııııüüııııüııııüııııııııııııııışıüııııüıııııüııııııııüııüııııııııüııııüııüııııııııııüııııııııııııüıııııııııııüışııııııııııüıııııüüııııııüüüııııüııııııışıüııııııııüııııüııüıııııüııüıııııııııüıııüııııııııııııüıııüıııııııüııııüıüıııüışıııüııııüüııııüıııııııüııüııııııııııııışıııııııııııııııüıııııııııııııııııııüıııııııüıııııııüıııııüüıııııııııııııüııııüışıüıııııııııııüııııııııüıüıüıııııııııııışıııııııııııııııııııııııüıııııııııüııııışııııııııııııııııııüıııııüıııııııııııııüşııüıüüüııüııııüıııııııııııüııüııııııüıışııııııııııııııııııııııııııııııııııüıııııüııııüıııııııııııııııııııüıııııüııııüıışııııüıüıııüıııııııııüııüüıııııüıııııııışııııııııııııııııııüııüüııııııüııııııııüşıııüüüıüüııııııııııııüıııııııııüııııııüşııııııııııııııııüııüıııüııüüıııııııüııışıııüııııııııııııüüııııııııııııııııııııışııııııııııııııııııüüıııııııııııııüııııışıııııııııüıııüııüıııııııııııüıııııııüıışüıııııüüıııüıııııııııüıııüıüıüııııııııışııııııııııüıüüııııüııııııııııııııüıııüışıııııüıııııüıııüıüııııüııüııııııııııııışıııııııııııüıııııüııııııııııııııııııııışıüüıııııııııııüııüıüııııüııııııüıııüııışıııüııııııııüııııııııııııııııııüııııııışııııııııııııüııııııııııııııııüııııııııışıııııııüııııııııııüıııııııüııııııüııııüşıııııııııüıüıüüıııııüııüııııııııııııııüşıııııııııııüıııııııııııııııııııııüııııışıııııüıııüıııııııııüıııııııııııüııııııışııııüüıııııııııüıııııüıııııııüıııüııüıışııııııııııııııııııııııııııııüıııüıııüıışııııüıııüıııııüüııüıüıııüıııııııııııııışüıııııüııüüıüıııüıııııııııııııııüııııüışıııııüııııüıüıııüııııüıııııüıüııüıııııışııııııııııııııııııııııııııııııııııııııışııııııııııııııııııııüııüııııııııııııııüşıııııııüııııııüıııııııüııııııııııııüııışııııııııııııııııüııııııüııııııııııııııışııııııııııüıııııüıııüıııııııııııııııııüşüııııııııüıııııııııııııüııııııüıııııııışıııııııııüııııııüüııüııııüıüüııııııııüüııııüıııııüııııııııüııııııııııııııııııüıııııııüüıüııııııııııııııüııııüıııııııııışıııııııııııııııııııüııüııııüııııııııııışıııııııııııııııııııııııııııüıııııüııııışııııııııüıııııüııııüüıııııüııııııııııüüşıııııııüııııüıüıııüıııııııüııııüıııııııııııüııııııııııııııııııııüıııııııııüıııışıııüıııııııııııııüüüııııııııııııııüıııışııııııüıııııııııııııüııııüıüııüıüıııııışıııııııüııııüüııııııüıııüıııııııüııııııııııııüıııııııüııüıııııııııııııııııııııışıııııüıııüııııüüııııııııııııııııııııııışıııııııııııüııııııüııııııüııııııııııııışııııııüüıııüıııııüııııüıüıııııııııııııışııııııüıüııııııüıııııııııııııüıııııüııışıüııııııııııııııııııüııııüııııüıııııııışüıııııııııııııııüıııüııüıııııııııııüıüışüııüııııııııııüıııııııııııııüıııııııııışııııııııııııüııııııııüııııııııııüııüııışüııüııııııııüıııııüııııııııııüıııüıüııışııııııııüıııııııııııııııııııııııııııııışıııııııııııııııüııııııııııüüııııüıııııışıııııüııııüıııııııııııııııııııııııııııışıüıııııııüııııııııııııüııııııııııııüııışıııııııııııııııüıüıüıııııııııııııüııııışıüııııüııüüııııııııııüııııııııııııııııışıııııııüııüııııüıııııııüııııııııııııııışüııüıııııııııııııııüııııııııııııııııııııııııııııııüııııııııııüııüııüııııııııııüşıııüıııııüıııııııııüüıııııııııııııııııışüıııııüııııııııııııııııüıııııııııüııüıüşıııııııııııııııııııııııüıııüıüııııııüıüşııııııııııııııııııııııııııüıııııııııııışııııııüıııııüüüüıııüıııüıııııııüıııüııışııüıııüıııııüıııüııııüıııııııııııııüıüüşıııııııııııııııııııııüııııııııııüıııııışüıüııııııııııııııııııııüüıııüıüııııııııııııııııüıııııüııüıııııııııııııııııııııışıııııııııııııııııııııııııııııııııııııııııııııııııııııııııııüııııııııüıüııüııııışııüıııııüııııııııüııüüüıııııııııııııııışüüııüıııııııııııııııııüıııııııüıııııııışıııııııııııııııüıııüıııııııııüüüıııııüışıüıııüııııııııııüıııııııııııııııııııııışüıüııııııııııııııııüıııııüıııııııııüüıışıııııüıüıııııııüıııııııııüıııüııııııııışıııııııııüıııııııııııııııııüıııııüııııüşııııııııııııııüıııııııııııııııüııüııııııııüııüııııııııııüüüüıııııııüüıüıııııııışıııııüııııııııııüıııııııııııııııüıüüııışııüııüüıııııııüıüüııüıııııııııüıııııııışııııııııııııııııııııııııııııııııııüıııışıüııııııüıııııııııııüüııııııııııııııııışııııüıııııııııüıııııııüıııüıüııüüıııııüşııııüıııııııııııııııııııüııııüııııııııışııııııııüııııüııııııııııııııııüüııııııüşııııııııııııııüııııııııııüııııııııııııışüüııııüıııııııııııııııııııııüıııııüıüıışııııııııııııııııüııüııııııüıııııüıüııüışııüııııııııııüııııııııüıııııııııüııııüışııııııııııııüüıııüıııüıııüıııııüııııııışüııııııüıııııııııüııııüııııııııııüııüüışıüııııııııüııııııııııüııııııııüııııüııışıııııııııüüüüııııııııııııııııııüüııııüışııııııııııııııııııııııııııııııııııııııışııııııııüııüıııııııııııııııüııüıııııııışıııııııııııüııııııüııüıııııüııııııııııüşııııüııııııııııııüıııııııııüıııııııüüıışııüııııııııııııııüüıııüııııüııııüıııüıışıııııııııüııııııııııııııııııııııııııııışıııüııııııııııııüıııııııüıııııııııüıııııüıııüıııııııııııüıııııııııııııüıııııııışıııııüüüııüııııııııııııüııııııııııııııışıııüıııüıüııüıüüıüıüıııııııüııııııüıııışıııııııııııııııııııııııüıüııııııııııııışııüııııüıııııüüııüııııııııııııııııııııışıııııüııııııııüııııııııüııııııııüıııııış \ No newline at end of file diff --git a/voice/silence2.ul b/voice/silence2.ul new file mode 100755 index 0000000..9323f54 --- /dev/null +++ b/voice/silence2.ul @@ -0,0 +1 @@ +şÿÿışşışşıışıııııüııııııııüııııııııüııışııııüıııııüııııııüüıııııııııııııııııııüııııüııııüııııııüüıüııııüıııüııııııüıııışıııııııııııüıııııııııüıııııüıüıııüııııışııııüıııııüııııııııııııüııııüıüıüıııııışıııüıııüıııııııüııııııııüüıüıııııııüüıışııııııüııııııııııııııııııııııüıüüıııüıışııııııııııııüıııüıııüıııııııııııııııııışüııüıııüıııüüıııııüıııııııııııııüüıııüışıüıııııııııüıııüıüııııııüııııüıııüııııışıııııııııııüııııııııııııııııüııııııııüışüıııııııııüıııııııııııııııııüııııııııüışııııüıııüııüııııııııııııııııııııııııııışıüııııııııııüııııııüııııııüıııııııııııışıııııııııııüüııııııııüııüüüüıııııııııüışıııııııüıııııııııııııüıııııııüııııııııışııüııııııııııııüııüıüıııııııııııııııüıııııüıııııııııııııııııııııııüıııüııııüııışüıııııııüııüıüııııııııııııııüıııııüııüüşıüıııııüıııııııııııııüüıııııııııııııııışıııüıııııııııııııııüıüııııııııııüıııııışıııııııüııııüıııııüıııııııııııııııııııışııüııııııııüııııııııüıüıııııüüııüıııııışıüıüııııııııııııııııııııııüıııııııüıüıüşııııııüıııııııııııııüııııüıııüııüıııııışıııııüııüııııııııııüııııııııııııüüüıııışıüıüııııııııııüııüıııııüıııüıııııüııııışüıııüıüııııııııııüııııüıııııüııııüııııışııııüıııııııııııııııııııııııııııüıııııüşııııüııııııııııııııııııııııüıııüııııııışııııüıııııııııııııııııııııııııııııüüıüıııııııüııııııııııııııııııııııııııııııııışıııııııııüııııııııııııııııııııııııııııııüıııııııııııüıııııııııııııııııııııııııışıııııııııııııııııııııııüıüııııııııııııışıüıııüüııııııııııııııııüııııııııııııııııııııııııüııııüıııııııııııııııüııııııııııııııııııııüııııııııııüııııııııııııııııışııııııııııııüııııııııııüııııııııııııııışııııııııııüüııııüıııııııııııııüıııııüıışıüıııııııııııüııııııııııııııııııııııııışııüııııııııııııüııııüüııııüııııııııüııüşıüııııııııııııüııüıüııııııııııııııııııışıııüıüııııııüııüıııııııııııüıüıııüııııışııüııüüıüııııııüııııüıııııüıııüıüııııüüşıııııııııııııüııüııııüüıııııııııııüıüıışıüıııııııııııııııüııııııüııüıüııııııııüşıııııııüıııııııııüııııııüıııııııüıııııışüııııııııııııüüıııııüııııııııııııüııııışııüıııııııııııııııııııııüıııüııııııııııııııüııııııııııüııııüıııüııııııüıüıııııışüıııüıııüüııııüıııııüıııüıııüıııııııııışüııııııııüıııüııııııııııüıııııııııüıııışııııııııııııüıııııııııııııııüüııııüüııışııııüıııüüııııüııııııııüüıııııııüıııııışıııııııııııüıııııııııııııııııııüııııııııııüııııııııüııııııüıııııııüııııııııüııışıııüııııııüııüıüııııııııııüıııııııııııışııııüıııııııııııııııııııııııııüıııııüıışııııüıııııııııııüııııüııııııııııııııııışııüıııııııüıüıııüüıüııııııııııııııııııışüıııııııııııüııııüııııııüıüıııııüüııııüşııüıüıııüıüıüııııııııüüıııüııııııüııüıışıüııüıüıüııııııııüıüüııııııııııüıııüııışıııııııııııüııüüııııııııüıııııııııüıııışııüıııııııııııııııüıııııııııııüııııııüüşıııııııııııııııııııııüıııüıııııııııüıııııııüııııüıüıııııııüıııııııüıııııııııııışüııüııüüıııüııüüüııııııııüııüüııüıııııışııııüııııüııııüıııııüııııııııııııüııııışıııııüıııııııüııııııııııııııııııııııııışııııııüüüüıııüıııııüııııııııııııııııüıüşüııııııııüııııııııüüııııııııııııııııııüşıııııııııııııııııııüıüııııııııüıııııııüşııııııüıüüııüııııııııüıııüüııüıüııııııışıııııııııııüıüıııııııııııııııııüııüüıüışıııııüııııııüüııüıııııııııüııııüııııııışıııüııııııııııııııüıııııııııııııııııüıışııııııııııııüıııüüıııüüııııüıııııııııüıııııııııııııüııııııııııııııııııüııııııüııüııüııüııııüıııüııııııııııııııııııııııışıııııüüııııüııııüııııııııııııııııüııııııııııııııııııııüıııüıııııııüıııüıııüıııışüıııııııııııııııııııııııüıüıııııııııııışıııııüııııüıüııııııııııııüııüüıııüııııııııııııııııııııüıııııııııüıııııııııııııüşııüıüüııııııııııııııüıııııııııııüıııııışııııüıüııııııııüıııııııııüıııııüüıııııışııııııııııııüüııııııııııııüüııııııııüıışııııııüııüıııııııııııııııııııüııııııüıışıüııııüüııııııııııııııııııııııııüüııııışııııııııüııııııııııüııııııııüııııüııııışüııııııüııüüıııüııüıııııııııııııııııııışıııııüıııııııııııüııııııııııııııııııııüşıııüıııııüıııüıııııııııııııüııııııüıııışıııııııııüııüıııııııııııııııüııııııııııııüııııııııııııüııııııııııüııııüıüıüıııışıııııüııııııııııııııııııüııüıııııüııııışıüıüııüıııııüıııııııııııııııııüıııııııışııııııııııııııııüıııııııııııııüüııııııışüııııııııııııııııııııııııııııııııııııııııııüıııııüıııııııüıüıııııııııııııüüıüııııııııııııııııüıüıüıııüııııııüıııııııııışııııüüüııııııüııııııııüııııüıüııüıııııüşıııııüııııııııııııııııııııııııııııııüıüııüııüüıııüıüııııııüııüııııııııııııııııışıııııııııııııüııııııııııııııüıüüüııüııışüıııııııııııııüıııüüııüııııııııııııııüışıüııııııııııııüııüııııüııüııııüıııııııışüııııüıüıııııııüııııııııııııüüııııııııışııııııııııııüııııııııııııııııııııüıııııııııııııüııüüıııüıııııııııüııııüıııııııışııüıııııııııııııüııııııııııııüıüıııüııışııüııııııııüııııııııııııüıııııııııııııüşıüıııııııııııııııııüıüııııııııüııüııııışüıııııııııüııııııııııııüııııııııııııııışıııııııııüıııüııııııııııııııııııüıııııışıııııııııııüıııüııııııııııııııııııııııışüıııııııüıııııııııııııııııııııııııııüıüıııııüıııııııııüıııııııııııııııüıııııııııııııııııııüıüııııııııııııııııüııııııüıışııııııııııııııüıııüıüıııııııııııüıııüıışııııııııııııııııııüııüıüııııııüıııüıüıışıııııııüııııııııııııııııııııüııüüıııüıışııııüıııııııııüıııııııııııııııııııııııışüııııııııııııııııııııııııııııüıııüııııüşııııııııııııııııııııııııüıııüııııııüııışıııüııııııııııııııııııııüüıüıııııüııüıüşıııüıııüıüüııüııüııüüıııııııüııııııııüışıüııüıııııııııııııııııııııııııııııııııışıııııııııııııııüıııııııüıııııııüıııııüışıüııüıııııııııııııüüııııüüıüıııııııııııııııııııııııııııııııııııııııııüııııüıüııııüıüüııııııııüıııııııüııııüıııııüıııııışııüüüııüıüıüıııüııııııııııııııııüüııııışııııııııııııııııüıüıııııııııııııııııııışııııüııüııııııüııııııııııııüıııüııııııışüüııııııııüıüüıııııııııııııııııııııııüışıııııüüııııııııııııüııııııüııüüıııüıııışıııııüüıııııııüüıııııüıüııııııııııüıııışüüııııııııııüıııııııııııııııııııııııüıışüıııııııııııııııııüııııüıııııııüııüıııışıüııııııııııııüıüıııııııüııııııüııııüıışıüııııııııııııııııııüıııııııııııüıııııışııüııüıııııüüüıııüııüüııııııııııııüüıııııııüıııııııııııüüııııııııııııııııııııüışııııüıııııııııııııııııııııüıüüııııııııışııüıııııııııııııııüüüüııııııüıııııııııışıııııüıüüıııııııııııüıııııııüıııııııııışııııüııııııııııııııııüııııııııüıüııüııışıııııııııııııııııııııııııüııııııüııüııışüııüıııııııııııııııüıııııüııııııüıııııüşııııııııııııııüıııııüııüııııııııııüıııışııııııüüüıııüıııııüııııııııüüııııııııüışıııııııııııııııııııııııııııüııüıııııııışıüıüüıııııııııüıııııııııııüıııııııııııışıııııııüııııııııııııııüııııııııııııııüüşııüıııııııııııııüııııııııııııııüııııııışüııüüıüıııııııııııııııııüııüüıüıııııııışııııııııııııııııııııııııııııüıüıııııııışııııııııüüıııııııııııüıııüıüııııııüüııışıııııııııüıüüıııüıüıııııüıüııüıüııııüıışııüııııııııüııııııııııüıııııııııüıııııışıııııııııüııııııııııııııııııııüıııııııışıııııııüıııııııııııııııüıııııüüıııııııüşüııııııüııııııııııııııüıııııüüııııııııışıüüııııııııııııııııııııııııııııüüııüııışııııııııııüııııııııüııııüıııııııııııüıışııııııııııııııııııııııüııııııüııüıııııııııııııııüıııüııııııııııııııüııııüıııııüıııııııüıüııüüıüıüıııııüıüııüııııııııııışııııüıııııııüııııııııııııüıııııüııııııışıııüüıııüıüııüıııüıııııııüııüıııüıııııışıııııııüıııııııııııııııüııııııııııııııışııııııııııııııııııııııııııüııııüıııüııışııüıııııııüııııııüıııııııüııııüıııııııüşıııüıııııüıııııüüııııüıııııııüüıııııııışıııııııııüııııııııüııııııııııııüıııııüüşııııııııııııııııııııııüüüııııııııııüııışıııııııııüıııııııııüııııııııııııüıııııışııııııııııııüııııüııüüııııııüıııııııııışıııüıııııüıııııııııııııüııııııııııııııışııııııüıııııııııııııııııııııııııııııııışııııüııııüüıııüııııııüııııııııııııııüıışıüııııııüııüüııııüıüıııııüııııııüüıııüıııııııııııııııüıııııııııııüıııüüıııüıııışıııııııüııııüıııüıııııııııüıııııüıııııışııııııüııııııüüııııüıııııııüııııııııııışııüııüüııüııııııııııııııııüıüıııııııııııııııııııııııııııııüııııııııüıııııııııııııüüıüıııııııüıııııüıüııııııııııüııııııışüıııııııııüıııııııüııüııüıüııüııüıııııışııııııııııüııııııüıııııııüııüıııüıııııışıüııııüııııüüıüüıüııüıııııııııııııııııışıııııııııüıııııııııııııııııııııııııııüüşııııüıııııüıııüııııııııüıııüıüııııüıııışıııııüıııııııııııııııııüııııüıııüüıııüışııııııüüüıııııııııııııııııııııııııııııışıııııııııııııııııüııııııüıııııııııııııışııüıııııııııüııııııüıııııııııüüııııııüışıııııüüüııııııııııııııııııııüıııııüüüıışıııııüıııııııııııııııııııüüııüıüııııııışüııııııııııııüııııııüıııııüııüıüııııııüşııüııııııııııııııııııüııııııııııııııııışıüııııııüııııııüııııııııııııııııııııııışııüıııüıııııııüıüıııııııüıüııııüıııııüıııııüıııüüııııııııııııüıııııııııüıııüııışıııııııüıııııııııüıııüııııııııüıııııııışııııııııüıııııııııııııııııııııııııüıııışııııııııııııııııüıüııııııııüıııııııııüııüıııııııııııııııııııııııüıııııııııııııışıııüııııııııüııııııüıüıııııııııııüııüıışııııüııııııııüüııüııüııııııüııııııııııüşıüıııııııııııııııııııııııııııııüııııııüşııııııııüüııııııüıııııııııüıııııüıııııüşıııııüıııııııııııııııııııııüııııııüıııışııııüıııüııüııüııüııüıııııııııııııüüııışııııüıııııııııııııüııüııııııüııııüıııııııııüııııııııııııüıııüııııııııüııııüıüıışüıııııııııııııııııııııııııııııııııııüıışııııııııııüııüııııııııüıııüıııüıııııııüııııııııııııüııüüıııüüıııüıııııııüııııüışıııııııııııüıııııüııııııııııüıııııııııışııııııııüıııııııııüııııııııııüüıııııııışıüııııııııııııııııüıııııııııııııüııüıüııııııııüııüıüıüüııııııııııııııııüııııııışüııııüıııııııııııııııııııüııııııııııııışıııııııııııııııüııüüüüüüııııııııııııııışıııııııııüıııııııııüıııııııııüııııııııüşııııııııüıııııııüııııııııüııııüııııııııııııııııııııııııııııııııııııüıüııııııııışııüıııüııııüıüııııııüııııüıüııııııııııışııııııııııııüıııüııııüııııııııüıııııııışıııüııııüıııüııüıııııüııüıııııııııııııışıüıııııııüııııüıııııııııüııııııüııııııışıııııııııüııüııüıüııııüııüıııııüııııııışıııüııııııııııııüııüııııııııııııııııııışıüııııüııüııııüııııııııııııııııııüüıüıışıııüüıııııııııııüıüıııııııııüıüıüıııııışııııüıııüıııüıüııııııııüıııııııııııııüışüııııüüıııııııııııııüıııııııııııııüıııııııııııüıııııııııııüıııııüıııııııııııııışüııııııııııııüııııüıııııııııııııııııııışııııüıüıııüüüıııııııııııııııııııııııııışıııııııııııııüüüıüııııııııııııııııııııışıııııııüıııüııııııııııııııüıııııııııııüııııııııııııüüıüııııüııııııııııııııııııışıııüıüııüüıııııııııııııııııııüıüııııııııııııııııüüııüııııııııııüııııüıııııııııışıııııüüıııııııüıııııııııııııııııııüıııüııııııııüıüüııııııııııııııııııııııüıüııışıııııııüıııııüııııııııııüıııüıııııııııışııüııııüıııüıııııııııııııııııııııııııüışııııüııııııııııııııüıııııüıııııüıııııüüşıııüııııııııııüıüııııüıııüıııııüıüııüüışııııüıüıııııııııııııııüüııııııüüııııııüşüıııııııııüııüııüıııııııııııüıııııııııışııııııııüıııııııııııııııüııüıüııüıııüıışüüıııııııııııüüıııııııüıııüıııııııüııüııııııııııııııüııııııüııııııııııııııııııışıüıııııııııüıııııııüıııııııııııııııüııışıııııııııııüııüııııııııüıııııııüııııııüşıııııııüüııııııııüıııııüııııııııııııııışıüııııııüıüıııııüıııııııııııııııüıııııışıııüııııııııııııııüüııııııüııııüıııııüışıııııııııııüıııııüııııııüüııııııüııüııışııııııııüıüüıüııııııııııııııııüııııüııışııııüıııııüıııüıııüııııııııııüııııııııışüüıııııüııııııııııııııııüıııııııııııııışııüıııüıııııııüıııııüııııüıüııııüıııııışııııııüıııüıııııüııııııııııüııııııııııışııüıııııüııııııııüııııüıüıııııııııııııışııııııııııüıııııüüüııııııııııııııüüıııışıüüııüııııııııüıııüııüüıııııııııııııııışıııııııııııııııııüıüııüııııııııüıııııüışıııııüıııııüııııııııııüıüıııııııııııüıışıüııııııııııııüııüııııııııııııııııııııışııııııııııııııııııııııüıııııııııııııııışıııüııııııüıııüıııııııııııüııııııııııııııüıııüıııüııııüıııııııüııüııııüıııııııışüıııüııııüııııüıııüıııııııııııııııııııışııııııııııııııııııııııııııııııüıüıııüıışııüııııüıııüııüüııııııııüıııııııııııüıışıııüıııııııııııüüıııııııııııııüıııııııışıııııüııııııüıııııııııııııııııııııııııııııııüııııüııüııııııııııüııııüıüıüıııııışııııüııııııüıııııııııııııııııııııııüııışıüüııııııııııııııııııüıüıüııııııııııııışüüıııüııııııııüıııııüıııııııııııüıııııışüıüııüııııııııııüıııüıııııııııııııııııışıüııııııııııüıııüüüıüııııııııııüııüıııüşııııüııııııııııııüıııııııııııııııııüııışıııııüııııııııııııııııııııııııııııııııışıııüııüıüıııııııııüıııııııüııııııüııııışıüııııııııııüıııüıııüııüüüııııııııııııışııııüıııııııüüıııııııüıııüıııüıüııııııışüııııııüıüııııııüııüııüııııüıııüııııııışııüüııııııııüıııııııııııııııııııııııııışıııüüıüııüıııııııııüııııııııııııııııııışııııııııüııııüııııııııııüıııııııııüıııışıüııııııııüıııııüııııııııüüıııııııüıııışııııııııııııııııüııııüıııııııııııııııııııüııüıııııııııııııııııııııııııııııııııışııııüııııııııüıııüııııııüüııııııııüıııışııııııııııııııııüıüııııüıüüııııüıüüıııışıııııııııııııııııııııüüııııııüıüııııııııııııııııüıııııııüıııııııüııııüııııııııışııııııııııüıııüııııııııııııüıüııüıııııışııüıııııııııııııııüıüııııııııııııııüııışıııııııııüıııııııüııııııııüııııııııüııışııııııııüıııüııııııııııııııııııııüıııüışııııııııııüıııııııüıııııııııüııııüııııışıııııııııııııııııııııııııııüıııııııııııııııüıııııüııııııüıııııüııüııııııııııııışııııııııııııüııııııııııııııııüııııııııışııüüıııııııııııııüıııııııııııııüııüıııüşıııııııııııııııüııııııııııüüııııııııııışııııüııııııııııııııııııııııüııııııııııışııııııüıııııııııııııııııııııııııııııııışııüııııüııııııııııııüııııııııüıııııüııışıııüııııııııııııııııııııııııııııııüıüüışıüııııüüııııııııııııüııüııııııııııııııüşııüıüııııııııııüıııııüıııüııııııııüııııııüıııııııüııııııııııııııııııüıııııııııışıııııüıııııııüıüııııııııüüüıüıııüıııııışııııııııııııııııııııııııııüıüııııüııııışııııııııııııııüıüıııııııııııııüüııııııışııııııııüıııııııııııııııııııüıııııııııışııııııııııııııııııüıııııııııııııııııııışııııüüııııııüııııııııüııııııııııııııüüışüıüıııııüıııııııııııııııııııııııüıııııışıııııııııııııüıııııııııııüııııüıııııüıışıııııııüüııüıııııııııııııııııüııııııüııııııııııııııııııııııııııııııııüııııııııışüııııııııııüıııııııııııııııııııüüıııııışıııııüıııııııııııııııııııııüııııüüııüıüşıüıııııııüıııııııııııııııııııııııııııııııııııııııııüıüııııııııüııııııııııııüıüışıüıııııııııııııııııııııııııııııüıüıüııışııııııüııııııııüııııııııııııııııııııııışüüıııııııııııııııııüıııııııııııüııııııışıııııııııüııııııııııııııııııııııııııııüşıııııııııııııııııııüıüııııııııııııııııışüıııııııüııüüüııüıııııııııııııııııııııııııüüııııııüüıııııııııııııüıııüııııııüıüıııüüıııııüıııııııııııııııüıüıııııüııııışıııııııııııııüıııııııııüıııııüııııııııışıııııııııüıııüıııııııüııııııııııııııııışııüıüıııüıııüııııııııııüıııııııüııııııışıııııüıüııııııııııııüıııııııııııııııııışıııııııııııııüııııııııııııııııııııııııışııüııüüıüıııııııııııııııııııııııııııüıışıüıüııııııııııııııııııııııııııııııııııışııııüııııııüıüıııııııüııııııııııııııııııüüııııııııııııııüıüıııııııııııııııııüıışııııüüııııııııııüıııüıııııııüıııııüıüıııııüııııüıııııüııııııııüııüııııııııııııışıııııııüııııııııüıııııııııııııııııııııışıııııııııııııııüıııııııııüııııııııııüıışıııııııüııüııııüıııııııüüııııüııııııııışüüııııüıııııııııııııııııııııııııııııııışııııüıııııııııııüıııııııııııııııııüıııışııııııııüııııııııüııııııııüıııüıüıııııışıııııııüıüıııııııııüıüüüıııııüııııııüıışüııııüııııııııııııııüııüııııııııııııııışıüııııııııüüııııııııııııııüııııüııııııışıııııııııııııııııııııııııüıııııııüııııışıııııııüııııııııııüııııııııııııııııüııışııııüıüıüıüııüıııııııııııııııııüııııııışıııııııııııııııüıııııüııüıııüıııııııııışıüııııııııııııııııııııüüııüıııııııüııüışüıııııüıııüıııüıııüüııııııııııııııııııışıııııııüııııüıııııııııııııüıüıııııııııışııııüıııııııüıııııııııııııııııııııııııışııııııııııııııııııüııüıüüııııııııııüııışıııııııüııııııııııııııııüıııııııııııııışıüıııııüıııııııııııüüııııııııııııııüııüşııııııııııııııııııııııııüüıııııııüüıııışııııııııııııııııııüıııııııııııüııııüııışııııüııüııııııııııııııüıüıüüıüıüııııııııııııüııııüııııüıııüüıııüıııüııııııııııııııııııııüüııüıııııııııııııııııııııııııışııııııııüıııııııüııııııııııııııııııııııııııııüıııüıııııııııııııüııııııııııııııışıüıııııııııııııııııııııııııüıüııııüıııışıüüııüıııııııııüüıııııııııüıııııııııııışıııüıüüıııııüüııııııııııııııııııııııııışüıııııüıııııııüıııüııııüııııııııııııııışııııııııııııüıııııııııııııııııııııııııışııüııııııııııııııüııııııüüıııııüüıııııışııııüııııüııııııııüıııüııııüıııüıııııııııüıııııııııııııüıııııııııııııııııııüııüşıııııııııııııııııııııııııüııııııııııııışıııüııüıüıüııüıııııııııııııııüıııüüüııışıııııııııııııııüıııııüııııııııüüıııüııüşıııııüıııııııııüıııııııııııüııüıııııııışüıııııııııııııııııüııüıııııüıııııııüııııııııüıüıııüııııııııııııüıııııüüıııııüııııııııııııüüııüııııııııııııııüıııııııııışüııııııııııüııııııııııüıııııüıüıııüıııış \ No newline at end of file diff --git a/voice/silence3.ul b/voice/silence3.ul new file mode 100755 index 0000000..9bcaf48 --- /dev/null +++ b/voice/silence3.ul @@ -0,0 +1 @@ +şÿÿşşııışıışııüüııüıüüüııüüıüıııııüıııııııüııııüııüıııııııüııııüııüıııııııııııışııııııııııüııııııııııııüııııııııııüıııışıııııııııııııııııııııııııüııüııııııııüışııııüııııııüıııüıüüıııııııııııııııüıııııııüıııııııııııııııüııııııııııııııııııüışııüııüıüııııııııüıüıııııııııüıııııııııııııüüıııüıüııııüıııııııııııııııııııııüıüşıııııııııııııııııııııııııııüııııııııüıışüııııüııııııüıııüıüıüııııııüıııııüııııışıüııııııııııııııııüıııüııüııııııııııııışıüııııııııııııüıııııııııııııııüııııııııııııüıııüıııüüüııııııııüıııııııııüıüıııüşııııüüıııııııııüııııııııııııııııııııııışııııııııııüııüııııııııııııııııııüıııııışıııııııııııııııııııııııüııüüüıııııııııışıüııüüııııııııüüııııııııııüııııüıüüıııışıııııııüııüüıııııııııııııııüııııııüıııışııüııüııııııııııııııııııüıııııüıııııııışııııııııııüııııııııııııııııııüııııüıüüışıııüüııüııııüıııüüııııııııııııııııııüüışııııııııııüııııııüııııııııııııııııüııüışıııüüıııııüıııııııııııııııııüıııııüüıüüşıüıııııııııııüıııüıııııııııııüııüıüıııııııııııııııııııııııüıııııııııııııııııııışıııııııııııüüııııüııııüıııüııııııüıııüışııüııüıııüıııııııııııüıüııııııııııüıııüııııııııııııııııııüıüıııüüııııüııııüıüıışıııııüıııııııııııııııüııüıııııııııııııışüüııııııııııüıııııııııüıııüııüııııııııüşıüıııüıııııııııııııııııııüıııüııııııııışııııııııııııııüıııüüııııııüıııııııüıüıışııııııııııııııııııııüııüıııııııııııüıüışıüııııııııııııııııııııııııüıııüıııııııışıııııııııııııüıııııııııııüıüııııııııııışııüıııııüııııüııııııııüııııııüııııııııışııııııüııüüııııııııııııııüııüııüııııüıışııııııııüııüıüııııııııııııııüıııııııııışııııüıııüıııııııııııııııııııııııııııııışüıııııııııııııııııııııııııııııııııııııışıüııııııııııüıııüııııüıüııııüıııııııııışııııııııüııııııııııııııııııüııııııııııışııııııııııııııııııııüııııııııııııııüıüışııııııııüüıııüüüıüııııııııııııııüüıııüışıııııııııııüıüıııııııııııııüııııııııııışüııüııüııüıüıııııııüüııüııııııııııııııışııııııııııııüııııüıüııııüıüüııııııııııışıııüııüıüıııııııııııııııııııııııüıııııüşüüııııııüıııııııııııııııııüıııııııııüüışüüııııııııııııııııııııııııüııııııııııııııııııüıııııııııüıüııııüıııııııüüııııııışüııııüııüııııııüııüıııüıııüıııııııııüıışıııııııııüıııııüıııüıüııııüıııııııııııışııüııııııııııüııııııııııııııııüııııüııışıııüııüıııııııııııııııııııııııııııııııışııüııııüııııııııııüıııııııüıüıüüııüıııışııııııııııııııııııııııııııııııııııııüııııııııııııııııııııııüıııüııııüıııııııııışıüıüııüıııüııııııııııııııııııııııııüüıışııııııııııüııııııııııııııııüııııııııııışııııııııııüıııııııııüııııııııııııııııüışıııııııüüıııüııııııüııııüıııüıııııııııışıııııııııüııııüııııııüıüıııüııııııııııışıııııüıüıııııııııüıııüüıııüıııııııııııışıüııııüüıııııııüıüııııııııııııııııııııışııııııııııııııüıüııııüüııııııııüııııııışıııııüıııııııııüüııııııııııııııııüııüıışıııııııüıııüıüııııııııııııııııııııııııışıııııüıııüıııüüıııııııüüıüııııııııüıııışıüııııııııııııııııııüıüııııııüııüııııııııııııııııüııüıııüııııııüıııüııııııııııışııııüıüıııııüüııüııüüıııııııııııııııııışıüııüıııüüııüıııııııüıııııııııııııııııııııııüııüııııııııııııüıııııııııııüıııüıüıııııııııııııııüüııııüııııııüııııııııüıışıııüıııııüıııııııııııııııüııııüıııııııışıııııııııııüüııııııııııııııüıüıııııııüışüııııııııüıııııııııüııııııııııııııııııışıııııııııüüıııııııııııııüıııüıüıüıııııışüıüııııüııııııüııııııııııııüııııüııüııışıııüıııııııııııııııüıııııııııııııııııüışııııııııııııııııııııııııııüıııüıııııııışıııııııüıııııüııııııııııııııııııııüıııüıııııııııııııııüüıüüıüııüııııııııüıııııüııııııüıııııııııııııııııııııııüııııııııışııııüıııııüıııııııııııııııüıııııııııııışıııııııııııııııüııııııııııüııüııııııııışııııııııııııüıııııııüıüıııııııüıııııııııııııüııııııııııııüııııııüıııııııııııııışııııııııııııııııııııııııüııııüııüııııüışııııııııüııııııııııüıııııüııüııııııııüışııüııııııüıııııııııııııııııııııııııııüışüıüüıııüııııııüıııüıüıüııııııııııııüııışııııııııııııüıııııııııııııııüıııııııııışıııııııııııüıııııııııııııııııııııüııııışıııüıııüıııüıııııııııııüııııııüııııüııüşıüııııııııııüüııııııııııüıııüııııııııüışıııüııııııııııüııııııüııııııııüıüıııüıışıııııııııııııüıüüıüııııııııüıııııııııüüşıııııııııııııüııüıüıııııııııııııüıııııışıııııüıııııııııııııııııııııüıııüııııııışıııııııııııııüııııııııııııüııııııııüııışııüııııııııııııııııııııııııııııııııııüışııüıııııııııııııııııııııııııııüııııııüışıııüıııııııııııııüııııııııııııııııııııııııııüıııüııüııııııüııııııüııııüıııııııışüıüııüııııııııııııııııııüıııüııııüııııışıııüıııııııııüıııııüıııııüııüıııııııııışııüüııııııııııııııııııııüıııııııııııııışııüüüııııııııııııııııııııııııııııııııüışııııııııııııııııüıüııııııııııııııııüııışıııııııüıııııııüıııüıııüııııııııııııııııüıııııııııüıııııııııııııııüıııııııııııışıııııüııüıııııııüıııııüıııııııııııııııüşıüıııııııııııııüıüüıııııüııüııüıııüıııışııııüüııııüıııııııııüıııüıüıııııııııüıııııııııııııııııııııııııııüüüııııüııııııışııııüııııııııııüıııüıııııüıııııııııüııışıııııııııııüııııııııııııııııııııııııııışüüıııüııııııııııııüıııııııııııııııııııışııııüııııııııııüııııüııııııııııüııııııışıııüııııüıııııııııııııııııııüıııııııııışıüııııııüıııüıııüııııııüııııııııııüıııışııııüıııııııııııııııııüıııııııııııüıııışıııüııııüıııııııııııüıııııııııııüüııııışıüıııııııüıüıııüııüıııııııııüııııüııüıışııııııüıüıüııüıııııııııııüııııııııııüıışııııııııııııüıııııııııııııııııııııııııışııııııııııııııııüıııııııııııııüıııııııııııııııııııııııııııüııııııııııııüııüıııışıııııııııüııüıııııııııııııııııııııııııışııııüüııııüııüııüııııüııııııııııııüıııışüııüııııııüıııııııııııııııııııııııııııışıüııııııııııııııııııııııııüıüıııüüııııışıııııüııııııüııııııııüıııııııüüııüııııüşüıııııüııııııııııüııııııüıııııııüıııüıışııııııüııııııııııüııııııııııııüııüıüıüışıııııııııııııüııüııüııııııüıııııııııııışıııııııııııııııııııııııüııııııııııııııışıııııııııııııııııııııııüııüııüüıııııüüışıııüıııııııüııııııııııııııııüüüıüıüıııışııııııııııüıııüüııııııııııııııııııııııışııııüıııııııııııııüııııııııııııııııüüıışıııııııüıııııııüıııııııııııııııüıüüıııışıııııııııııııııııııııııııüııııııııııııışıııııııııııüıııııııüıüıüııııüııüııııııışüıüııııııııııııüııüııüıüıüııııııııııııışıııüııüııııüıııııııüııııııııııııııııııışıııüıııııııüııııııüııııüııııııüııııüııışıııııııııııııüıüüıııııııııııııııııııııışüüııııııııııııııııııııııııııüıııüıııııışııııııııüüıııııııııııııııüıııüııııııüıışııııüıııııııııııııııııııııııııııüıüıııışııüııııııııııııııııııııııııııüüıııııııışııüııüüııııııııııııııüıııııııııııııııüışıüüıııııııııııüııııııııııııüüıııüıııııışüııııııüııüııııııııııııüıııııııııııüııışıüüııııııııııııııııııııüüıııııııııüüüııııııııııüüüıııüııııııııııııüıııııııııııışıüııııııııııııııııüııııüııüüıııııııüııışııııüııııııııüııııııııııııüııııııüııııışıııüııııııııııııüıııııııııııııüıııüıüüışııüıııııııüııııııııııııııııııüııııııııışıııüııııııııııııııııüııüııııııııııııııışııııüııüııüüııüıııüüııııııııııııııııüıışüııııııııııüıııııııııüııııüıııııııııııışüıııııııııııüıııııııııııüüıııııııııüııışııııııııııııııııııııııııüııııüıüııüııüışıııııüıüüıııııııııııııııııüııüüıııııııışıııııüıııııüıııııııüııııııııüıııııııüıışüıııııııüüııııııııııııııııııııııııııııüşıııüııııııııııııııııııııııüıııııüııııııııııııııııüııüııııııııııııııüııüııüııüıışııııüııııııüıııııııııııııüııııııııüüııışııüııııııııüıüıııııııüıııııııüıııııüüüışüıııııııııııııııııııııııüıııııııııııüıışııüııııııııııııııııııııııııııüıüııııııüşııııııııııüııııııııüııııüıııııııüıııüüışııııııııüüııııüıııüııııııııııııııııüııışıııııııüıııüııııüııııııııııııüııııııııışıııııüüüııııüıııııııüııııııııııııııüııüııııııııüııııüıııüııııııüııııııııııııııüşııüııııııııııüıııııııııüıııüıııııüııııışüıııııııııııüıııııııııııııüıüıııııııüıışıııııııııııııüüıııııüıııııüıııııııııüıışıııüııııııııüüııııüüııııüıııüıııııııııışııüüııııüıııııııüıııııııııııııııüıııııışıııııııııüıııüıııııüıüüııııııııııüııııışııüıııııııııııııüıııııııııııııııüıııııışıııııüüııııııüıüıııııııııııııüıııııüııışıııııüııüıüııüııüııııııııııüııüıııııüıışüııııııııüııüıııııııııüıüıııüıııııüıııüşıüıııııüıııııııııüııııüıııüıııııııııüıışııııııııııııııııııüıııüıııııııııııııüıııııüıııııııııııııııııııüıııııüıııııııııışıüüıııııııııııüıııııııııııııııııııııııüşııııııııüııüııııııııııııııüııüıııııııüışıııüııııııüıııııııııııııııııııııııııııışıııüııııııııııııüııııııııüııııııııııııışıüıııııııüııüıııüıüıııııüıııııııüııüııışüıııüııııüıııüüııııııııııııııııııüııüüışıüııııüüııüıııııüııııııüüıüıııııııııııışııııııüıııııııııüııııııııııııüııııııııııııııüııııüüıııüııııüııııııüııııııııııüışııııııııııüııııüııııııııııııııııııııııışıüıııüııııııııııııııııüüııııııııııııııüşıııııııüııııııııııııııüııııııııüüıııııışıııııııııüııııııııııııııüıııııııüıııııüşıııııııııüııüıııııııııüüııııııııııüıııışııııüıııııııııııüüııııııııııııııııııııışıııüııııüıüııııııııııııüııııııııııııüıışüıııııııııüııııııııııııııüıııııııüııııışıııııııııııüııııııııııııııııııüıııııııışıııııüııııııııüıııüıııııııüııııııııııüııııııııııüüıııüıııüıııııüıüııııııııııııışıııüıııııııııııııııııııııııııııüııııııııııııııııııüıüııııüıııüııııııüıüııııüııışıııııııüıııüııüııııüıııüııııııııııııüıııııııııııııııüııııııüııııııııııııııııııışııııııüııııııüııııııııııııııııııııııııııııııııııııııüııııüüııııııııııııııüıııııııııııııııııüııııııııııııüüıüüııüııııııışıııııüıııııııııııüııııııııüıııüııııııüüşııııüıııııııııüııııııııııııııııııüııııışıüıııııııııııııııüıüıüıııüııüııüüıııııışııııııııııüııııııüııüıııüııüıııüııııııışüıüııııııııııııııııüıııüıııüııııııııııışüııııııııııııııııııııüııııııııııııııııışııııüıııııııüııııııüıııııııüııııııüıüıışıııüıııııııııüııüıııııııüıııııüıııııııışüüıııııııııııııııııııııııııııııııüıııüışüııııüııııııııııııııııııııüıııııııııııışıüııüııııııııııııııııııııııüııüıııüıııüşıııııııüııııüııııııııüııııüıııııüıııııışıııııııııüııııııııııııııııüüııııııııüıışııııııııııııııııüııııııııııııüııüıııııışüıııııııııııııııııııııııııüıııüüıüııüıışııııüüüııüüüüüııüııııııııııüııııııııııışıııııııüııııııüıııııııııııııüııııııüııışıııüüııııüıııııııüıüıııüıııııüıüıııüııışıııııüııııııııııııııııııııııüüıııııııııııııııııııııüııııüıııııııııııııııııııııüşıüııııııııııüıııııııüıııııııııııüıııııışıüıııııııüııııııııııııııııüıııııııııııüşıüııııüıüüıııııııııııııııüıııüııııüıııüşıııııüıııııııııııııııııııııııııııüııııışııııüııııııııııüııııııüııııııııüııüıııışııııüıııııııııııııııııııııııııııııüıııışıııııııüıüııııüııııüııııüıııııüıııııııışıüıııüüııııüıııııııııııııüııııııııııııışıııııüııııııııııııııııııııııüıııııııııışıııııııüııüııııııııııııüııııııııüııüııüşııııııııüııııııüıüüüııııııııııııııııııüşııııüııııııııııııııııııııüüııüıııüıııüüşüıııııııııııııııııııüııııııııııüııüüııışıııüıııııııııııııııııııııııüüüııııııııışıııııııııııüııııııüıüııııııüıüııııııııışııııüüüüıııııııııııııııııüııııııııııııışıııııüııııııııııüıııüıııııüııüıüıııüııışııııııııüıııııııııııııııııııııııııııııışıııııııııııüüıüııüııııııııııııüıüıııııışüııııııııüııüıııııüııııüııııııııııııüıışııııııııııııııüüııüııııüııııüıüıııııııışııııüıııııüüıııııüııııııııııııııııııııışııııııııııııııııııııııüııüıııııııııüııışıııııııııııııııüııııııııüııııııııüüıüıışııııııüüıııüüıııııııüıııııüıııüıııııııışıııııüııııııüııüııüııııııııııııııııüııışıııüıııııııııııııııııüıııüıııııııüııııışıüııııııııııüıııııııııııııııüüııııııııışüıııııııııııııüıüüııııııııııııııııııüüışııüııııııııüııııııüııııııııııııııııııııııııııııııüüıüııııüıüııııüıüıııııüıııııışııııııüüııııııııüıııııüıııüıııııııüıııışııııııııııüııııüıüııüıııüüııııııııııııışıııııııııııııııııııııııııüıııııııııııııııııııııüüıııııııüııııııııııııııııüıııııııııüıııııııııüııüııııııüııüıııııııııııışıüııııııııııııııüıııııııııııııüüııııııışııııııüıüıüııüüıııııııııııııııüııııııııııııüıııııııüıııııııüııııııııııüıııııııışıııııııüııüııııııııııüııııııııııııııııışıııüüııüııııııüııüııııııüıııııüıııııııışıüıüıüüıııııııüıııııııııııııııııııüıııııııııııııııııııııüüüıııııııüıııııııııııışııüıııüüüıııııııııüııııııııüııııııııııışııııııııııııııııııııııııııüııııüüıüıııışıııııııııııııüııııııııııııııııııııııııışıııııııııüüıııııııııııııııııııııüıııııışıııııııüıüııüıüııüıüııııııııııııııüıııışıııııııııııüıüıüııııııııııüıııııııııüıışıııııüıııüııııııııııııııııııııııııııııışıüıüıııııııüııııııııııııııııııııııüıüıışıııüııııııııüıüüııııüııııııııüııııııııışüıııüııııııııııüüııüıııüııııııııııııüıışııııııııııııüıııııııüıııııııııııııııııışıüıüüııııüıııııüıüııııüııııııııüııııııüşüııııııııııüııııııüıııııııııııüıııııüıışüııüüııııııııııııııüıııüüıııüıııüıııüıışııııııııüıııııııııııüııüüııııııııııüııüşıııüüııııııııııııııııüıııüııııııııııııışııııüııııııııııüııüııüıııııııüııııııııışıııııııııııııııııııııüüııııııııüııııııışııüıııııııııııüıııııııııııııııııııııııışııııııııııııııııııııııııııııııııııııüıışııııııüıııüıııııııüıııııııııüüüüıııüııışıııııııııııııııııııııııııııııııüüıııııışıııııüıüııııııııııııııııııııııııııüüıııııııııııııııııııııııııııııüüıııüıüııııüııııüııüüıııııüııııııüıııııııııüııııııııüşıııııüııııüıııııııııııııııüıııııııııııışıııııııııııııüıüıııııııııııııııüüıııııışıııııııııüııııııııüıııüüıııüııııüıııüıışııııııııııııııııııııııııııııııüıııııııışüııııııüıüüıııııııııııüıııııııııııııııışıııııııııııııııııııııııııııııııııııııüışııııııüıüüııııüııııüıııüüıııııüıııııııışüııüııııııııııııııııüııııııııııııııüııışıııııııııııüıııııııüıııııııııüüüıüüıüııııııııııııııııııııııııüıüıüıııüıııııııüışııüıııııııııııııüıüıııııııııııııııııııüşıııüııııııııııııııııııüıııüııııüüıııııışıııııııııııııııııııııııııııııüüııııüııışıııııııııııııııııııııııııııüııııııııııışııııııüüıüıııııııııııııııııııııüııııüııııüıııııııııııııııııııııııııııııııııııüışıııııüıııııüüıüıııııııüüıııııııüııüıııışııııııııııüıüııııııüıııııııüııııııııııışııııııııııııııııüıııııııüıııııııııııüıışııııııııııııııııııııüıııııııııııııııııışıııııııııııııüıüııııııııııııııııüıııııışııüıııııııüıııııııııüıııııııııııııııııışııııııüııııııııııııııüüııııııııııüııııışıııüıııııııııııııııüıııııüıııııııııııüışııııııııııııııııııııüıüıııııııııüııüııüşıııüüııııııııııııııııııııüııııııııııııışııüıııüıııüııııüüıııııüıııııııııııııüüüşüııııııııııııııüııııııııüıııııııııüüıüışııııııııııııııüıııüıııııııııüııüııüıııışüııüııııüııüıııüıüıııüıııüüüııııııııııııııııııııııııııüıııüııııııııııııüııııüıışıııııııııııııııüııııüııııııııııüııııııışııııııüüııııııııııüııııııııüııüıüıüıııışııııııııııııüııüıüııııııııııııııııııııışıııııııüıııııııııııııııııüııııııııııııüşıııüııııııııüııııııııııııııüııııııııııışııııüıııııııııııııııııııııııııııııüıııışııüıııüııüııüıüııııııııııııüüııııüıüııışıııüüııııııııııııııııııüıüııııııııııııışıııııııüııüıüııııüıııııüıııııüüıüııııııııııııııııııııııııüııııııııııııııııııııışüııüıııııııııııııııııııııııııııüııııııışıııııııüıııııııııııüıüııııııüıüııııüüıışııııüııııııııııııııııııııııııııüııııüııııııııııüııııııüııııııüııııüııüüıüıııııüşııııııııüıüııüüıııüıııüüıııııııııııııüışüııııüıııüııııııııüıüııııııııııııııüııışııııüüııııııııııüıııüüııüııııııüııııııışııııııııüıııııııııııııııııııııııüüııııışıııııııüıııııııüıüııııııııııüııııııüüıüıııııııııııııüııııııııııııüııııııüııııııııııııııııüıııüıııııııııııııııüııııııııışıııııııııııııüııııııııııüüııııııııııııışıııııııüııııııııüıııııııüııııüıüııııııışıüıııııııııııüııııııüıııııüıııüüıııüııışıııııııııııüıııııııüıüüıııııııııııııııüşııııııııııııüıııııııııüııııııüıııüııııışıüıüııııııüıııııııııııııııııııııııııııüşıııüııııııııııııııüıııııııııüıüııııüııışııııııııııııııııüıııüıııııııııııııüüııışıııııııııüııııııüııııııııııııııııııüııışııııııüüııııııııüıııııııüıııııııııııııüşıüııııııııııııüııııüııııııııüııüıüııııüşııııııüııııııııııııııııüıııııüıüıüıüııışıüıüııııııııııııııııııııııüııııııüııııışıııııııüıııııüüıııııııııııüıııııııııüıışııüııııııüııüıııııııııüıııııııııııııııışıııııııııüııııüıııüıüıııııııııııııııııışııııııııüıüıııııııııııııııııııüııııııüışıüııııııüüıııııııııııüııııııııüüııııııışıııııüııüıııııüııüıııııııııüüıııııüıııüşııııüıııııııüııııııııııııııüııııüıııııışıııüııııııııııüıııııııııııüııüııııııııışıııııııııııüıııüııüııııııüıııüııııüıııışııüıüıııüıııııııüüııııııııııüıııııüııııııııııııüııııüıüüıııııııııııııııııüıüııışıııııııüıııııüüıüıııııüıııııııüıııııııüşııııııııııüıııııııııııııııüıııııııüıııışüıııüüııııııııııııııııııııüııııııııüııışıııııüııüııııııııııüııııüüııııııüüıııııııııııııııııııııııııııııüıııııııııııüıüışıııııüıııııııııüıııııııııııııııııüııııışııııııüıııııııııııııııüıııüüııııııııııışıııııııııııııııüııüıııııııııııııııııııışıüııııııııııüıııııüıııııııüııüııııüıııışıüııııııııııııııııüıııııııııııııııııııışıııııııüııııııııııüıüıııüıııııııııııııüşıüıııııüıüııııııııüıııüüııııııüıüıüıııııııııııııııııııııüııııııııııııüııüııüüıışıüıııüııüııııııüıııüııııüıııüıııııüıııışııüııııııııüııııüıııııııııııııııııııııışıııııüıııııııııııııııııııııüııııüıııııışııııüıııııııııııüıııııüıııııııııııüıüııııııııüüüııııııııııııııüııııüüıııüıııııışııııııııııüıııııüüıııııııüıııüıııııııüüşıııııııııüıüııııüııııııııııııııııııüııışüıııııııüıııüııüııııııııııııııııııüıııışıııııııüııııııııııııııııııııııüıııııııışıııüıııııııııııııııüııııııııüııüııüıııışüııüüüııııüııııııüıııııııııııııııüııııııııüıııııııüııııııııııııüııııııııııııııışııııııııııüııııııııııııııııııııııüııııışıüıııııüıııııııııııııııııııııııııüııııışııüııııııııııüııüıüııııııııııııııııııüışıüıüııııııüıııııııııııııııııııııüüııııııüııııııııııııııııııııııııııüüıııüııüııışıııııııııııııııııüıııüııııııııııııııııışüııüüıüıııııııııııııııııııııııııııııııışııüııııııııüıüııııııııüııııüııııııııııüşıııııüııııııııüııııııüııııüııııııüüıüıışıııııııııııııüıııııııııııüüıııüıııııııüşüüıııüııııııüıııııııııüııııııüıııııııııııüıııııııüııııüıııııııııüıııııııııüıııüşııııüıııııııüııııııııııııııııüüıııııııııüııııüııııııııııııııüıüııüıııüüıııııııışııüııııüııııııııııııııııııııııııüıüıııışııııııııüıııııııııüııııııüüıııııııııııışüıııııııüııüııııııııüııııııııııııııııııııııııüıııııııııııııııüıııüııııııııııııışıııııııııııııııüüııüıııııııüıüııııııııışıııüüıııııııııııııüıııııııııııüıııııııışıııııııııııııııüıııııüııüııııııııııııııııııııııııüüıüıııııüıııııııııııııııııııışıııııııııııııııııüııııüııüıııııııııüıüışııüıııııııüııııııüıııııııııııııııııüııışııüıııüııııııııüıııııüııüıüıııııııüıııışııüıııııııüııııııııııüııııüııııııııüııışıııııııııııııııüııııüııüııııııııııüüııışüııııııııııııııııııııüıııüııııııııııüüışıııııııüıııüıüııııüıüıııııııııııııııııışıııüüıııııüıııııııüııııüüıııııııııııııüııııııüııııııııüııııııüııııııııııııııüıışıııııııııııııüıüıııııüıııüıüıüııııııııüşıüıııııııııııııııııııııüüıııüıııııııüıışıııııııııııııııııııııııııııııüıııüüıııüşııııııüıııııüıüıııııüııııııııüıüııııııışııııııııııüııııııııııııııııııııııııüııışüııüıüıııııııüıııüıııııüııııııııüıııııüşıüııııüıüıııııııııüıııııııüııııııııııııııııüııııüüıııııüııııııüüüıüıııııııııııııııüııııııııııııüııııııııııüıüıııııııüıışııııııııııııııüıııııııüıııüıııııııııüıışıüıüıııııııüüıııııııııııııııııııııııııışııııııııııııüıııııüııııııııııüııııııüıışüıııııııüüıüıııııüıııııııııııüııııııııışııııııııııııııüııııııııııııııııııııııüüııııııııııııııüıüıüııııüıııüıüıııüıııüıışııııııııııııııııııııııııııüıııııııııüıüşııııııüıııııııııııüıııııııııııııııüıüıışııııııııııııııııüüııüıııııııııııııııııışıııüıııııııııııüüıııııııııııüıııııüüııışıııııüüıııııııııııııııııııııııııııııııışıüıııııüııııüıııııııııııııııııııııııııııııüııııııüüııüıııııııııııııııııııııüııüşıııııüüüıııüüııııüııııııııüıııııııııııışıııııııııııüııüıııııııııııııııııüıııııııüıııııüıııııııüüüıüıüıııııııüıııııııüıışıııüııııııııııııııııüıııııııııüııııııııııııııüııııııüıııııııüıııııııııııııııııışıııüıııüıııııüııııııııüıııııııııııııııışıııııııııııııııııııııüıüııııüüıııııüııışıııııııııııııüıüııııüıııüıııııüıııııııışııııüıııııüüııııüıııüııııııııııüıııüııışıüıııüııüııüııüıııııüüııüııııııııııııüışııüıııııııııııııııüııııııııııüııüıııııışııııııııııüıüıııııııüııüııııııııııııüıışıııııııııııııııııııüıııııüüııııııııııüışııııüıııııııııııüııüııııııııüüııüıııııışıııüıııııııııııııııüıüıııııııııüıüıııııııııüüıüııüıüııııııııııüıııııüıııııııııışııııııüıııııııüııııııııııııııııııüıııüışıııııııııüııııııııııııııııüııııüüııııııııüııııııüııııııııııııüııııııııııüıııııüşııııııııııııııüıııııüıııııııııııııüıııışııııııııııııııııııııııııııııııııııııııüşüıııüıııııııııüııııüüıüüııııııııııııııışııııııüııııııııüııııııüıüıııııııııııüıışüııüıııııııııııııııııüıııüııııııııııııışııııııüıüıııııııüııııüıüııııüıııüıııııüşüııııııııııııııüıııııüıüıüıüııııüııııüışııııııüııııııııüııüıııııııııııüıüüııııışııııııııııııııııııııııüıııııııııııııııışıııııııııııııııııııııııııııııııııııüııışııııııııüıııııııııııııııııııııııııııııüşııüııııııüııııııııııııııııııııüıııııııışüıııııııııııüıüıııııııııııııııııııııııışııüüııııııııııııııııııüıııııııııııııııışıııüııııııııııüıııııııııııııııııııııııışııüüıüıııııııııııııııııııüıüıüııııııııışüııııııııüııııııüııııııııııııııııııııııııııııııııııııııııııııüıııııüııııııııııüşıııüıııııııııııüııüıüıüıııüıııııüüııııışıııııııııııııüııııüıüıüıııüııüııııııııışıııııııııııııııııııüıüıııüıııüııııııııışüııııııııııüıüüııııııüüıııüıııııııııııışüıııüııııııııııııııııııııııııııüıııüııışııüıııııııııüüııııııııııüııııııııüıııüışııüüıııııııııııııüıııııııııııııııüıııüışııııüııüııııııııııııııııııııııüıııııııüııüııııııııııüıııııüıııııııüıüıııııııııışıüıüııııııııüıııııııııııııııııııııüııııııııııııüııııııııııııüıııııııııııııııııışııııüııüıııııııııııııııııııııüüııııııııııııüıüıııııııııııııııııııııııüıüııııııışıüıııııııııııüıııııııııııııııııııüıüııışııııüıııüıııüııüıııııııııııııııııüıııüııııııııııııııııııüıııııııııııüııııüıüııışııııüııııüıııüııııııııııııııııııııııııışııüıııııııııüııııııııüıııüııüıııııüıııışııııııııııııııııııüııüııııııüıüüıüııııışüııııııııııüüııııııüııııüüıııııüüııııııııııüüııüııııııııüıııııüıııııııııııııııüııüııüııııııüııııııüıııııüıııııııııııııüşııııııııüıııııııııııııııııüüıııüüııııüüşııüıüııııııüııüııııüıüııııüıııüıııııüıışııııııııııııııııüııııııııııüııüüııııııışııııııııııııııııııııııüııııııııııüııııışııııııııııııııııııüıııııüıııııüııııııüışıııııııııııııııııııüıüıııüııııııııııııüşıııııüııııııııüııüıııüıüııııııııüıııııışııııııııııüıııüıüüııııııüıııııııııııııışüııııüıııııııüıııııııüüııüıııııııııııııııııüııııüıııııııııııııııııııııüıııııııışıüüıııııüüııııııüıııııııııııııııııııııışıııııııııııııııııııüııııııııııııııüııüışıııııııııııııııııııııııııııüııııııııııışııııüııııüüüıııııııııüıııııüıııııüüıııüşııüııııüüıııııııııııııııüııııııüııııııışııüııııııııııııııııııııııüıııüııııııııışııııııııüııüüııııııııüıüıııııüııııııııışııüııııııüııııııüııüüııııııüüüııüıüıüıışııııııııııüıııııııüııüıüııııüıııııııııışıııüıııüııııııüıüııııııııııüıııüııııııışııııüıııüıııüüııüıııııııüıııüıııııııııııııııüıııüıııııııüıııııııııııııüıııııııışııüııııııııüııııııııııııııüıııııııııııışıııııııııııııııııııııüııııüııııüıııııüışüıııııııııııııüııııüııııııııııüüıüıııııııııııııııııüııııııüııııııııııüüıııııııışıüııııııüıııııııııııııııııüıııüıüıüıııüşııııüıııııııııııııııııııüııııüüıııüıııüşıııııııııııııııııüüııııııüııııııııııııışıüüıııııııııüıüıııııııııııııüııııııüııışııııııııııüıııııüıııııııııııııüüııııııüşıııııııııııııııııııüıııııüııııııııııııışıııüııüıııııııııüııııııııııüııüıüıııııışıııııııııııüıııııüıııüüıııııüııııııııüışııııııııııııüıııııııüıııüıııııüıııııııışüııııııııııııııııııııııüııüııııııııııüışııııııüıııııııüıüııııüııııııüııüııııııüşııııııııııııüıııııııııııııııııııııııııışııııııııııııııııüııııüıııııııııüıüııııışıııııüııııııııııııııııııııııııııııııııışıııııüıııııııııııııüıııııııüııııüııüüıışıııııııııııüıııııııııüıııüıııııııııııüüşıüıııııııüıııııııııııüııııııııııııııııışıııııııııüııııııııııüüıııüııııııııııııııüıüııııııııüıııııııııııııııııüıüıııüııııııüıüııüıııııüıııııüııııııüüııüıııııüıışıııııüıüüııııııüııııııııııüıüıııııııııııııııüıııııüüüıüıııüıüıüıııııııııııııııüşııüıüıııııııııııüıüııııııııııüıııııüııışıııııüıııııııııııüııııııııııııııııüıııışııııııüüııııııüııııııııııııııııııüıüııışıııüıııüıııııüıüıııüıüııüıııüıııııııııışııııııııııııııııııııııııııııııııııııııışıııüüıııııüııüıııııııııüııııııüüııüıııışüııııüıüıııııııüıüıııııüııııııııııüüıüışüıııııııııııııııüüııııııııııııııııııııışıııııüııııııııııııııııüıııüııııııııııüışııııııııüııııııııııüıüııııııııııııüııüışıııııııüıııııüııüıııııııııııııııüıııııışıııııııüıııııııııüııüıüııüıüııııııııııışüıııııııııııııııııüıııııııııüıııııııııışııüüııııııııııüıııııııııııııııııııııııışıııııııııııüııııüıııııüüıüıııııııüııüıışııüıııüııüııııııııüııüıııüııııııııııııışıüıııııııııııııııııııııııüııüıııüüııııüşıııüüııııııııııııüııııııııııüııüııııııüşııüııııüıııııııııııııııııııııııııııııııııüııııııııııüııııııııııüıııüııııııııııışıüııııııııüııııııüııııııııüıııııııııııışıııııııüıüııüııııüııııüııııııüııııııııışııııııııııüıııııııüıüıııııııııııüıııııüşııııııııııııııüııüıııııüııııııııııııııııııüııüııüııüııııııııııııııııııııııııııışııııııııııııııııüıııııııııüıııııııııııışıüıüüıüııııııüııüıııııııııüıüıııııııııışııııııııııııııııııüıııııüııııııııüııııışıüüıüııüıüıııııııııııııüııııüıııııııııış \ No newline at end of file diff --git a/wx_alert_product.txt b/wx_alert_product.txt new file mode 100755 index 0000000..84945b6 --- /dev/null +++ b/wx_alert_product.txt @@ -0,0 +1,99 @@ +TORNADO WARNING +SEVERE THUNDERSTORM WARNING +FLASH FLOOD WARNING +TSUNAMI WARNING +INLAND HURRICANE WIND WARNING +HURRICANE FORCE WIND WARNING +HURRICANE WARNING +TYPHOON WARNING +BLIZZARD WARNING +ICE STORM WARNING +TROPICAL STORM WARNING +HEAVY SNOW WARNING +WINTER STORM WARNING +INLAND TROPICAL STORM WARNING +DUST STORM WARNING +STORM WARNING +COASTAL FLOOD WARNING +LAKESHORE FLOOD WARNING +HIGH SURF WARNING +HEAVY SLEET WARNING +FLOOD WARNING +HIGH WIND WARNING +LAKE EFFECT SNOW WARNING +EXCESSIVE HEAT WARNING +RED FLAG WARNING +WIND CHILL WARNING +AVALANCHE WARNING +FREEZE WARNING +GALE WARNING +FLASH FLOOD STATEMENT +SPECIAL MARINE WARNING +SEVERE WEATHER STATEMENT +TORNADO WATCH +SEVERE THUNDERSTORM WATCH +FLASH FLOOD WATCH +HURRICANE WATCH +TYPHOON WATCH +HURRICANE LOCAL STATEMENT +TYPHOON LOCAL STATEMENT +SNOW AND BLOWING SNOW ADVISORY +FREEZING RAIN ADVISORY +FREEZING DRIZZLE ADVISORY +SNOW ADVISORY +SLEET ADVISORY +WINTER WEATHER ADVISORY +LAKE EFFECT SNOW ADVISORY +WIND CHILL ADVISORY +HEAT ADVISORY +HIGH SURF ADVISORY +BLOWING SNOW ADVISORY +HEAVY FREEZING SPRAY WARNING +DENSE SMOKE ADVISORY +SMALL CRAFT ADVISORY +DENSE FOG ADVISORY +MARINE WEATHER STATEMENT +WIND ADVISORY +BLOWING DUST ADVISORY +FROST ADVISORY +LAKE WIND ADVISORY +ASHFALL ADVISORY +FREEZING FOG ADVISORY +AIR STAGNATION ADVISORY +TSUNAMI WATCH +COASTAL FLOOD WATCH +LAKESHORE FLOOD WATCH +BLIZZARD WATCH +TROPICAL STORM WATCH +INLAND TROPICAL STORM WATCH +INLAND HURRICANE WIND WATCH +WINTER STORM WATCH +FLOOD WATCH +LAKE EFFECT SNOW WATCH +HIGH WIND WATCH +EXCESSIVE HEAT WATCH +WIND CHILL WATCH +FREEZE WATCH +FIRE WEATHER WATCH +AVALANCHE WATCH +EARTHQUAKE WARNING +LOCAL AREA EMERGENCY +LAW ENFORCEMENT WARNING +911 TELEPHONE OUTAGE +HAZARDOUS MATERIALS WARNING +NUCLEAR POWER PLANT WARNING +RADIOLOGICAL HAZARD WARNING +CIVIL DANGER WARNING +CIVIL EMERGENCY MESSAGE +EVACUATION IMMEDIATE +FIRE WARNING +SHELTER IN PLACE WARNING +VOLCANO WARNING +FLOOD STATEMENT +COASTAL FLOOD STATEMENT +LAKESHORE FLOOD STATEMENT +SPECIAL WEATHER STATEMENT +SHORT TERM FORECAST +FIRE DANGER STATEMENT +HAZARDOUS WEATHER OUTLOOK +CHILD ABDUCTION EMERGENCY diff --git a/wx_critical_alerts.txt b/wx_critical_alerts.txt new file mode 100755 index 0000000..e1e4b24 --- /dev/null +++ b/wx_critical_alerts.txt @@ -0,0 +1,10 @@ +SEVERE THUNDERSTORM WARNING +TORNADO WARNING +TORNADO WATCH +ICE STORM WARNING +NUCLEAR POWER PLANT WARNING +EVACUATION IMMEDIATE +VOLCANO WARNING +WIND CHILL WARNING +WINTER STORM WARNING +EMERGENCY diff --git a/wx_haz.txt b/wx_haz.txt new file mode 100755 index 0000000..b32011b --- /dev/null +++ b/wx_haz.txt @@ -0,0 +1,44 @@ +FLUS41 KILN 232049 +HWOILN + +Hazardous Weather Outlook +National Weather Service Wilmington OH +349 PM EST Thu Feb 23 2017 + +INZ050-058-059-066-073>075-080-KYZ089>100-OHZ026-034-035-042>046- +051>056-060>065-070>074-077>082-088-241200- +Wayne-Fayette IN-Union IN-Franklin IN-Ripley-Dearborn-Ohio- +Switzerland-Carroll-Gallatin-Boone-Kenton-Campbell-Owen-Grant- +Pendleton-Bracken-Robertson-Mason-Lewis-Hardin-Mercer-Auglaize-Darke- +Shelby-Logan-Union OH-Delaware-Miami-Champaign-Clark-Madison- +Franklin OH-Licking-Preble-Montgomery-Greene-Fayette OH-Pickaway- +Fairfield-Butler-Warren-Clinton-Ross-Hocking-Hamilton-Clermont-Brown- +Highland-Adams-Pike-Scioto- +349 PM EST Thu Feb 23 2017 + +This Hazardous Weather Outlook is for East Central Indiana, +Southeast Indiana, Northeast Kentucky, Northern Kentucky, Central + +.DAY ONE...This Afternoon and Tonight. + +Hazardous weather is not expected at this time. + +.DAYS TWO THROUGH SEVEN...Friday through Wednesday. + +A strong cold front is forecast to sweep east through the region +Friday night. Thunderstorms will be likely along and ahead of this +front. The potential exists for some thunderstorms to reach severe +limits. The main severe weather threat will be damaging winds. +However, large hail and isolated tornadoes will also be +possible. + +Gusty winds of 30 mph to 40 mph will be possible Saturday behind +cold frontal passage. + +.SPOTTER INFORMATION STATEMENT... + +Spotter activation may be required on Friday. + +$$ + + diff --git a/wx_normal_alerts.txt b/wx_normal_alerts.txt new file mode 100755 index 0000000..cbea0de --- /dev/null +++ b/wx_normal_alerts.txt @@ -0,0 +1,2 @@ +WARNING +WATCH diff --git a/wx_scripts.conf b/wx_scripts.conf new file mode 100755 index 0000000..f70a63c --- /dev/null +++ b/wx_scripts.conf @@ -0,0 +1,139 @@ +#!/bin/bash +# Weather Script Configuration File. Sets up the variables used by the various weather scripts. +# +# $Id: wx_scripts.conf 78 2011-04-22 18:04:11Z $ + +# The weather scirpts require: +# text to speech programs - +# Festival [http://www.cstr.ed.ac.uk/projects/festival/], +# **Or** +# Cepstral Text to Speech. [http://www.cepstral.com] +# +# wget for proper operation. +# +# +CUSTOM=/home/irlp/custom +# node call with spaced letters, for speech programs +CALL_SPACED="N 8 M F N" +export CALL_SPACED + +# Choose the speech to text software desired. If cepstal is choosen, you must +# install the new software and configure the voice. + +# Uncomment one only. +TEXT2SPEECH=festival # Festival Text to speech sw +#TEXT2SPEECH=cepstral # Cepstral Text to speech sw + +# text2wave binary location for festival +TEXT2WAVEBIN=/usr/bin/text2wave + +#if using Cepstral, define defualt voice below +SWIFT_DEFAULT_VOICE=David #define the voice +SWIFT_VOL=100 # Volue control for swift voice, + # volume in precentage + +# location of swift binary, can also be in opt +SWIFTBIN=/opt/swift/bin/swift + +# Zone information for Weather Alerts +# See WxScripts.txt documentation +ZONE=OHZ070 + +# NWS County Information, MNC171 plus county name for example: +# COUNTY="MNC171, Wright County" +COUNTY="OHC017, BUTLER County" # NWS County Information, MNC171 +COUNTY_NAME="Bulter County" + +ICAO_STN=KHAO + +# for Weather Underground Stations +WX_UNDERGRND_STN=ME3028 + +# Email address to where skywarn notices will be sent. Must have email +# configured correctly. If not used, comment out option. +#EMAIL="151347336840@tmomail.net" + +# Play Weather Alert Beacon +WXALERT_BEACON="Y" # Play weather alert message + # "C" = critical alerts only + # "Y" = yes, "N" = no + +ACTIVE_PLAY="TRUE" # if TRUE, allows playing of weather + # messages when connected to other + # nodes. If not desired, change to + # "FALSE" + +################################################################## +# Should not need to modify the following, but just in case.. +# Binary file locations +# +WGET="/usr/bin/wget" + +# Directories used by weather scripts: +# +WXDIR="$AUDIO/custom/wx" + +# Weather Alert Specific Variables +# Alert spool directory +WXALERT_SPOOLDIR="$WXDIR/alert" # Location for raw audio and data + +# Weather Forcast Specific Variables +# Forcast spool directory +WXFOR_SPOOLDIR="$WXDIR/forecast" + +###################################################################### +# No editing required from this point. +###################################################################### + +# export Cepstral Voice +if [ "$TEXT2SPEECH" = "cepstral" ] ; then + export SWIFT_DEFAULT_VOICE +fi + +# Create Spool directory (WXALERT_SPOOLDIR) +if [ ! -d $WXALERT_SPOOLDIR ] ; then + mkdir -p $WXALERT_SPOOLDIR +fi + +# create spool directory if not preset +if [ ! -d $WXFOR_SPOOLDIR ] ; then + mkdir -p $WXFOR_SPOOLDIR +fi + +# Setup Text to Speech command +if [ "$TEXT2SPEECH" = "festival" ] ; then + TEXT2WAVE=$TEXT2WAVEBIN +fi +if [ "$TEXT2SPEECH" = "cepstral" ] ; then + TEXT2WAVE=$SWIFTBIN +fi + +# irlp common functions: +# +# description: Places the commonly used functions into one place where +# it is eay to get to. This eliminates having to place the +# commands in each script where they are used. Just need +# to source this one file to get all of its functions. +# +# history: +# 20030706 kc6hur Original release +# 20050806 kc6hur Changed "must be repeater" message +######################################################################## + +######################################################################## +# +# Convenience functions +# +# Send message to LOGFILE +function log () { + MESSAGE="${0##*/}: $@" + echo "$MESSAGE" + if [ -n "$LOGFILE" ]; then + echo "`date '+%b %d %Y %T %z'` $MESSAGE" >> $LOGFILE + fi +} + +####################################################################### +# +# +# END Common Functions diff --git a/wx_scripts.conf.RPMNEW b/wx_scripts.conf.RPMNEW new file mode 100755 index 0000000..50c3c2c --- /dev/null +++ b/wx_scripts.conf.RPMNEW @@ -0,0 +1,155 @@ +#!/bin/bash +# Weather Script Configuration File. Sets up the variables used by the various weather scripts. +# +# $Id: wx_scripts.conf 85 2012-07-21 23:13:23Z $ + +# The weather scirpts require: +# text to speech programs - +# Festival [http://www.cstr.ed.ac.uk/projects/festival/], +# **Or** +# Cepstral Text to Speech. [http://www.cepstral.com] +# +# wget for proper operation. +# +# + +# node call with spaced letters, for speech programs +CALL_SPACED="W 0 A N M" +export CALL_SPACED + +# Choose the speech to text software desired. If cepstal is choosen, you must +# install the new software and configure the voice. + +# Uncomment one only. +# TEXT2SPEECH=festival # Festival Text to speech sw +TEXT2SPEECH=cepstral # Cepstral Text to speech sw + +# text2wave binary location for festival +TEXT2WAVEBIN=/usr/bin/text2wave + +#if using Cepstral, define defualt voice below +SWIFT_DEFAULT_VOICE=David #define the voice +SWIFT_VOL=100 # Volue control for swift voice, + # volume in precentage + +# location of swift binary, can also be in opt +SWIFTBIN=/opt/swift/bin/swift + +# Zone information for Weather Alerts +# See WxScripts.txt documentation +ZONE=MNZ059 + +# NWS County Information, MNC171 plus county name for example: +# COUNTY="MNC171, Wright County" +COUNTY="NOTSET, County Name" # NWS County Information, MNC171 + +ICAO_STN=KCFE + +# for Weather Underground Stations +WX_UNDERGRND_STN=KMNSTMIC3 + +# Email address to where skywarn notices will be sent. Must have email +# configured correctly. If not used, comment out option. +# EMAIL="chris@myisp.com, w0anm_73@arrl.net" + +# Play Weather Alert Beacon +WXALERT_BEACON="Y" # Play weather alert message + # "C" = critical alerts only + # "Y" = yes, "N" = no + +ACTIVE_PLAY="TRUE" # if TRUE, allows playing of weather + # messages when connected to other + # nodes. If not desired, change to + # "FALSE" + +FULL_ALERT="N" # Alert Summary, Full or Truncated + # "Y" - Full alert info + # "N" - No (truncated) + +################################################################## +# Should not need to modify the following, but just in case.. +# Binary file locations +# +WGET="/usr/bin/wget" + +# Directories used by weather scripts: +# +WXDIR="$AUDIO/custom/wx" + +# Weather Alert Specific Variables +# Alert spool directory +WXALERT_SPOOLDIR="$WXDIR/alert" # Location for raw audio and data + +# Weather Forcast Specific Variables +# Forcast spool directory +WXFOR_SPOOLDIR="$WXDIR/forecast" + +###################################################################### +# No editing required from this point. +###################################################################### + +# export Cepstral Voice +if [ "$TEXT2SPEECH" = "cepstral" ] ; then + export SWIFT_DEFAULT_VOICE +fi + +# Create Spool directory (WXALERT_SPOOLDIR) +if [ ! -d $WXALERT_SPOOLDIR ] ; then + mkdir -p $WXALERT_SPOOLDIR +fi + +# create spool directory if not preset +if [ ! -d $WXFOR_SPOOLDIR ] ; then + mkdir -p $WXFOR_SPOOLDIR +fi + +# Setup Text to Speech command +if [ "$TEXT2SPEECH" = "festival" ] ; then + TEXT2WAVE=$TEXT2WAVEBIN +fi +if [ "$TEXT2SPEECH" = "cepstral" ] ; then + TEXT2WAVE=$SWIFTBIN +fi + +# irlp common functions: +# +# description: Places the commonly used functions into one place where +# it is eay to get to. This eliminates having to place the +# commands in each script where they are used. Just need +# to source this one file to get all of its functions. +# +# history: +# 20030706 kc6hur Original release +# 20050806 kc6hur Changed "must be repeater" message +######################################################################## + +######################################################################## +# +# Convenience functions +# +# Send message to LOGFILE +function log () { + MESSAGE="${0##*/}: $@" + echo "$MESSAGE" + if [ -n "$LOGFILE" ]; then + echo "`date '+%b %d %Y %T %z'` $MESSAGE" >> $LOGFILE + fi +} + +####################################################################### +# +# Standard Script Opening +# +# Make sure we are user repeater!!! +if [ `/usr/bin/whoami` != "repeater" ] ; then + echo "${0##*/} must be run as user \"repeater\"!" + exit 1 +fi + +# Make sure we have sourced the environment file +if [ "$RUN_ENV" != "TRUE" ] ; then + . /home/irlp/custom/environment +fi + +# +# END Common Functions diff --git a/wx_scripts.conf.RPMSAVE b/wx_scripts.conf.RPMSAVE new file mode 100755 index 0000000..996a1e8 --- /dev/null +++ b/wx_scripts.conf.RPMSAVE @@ -0,0 +1,151 @@ +#!/bin/bash +# Weather Script Configuration File. Sets up the variables used by the various weather scripts. +# +# $Id: wx_scripts.conf 78 2011-04-22 18:04:11Z $ + +# The weather scirpts require: +# text to speech programs - +# Festival [http://www.cstr.ed.ac.uk/projects/festival/], +# **Or** +# Cepstral Text to Speech. [http://www.cepstral.com] +# +# wget for proper operation. +# +# + +# node call with spaced letters, for speech programs +CALL_SPACED="K B 8 P M Y" +export CALL_SPACED + +# Choose the speech to text software desired. If cepstal is choosen, you must +# install the new software and configure the voice. + +# Uncomment one only. +TEXT2SPEECH=festival # Festival Text to speech sw +#TEXT2SPEECH=cepstral # Cepstral Text to speech sw + +# text2wave binary location for festival +TEXT2WAVEBIN=/usr/bin/text2wave + +#if using Cepstral, define defualt voice below +SWIFT_DEFAULT_VOICE=David #define the voice +SWIFT_VOL=100 # Volue control for swift voice, + # volume in precentage + +# location of swift binary, can also be in opt +SWIFTBIN=/opt/swift/bin/swift + +# Zone information for Weather Alerts +# See WxScripts.txt documentation +ZONE=OHZ070 + +# NWS County Information, MNC171 plus county name for example: +# COUNTY="MNC171, Wright County" +COUNTY="OHC017, BUTLER County" # NWS County Information, MNC171 + +ICAO_STN=KHAO + +# for Weather Underground Stations +WX_UNDERGRND_STN=KMNSTMIC3 + +# Email address to where skywarn notices will be sent. Must have email +# configured correctly. If not used, comment out option. +# EMAIL="chris@myisp.com, w0anm_73@arrl.net" + +# Play Weather Alert Beacon +WXALERT_BEACON="Y" # Play weather alert message + # "C" = critical alerts only + # "Y" = yes, "N" = no + +ACTIVE_PLAY="TRUE" # if TRUE, allows playing of weather + # messages when connected to other + # nodes. If not desired, change to + # "FALSE" + +################################################################## +# Should not need to modify the following, but just in case.. +# Binary file locations +# +WGET="/usr/bin/wget" + +# Directories used by weather scripts: +# +WXDIR="$AUDIO/custom/wx" + +# Weather Alert Specific Variables +# Alert spool directory +WXALERT_SPOOLDIR="$WXDIR/alert" # Location for raw audio and data + +# Weather Forcast Specific Variables +# Forcast spool directory +WXFOR_SPOOLDIR="$WXDIR/forecast" + +###################################################################### +# No editing required from this point. +###################################################################### + +# export Cepstral Voice +if [ "$TEXT2SPEECH" = "cepstral" ] ; then + export SWIFT_DEFAULT_VOICE +fi + +# Create Spool directory (WXALERT_SPOOLDIR) +if [ ! -d $WXALERT_SPOOLDIR ] ; then + mkdir -p $WXALERT_SPOOLDIR +fi + +# create spool directory if not preset +if [ ! -d $WXFOR_SPOOLDIR ] ; then + mkdir -p $WXFOR_SPOOLDIR +fi + +# Setup Text to Speech command +if [ "$TEXT2SPEECH" = "festival" ] ; then + TEXT2WAVE=$TEXT2WAVEBIN +fi +if [ "$TEXT2SPEECH" = "cepstral" ] ; then + TEXT2WAVE=$SWIFTBIN +fi + +# irlp common functions: +# +# description: Places the commonly used functions into one place where +# it is eay to get to. This eliminates having to place the +# commands in each script where they are used. Just need +# to source this one file to get all of its functions. +# +# history: +# 20030706 kc6hur Original release +# 20050806 kc6hur Changed "must be repeater" message +######################################################################## + +######################################################################## +# +# Convenience functions +# +# Send message to LOGFILE +function log () { + MESSAGE="${0##*/}: $@" + echo "$MESSAGE" + if [ -n "$LOGFILE" ]; then + echo "`date '+%b %d %Y %T %z'` $MESSAGE" >> $LOGFILE + fi +} + +####################################################################### +# +# Standard Script Opening +# +# Make sure we are user repeater!!! +if [ `/usr/bin/whoami` != "repeater" ] ; then + echo "${0##*/} must be run as user \"repeater\"!" + exit 1 +fi + +# Make sure we have sourced the environment file +if [ "$RUN_ENV" != "TRUE" ] ; then + . /home/irlp/custom/environment +fi + +# +# END Common Functions diff --git a/wxtext_conv.sed b/wxtext_conv.sed new file mode 100755 index 0000000..73a2478 --- /dev/null +++ b/wxtext_conv.sed @@ -0,0 +1,18 @@ +s/Minneapolis-St./Minneapolis Saint/g +s/ EST/ Eastern Standard Time /g +s/ est/ Eastern Standard Time /g +s/ EDT/ Eastern Daylight Time /g +s/ edt/ Eastern Daylight Time /g +s/ MPH/ miles per hour /g +s/ mph/ miles per hour /g +s/ MPH./ miles per hour./g +s/ mph./ miles per hour./g +s/ AM / A M /g +s/ PM / P M /g +s/ WIND/ wend/g +s/WIND/wend/g +s/ wind/ wend/g +s/ SNOW/ sno/g +s/ snow/ sno/g +s/NWS/National Weather Service/g +s/nws/National Weather Service/g diff --git a/wxtext_conv.sed.RPMNEW b/wxtext_conv.sed.RPMNEW new file mode 100755 index 0000000..2be99ca --- /dev/null +++ b/wxtext_conv.sed.RPMNEW @@ -0,0 +1,18 @@ +s/Minneapolis-St./Minneapolis Saint/g +s/ CST/ Central Standard Time /g +s/ cst/ Central Standard Time /g +s/ CDT/ Central Daylight Time /g +s/ cdt/ Central Daylight Time /g +s/ MPH/ miles per hour /g +s/ mph/ miles per hour /g +s/ MPH./ miles per hour./g +s/ mph./ miles per hour./g +s/ AM / A M /g +s/ PM / P M /g +s/ WIND/ wend/g +s/WIND/wend/g +s/ wind/ wend/g +s/ SNOW/ sno/g +s/ snow/ sno/g +s/NWS/National Weather Service/g +s/nws/National Weather Service/g