diff --git a/README.md b/README.md index 35f5de0..d95ede9 100644 --- a/README.md +++ b/README.md @@ -12,15 +12,16 @@ addition is the new adapter.c file: It encapsulates all those APIs that interfac JavaScript/Web world. ## Credits -This "project" is based on libxmp (4.3.0): http://xmp.sourceforge.net/ +This "project" is based on libxmp (4.4.1): http://xmp.sourceforge.net/ ## Howto build + You'll need Emscripten (http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html). The make script is designed for use of emscripten version 1.37.29 (unless you want to create WebAssembly output, older versions might also still work). -The below instructions assume that the libxmp-4.3.0 project folder has been moved into the main emscripten +The below instructions assume that the libxmp-4.4.1 project folder has been moved into the main emscripten installation folder (maybe not necessary) and that a command prompt has been opened within the project's "emscripten" sub-folder, and that the Emscripten environment vars have been previously set (run emsdk_env.bat). diff --git a/docs/COPYING.LIB b/docs/COPYING.LIB deleted file mode 100644 index 4362b49..0000000 --- a/docs/COPYING.LIB +++ /dev/null @@ -1,502 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/docs/CREDITS b/docs/CREDITS deleted file mode 100644 index 12cc891..0000000 --- a/docs/CREDITS +++ /dev/null @@ -1,230 +0,0 @@ -The Authors - -- Mirko Buffoni - * Windows port fixes - * random hacks and improvements - -- Frederic Bujon - * XM pan fix - -- Hipolito Carraro Jr - * main player coding - * software mixer - * virtual channel system design and implementation - -- Rudolf Cejka - * MED loader alignment and endianism fixes - * XM loader endianism fixes - * S3M loader fixes - -- Sylvain Chipaux - * Prowizard loaders - -- Chris Cox - * S3M loader fixes - -- Michael Doering - * RAR unpacking support - * PP20 decrunching fixes - -- Rune Elvemo - * fixes for endianism problems in Linux/PPC - -- Mike Gorchak - * misc hacks - -- Tom Hargreaves - * Digital Symphony and Archimedes Tracker loader fixes - -- Kevin Langman - * OS/2 port - -- Stephen Leary - * AMOS Music Bank format loader - -- Claudio Matsuoka - * main player coding - * module loaders - -- Dominik Mierzejewski - * fixes for gcc 2.96/glibc 2.2 - -- Francis Russell - * OctaMED tempo fixes - -- Adam Sampson - * buildsystem and configuration file location fixes - -- Johan Samuelsson - * Amiga port and fixes - -- Attila Sipos - * SQSH decruncher checksum - -- Miodrag Vallat - * 669 loader fixes - * XM loader endianism fixes - -- Chris Young - * Amiga port and fixes - - -Other contributors: - -Antti Huovilainen, Michael Janson, Matthias Leonhardt, Andy Eltsov, -Davi Lima, Geoff Reedy, Sipos Attila, Bjoern Fisher, Matus Telgarsky, -Bernhard März, Cyke O'Path, Rudolf Cejka, Igor Krpanic, Chris Cox, -Rudá Moura, Paul Wise, Henrik Pauli, Zbigniew Luszpinski, Jon Rafkind, -Reynir Stefansson, Ralf Hoffmann, Douglas Carmichael, Adric Riedel, -Gürkan Sengün, Lorence Lombardo, Martin Willers, Laurent Clevy, -Michael Doering, Bert Jahn, Adi Sapir, Jools Smyth, Martin Jeppesen, -Stuart Caie, Bernhard März, Matthias Arndt. - - -Third-party code licenses: - -MD5 digest - - This code implements the MD5 message-digest algorithm. - The algorithm is due to Ron Rivest. This code was - written by Colin Plumb in 1993, no copyright is claimed. - This code is in the public domain; do with it what you wish. - - Equivalent code is available from RSA Data Security, Inc. - This code has been tested against that, and is equivalent, - except that you don't need to include two pages of legalese - with every copy. - - -Powerpack depacker - - Based on code by Stuart Caie - Modified by Michael Doering and Claudio Matsuoka - This software is in the Public Domain - - -YM3812 emulator - - fmopl.c -- software implementation of FM sound generator - This version of fmopl.c is a fork of the MAME one, relicensed under the LGPL. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - -XZ decompressor - - XZ Embedded is a relatively small, limited implementation of the .xz - file format. Currently only decoding is implemented. - - Authors: Lasse Collin - Igor Pavlov - This file has been put into the public domain. - You can do whatever you want with this file. - - -Zip decompressor - - This code is Copyright 2005-2006 by Michael Kohn - - This package is licensed under the LGPL. You are free to use this library - in both commercial and non-commercial applications as long as you dynamically - link to it. If you statically link this library you must also release your - software under the LGPL. If you need more flexibility in the license email - and we can work something out. - - -Stonecracker decompressor - - StoneCracker S404 algorithm data decompression routine - (c) 2006 Jouni 'Mr.Spiv' Korhonen. The code is in public domain. - - -Bzip2 decompressor - - Small bzip2 deflate implementation, by Rob Landley (rob@landley.net). - - Based on bzip2 decompression code by Julian R Seward (jseward@acm.org), - which also acknowledges contributions by Mike Burrows, David Wheeler, - Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten, - Robert Sedgewick, and Jon L. Bentley. - - This code is licensed under the LGPLv2: - LGPL (http://www.gnu.org/copyleft/lgpl.html) - - Size and speed optimizations by Manuel Novoa III (mjn3@codepoet.org) - - -Arc decompressor - - nomarch 1.4 - extract old `.arc' archives. - Copyright (C) 2001-2006 Russell Marks. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - -LHA decompressor - - LhA file archiver client - XAD library system for archive handling - Copyright (C) 1998 and later by Dirk Stoecker - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - -LZX decompressor - - LZX file archiver client - XAD library system for archive handling - Copyright (C) 1998 and later by Dirk Stöcker - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - -DMF sample decompressor -IT resonant filters -IT sample decompressor - - Modplug Plugin for XMMS v2.0 / libmodplug v0.8.5 - Based on the ModPlug sound engine by Olivier Lapicque - - This source code is public domain. - Authors: Olivier Lapicque - - -MED2 module loading code - - V2.00 file loading/saving routines by T. Kinnunen 1990 - MED2.00 by Teijo Kinnunen, 1990 - MED is in Public Domain - - -Vorbis decoder - - Ogg Vorbis I audio decoder -- version 0.99996 - Written in April 2007 by Sean Barrett, sponsored by RAD Game Tools. - - Placed in the public domain April 2007 by the author: no copyright is - claimed, and you may use it for any purpose you like. - - -ptpopen - A Windows replacement for popen() - - pt_popen/pt_pclose functions - Written somewhere in the 90s by Kurt Keller - - This piece of code is in the public domain. I do not claim any rights - on it. Do whatever you want to do with it and I hope it will be still - useful. - diff --git a/docs/Changelog b/docs/Changelog deleted file mode 100644 index ac19432..0000000 --- a/docs/Changelog +++ /dev/null @@ -1,1402 +0,0 @@ -Stable versions ---------------- - -4.3.0 (): - Fix bugs reported by Sami Jumppanen: - - fix MED4 instrument numbering - - fix MED effect FFF (turn note off) - - fix MED synth finetune effect - Fix bugs reported by Alexander Null: - - fix fine volume slide memory - - fix IT portamento after note end in sample mode - - fix S3M portamento after note end - Fix bugs caught in the OpenMPT test cases: - - add XM and IT envelope loop and sustain point quirk - - fix Amiga limits for notes with finetune - - fix XM invalid offset handling - - fix XM note release reset on new volume - - fix XM pattern loader to honor header size - - fix XM fine volume slide effect memory - - fix XM fine pitch slide effect memory - - fix XM finetune effect - - fix IT portamento if offset effect is used - - fix IT NNA on invalid sample mapping - - fix IT filter envelope index reset - - fix IT envelope carry on note cut events - - fix IT envelope reset on new instrument - - fix IT instrument change on portamento in compatible GXX mode - - fix IT unmapped sample parsing - - fix IT filter cutoff reset - Other changes: - - add API call to load a module from a file handle - - add API call to set default pan separation value - - add OpenMPT test cases to regression test suite - - add AMOS Music Bank loader (by Stephen Leary) - - refactor memory I/O calls - - read OctaMED annotation and song info text - - fix segfault in mixer caused by sample position overflow - - fix MED synth pitch slide reset on new note - - fix OctaMED SS default pitch transpose (reported by Karl Churchill) - - fix OctaMED instrument name loading - - fix XM, S3M, IT and MED offset effect handling - - fix IT fadeout and envelope reset on new virtual channel - - fix S3M shared effect parameter memory - - fix S3M default pan positions - - fix S3M set BPM effect with values < 32 (reported by Kyu S.) - - fix incorrect Noisetracker effect filtering (reported by Kyu S.) - - fix loop counter reset on play buffer reset - - fix finetune effect - -4.2.8 (20140714): - Fix bugs reported by Sami Jumppanen: - - fix OctaMED decimal volume decoding - - fix MED4 sampled instrument octave range - - fix mishandling of MED4 effect FFD - - fix MED synth waveform command CHD - Other changes: - - fix sequence number reset on player start - - fix stray notes in XM (reported by Andreas Argirakis) - - limit note number to avoid crash (reported by Bastian Pflieger) - - disable recursive file decompression - -4.2.7 (20140412): - - add support for XM with ADPCM samples (reported by mk.bikash) - - add OctaMED effect 2E (reported by Andreas Argirakis) - - fix MMD2/3 note event mapping (reported by Andreas Argirakis) - - fix XM set pan effect - - fix IT disabled instrument pan - -4.2.6 (20140407): - Fix bugs reported by Andreas Argirakis: - - add OctaMED 2 to 7 octave IFFOCT sample loader - - fix volume in MED synth instruments - - fix OctaMED V5 MMD2 sample transpose - Other changes: - - fix double free in module loaded from memory (by Arnaud Trol) - - fix old Soundtracker sample loops (reported by Dennis Lindroos) - - fix Win64 portability issues (reported by Ozkan Sezer) - - fix OctaMED 3 octave limit for sampled instruments - - fix OctaMED hold/decay event support - - fix OctaMED vibrato effect depth - - fix IT tempo slide effect - - fix Visual C++ nmake build issues - - refactor OctaMED event reader - - generate Android NDK static libraries - -4.2.5 (20140302): - - fix Oktalyzer sample numbering (reported by Andreas Argirakis) - - fix XM delay effect with invalid instrument - - disable incomplete Graoumf Tracker loader - - disable incomplete TCB Tracker loader - - code refactor for core mod player library subset - -4.2.4 (20140222): - Fix bugs reported by Justin Crawford: - - fix XM note and envelope retrig on delay effect - - fix XM keyoff reset on new note event - - fix retrig effect frame counter - - fix envelope update after manually set point - Other changes: - - fix Chiptracker pattern decoding (reported by Andreas Argirakis) - - fix AMF sample loop end - - fix false positives in Slamtilt format test - - refactor S3M arpeggio effect memory - - disable incomplete DMF loader - - disable incomplete DTT loader - - address clang-analyzer warnings - -4.2.3 (20140118): - - remove limit of samples in RTM loader - - fix S3M length bug introduced in 4.2.1 (reported by Misty De Meo) - - fix MDL effect decoding - - fix MDL envelope decoding - - fix MDL fadeout setting when envelopes are disabled - - fix MDL instrument vibrato depth - - fix MDL sample loop size - - fix MDL fine volume slide effect - - fix MacOS X dylib versioning - -4.2.2 (20140111): - - re-enable Falcon MegaTracker loader - - fix DIGI Booster finetune (reported by Andreas Argirakis) - - fix tempo in BPM mode MMD modules (reported by Andreas Argirakis) - - fix crash in zip depacker - - fix MED4 large (>64KB) sample loading - - fix MED4 sample loop flag setting - - fix MMD Protracker-compatible volume slide effect - - fix number of channels in GDM loader - - fix number of channels in MED4 loader - - fix instrument name setting in MDL loader - - replace LZX decompressor code with LGPL version from XAD - -4.2.1 (20131229): - Many fixes by Vitamin/CAIG: - - fixes in memory I/O layer - - improve loading of many module formats including XM and S3M - - fix resource leak in case of invalid module structure - - portability fixes - Other changes: - - disable YM2149 emulator - - disable poorly implemented and rarely used module formats - - fix mod loop setting in very small loops (reported by Misty De Meo) - - fix linear period mode vibrato handling - - refactor vibrato effect processing - - code cleanup - -4.2.0 (20131109): - - ignore invalid Noisetracker effects - - add API call to load a module from a buffer in memory - - add API call to read the player state (loaded, playing, etc) - - add API call to set the player master volume - - add API calls to reserve channels and play instruments on them - - add loader for His Master's Noise modules - - fix loop parameter in xmp_play_buffer() - - fix MED synth volume slide reset on new note - - fix instrument mapping in IT old instrument format - - fix number of tracks in IT loader - - fix LHA depacker header parsing - - fix thread-unsafe Archimedes Tracker loader - - fix thread-unsafe Digital Tracker loader - - fix handling of loader errors - - fix S3M 16-bit sample replay - - refactor handling of format-specific instrument and channel data - - refactor MED synth command interpreter - - rewrite SQSH depacker code - - disable rarely used ZOO depacker - - disable rarely used ALM loader - - code cleanup - -4.1.5 (20130527): - Fix bugs reported by Andreas Falkenhahn: - - fix OctaMED decay event and effect decoding - - fix The Player 6.0A pattern depacking - - fix Oktalyzer instrument to sample mapping - -4.1.4 (20130519): - - fix array initialization in IT loader (reported by Jacques Philippe) - - remove regression tests from the distribution package - - address license issues in md5 digest code - - address Visual C++ portability issues - - code cleanup - -4.1.3 (20130511): - - fix envelope reset on new instrument (reported by ArtRemix) - - fix JMP END sequences in MED synth wave table - - fix IT portamento after note cut - - fix IT and XM envelope resets - - refactor virtual channel code - - code cleanup - -4.1.2 (20130504): - - fix Graoumf Tracker arpeggio, set linear volume and set number - of frames effects (reported by Misty De Meo) - - fix MTM sample fine tuning - - fix unsigned conversion sample range when downmixing - - fix memory leaks when attempting to load corrupted modules - - refactor note slide effect code - -4.1.1 (20130428): - - add XM set envelope position effect - - fix XM note with no instrument after keyoff - - fix detection of compiler flags - - fix library symbol versioning in OS X (by Douglas Carmichael) - - fix loss of precision in portamento (reported by Misty De Meo) - - fix OS X, Solaris and BeOS/Haiku build issues - -4.1.0 (20130420): - - add API call to fill equally-sized data chunks with PCM data - - add configurable player parameter to disable sample loading - - add configurable player parameter to set/get current module flags - - changed maximum sampling rate to 49170 Hz - - fix floating point values in lowpass filter - - fix buffer overflow in MASI loader (reported by Douglas Carmichael) - - fix simultaneous volume slide up and down - - fix IT vs XM vibrato rate using quirk - - fix IT portamento after note cut (reported by Benjamin Shadwick) - - fix segfault in AMD module loader (reported by Jacques Philippe) - - fix memory leak in AMD module loader - - fix sequence scanner to prevent listing empty sequences - - fix build issues in Cygwin (reported by Benjamin Shadwick) - - fix pkg-config library definition - - fix loop count reset when restarting module - - fix MMD0-3 pitch slides (reported by Simon Spiers) - - fix MED4 pattern reading (reported by Simon Spiers) - - fix MED2/3/4 portamento effect - - fix Stonecracker depacker - - fix IT envelopes with no envelope points - - fix XM invalid instrument event (reported by Banjamin Shadwick) - -4.0.4 (20130406): - - fix IT volume column slide to note - - fix IT pan setting effect - - fix IT vibrato effect depth - - fix IT portamento after fadeout - - fix IT panbrello waveform setting - - fix tremolo effect depth - - fix random waveform generator - -4.0.3 (20130331): - - add module quirks for well-known cases - - add built-in zoo depacker - - add IT pan slide effect - - add IT panbrello effect - - fix IT pan setting effect (reported by Jan Engelhardt) - - fix IT fine vibrato effect - - fix MED BPM mode tempo setting - - fix global volume slides - - fix bidirectional sample loops - - fix sequence entry points - - rescan sequences if timing flag is changed - -4.0.2 (20130223): - - add IT volume column vibrato - - add IT pattern row delay effect - - add fine global volume slide effect - - fix IT instrument vibrato depth and sweep - - fix IT past note effects - - fix IT fadeout values - - fix IT fadeout event loading - - fix period range for values lower than 8 - - fix global volume slides - - fix channel volume setting - - fix multi-retrig effect counter - - fix invalid sample number access - - fix memory access violation in MMCMP depacker - - fix global volume setting in module scan - - reset virtual channel flags on creation - - change maximum number of mixer voices to 128 - -4.0.1 (20130216): - - fix license issues reported by Jan Engelhardt - - minor documentation updates - -4.0.0 (20130213): - - split library and application in different packages - - remove OSS sequencer support - - remove platform-specific device drivers - - remove all global data, make library code fully thread-safe - - remove configuration files (moved to front-end) - - remove support to uLaw-encoded output - - remove bogus lzma file detection (by Bodo Thiesen) - - extend note range to full 10-octave range - - extensive code refactoring - - rewrite MMCMP decompressor to be endian-safe - - replaced IT sample decompressor with public domain version - - add cubic spline sample interpolation - - add built-in zip file decompressor - - add built-in gzip file decompressor - - add built-in compress file decompressor - - add built-in bzip2 file decompressor - - add built-in xz file decompressor - - add built-in lha file decompressor - - add built-in vorbis sample decoder - - add support to IT envelope carry - - add support to IT sample vibrato - - add ASYLUM Music Format V1.0 loader - - add regression tests - - fix interpolation and sample loop processing - - fix S404 depacker integration - - fix note delay effect - - fix FT2 old instrument volume quirk - - fix XM tone portamento with finetune (reported by Rakesh Sewgolam) - - fix instrument envelope loops (Storlek test #24) - - fix IT tremor effect (Storlek tests #12 and #13) - - fix IT global volume (Storlek test #16) - - fix IT stray tone portamento handling (Storlek test #23) - - fix IT unified pitch slide memory (Storlek test #25) - - fix IT retrigger effect (Storlek test #15) - - fix IT filters - - fix IT fadeout event handling - - fix persistent slide down effect - -3.5.0 (20120127): - - fix AMF 1.0 module loading (reported by Andre Timmermans), probe - for sample loop size - - fix AMF 1.1+ sample loops when loop start is zero - - fix AMF track index including track 0 as empty track (reported by - Andre Timmermans) - - fix AMF tremolo effect (reported by Andre Timmermans) - - fix AMF pitchbend effects (reported by Andre Timmermans) - - fix AMF volume slide effect - - fix AMF track allocation - - fix OpenBSD driver configuration - - fix patern delay + pattern break command (reported by The Welder) - - fix memory leaks found by cppcheck (reported by Paul Wise) - - fix XM note cut on invalid instrument (reported by Benjamin Shadwick) - - fix invalid memory access in case of mismatched track/pattern lengths - - fix uninitialized values when loading BoobieSqueezer XM modules - - fix subinstrument mapping for certain parameters - - fix invalid memory access in The Player loader - - fix plugin for Audacious 2.5.4 - - add support to DSMS mod files - - add YM2149 emulator and improved chip sound support - - add support to ZX Spectrum AY-3-8192 chiptunes - - add ZX Spectrum Soundtracker module loader - -3.4.1 (20110813): - - test for unused but set variable warning in gcc (needed to - build on MacOS X, reported by Misty De Meo) - - fix format specifiers in CoreAudio driver messages (reported - by Misty De Meo) - - build audacious3 driver if system has Audacious 2.5 - - change dependency generation flags for clang (reported by Misty - De Meo) - - fix OXM module loading - -3.4.0 (20110808): - - fix reported elapsed time with looped modules - - fix portamento of mapped instruments (reported by Null Vista) - - add MED2 (MED 1.12) module support - - add Noiserunner module support - - add support for MED4 synth instruments (reported by Tim Newsham) - - fix MED4 Soundtracker-compatible tempo setting (Song2.med) - - fix Audacious plugin crash if module is invalid (reported by - Dominik Mierzejewski) - - fix Audacious plugin seek widget position setting - - remove nonexistent Modplug Tracker IT quirk (reported by Johannes - Schultz, voice samples shouldn't play in Deep in Her Eyes remake) - - fix Startrekker Packer loader - - fix IT215 compressed sample loader (reported by Ben "GreaseMonkey" - Russell) - - use start/stoptimer also for pause in OSS driver (by Test Rat) - - identify modules created with munch.py in IT loader - - OctaMED MMD0/1/2/3 tempo fixes (by Francis Russell) - - MMD0/1 note limit fix (by Francis Russell) - - improve latency in ALSA driver output - - Audacious 2.4 API 17 plugin fixes - - add Audacious 3.0 plugin (by Michael Schwendt) - -3.3.0 (20101202): - - change MED BPM mode tempo setting (reported by Lorence Lombardo) - - fix OSS driver fragment setting - - add interactive loop toggle (requested by Emanuel Haupt) - - add filter to prevent loading NoiseRunner modules as Protracker - - add NoiseRunner loader (requested by Johan Samuelsson) - - add improved Impulse Tracker fingerprinting (from Schism Tracker) - - add Archimedes Tracker StasisMod effects support (Tom Hargreaves) - - add tarball decompressor (Tom Hargreaves) - - limit uncompression recursion (Tom Hargreaves) - - fix Tracker Packer 3 loader (Tom Hargreaves) - - fix load issue with BoobieSqueezer XMs (reported by Null Vista) - - fix modinfo tempo/bpm setting - - fix Zip file detection (Tom Hargreaves) - - fix Archimedes Tracker effects (Tom Hargreaves) - - update Audacious plugin to API 16 - - code cleanup - -3.2.0 (20100530): - - Digital Symphony fixes by Tom Hargreaves - - Archimedes Tracker fixes by Tom Hargreaves - - add shared logarithmic volume table for Archimedes formats - - fix default Archimedes formats pan (RLLR instead of LRRL) - - add Coconizer file loader - - portability fixes for BeOS and Haiku - - code cleanup and optimizations - - Android port using NDK - - fix time echoback event for MED - - fix module time count not reseting at new module - - make zipfile detection stricter (by Solomon Peachy) - - fix DSMI loader volume event (by Solomon Peachy) - - initialize formats only once - - fix build with Audacious plugin API 13 - - fix seek in Audacious plugin - -3.1.0 (20100107): - - implement MED4 instrument transposition - - fix build with MSVC++ 2008 - - fix bogus information in winamp plugin file info display - - fix Audacious plugin dialog stacking order (by Michael Schwendt) - - add Titanics Player prowizard loader - - add SKYT Packer prowizard loader - - add Novotrade Packer prowizard loader - - add Hornet Packer prowizard loader - - fix empty instruments in Digital Illusions loader - - fix silent Liquid Tracker module bug - - add Magnetic Fields Packer loader - - add The Player 6.1a prowizard loader - - add StoneCracker S404 decompressor (from amigadepacker) - - add extra Funktracker file tests to prevent false positives - - add Polly Tracker module loader - - code cleanup and optimizations - -3.0.1 (20091221): - - better handling of corrupted modules - - load Real Tracker RTMM 1.12 modules (tested with odyssey.rtm) - - fix tuning of Real Tracker modules - - fix Real Tracker patern decoding - - fix segfault in modules with 0 orders or 0 channels - - fix loading of MED4 module patterns with less than 32 lines - - fix memory leak when loading corrupt MED4 files - -3.0.0 (20091210): 13 years after the 0.09b release - - allow parallel build (R.I.P. 1996 buildsystem) - - implement the long postponed open player loop - - generate win32 project files when packaging distfile - - remove callback driver - - split unified flags/quirks into separate variables - - add elapsed time echoback event - - add option to display elapsed and remaining time - - implement IT volume column fine effects quirk (Storlek test #6) - - fix bmp plugin build - - fix FreeBSD build (by swell k) - - fix terminal handling in Cygwin (by daniel kerud) - - add OpenMPT id to S3M loader - - add Epic MegaGames MUSE data decompression - - add Galaxy Music System (Jazz Jackrabbit 2 J2B) module loader - - fix parsing of driver-specific parameters - - fix GDM length, number of patterns and number of samples - - fix memory access error in MDL sample depacker - - fix ProRunner1 samples size - - OSS driver resets the DSP device on exit (by Andrew Church) - - fix handling of PT portamento+vslide effect (by Andrew Church) - - move driver init from player core to main application or plugin - - Epic MegaGames MASI loader fixes - - add Amiga TuneNet plugin (by Chris Young) - - fix Module Protector loader - - fix lha depacking in Amiga (reported by Chris Young) - - fix clang build (by swell k) - - add support for xz decompressor (by swell k) - - add built-in LZX decompressor - - remove pause-related functions from player core - - fix build in Solaris 10 and Sun Studio 12 Update 1 C++ compiler - (reported by Douglas Carmichael) - - fix plugin to work with Audacious 2.2 (reported by Gtz Waschk) - - fix invalid and uninitialized data accesses reported by Valgrind - - fix memory leaks reported by Valgrind - -2.7.1 (20090718): - - fix -l option in manpage (debian bug #442147) - - fix endianism in MDL sample depacking (reported by Grkan Sengn) - - fix loading of MOD2XM 1.0 modules (reported by Grkan Sengn) - - add some sanity checks in XM module loading - - fix IT note cut and delay (Storlek test #22) - - increase period resolution for better tuning (reported by Mirko - Buffoni and Grkan Sengn) - - allow lower BPM settings (fixes Lemmings 2 circus music) - -2.7.0 (20090711): - - add StarTrekker packer loader (untested, need samples) - - extended key range to IT octave 9 (fixes beek-my_eleventh_year.it, - reported by Mirko Buffoni) - - ignore tempo/bpm settings to 0 in module scan (fixes albacore.it, - reported by Storlek) - - implement IT T0x and T1x tempo slides - - process effects in IT muted channels (Storlek test #10) - - generalized delayed event support (Storlek test #8) - - emulate "always store instrument" IT bug (Storlek test #8) - - add extra click removal step in mixer routines - - fix loop size in GMC loader (reported by Mirko Buffoni) - - GMC loader code cleanup - - store in-file comments - - apply amplification in the final downmix - - set sample format to unsigned on 8-bit wav file output - - attempt to handle BPM-based MED tempos a bit better - - add option to use the IT LPF as a click/noise filter - - deprecate $HOME/.xmprc, use $HOME/.xmp/xmp.conf instead - - reintroduce modules.conf, move SYSCONFDIR back to /etc/xmp - - display checksum for platforms where cksum(1) not readily available - - add filter quirk for rn-alone.it - - reintroduce manual setting for vblank timing in Amiga modules - - add vblank quirk for mod.siedler ii (by Daniel kerud) - - don't crash if SoundSmith instruments not found - -2.6.2 (20090630): - - Promizer 1.8a loader code cleanup - - fix portamento to skip first frame of each row - - fix periods in instruments with finetune - -2.6.1 (20090627): - - fix XMMS plugin build (reported by Gtz Waschk) - - add Chibi Tracker fingerprint to IT loader (info by Storlek) - - add Schism Tracker fingerprint to S3M loader (info by Storlek) - - fix Modplug Tracker/OpenMPT identification in IT loader - - IT instrument and sample modes use same quirks (Storlek test #9) - - transposed period scale base down one semitone (Storlek test #1) - - remove previous portamento in SpaceDebris.mod fix - - add unified pitch slide/portamento memory (Storlek test #3) - - no Amiga limits for multichannel mods (fixes Bending CD61) - -2.6.0 (20090625): - - cleanup: remove rarely used Unix IPC code that difficults porting - - cleanup: remove per-module configuration that nobody uses - - cleanup: moved Prowizard depacking to loader section - - don't abort loading if IT sample magic not found (fixes loading - of use-brdg.it and use-funk.it, reported by Mirko Buffoni) - - multichannel mods written with Scream Tracker don't use Amiga note - limits (fixes Earth Mountains, reported by Samuli Sorvakko) - - fix start option in DeusEx's .umx files (by erlk ozlr) - - add OpenBSD sndio driver (by Thomas Pfaff) - - fix memory leak: free extra pattern allocated by the XM loader - - fix memory leak: free temporary pointer arrays in the IT loader - - fix memory leak: free temporary pointer arrays in the S3M loader - - fix memory leak: free header and filename when file is invalid - - fix memory leak: free temporary buffer in MDL loader - - fix memory leak: move UNIC check to test section of mod loader - - fix memory leak: free Digital Symphony extra empty track - - fix memory leak: free Music Module Compressor buffers - - fix memory access violation freeing list nodes using list_for_each - - fix memory access violation in MDL track allocation - - fix memory access violation in MDL sample decompression - - fix memory access violation in LIQ pattern loading - - fix memory access violation in P18A format test - - fix free of unallocated block in IT sample-only mode - - fix buffer overflow in OXM/DTT loaders (reported by Luigi Auriemma) - - rename oss_mix driver to oss and alsa_mix to alsa - - restrict MMD0/MMD1 non-synth instrument note range to 3 octaves - (reported by Daniel kerud and Mirko Buffoni) - - assume wav driver if output filename ends in .wav - - fix volume slides with 00 parameter (by Mirko Buffoni) - - fix crash when S3M C2spd is zero (by Mirko Buffoni) - - merged Mirko Buffoni's Windows Visual C++ port - - don't process tone portamento in first frame of each row, fixes - Space Debris.mod (by Mirko Buffoni) - - add amplification factor option (by Mirko Buffoni) - - improved Winamp plugin (by Mirko Buffoni) - - don't unlink open files (for Windows port, by Mirko Buffoni) - - add experimental DxF/DFx handling with volume slides in all frames - - add better Archimedes .arc compressed file test - - reverted to older YM3812 emulator for license compliance - - fix byte swap error in HSC to SBI Adlib OPL2 instrument conversion - - fix Reality Adlib tracker loader - - implement Adlib OPL2 synth volume setting - - improve tempo, tuning and envelope of HSC modules - - fix scanning of patterns containing short tracks - - don't play notes outside the valid 8 octave note range - - enable The Player 5.0A loader (tested with Full Moon mods) - - enable ProPacker 2.1 loader (tested with Cool World mods) - - fix endianism issues in The Player 5.0 and 6.0 loaders - - fix AMF track remapping error - - enable instrument retriggering quirk in IT loader - - configuration file moved back to /etc - - fix estimated tempo for S3M/IT modules with BPM changes - -2.5.1 (20071207): 11 years after xmp 0.09a, the first public release! - - fix Winamp plugin default sampling rate (reported by Mirko Buffoni) - - Winamp plugin number of channels fixed by Mirko Buffoni - - recognize TakeTracker TDZ4 modules (reported by Lorence Lombardo) - - fix crash in anticlick when pan amplitude is set to 100% (reported - by Mirko Buffoni) - - extend playable octave range (fixes replay of octave 9 notes in - beek-my_eleventh_year.it, reported by Mirko Buffoni) - - Protracker-style sample loops only valid with loop start 0 (fixes - M.K. Amegas conversion and others, reported by Mirko Buffoni) - - reset fadeout on new instrument fetch (fixes echo in "pain of lace" - pat 0 ch 2-3, reported by Mirko Buffoni) - - add quirk for simultaneous volume slide up and down (M.K. allows it - but S3M doesn't, fixes Red Dream.mod reported by Ralf Hoffmann) - - Impulse Tracker in sample mode has instrument priority quirk - - fix IT far right (64) stereo channel panning - - merge Amiga port improvements by Johan Samuelsson - - merge Amiga xfdmaster.library support by Chris Young - - Amiga port also buildable for AROS (AHI driver not tested) - - fix global track parsing in DMF loader (fixes mok-trea.dmf, reported - by Lorence Lombardo) - - fix Winamp plugin to use the equalizer (reported by Mirko Buffoni) - - skip 0xfe and 0xff S3M/IT control patterns at load time - - fix scan of pattern break in the last pattern of the module - - add BPM quirk for XMs converted with MED2XM (fixes Fascinated.xm, - reported by Lorence Lombardo) - - merge Windows patch for decompression by Mirko Buffoni - -2.5.0 (20071127): - - remove DMP-specific effect from MOD loader - - extend Protracker sample loops to Noisetracker and Startrekker - - FLT loader recognizes Startrekker FLTM modules (only PCM channels) - - implement support for Startrekker/ADSC AM synth instruments - - fixed cast to signed type in finetune display - - fixed Protracker 3 IFFMODL loader (process VERS chunk manually) - - added support to Protracker sample loops in the Protracker 3 loader - - added PulseAudio driver (using the simple API) - - remove restrictive tests for Soundtracker modules (fixes - 99redballoons.mod and atmosfer4.mod, reported by Adric Riedel) - - fixed infinite loop control (allows full replay time of 11:04 for - Gryzor's extended Global Trash 3.mod, reported by Adric Riedel) - - use floating point period generation for the software mixer - - fix S3M tempo/bpm setting effect (fixes seaside_hotel.s3m) - - MinGW32 build fixes and new Windows driver (based on MikMod) - - merged Amiga AHI driver written by Lorence Lombardo - - don't read commands from terminal in Windows and Amiga - - reset parameter in case of MDL "no effect" (saa.mdl pos 13 ch 9 - plays correctly, reported by Grkan Sengn) - - fixed wav and file drivers binary file creation for win32 - - add support for Octamed V6 16bit samples (fixes instruments in - LaEsperanza.mmd3, reported by Lorence Lombardo) - - enforce minimum allowed BPM to prevent large frames (fix crash with - MED2XM modules such as Fascinated.xm, reported by Lorence Lombardo) - - fixed conversion of big-endian 16-bit samples in big-endian machines - - fixed decompression of 16-bit IT samples in big-endian machines - - added experimental Winamp plugin - - added handler for Ultra Tracker sample type 20 (fixes seasons.ult, - reported by Lorence Lombardo) - - fixed instrument parameter handling in MED4 loader - - added Generic Digital Music (GDM) loader - - plugin code cleanup, remove mode button and hold buffer - - merged AmigaOS4 patches by Chris Young - -2.4.1 (20071029): - - fixed portamento after keyoff problem in metamorph_part_ii.xm - where new note is not recognized (reported by Adric Riedel) - - implement Protracker-style sample loops: first play entire sample, - then play the loop (needed to play MeNoWantMiseria.mod correctly, - reported by Adric Riedel) - - fixed finetune test in UNIC Tracker detection to prevent false - positive with all that she wants.mod (reported by Adric Riedel) - - fixed test for ?CHN and ??CH TakeTracker/FastTracker2 modules - - fixed data type in the XM loader to work in 64-bit systems - - don't ignore effect on event with invalid instrument (fixes tempo - in 39.mod pos 11, reported by Adric Riedel) - - removed restrictive tests for Ultimate Soundtracker (false negative - in Karsten Obarski's sleepwalk and others, reported by Adric Riedel) - - minimum sample size changed from 5 to 4 bytes, childhood.it actually - has 4 byte samples (reported by Adric Riedel) - - cut effect doesn't retrigger sample (fixes Comic Bakery Remix pos 1 - ch 3, reported by Adric Riedel) - - allow period 162 in ST mods (for blueberry.mod UST, reported by AR) - - fixed period interpolation using real log function instead of table - -2.4.0 (20071025): - - added Oktalyzer note slide and fine note slide effects - - added Oktalyzer arpeggio 3, arpeggio 4 and arpeggio 5 effects - - added MED synth programmable arpeggio commands ARP and ARE - - added MED synth vibrato commands VBS, VBD and VWF - - added module probe method without loading (Audacious plugin can - test for files while a module is playing) - - added persistent effects for 669, FNK and FAR - - fixed MED synth volume slide commands CHD and CHU - - fixed detuning in short samples with bidirectional loop by adjusting - the loop size to match forward loop size - - fixed sound cut bug when changing samples in the MED synth (don't - reset channel on attempt to set invalid sample position) - - fixed identification of IIgs MegaTracker modules - - fixed 669 persistent vibrato and portamento effects - - fixed FAR persistent vibrato/portamento and pattern break effects - - fixed sample loading in FAR modules - - fixed multi-retrig effect processing (see cyberculosis.xm ch 7) - - fixed segfault when output file is specified but driver isn't - - fixed XM sample loop size in XMs made with Digitrakker - - revert CoreAudio driver pause patch (fix memory management problem) - - reset MED synth program at each new note event - - removed filesize-based module format detection - - replaced XANN loader with Prowizard XANN depacker - - reorganized internal data to remove lots of global variables - - changed all loaders to load module from relative offset - - changed UMX depacker to be a real loader (using relative offsets) - - ported Audacious plugin to the Audacious 1.4.0 API - - fixed sample offset on portamento after keyoff (Decibeter - Cosmic - 'Wegian Mamas.xm plays correctly now) - - fixed length of XM loops (jt_xmas.xm no longer out of tune) - - fixed Audacious plugin to display duration when adding to playlist - - fixed memory access violations reported by Valgrind - - split XMMS/BMP/Audacious plugin source - - invalid patterns in sequence ignored instead of aborting replay - - fixed load of DBM 16-bit samples (reported by Ralf Hoffmann) - - fixed DBM envelope offset error (reported by Ralf Hoffmann) - - disabled AMF volslide effect (problems with CannonFodder2-Done.AMF) - - fixed MMD1/MMD3 loaders to skip invalid synth instruments (reported - by Ralf Hoffmann, Misanthropy.MED loads correctly) - - fixed number of patterns in Funktracker modules - - added Funktracker persistent portamento and volume slide effects - - fixed offset effect with parameter 00 (reported by Adric Riedel) - - changed volume dynamic range to fix steps in volume ramps (tested - with departure soundtrack.xm, reported by Adric Riedel) - - set priority to slide down when volume slide up and down is used, - fixes Skaven's 2nd Reality blast (reported by Douglas Carmichael) - -2.3.2 (20071009): - - added ModPlug Tracker IT quirk: ignore sample global volume (fixes - speech in "Deep In Her Eyes Remake", reported by Douglas Carmichael) - - added PTM/IMF note slide effects and PTM note slide + retrig effect - - added partial support to MED synth sounds (ported from xmp 2.1.0) - - added experimental BeOS driver based on the CoreAudio driver - - fixed copy of overlapping memory areas in IT loader - - fixed initialization of channel flags before loading module - - fixed PTM sample loop size (tested with abnormality.ptm) - - fixed PTM effects translation (PTM-specific effects were ignored) - - fixed effects settings in AIX and OSX CoreAudio drivers (reported - by Douglas Carmichael and Chris Cox) - - fixed pause in OSX CoreAudio driver - - fixed Fuchs Tracker prowizard loader format detection - - fixed --time option time counter for MED files - - decoupled PT3 PTDT and MOD loader - -2.3.1 (20071005): - - added PTM global volume effect - - fixed output filename setting in wav output - - fixed size field setting in wav driver - - fixed configure option --sysconfdir (reported by Douglas Carmichael) - - fixed major bug in anticlick routine generating clicks in the - right audio channel (reported by Douglas Carmichael) - - changed rampdown time in Hipolito's anticlick algorithm (removes - clicks from PM's 2nd Reality, reported by Douglas Carmichael) - - changed default file name when writing to WAV to .wav - -2.3.0 (20071002): - - added runtime endianism detection - - added extractor for Epic Games' Unreal UMX files - - added workaround for S3M "Return of Litmus" 0x87 quirk (reported - by Ralf Hoffmann) - - added DigiBooster Pro module loader - - added Fmod OXM depacker (depends on oggdec) - - enabled Tracker Packer 3 prowizard loader - - enabled The Player 4.x prowizard loader - - removed reverse-endian sample reading options and XMP_CTL_BIGEND - - fixed semantics of big/little endian options, moved to file driver - - fixed memory corruption in Quadra Composer module loader - - fixed Quadra Composer vibrato, offset and jump effects - - fixed endianism problem in KSM and Zen Packer loaders - - fixed transposition of Digital Tracker module notes - - fixed build for QNX Neutrino 6.3.2 - - fixed OSS sequencer driver timing (reported by Reynir Stefansson) - - fixed BMP/Audacious plugin to build also as XMMS plugin - - fixed Impulse Tracker identification in S3M loader - - fixed Module Protector test to recognize mods from "Made In Croatia" - - fixed crash when scanning modules with length zero (bug #1800766) - - fixed driver detection in NetBSD (don't try to build OSS driver) - - fixed crash when restart value is invalid (reported by Ralf Hoffmann) - - fixed handling of S3M pattern 0xfe (reported by Ralf Hoffmann) - - fixed data size in MMD3 pattern sequence loading - - fixed MMD1/MMD3 invalid/unhandled effect translation - - fixed MMD1/MMD3 mixing buffer size setting (for PrivInv.med) - - fixed Soundtracker 15-instrument module tracker fingerprinting - - format management code cleanup - - prowizard code cleanup - -2.2.1 (20070917): - - added IT tracker fingerprinting - - enabled track volumes (fixes znm-believe.it, reported by Jon Rafkind) - - fixed DESTDIR and config file location (by Adam Sampson) - - fixed volume overdrive in the Megatracker loader - - fixed probing order of PW-packed and Arc - - raised sample number limit from 255 to 1024 (fixes megaman.xm - tempo and missing instruments reported by Jon Rafkind) - - build plugin files as PIC - -2.2.0 (20070915): - - added more module format specs - - added CD61 Octalyser module support - - added Flextrax FLX module detection - - added TCB Tracker module loader - - added Digital Tracker DTM module loader - - added Digital Tracker FA04/6/8 module support - - added Real Tracker module loader - - added X-Tracker module loader - - added portable, 64bit-safe MMD0/1/2/3 MED loader - - added Graoumf Tracker GTK module loader - - added old Liquid Tracker "NO" module loader - - added OSX CoreAudio driver - - added S3M/PTM/IMF/LIQ/IT fine vibrato effect - - added Archimedes Tracker loader - - added Arc/!Spark depacker - - added ArcFS depacker - - added Archimedes VIDC sample converter - - added Digital Symphony module loader - - added Megatracker module loader - - added Desktop Tracker module loader - - added Zoo depacker - - added MED3 module loader - - added MED4 module loader - - added IIgs ASIF sample converter - - added IIgs SoundSmith/MegaTracker loader - - added Audacious plugin - - enabled WAV writer - - enabled IMF filter effects - - enabled Game Music Creator prowizard converter - - removed broken shared lib generation - - removed packed structures - - replaced non-free PowerPack depacker with Kyzer's PD version - - replaced list management in IFF loader with kernel list helpers - - replaced XMMS plugin with Beep Media Player plugin - - fixed long-standing bug in S3M BPM handling, "Panic" plays correctly - - fixed MDL effects translation - - fixed MDL pattern order loading missing first pattern - - fixed MDL memory corruption in envelope initialization - - fixed MDL 16-bit sample depacking (reported by Paul Wise) - - fixed MDL multisampled instrument mapping - - fixed MDL note event keyoff (gothlord.mdl plays better) - - fixed XM and MDL sample loop size - - fixed XM BPM setting (speedup.xm plays correctly) - - fixed LIQ effects and 16-bit sample loading - - fixed S3M pan settings - - fixed IT old instrument volume mode setting - - fixed IT 16-bit sample loading (reported by Henrik Pauli) - - fixed IT effect S00 and delta sample loading (fixes O4UFRDMX.IT) - - fixed multi-retrig effect (reported by Henrik Pauli) - - fixed infinite loop scan (reported by Zbigniew Luszpinski) - - fixed Sinaria sample size and finetune - - fixed issues with OpenBSD - - fixed issues with 64-bit machines - - fixed loading of big-endian 16-bit samples - - using Asle's Prowizard to handle packed MODs - -2.1.1 (unreleased): - - added more module format specs - - added MO3 unpacking support - - added file detection to the XMMS plugin - - added Beep Media Player support to the XMMS plugin - - added Epic Megagames PSM module support - - added Epic Megagames old PSM (Silverball) module support - - added DSMI/DMP Advanced Module Format support - - added support to Ultimate Soundtracker modules - - added ALSA 0.9/1.0 sound output support - - fixed recursive decrunching of module files - - fixed QNX6 portability issues (by Mike Gorchak) - - fixed heavy memory leak in the XMMS plugin - - fixed --time command-line parameter - - fixed portamento-after-keyoff bug (Jeronen Tel's "Nine One One" - now plays correctly) - - fixed IFF file loading to avoid data alignment errors - - fixed endianism issues in MDL loader - - updated OPL emulation (by Mike Gorchak) - - default verbosity level changed to 1 - - default sound mode set to stereo - - disabled MED loader (nonportable, didn't work well) - -2.1.0 (unreleased): - - Added Takuya Ooura's FFT code - - Added scope/spectrum analyser modes to xxmp - - Fixed dynamic driver loading to honour the configuration prefix - - Added --with-esd option to the configuration script for esd in - FreeBSD (reported by Nate Dannenberg ) - - Added xxmp panel and module info to XMMS info box - - Fixed YM3812 emulator output in mono and stereo modes - - Reordered extra libraries in Makefile.rules to build correctly in - IRIX 6.5.10/gcc 2.95.2 (reported by Johan Hattne ) - - Added aRts driver - - Added NAS driver (based on Martin Denn's mpg123 NAS driver) - - Added experimental QNX4 driver based on Mike Gorchak's nspmod port - - Added experimental win32 driver based on Tony Million's mpg123 driver - - Added NEO Software/Electronic Rats HSC module loader - - Added Liquid Tracker module 0.0 and 1.0 support - - Added callback driver for plugins - - XMMS plugin changed to use the callback driver - - Added Images Music System support - -2.0.4 (20010119): - - Added driver for synthesized sounds - - Added Tatsuyuki Satoh's YM3812 emulator - - Added support to The Player 6.0a modules (using Sylvain "Asle" - Chipaux's P60A loader) - - Added seek capability to XMMS plugin - - Added (very) experimental AIX driver - - Added envelope point sanity checks (fixed "Beautiful Ones" IT - envelope bug reported by Chris Cox) - - Added support to dynamic linked drivers (for better packaging) - - Added option to package only DFSG-compliant code - - Fixed audioio.h detection in OpenBSD 2.8 (by Chris Cox - ) - - Max. filter cutoff value changed from 254 to 253 to avoid problems - in "Beautiful Ones") - - Fixed external drivers problem with the XMMS plugin (reported by - greg ) - - Fixed xmp_ord_set() bug (was calling XMP_ORD_PREV) - - Fixed period calculation algorithm (that was an OLD bug!) - - Started adding support to MED 1.11, 1.12, 2.00 and 3.22 - - Replaced RPM spec with Dominik Mierzejewski's version - -2.0.3 (20001229): - - Fixes for enabling/disabling features in configure.in - - gcc 2.96/glibc 2.2 related fixes by Dominik Mierzejewski - - - Support for RAR packed files by Michael Doering - - Improved powerpacker decrunching by Michael Doering - - IT lowpass filters for the software mixer - - Fixed "yes/no" switch in xmp-modules.conf - - XMMS plugin in big-endian machines fixed by Griff Miller II - - - Updated RPM specfile - -2.0.2 (20000506): - - Fixes in the NetBSD driver (by Michael ) - - Fixed sample size for MED synth instruments - - Fixed the set offset effect for (offset > sample length) bug - reported by Igor Krpanic - - Fixed configuration file loading in OS/2 (by Kevin Langman - ) - - Fixed S3M tone portamento bug introduced in 2.0.1 - - Fixed option --fix-sample-loops - - Improved Noisetracker and Octalyser module detection - - Fixed UNIC tracker and Mod's Grave module detection - - Fixed Protracker song detection - - Event loading in S3M fixed by Rudolf Cejka - - - ALSA 0.5 driver fixed by Rob Adamson - - Added experimental XMMS plugin - - Removed calls to tempnam(3) - - Big-endian sound output finally fixed? - -2.0.1 (20000223): - - Endianism problems in Linux/PPC (Amiga) fixed by Rune Elvemo - - - Added enhanced NetBSD/OpenBSD drivers written by Michael - - - Fixed sample loop detection bug in the MOD loader - - ALSA 0.5 support fixes by Tijs van Bakel - - Moved the YM3128 emulator sources to the 2.1 branch (shouldn't - be in the 2.0.0 package) - - Added extra sanity tests for 15 instrument MODs (based on sample - size/loop info), relaxed file size test, added check for NT mods - - Fixed pathname for Protracker song sample loading - - Fixed XM loader for nonstandard mods sent by Cyke O'Path - - - Added workaround for IT fine global volume slides - - Added support for EXO4/EXO8 Startrekker/Audio Sculpture modules - - Added support for Soundtracker 2.6/Ice Tracker modules - - MED synth instruments MUCH better now (but still far from perfection) - - Fixed S3M instrument retriggering on portamento bug reported by - Igor Krpanic - -2.0.0 (20000202): - - Allocations checked with Electric Fence - - Fixed powerpack decruncher counter initialization - - Number of tracks fixed in the XM loader - - 0 byte allocation fixed in the XM loader - - Vibrato depth fixed (>>1) - - Independent effect memory for XM volume slide effect and volume - column effect - - Disable sample loop when loop end < loop start - - Continue S3M fine effects (e.g. x00 after xF5) - - Loader for Startrekker FLT8 modules - - Pattern loop fixed - - Set offset effect bug fixed (reported by Martin Willers - ) - - Sample length in the software mixer - - 669 effects fixed by Miod Vallat - - Fixed S3M/IT continue arpeggio effect - - Fixed S3M/IT set tempo effect - - Fixed set finetune effect (<<4) - - Fixed S3M and XM global volume settings - - Fixed STX memory leaks - - Added support for XM 1.03 modules in the XM loader - - Speed 0x20 correctly recognized - - STM loader accepts BMOD2STM stms (reported by Bernhard Mrz) - - Fixed wrong number of patterns in FAR loader (reported by Bernhard - Mrz ) - - Fixed IFF chunk buffer allocation for MDL samples - - Fixed sample buffer size for MDL 16 bit samples - - SMIX_C4NOTE changed to from 6947 to 6864 in mixer.h (reported by - Christoph Groth -- fixes Cannon Fodder replaying) - - Ignore garbage in the order list (reported by Spirilis - -- fixes dragnet.mod) - - Event fetch now emulates ST3, FT2 and Protracker - - Added virtual channel system (for IT NNAs etc) - - Added loaders for Protracker 3.59 IFFMODL, STMIK 0.2, Promizer 0.1/ - 2.0/4.0, SoundFX 1.3/2.0, Slamtilt, MED/OctaMED, DIGIBooster, Quadra - Composer, Digital Illusions, Module Protector, Zen Packer, Kefrens - Sound Machine, Heatseeker, Imago Orpheus and Impulse Tracker modules - - Added support for MED synth sounds (incomplete) - - Added support for MED BPM tempos (incomplete) - - S3M loader recognizes Imago Orpheus - - xmprc renamed to xmp.conf - - Configuration for specific mods using xmp-modules.conf - - User configuration stored in $HOME/.xmp - - Protracker effect 9 bug emulation - - Support for Protracker song files - - AWE support for IT filter envelopes - - Filename in the xxmp window title (added by Geoff Reedy - ) - - Sample crunching for soundcards with limited memory - (requested by janne ) - - Bidirectional loop expansion and 16-bit conversion for AWE - - Added anti-click routines in the mixer (requested by Teemu Kiviniemi - ) - - Zirconia's MMCMP decrunching support - - Old volume mode set for awedrv 0.4.3 - - Added option --loadonly - - Changed finalvol formula - - MOD loader split in M.K./xCHN, FLT and ST loaders - - xmp_options changed to xmp_control - - Removed redundant code from loaders - - Dropped options -p (period mode), --disable-envelopes, --modrange - and --ntsc - - UNIC and LAX collapsed in a single loader - - Added test for AWE_MD_NEW_VOLUME_CALC definition in oss_seq.c - - Fixed buffer write() after EINTR on SIGSTOP (reported by Ruda Moura - ) - - Title line in xxmp fixed by Geoff Reedy - - Tweak configure.in to honour predefined CPPFLAGS in environment - since awe_voice.h moves around in FreeBSD. At the time it is in - /usr/src/sys/gnu/i386/isa/sound/ (by Bjoern Fisher - ) - - Added missing #include "config.h" in main.c (by Bjoern Fisher - ) - - Default mixing rate raised to 44.1 kHz - - Fixed OSS sequencer timing in Linux/Alpha (by Nils Faerber - , reported by Andrew Hobgood - -- improved using Miodrag Vallat's HZ checking) - - Added native ALSA PCM driver - - Fixed xxmp title wrap - - Fixed 4-bit ADPCM sample decompression - - Solaris driver fixed by Keith Hargrove - - IRIX driver fixed by Brian Downing - - Merged OS/2 DART port by Kevin Langman - - Added BMOD2STM support in STX mods (reported by Miod Vallat) - -1.2.0 (Unreleased): - - Added support for 16-bit samples in S3M (reported by Geoff - Reedy and Chris Jantzen ) - - Status display in main.c changed from curr_row/num_rows - to curr_row/max_rows. - - esd driver fixed by Terry Glass - - (Yet another scanner bugfix) scanner ignores tempo 0 - - (Yet another scanner bugfix) estimated time limit extended - from 15 min. to approx. 4 hours (should be sufficient) - - (Yet another scanner bugfix) scanner sets global volume - - (Yet another scanner bugfix) S3M_END test fixed - - Skip to previous module fixed - - Loop start set in bytes in 15 instrument MOD files - - Added return status for failure in decompression - - Temporary file unlink after failed decompression - - Fixed S_ISDIR using wrong argument - - Fixed clear chunk ID buffer in the IFF loader - - Fixed chunk ID test fixed in the IFF loader - - Release the IFF loader linked list after loading - - Init default options in load.c - - Volume echo event normalized to 0x40 - - Fixed sample loop in UNIC/LAX modules - - Fixed FAR number of patterns - - Fixed FAR tempo effect - - Fixed FAR effect parameter setting - - STM loader now rejects STX files - - Fixed XM note fadeout value - - Option --fix-sample-loop sets sample loop start in bytes - - Added support for NoisePacker 1/2/3, Digitrakker 0.0/1.0/1.1 - and Promizer 1.0/1.8 module formats - - SIGUSR1 and SIGUSR2 handlers for skipping to next/previous - module (requested by Geoff Reedy ) - - Recursive module unpacking - - drv_solaris renamed to drv_bsd_sparc - - Other cosmetic changes - -1.1.6 (19981019): - - xxmp compilation in FreeBSD fixed by Adam Hodson - - - Makefile fixed for bash 2 - - S3M global volume setting removed (reported by John v/d Kamp - ) - - S3M tempo/BPM effect fixed (reported by Joel Jordan - ) - - XM loader checks module version - - XM loader fixed for DEC UNIX by Andrew Leahy - - - finalvol shifted right one bit to prevent volume overflow with - dh-pofot.xm (Party On Funk-o-tron) - - File uncompression based on magic instead of file suffix - - Loop detection and time estimation improved; --noback - option removed (reported by Scott Scriven ) - - Invalid values for module restart are ignored (reported by - John v/d Kamp ) - - Don't play invalid samples and instruments - - Fine effect processing changed to the Protracker standard - instead of FT2 (i.e. effects EB1-EE5 play fine vol slide five times) - - OSS audio driver fragment setting fixed - - Added test for file type before loading - - MOD/XM tempo/BPM setting fixed (reported by Gabor Lenart - ) - - XM loader limits number of samples (needed to play Jeronen Tel's - "Pools of Poison") - - Invalid sample number in instrument map is set to 0xff and ignored - by the player (needed to play Jeronen Tel's "Pools of Poison") - - Jump to previous order in order zero ignored. - - Channel 1 to 10 mute/unmute keys changed - - cfg.mode -1 bias removed - - --ignoreff option removed - - Reserved & unsed fields removed from structures - - S3M tremor effect implemented - - XM keyoff effect implemented - - Experimental (untested) SGI driver - - Experimental (untested) OpenBSD driver - - --nocmd option added by Mark R. Boyns - - Added support for XM 1.02, Ultra Tracker, ProRunner, Propacker, - Tracker, Unic Tracker, Laxity, FC-M, XANN and AC1D modules - - Added built-in uncompressors for Powerpacker and XPK-SQSH - - Option for realtime priority in FreeBSD added by Douglas - Carmichael - - Support for 15 bpp in xxmp added by John v/d Kamp - -1.1.5 (19980321): - - Bidirectional sample loop fixed (reported by Andy Eltsov) - - Set pan effect bug fixed by Frederic Bujon - - Solaris/Sparclinux driver for the AMD 7930 audio chip (tested in - Solaris 2.5.1 and Linux 2.0.33) - - Support for the Enlightened Sound Daemon - - Better SIGSTOP/SIGCONT handling - -1.1.4.1 (19980330): - - New URL updated in docs - -1.1.4 (19980204): - - Added missing error check in Solaris and HP-UX drivers - - Fixed includes for FreeBSD - - Fixed X setup in the configure script - - Fixed X include path in Makefile.rules and src/main/Makefile - - scan.c replaced by a new version from 1.2.0 development tree - - HP-UX driver works (tested in a 9000/710 with HP-UX 9.05) - - Misc doc updates - -1.1.3 (19980128): - - xxmp color #000000 changed to #020202 (needed in Solaris) - - `cmd' type changed to char - - Interactive commands to unmute channels 6, 7 and 8 - - MTM loader works in big-endian machines - - Experimental HP-UX support added (not tested) - - Panel background colors changed - - New INSTALL file - - Misc doc updates - -1.1.2 (19980105): - - Fixed xxmp palette corruption - - Fixed xxmp error messages - - Misc doc updates - -1.1.1 (19980103): - - Fixed coredump in Oktalyzer loader (resetting pattern and - sample counters) - - Fixed coredump with Adlib instruments - - Fixed xxmp window update (added missing XSync, xxmp shows - current pattern and row) - - Fixed color palette in 16 bpp True Color - - Fixed command line arguments -S and -M - -1.1.0 (19971224): "The Nightmare Before Christmas" release - - Package license changed to GPL - - Configuration made by GNU autoconf - - Software mixer and /dev/dsp support - - Compiles on FreeBSD 2.2 and Solaris 2.4 - - Command line options changed, long options added - - Random play mode added - - AWE reverb and chorus options added - - Support for OPL2 FM synthesizer - - New formats supported: Elyssis Adlib Tracker (AMD), Reality Adlib - Tracker (RAD), Aley's Modules (ALM) - - Support for multiple output devices - - Support for Scream Tracker 3.00 modules (volslides in every frame) - - Support for S3M Adlib instruments - - Support for S3M (very old) signed samples - - Support for S3M pan ("The Crossing" plays correctly) - - Support for S3M global volume - - Support for Oktalyzer 7 bit samples - - Support for IFF modules and variations - - S3M arpeggio kludge removed - - S3M module length adjusted discarding 0xff paterns - - S3M set tempo/BPM effect adjusted - - XM envelope loop bug fixed ("Shooting Star" plays correctly) - - XM 16 bit sample conversion bug fixed ("Hyperdrive" plays correctly) - - Support for XM instruments with 29 byte headers (for "Braintomb") - - AWE32 pan setting fixed - - Glissando in linear period mod bug fixed - - Volume overflow bug fixed (again) - - Tone portamento update bug fixed - - Period setting workaround for panic.s3m - - Pattern jump effect bug fixed - - Oktalyzer loader bugs fixed - - period_to_bend precision loss bug fixed - - Option -s fixed to play with correct tempo/BPM/volume - - Added support for bzip, compress, zip and lha compressed modules - - Added Protracker and Soundtracker wrappers to the MOD loader - - Support for MDZ modules with ADPCM samples - - IPC stuff removed, player engine built as a library - - Fixed memory leak in MOD loader - - Fixed memory leak in oss_seq - - X11 version (xxmp) - - Interactive commands - - xmprc file - -1.0.1 (19970419): - - IPC global volume setting bug fixed - - FAR number of patterns bug fixed - - S3M volume setting effect correctly handled (fixes Skaven's - 2nd Reality) - - Option to disable dynamic panning to prevent AWE-32 clicking - -1.0.0 (19970330): First non-experimental release - - Added option -t (maximum playing time) - - Added option -K to enable IPC - - Test module removed from package - - -Experimental versions ---------------------- - -0.99c (19970320): Fixed more bugs reported by Michael Janson - - S3M loader changed to recognize fine and extra fine volume slides - only when the slide nibble is not zero (fixes PM's 2nd Reality) - - XM patterns with 0 (==0xff) rows are being correctly handled - (Wave's Home Vist should play better) - - Tone portamento effect does not reset envelopes (fixes Wave's - Home Visit pattern 0, channels 0 to 5) - - Loop click removal fixed & improved - chipsamples sound smoother - using gmod's method to prevent clicking - - Continue vibrato effect bug fixed - -0.99b (19970318): Fixed bugs reported by Antti Huovilainen and Michael Janson - - Extra fine portamento bug fixed (ascent.s3m should play better) - - Volume column tone portamento in XM shifted left 4 bits (fixes - guitar in Zodiak's Status Mooh order 7, channel 7) - - Note delay bug fixed (fixes bass in Jogeir Liljedahl's Guitar - Slinger) - delay was working as note retrig - - Sample offset effect bug fixed (fixes snare drum in Zodiak's - Status Mooh order 0D channel 5) - offset 00 uses previous offset - - New instrument event with same instrument does not retrig the - sample (fixes pad in Romeo Knight's Wir Happy Hippos) - - Global volume limited to 0x40 (fixes fadeout in Zodiak's Reflecter) - - Sample loop adjusted for click removal - - 669 loader changed to use secondary effects for tempo/break - - S3M loader changed to use generic pattern loops (S3M-specific - pattern loop kluge removed from xm_play.c) - - MOD loader fixed - the module may have unused patterns stored - and this situation was confusing the loader - - Effect F changed to recognize 32 frames per row - -0.99a (19970313): - - General code review - - Internal module format changed to XXM - - Added endianism correction - - Volume overdrive bug fixed - - Verbosity levels adjusted - - Vibrato implementation bug fixed - - Instrument vibrato sweep implemented - - New module formats supported: STM, 669, WOW, MTM, PTM, OKT, FAR - - Added mute/solo channel command line options - - Tempo 0 ignored - - Lots of cosmetic changes - - Option to reduce sample resolution to 8 bits - - Envelope sustain bug ("Zodiak bug") fixed (reported by Beta) - - Infinite loop in pattern jump bug fixed - -0.09e (19970105): Improved S3M support and general bugfixes - - Yet another pattern loop bug fixed - - S3M J00 (arpeggio) effect workaround - - S3M stereo enable/disable implemented - - S3M sample pan bug fixed - - Added warning for S3M Adlib channels - - Improved S3M channel pan handling - - Incremental verbosity option - - Tone portamento behaviour fixed (for "Elimination Part I") - - Added parameter -i to ignore S3M end of module markers - - S3M FFx/F00 (continue fine period slide) effect bug fixed - (bug was audible in the Second Reality opening theme) - - Global volume slide bug fixed - - installbin target fixed in the Makefile - - Volume reset with no instrument for new note bug fixed - (bug was audible in "Knulla Kuk" by Moby) - -0.09d (19970101): - - Pattern jump bug fixed - - Added support for ??CH mods - thanks to Toru Egashira - - - Fine pitchbending effect bug fixed - - Signal handling fixed (again) - - USR1 and USR2 signals changed to ABRT and HUP - - Command line parameter to force MOD octave range - - NTSC timing for MOD files - - Glissando effect implemented - - Retrig and multi-retrig effects bug fixed - - S3M fine volume slide effect translation bug fixed - - S3M C2SPD translation to relnote/finetune bug fixed - - S3M pattern loop fixed - - S3M module loop bug fixed - - Pattern loop (for restart order>=0x7f) bug fixed - - version.o dependencies fixed in the Makefile - -0.09c (19970101): broken version (unreleased) - -0.09b (19961210): - - Note release and fadeout bug fixed - - Module restart (SIGUSR2) bug fixed - - Octave shift bug fixed ("Move to da beat" plays OK) - - "Squeak" bug fixed (the bug was caused by a tone portamento - with no destination note) - - Pitchbending effect bug fixed ("Crystal Dragon" plays OK) - -0.09a (19961207): First public release. - - Panel signal handling fixed - - base_note set with C4 frequency of 130.812 Hz (actually C3) - - GUS_VOICE_POS enabled for AWE_DEVICE (Iwai's patch) - - Envelope fadeout (release) fixed - - Note skip bug corrected after some shotgun debugging - - GUS panning fixed (bypassing sequencer.h) - - Added panning amplitude command line option - - Added a channel pan parameter - - Changed the XM loader to always unpack the patterns - - S3M pan positions fixed - - Timing variables changed to floating point - I really don't like - FP, maybe I've been hacking in assembly language too much - - Added 15-instrument MOD loader - - Added XM finetune interpolation - - Arpeggio bug fixed: pitchbend increments between semitones is 100 - and not 128 (why don't they use ROUND numbers?) - - Changed period2bend to prevent lossage in higher octaves - - Pattern loop effect implemented (running_lamer.mod plays OK) - - Auto-detector (?) for 15-instrument MODs (option -f removed) - - Added linear period support - - All source files checked into RCS - - -Development (unreleased) versions ---------------------------------- - -0.08 (19961031): - - Increased code mess - - Included Iwai's AWE support - - devices.c created to wrap output devices - - sequencer.c, awe.c and gus.c included in devices.c - - Portability macros set in the Makefile (but not used) - - Manpage draft included in the package - - Added command-line device selector - - Finally got rid of those ridiculous fread()s in xm_load.c - - xm_instrument_header split into xm_instrument_header and - xm_instrument - - Removed OSS macros from xm_play.c - - Volume overflow bug fixed ("Thematic Hymn" plays OK) - - Scream Tracker S3M loader - - Fixed the song length bug - - XM relnotes are working again! - - Added a garbage character filter to the MOD loader - - Floating point stuff removed - - Sequencer sync message support added - - Multiple file entry point bug fixed - - Song loop bug fixed, added a loop-enable option - - Tremolo and extra fine portamento effects fixed - - Player doesn't try to play invalid instruments (and dump core) - - SIGUSR1 and SIGUSR2 handlers added (abort/restart module) - - MOD effects with parameter 0 filtered in the loader (nasty bug) - - Finetunes partially fixed ("Ooo-uh-uh-uh" does not work) - - Started X11 panel (VERY experimental) - - Volume column effect fxp bug fixed - - Envelope retrig on tone portamento bug fixed - - MOD sample loop length fixed - - Finetune in tone portamento bug fixed - -0.07 (19961011): We've screwed up XM relnotes in this version. Yuck! - - Sample loop bug fixed - - Extra fine portamento effect implemented - - Global volume set/slide effects implemented - - Pan slide effect implemented - - Delay pattern effect implemented - - Retriggered tremolo/vibrato implemented - - Added tremolo/vibrato waveforms 4, 5 and 6 (no retrigger) - - Stereo reverse/mono command line options are now functional - - Pan slide effect implemented (but does it work?) - - Arpeggio effect implemented - - "Official" Amiga (exponential) periods implemented - - Multi-retrig and delay effects implemented - - Retrig and cut implemented as special cases of multi retrig - - Fixed vibrato/tremolo waveforms - - Added some macros to reduce the code mess - - Finetunes/relnotes processed by the player (and not by the loader) - -0.06 (19960924): This version can play most MODs - - Changed a lot of variable names - - Fixed envelope processing - - Fixed pitchbending (SEQ_BENDER vs SEQ_PITCHBEND) bug - - Fixed panning (SEQ_CONTROL vs SEQ_PANNING) bug - - Fixed multisample struct definition bug - - Fixed note number "obi-wan" bug ("Neverending Story" plays OK) - - Fixed tone portamento behavior ("Art of Chrome" plays OK) - - Added MOD finetune support ("Elimination Part I" plays OK) - - Added offset, cut, delay and retrig effects - -0.05 and before: - - Lots of changes. - - diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 4d48a27..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,37 +0,0 @@ - -DOCS_DFILES = Makefile COPYING.LIB CREDITS Changelog tracker_notes.txt \ - formats.txt adlib_sb.txt fixloop.txt \ - libxmp.rst custom.style $(DOCS_FILES) - -DOCS_PATH = docs - -DOCS_FILES = libxmp.html libxmp.3 libxmp.pdf - -DOCS += $(addprefix $(DOCS_PATH)/,$(DOCS_FILES)) - -all-docs: $(DOCS) - -$(DOCS): docs/Makefile - -install-docs: $(DOCS) - @echo "Installing manpages in $(DESTDIR)$(MANDIR)" - @[ -d $(DESTDIR)$(MANDIR) ] || mkdir -p $(DESTDIR)$(MANDIR) - @$(INSTALL_DATA) docs/libxmp.3 $(DESTDIR)$(MANDIR) - -dist-docs: - mkdir -p $(DIST)/$(DOCS_PATH) - cp -RPp $(addprefix $(DOCS_PATH)/,$(DOCS_DFILES)) $(DIST)/$(DOCS_PATH) - -docs/libxmp.3: docs/libxmp.man.rst - rst2man docs/libxmp.man.rst > $@ - -docs/libxmp.man.rst: docs/libxmp.rst docs/manpage-header.rst docs/Makefile - cp docs/manpage-header.rst $@ - sed -n '/^Introduction/,$$p' docs/libxmp.rst >> $@ - -docs/libxmp.html: docs/libxmp.rst - rst2html docs/libxmp.rst > $@ - -docs/libxmp.pdf: docs/libxmp.rst docs/custom.style - rst2pdf docs/libxmp.rst -c --smart-quotes=1 -s docs/custom.style --footer="###Page###" -o $@ - diff --git a/docs/adlib_sb.txt b/docs/adlib_sb.txt deleted file mode 100644 index 7716418..0000000 --- a/docs/adlib_sb.txt +++ /dev/null @@ -1,484 +0,0 @@ -Hello, all. I've updated my doc file on programming the AdLib/Sound Blaster -cards, and since I'm still getting requests for the original, I decided that -it would save time to post it here. Apologies to those who aren't interested. - -------------------------------------------------------------------------------- - - Programming the AdLib/Sound Blaster - FM Music Chips - Version 2.0 (24 Feb 1992) - - Copyright (c) 1991, 1992 by Jeffrey S. Lee - - jlee@smylex.uucp - - - - Warranty and Copyright Policy - - This document is provided on an "as-is" basis, and its author makes - no warranty or representation, express or implied, with respect to - its quality performance or fitness for a particular purpose. In no - event will the author of this document be liable for direct, indirect, - special, incidental, or consequential damages arising out of the use - or inability to use the information contained within. Use of this - document is at your own risk. - - This file may be used and copied freely so long as the applicable - copyright notices are retained, and no modifications are made to the - text of the document. No money shall be charged for its distribution - beyond reasonable shipping, handling and duplication costs, nor shall - proprietary changes be made to this document so that it cannot be - distributed freely. This document may not be included in published - material or commercial packages without the written consent of its - author. - - - - Overview - - Two of the most popular sound cards for the IBM-PC, the AdLib and the - Sound Blaster, suffer from a real dearth of clear documentation for - programmers. AdLib Inc. and Creative Labs, Inc. both sell developers' - kits for their sound cards, but these are expensive, and (in the case - of the Sound Blaster developers' kit) can be extremely cryptic. - - This document is intended to provide programmers with a FREE source - of information about the programming of these sound cards. - - The information contained in this document is a combination of - information found in the Sound Blaster Software Developer's Kit, and - that learned by painful experience. Some of the information may not - be valid for AdLib cards; if this is so, I apologize in advance. - - Please note that numbers will be given in hexadecimal, unless otherwise - indicated. If a number is written out longhand (sixteen instead of 16) - it is in decimal. - - | Changes from Version 1 of the file will be indicated by the use of change - | bars in the left-hand margin. - - - - Chapter One - Sound Card I/O - - The sound card is programmed by sending data to its internal registers - via its two I/O ports: - - 0388 (hex) - Address/Status port (R/W) - 0389 (hex) - Data port (W/O) - - | The Sound Blaster Pro is capable of stereo FM music, which is accessed - | in exactly the same manner. Ports 0220 and 0221 (hex) are the address/ - | data ports for the left speaker, and ports 0222 and 0223 (hex) are the - | ports for the right speaker. Ports 0388 and 0389 (hex) will cause both - | speakers to output sound. - - The sound card possesses an array of two hundred forty-four registers; - to write to a particular register, send the register number (01-F5) to - the address port, and the desired value to the data port. - - After writing to the register port, you must wait twelve cycles before - sending the data; after writing the data, eighty-four cycles must elapse - before any other sound card operation may be performed. - - | The AdLib manual gives the wait times in microseconds: three point three - | (3.3) microseconds for the address, and twenty-three (23) microseconds - | for the data. - | - | The most accurate method of producing the delay is to read the register - | port six times after writing to the register port, and read the register - | port thirty-five times after writing to the data port. - - The sound card registers are write-only. - - The address port also functions as a sound card status byte. To - retrieve the sound card's status, simply read port 388. The status - byte has the following structure: - - 7 6 5 4 3 2 1 0 - +------+------+------+------+------+------+------+------+ - | both | tmr | tmr | unused | - | tmrs | 1 | 2 | | - +------+------+------+------+------+------+------+------+ - - Bit 7 - set if either timer has expired. - 6 - set if timer 1 has expired. - 5 - set if timer 2 has expired. - - - - Chapter Two - The Registers - -The following table shows the function of each register in the sound -card. Registers will be explained in detail after the table. Registers -not listed are unused. - - Address Function - ------- ---------------------------------------------------- - 01 Test LSI / Enable waveform control - 02 Timer 1 data - 03 Timer 2 data - 04 Timer control flags - 08 Speech synthesis mode / Keyboard split note select - 20..35 Amp Mod / Vibrato / EG type / Key Scaling / Multiple - 40..55 Key scaling level / Operator output level - 60..75 Attack Rate / Decay Rate - 80..95 Sustain Level / Release Rate - A0..A8 Frequency (low 8 bits) - B0..B8 Key On / Octave / Frequency (high 2 bits) - BD AM depth / Vibrato depth / Rhythm control - C0..C8 Feedback strength / Connection type - E0..F5 Wave Select - -The groupings of twenty-two registers (20-35, 40-55, etc.) have an odd -order due to the use of two operators for each FM voice. The following -table shows the offsets within each group of registers for each operator. - - - Channel 1 2 3 4 5 6 7 8 9 - Operator 1 00 01 02 08 09 0A 10 11 12 - Operator 2 03 04 05 0B 0C 0D 13 14 15 - -Thus, the addresses of the attack/decay bytes for channel 3 are 62 for -the first operator, and 65 for the second. (The address of the second -operator is always the address of the first operator plus three). - -To further illustrate the relationship, the addresses needed to control -channel 5 are: - - 29 - Operator 1 AM/VIB/EG/KSR/Multiplier - 2C - Operator 2 AM/VIB/EG/KSR/Multiplier - 49 - Operator 1 KSL/Output Level - 4C - Operator 2 KSL/Output Level - 69 - Operator 1 Attack/Decay - 6C - Operator 2 Attack/Decay - 89 - Operator 1 Sustain/Release - 8C - Operator 2 Sustain/Release - A4 - Frequency (low 8 bits) - B4 - Key On/Octave/Frequency (high 2 bits) - C4 - Feedback/Connection Type - E9 - Operator 1 Waveform - EC - Operator 2 Waveform - - - - Explanations of Registers - -Byte 01 - This byte is normally used to test the LSI device. All bits - should normally be zero. Bit 5, if enabled, allows the FM - chips to control the waveform of each operator. - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | unused | WS | unused | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - -Byte 02 - Timer 1 Data. If Timer 1 is enabled, the value in this - register will be incremented until it overflows. Upon - overflow, the sound card will signal a TIMER interrupt - (INT 08) and set bits 7 and 6 in its status byte. The - value for this timer is incremented every eighty (80) - microseconds. - - -Byte 03 - Timer 2 Data. If Timer 2 is enabled, the value in this - register will be incremented until it overflows. Upon - overflow, the sound card will signal a TIMER interrupt - (INT 08) and set bits 7 and 5 in its status byte. The - value for this timer is incremented every three hundred - twenty (320) microseconds. - - -Byte 04 - Timer Control Byte - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | IRQ | T1 | T2 | unused | T2 | T1 | - | RST | MSK | MSK | | CTL | CTL | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - bit 7 - Resets the flags for timers 1 & 2. If set, - all other bits are ignored. - bit 6 - Masks Timer 1. If set, bit 0 is ignored. - bit 5 - Masks Timer 2. If set, bit 1 is ignored. - bit 1 - When clear, Timer 2 does not operate. - When set, the value from byte 03 is loaded into - Timer 2, and incrementation begins. - bit 0 - When clear, Timer 1 does not operate. - When set, the value from byte 02 is loaded into - Timer 1, and incrementation begins. - - -Byte 08 - CSM Mode / Keyboard Split. - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | CSM | Key | unused | - | sel | Spl | | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - bit 7 - When set, selects composite sine-wave speech synthesis - mode (all KEY-ON bits must be clear). When clear, - selects FM music mode. - - bit 6 - Selects the keyboard split point (in conjunction with - the F-Number data). The documentation in the Sound - Blaster manual is utterly incomprehensible on this; - I can't reproduce it without violating their copyright. - - -Bytes 20-35 - Amplitude Modulation / Vibrato / Envelope Generator Type / - Keyboard Scaling Rate / Modulator Frequency Multiple - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | Amp | Vib | EG | KSR | Modulator Frequency | - | Mod | | Typ | | Multiple | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - bit 7 - Apply amplitude modulation when set; AM depth is - controlled by the AM-Depth flag in address BD. - bit 6 - Apply vibrato when set; vibrato depth is controlled - by the Vib-Depth flag in address BD. - bit 5 - When set, the sustain level of the voice is maintained - until released; when clear, the sound begins to decay - immediately after hitting the SUSTAIN phase. - bit 4 - Keyboard scaling rate. This is another incomprehensible - bit in the Sound Blaster manual. From experience, if - this bit is set, the sound's envelope is foreshortened as - it rises in pitch. - bits 3-0 - These bits indicate which harmonic the operator will - produce sound (or modulation) in relation to the voice's - specified frequency: - - 0 - one octave below - 1 - at the voice's specified frequency - 2 - one octave above - 3 - an octave and a fifth above - 4 - two octaves above - 5 - two octaves and a major third above - 6 - two octaves and a fifth above - 7 - two octaves and a minor seventh above - 8 - three octaves above - 9 - three octaves and a major second above - A - three octaves and a major third above - B - " " " " " " " - C - three octaves and a fifth above - D - " " " " " " - E - three octaves and a major seventh above - F - " " " " " " " - - -Bytes 40-55 - Level Key Scaling / Total Level - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | Scaling | Total Level | - | Level | 24 12 6 3 1.5 .75 | <-- dB - +-----+-----+-----+-----+-----+-----+-----+-----+ - - bits 7-6 - causes output levels to decrease as the frequency - rises: - - 00 - no change - 10 - 1.5 dB/8ve - 01 - 3 dB/8ve - 11 - 6 dB/8ve - - bits 5-0 - controls the total output level of the operator. - all bits CLEAR is loudest; all bits SET is the - softest. Don't ask me why. - - -Bytes 60-75 - Attack Rate / Decay Rate - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | Attack | Decay | - | Rate | Rate | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - bits 7-4 - Attack rate. 0 is the slowest, F is the fastest. - bits 3-0 - Decay rate. 0 is the slowest, F is the fastest. - - -Bytes 80-95 - Sustain Level / Release Rate - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | Sustain Level | Release | - | 24 12 6 3 | Rate | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - bits 7-4 - Sustain Level. 0 is the loudest, F is the softest. - bits 3-0 - Release Rate. 0 is the slowest, F is the fastest. - - -Bytes A0-B8 - Octave / F-Number / Key-On - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | F-Number (least significant byte) | (A0-A8) - | | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | Unused | Key | Octave | F-Number | (B0-B8) - | | On | | most sig. | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - bit 5 - Channel is voiced when set, silent when clear. - bits 4-2 - Octave (0-7). 0 is lowest, 7 is highest. - bits 1-0 - Most significant bits of F-number. - - In octave 4, the F-number values for the chromatic scale and their - corresponding frequencies would be: - - F Number Frequency Note - 16B 277.2 C# - 181 293.7 D - 198 311.1 D# - 1B0 329.6 E - 1CA 349.2 F - 1E5 370.0 F# - 202 392.0 G - 220 415.3 G# - 241 440.0 A - 263 466.2 A# - 287 493.9 B - 2AE 523.3 C - - -Bytes C0-C8 - Feedback / Algorithm - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | unused | Feedback | Alg | - | | | | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - bits 3-1 - Feedback strength. If all three bits are set to - zero, no feedback is present. With values 1-7, - operator 1 will send a portion of its output back - into itself. 1 is the least amount of feedback, - 7 is the most. - bit 0 - If set to 0, operator 1 modulates operator 2. In this - case, operator 2 is the only one producing sound. - If set to 1, both operators produce sound directly. - Complex sounds are more easily created if the algorithm - is set to 0. - - -Byte BD - Amplitude Modulation Depth / Vibrato Depth / Rhythm - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | AM | Vib | Rhy | BD | SD | TOM | Top | HH | - | Dep | Dep | Ena | | | | Cym | | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - bit 7 - Set: AM depth is 4.8dB - Clear: AM depth is 1 dB - bit 6 - Set: Vibrato depth is 14 cent - Clear: Vibrato depth is 7 cent - bit 5 - Set: Rhythm enabled (6 melodic voices) - Clear: Rhythm disabled (9 melodic voices) - bit 4 - Bass drum on/off - bit 3 - Snare drum on/off - bit 2 - Tom tom on/off - bit 1 - Cymbal on/off - bit 0 - Hi Hat on/off - - Note: KEY-ON registers for channels 06, 07, and 08 must be OFF - in order to use the rhythm section. Other parameters - such as attack/decay/sustain/release must also be set - appropriately. - - -Bytes E0-F5 - Waveform Select - - 7 6 5 4 3 2 1 0 - +-----+-----+-----+-----+-----+-----+-----+-----+ - | unused | Waveform | - | | Select | - +-----+-----+-----+-----+-----+-----+-----+-----+ - - bits 1-0 - When bit 5 of address 01 is set, the output waveform - will be distorted according to the waveform indicated - by these two bits. I'll try to diagram them here, - but this medium is fairly restrictive. - - ___ ___ ___ ___ _ _ - / \ / \ / \ / \ / | / | - /_____\_______ /_____\_____ /_____\/_____\ /__|___/__|___ - \ / - \___/ - - 00 01 10 11 - - - - | Detecting a Sound Card - | - | According to the AdLib manual, the 'official' method of checking for a - | sound card is as follows: - | - | 1) Reset both timers by writing 60h to register 4. - | 2) Enable the interrupts by writing 80h to register 4. NOTE: this - | must be a separate step from number 1. - | 3) Read the status register (port 388h). Store the result. - | 4) Write FFh to register 2 (Timer 1). - | 5) Start timer 1 by writing 21h to register 4. - | 6) Delay for at least 80 microseconds. - | 7) Read the status register (port 388h). Store the result. - | 8) Reset both timers and interrupts (see steps 1 and 2). - | 9) Test the stored results of steps 3 and 7 by ANDing them - | with E0h. The result of step 3 should be 00h, and the - | result of step 7 should be C0h. If both are correct, an - | AdLib-compatible board is installed in the computer. - | - | - | Making a Sound - | - | Many people have asked me, upon reading this document, what the proper - | register values should be to make a simple sound. Well, here they are. - | - | First, clear out all of the registers by setting all of them to zero. - | This is the quick-and-dirty method of resetting the sound card, but it - | works. Note that if you wish to use different waveforms, you must then - | turn on bit 5 of register 1. (This reset need be done only once, at the - | start of the program, and optionally when the program exits, just to - | make sure that your program doesn't leave any notes on when it exits.) - | - | Now, set the following registers to the indicated value: - | - | REGISTER VALUE DESCRIPTION - | 20 01 Set the modulator's multiple to 1 - | 40 10 Set the modulator's level to about 40 dB - | 60 F0 Modulator attack: quick; decay: long - | 80 77 Modulator sustain: medium; release: medium - | A0 98 Set voice frequency's LSB (it'll be a D#) - | 23 01 Set the carrier's multiple to 1 - | 43 00 Set the carrier to maximum volume (about 47 dB) - | 63 F0 Carrier attack: quick; decay: long - | 83 77 Carrier sustain: medium; release: medium - | B0 31 Turn the voice on; set the octave and freq MSB - | - | To turn the voice off, set register B0h to 11h (or, in fact, any value - | which leaves bit 5 clear). It's generally preferable, of course, to - | induce a delay before doing so. - | - | - | Acknowledgements - | - | Thanks are due to the following people: - | - | Ezra M. Dreisbach (ed10+@andrew.cmu.edu), for providing the information - | about the recommended port write delay from the AdLib manual, and the - | 'official' method of detecting an AdLib-compatible sound card. - | - | Nathan Isaac Laredo (gt7080a@prism.gatech.edu), for providing the - | port numbers for stereo sound on the Sound Blaster Pro. diff --git a/docs/custom.style b/docs/custom.style deleted file mode 100644 index 6e360ab..0000000 --- a/docs/custom.style +++ /dev/null @@ -1,593 +0,0 @@ - -# List any fonts you would like to embed in the PDF here -embeddedFonts: [] - -# Default page setup. Can be overridden by including other -# stylesheets with -s - -pageSetup: - size: A4 -# firstTemplate: coverPage - margin-bottom: 8mm - margin-left: 12mm - margin-right: 12mm - margin-top: 8mm - margin-gutter: 0cm - spacing-header: 5mm - spacing-footer: 5mm - - # The first template is one of the 'pageTemplates" - # (See next section) - - firstTemplate: oneColumn - -# pageTemplates can be accessed with the .. raw:: pdf PageBreak command - -pageTemplates: - coverPage: - frames: [] - [0cm, 0cm, 100%, 100%] - showHeader : false - showFooter : false - - emptyPage: - frames: [] - [0cm, 0cm, 100%, 100%] - showHeader : false - showFooter : false - - oneColumn: - frames: [] - [0cm, 0cm, 100%, 100%] - showHeader : true - showFooter : true - - twoColumn: - frames: [] - [0cm, 0cm, 49%, 100%] - [51%, 0cm, 49%, 100%] - showHeader : true - showFooter : true - - threeColumn: - frames: [] - [2%, 0cm, 29.333%, 100%] - [35.333%, 0cm, 29.333%, 100%] - [68.666%, 0cm, 29.333%, 100%] - showHeader : true - showFooter : true - - cutePage: - frames: [] - [0%, 0%, 100%, 100%] - showHeader : true - showFooter : true - defaultFooter : ###Page### - defaultHeader : ###Section### - -fontsAlias: - stdFont: Helvetica - stdBold: Helvetica-Bold - stdItalic: Helvetica-Oblique - stdBoldItalic: Helvetica-BoldOblique - stdSans: Helvetica - stdSansBold: Helvetica-Bold - stdSansItalic: Helvetica-Oblique - stdSansBoldItalic: Helvetica-BoldOblique - stdMono: Courier - stdMonoItalic: Courier-Oblique - stdMonoBold: Courier-Bold - stdMonoBoldItalic: Courier-BoldOblique - stdSerif: Times-Roman - -linkColor: darkgreen - -styles: - base: - parent: null - fontName: stdFont - fontSize: 10 - leading: 12 - leftIndent: 0 - rightIndent: 0 - firstLineIndent: 0 - alignment: TA_LEFT - spaceBefore: 0 - spaceAfter: 0 - bulletFontName: stdFont - bulletFontSize: 10 - bulletIndent: 0 - textColor: black - backColor: null - wordWrap: null - borderWidth: 0 - borderPadding: 0 - borderColor: null - borderRadius: null - allowWidows: 3 - allowOrphans: 3 - hyphenation: false - kerning: false - underline: false - strike: false - commands: [] - - normal: - parent: base - - title-reference: - parent: heading - fontName: stdBold - - bodytext: - parent: normal - spaceBefore: 8 - alignment: TA_JUSTIFY - hyphenation: true - - toc: - parent: normal - leading: 9 - - blockquote: - parent: bodytext - leftIndent: 20 - - lineblock: - parent: bodytext - - line: - parent: lineblock - spaceBefore: 0 - - toc1: - parent: toc - fontName: stdBold - - toc2: - parent: toc - leftIndent: 20 - - toc3: - parent: toc - leading: 7 - leftIndent: 40 - fontSize: 90% - spaceAfter: 0 - spaceBefore: 0 - - toc4: - parent: toc - leftIndent: 60 - - toc5: - parent: toc - leftIndent: 80 - - toc6: - parent: toc - leftIndent: 100 - - toc7: - parent: toc - leftIndent: 100 - - toc8: - parent: toc - leftIndent: 100 - - toc9: - parent: toc - leftIndent: 100 - - toc10: - parent: toc - leftIndent: 100 - - toc11: - parent: toc - leftIndent: 100 - - toc12: - parent: toc - leftIndent: 100 - - toc13: - parent: toc - leftIndent: 100 - - toc14: - parent: toc - leftIndent: 100 - - toc15: - parent: toc - leftIndent: 100 - - footer: - parent: normal - alignment: TA_CENTER - - header: - parent: normal - alignment: TA_CENTER - - attribution: - parent: bodytext - alignment: TA_RIGHT - - figure: - parent: bodytext - alignment: TA_CENTER - commands: [] - [VALIGN, [ 0, 0 ], [ -1, -1 ], TOP ] - [ALIGN, [ 0, 0 ], [ -1, -1 ], CENTER ] - colWidths: [100%] - - figure-caption: - parent: bodytext - fontName: stdItalic - alignment: TA_CENTER - - figure-legend: - parent: bodytext - - bullet-list: - parent: bodytext - commands: [] - [VALIGN, [ 0, 0 ], [ -1, -1 ], TOP ] - [RIGHTPADDING, [ 0, 0 ], [ 1, -1 ], 0 ] - colWidths: ["20", null] - - bullet-list-item: - parent: bodytext - - item-list: - parent: bodytext - commands: [] - [VALIGN, [ 0, 0 ], [ -1, -1 ], TOP ] - [RIGHTPADDING, [ 0, 0 ], [ 1, -1 ], 0 ] - colWidths: [20pt,null] - - item-list-item: - parent: bodytext - - definition-list-term: - parent: normal - fontName: stdBold - spaceBefore: 4 - spaceAfter: 0 - keepWithNext: false - - definition-list-classifier: - parent: normal - fontName: stdItalic - - definition: - parent: bodytext - firstLineIndent: 0 - bulletIndent: 0 - spaceBefore: 0 - colWidths: [20pt,null] - commands: [] - [VALIGN, [ 0, 0 ], [ -1, -1 ], TOP ] - [LEFTPADDING, [ 0, 0 ], [ -1, -1 ], 0 ] - [BOTTOMPADDING, [ 0, 0 ], [ -1, -1 ], 0 ] - [RIGHTPADDING, [ 0, 0 ], [ -1, -1 ], 0 ] - - fieldname: - parent: bodytext - alignment: TA_RIGHT - fontName: stdBold - - fieldvalue: - parent: bodytext - - rubric: - parent: bodytext - textColor: darkred - alignment: TA_CENTER - - italic: - parent: bodytext - fontName: stdItalic - - heading: - parent: normal - keepWithNext: true - spaceBefore: 12 - spaceAfter: 6 - textColor: #20435C - - title: - parent: heading - fontName: stdBold - fontSize: 200% - alignment: TA_CENTER - keepWithNext: false - spaceAfter: 10 - - subtitle: - parent: title - spaceBefore: 12 - fontSize: 75% - - heading1: - parent: heading - fontName: stdBold - fontSize: 175% - spaceBefore: 24 - - heading2: - parent: heading - fontName: stdBold - fontSize: 150% - spaceBefore: 20 - - heading3: - parent: heading - fontName: stdBold - fontSize: 125% - spaceBefore: 16 - - heading4: - parent: heading - fontName: stdBold - - heading5: - parent: heading - fontName: stdBold - - heading6: - parent: heading - fontName: stdBold - - topic-title: - parent: heading3 - - sidebar-title: - parent: heading3 - - sidebar-subtitle: - parent: heading4 - - sidebar: - float: none - width: 100% - parent: normal - backColor: beige - borderColor: darkgray - borderPadding: 8 - borderWidth: 0.5 - - admonition: - parent: normal - spaceBefore: 12 - spaceAfter: 6 - borderPadding: [16,16,16,16] - backColor: beige - borderColor: darkgray - borderWidth: 0.5 - commands:[] - [VALIGN, [ 0, 0 ], [ -1, -1 ], TOP ] - - attention: - parent: admonition - - caution: - parent: admonition - - danger: - parent: admonition - - error: - parent: admonition - - hint: - parent: admonition - - important: - parent: admonition - - note: - parent: admonition - - tip: - parent: admonition - - warning: - parent: admonition - - admonition-title: - parent: heading3 - - admonition-heading: - parent: heading3 - - attention-heading: - parent: admonition-heading - - caution-heading: - parent: admonition-heading - - danger-heading: - parent: admonition-heading - - error-heading: - parent: admonition-heading - - hint-heading: - parent: admonition-heading - - important-heading: - parent: admonition-heading - - note-heading: - parent: admonition-heading - - tip-heading: - parent: admonition-heading - - warning-heading: - parent: admonition-heading - - literal: - parent: normal - fontName: stdMono - firstLineIndent: 0 - hyphenation: false - wordWrap: null - - aafigure: - parent: literal - - table: - spaceBefore:6 - spaceAfter:0 - alignment: TA_CENTER - commands: [] - [VALIGN, [ 0, 0 ], [ -1, -1 ], TOP ] - [INNERGRID, [ 0, 0 ], [ -1, -1 ], 0.25, black ] - [ROWBACKGROUNDS, [0, 0], [-1, -1], [white,#E0E0E0]] - [BOX, [ 0, 0 ], [ -1, -1 ], 0.25, black ] - - table-title: - parent : heading4 - keepWithNext: false - alignment : TA_CENTER - - table-heading: - parent : heading - backColor : beige - alignment : TA_CENTER - valign : BOTTOM - borderPadding : 0 - - table-body: - parent : normal - - dedication: - parent : normal - - abstract: - parent : normal - - contents: - parent : normal - - tableofcontents: - parent : normal - - code: - parent: literal - leftIndent: 0 - spaceBefore: 8 - spaceAfter: 8 - borderWidth: 0.5 - borderPadding: 6 - allowOrphans: 4 - allowWidows: 4 - backColor: #EEEEFF - borderColor: #AA99CC - borderPadding: [2, 2, 2, 2] - borderWidth: 0.3 - - linenumber: - parent: code - - right: - parent: bodytext - alignment: right - - center: - parent: bodytext - alignment: center - - pygments-n: parent: code - pygments-nx: parent: code - pygments-p: parent: code - pygments-hll: {parent: code, backColor: #ffffcc} - pygments-c: {textColor: #008800, parent: code} - pygments-err: {parent: code} - pygments-k: {textColor: #AA22FF, parent: code} - pygments-o: {textColor: #666666, parent: code} - pygments-cm: {textColor: #008800, parent: code} - pygments-cp: {textColor: #008800, parent: code} - pygments-c1: {textColor: #008800, parent: code} - pygments-cs: {textColor: #008800, parent: code} - pygments-gd: {textColor: #A00000, parent: code} - pygments-ge: {parent: code} - pygments-gr: {textColor: #FF0000, parent: code} - pygments-gh: {textColor: #000080, parent: code} - pygments-gi: {textColor: #00A000, parent: code} - pygments-go: {textColor: #808080, parent: code} - pygments-gp: {textColor: #000080, parent: code} - pygments-gs: {parent: code} - pygments-gu: {textColor: #800080, parent: code} - pygments-gt: {textColor: #0040D0, parent: code} - pygments-kc: {textColor: #AA22FF, parent: code} - pygments-kd: {textColor: #AA22FF, parent: code} - pygments-kn: {textColor: #AA22FF, parent: code} - pygments-kp: {textColor: #AA22FF, parent: code} - pygments-kr: {textColor: #AA22FF, parent: code} - pygments-kt: {textColor: #00BB00, parent: code} - pygments-m: {textColor: #666666, parent: code} - pygments-s: {textColor: #BB4444, parent: code} - pygments-na: {textColor: #BB4444, parent: code} - pygments-nb: {textColor: #AA22FF, parent: code} - pygments-nc: {textColor: #0000FF, parent: code} - pygments-no: {textColor: #880000, parent: code} - pygments-nd: {textColor: #AA22FF, parent: code} - pygments-ni: {textColor: #999999, parent: code} - pygments-ne: {textColor: #D2413A, parent: code} - pygments-nf: {textColor: #00A000, parent: code} - pygments-nl: {textColor: #A0A000, parent: code} - pygments-nn: {textColor: #0000FF, parent: code} - pygments-nt: {textColor: #008000, parent: code} - pygments-nv: {textColor: #B8860B, parent: code} - pygments-ow: {textColor: #AA22FF, parent: code} - pygments-w: {textColor: #bbbbbb, parent: code} - pygments-mf: {textColor: #666666, parent: code} - pygments-mh: {textColor: #666666, parent: code} - pygments-mi: {textColor: #666666, parent: code} - pygments-mo: {textColor: #666666, parent: code} - pygments-sb: {textColor: #BB4444, parent: code} - pygments-sc: {textColor: #BB4444, parent: code} - pygments-sd: {textColor: #BB4444, parent: code} - pygments-s2: {textColor: #BB4444, parent: code} - pygments-se: {textColor: #BB6622, parent: code} - pygments-sh: {textColor: #BB4444, parent: code} - pygments-si: {textColor: #BB6688, parent: code} - pygments-sx: {textColor: #008000, parent: code} - pygments-sr: {textColor: #BB6688, parent: code} - pygments-s1: {textColor: #BB4444, parent: code} - pygments-ss: {textColor: #B8860B, parent: code} - pygments-bp: {textColor: #AA22FF, parent: code} - pygments-vc: {textColor: #B8860B, parent: code} - pygments-vg: {textColor: #B8860B, parent: code} - pygments-vi: {textColor: #B8860B, parent: code} - pygments-il: {textColor: #666666, parent: code} - - endnote: - parent: bodytext - commands: [] - [VALIGN, [ 0, 0 ], [ -1, -1 ], TOP ] - [TOPPADDING, [ 0, 0 ], [ -1, -1 ], 0 ] - [BOTTOMPADDING, [ 0, 0 ], [ -1, -1 ], 0 ] - [RIGHTPADDING, [ 0, 0 ], [ 1, -1 ], 0 ] - colWidths: [3cm, null] - - field-list: - parent: bodytext - commands: [] - [VALIGN, [ 0, 0 ], [ -1, -1 ], TOP ] - [TOPPADDING, [ 0, 0 ], [ -1, -1 ], 0 ] - colWidths: [1.5cm, null] - spaceBefore: 6 - - option-list: - commands: [] - [VALIGN, [ 0, 0 ], [ -1, -1 ], TOP ] - [TOPPADDING, [ 0, 0 ], [ -1, -1 ], 0 ] - colWidths: [null,null] - diff --git a/docs/fixloop.txt b/docs/fixloop.txt deleted file mode 100644 index f133054..0000000 --- a/docs/fixloop.txt +++ /dev/null @@ -1,56 +0,0 @@ - -The flag XMP_FLAGS_FIXLOOP halves sample loop start values. You may -need to use it with modules where autodetection is either impossible -or unreliable. - -Case 1: Bad conversion from Soundtracker to M.K. - -In Soundtracker and derivatives using 15 instrument modules the loop -start is given in bytes instead of 16 bit words [1]. Many modules -have been converted from 15 instrument to 31 instrument format assuming -that the loop start was in 16 bit words instead of bytes, resulting in -broken loops [2]. In this case, use XMP_FLAGS_FIXLOOP to play the module -correctly. - -An example of damaged module is "mod.souvenir of china" - - -Case 2: NoisePacker v1 modules - -According to Asle [3], the only difference between NoisePacker 1.0 -and 2.0 is the loop start value. This situation is very hard to -detect, and XMP_FLAGS_FIXLOOP is needed to play NoisePacker 2.0 modules -correctly. - - -Case 3: Laxity/UNIC modules - -UNIC modules can have loop start specified in 16 bit words or in 32 bit -words [4]. Use XMP_FLAGS_FIXLOOP to set this value to 16 bit words. - - - -References: - -[1] Michael Schwendt (Sat, 24 Oct 1998 22:41:21 +0000) - "(...) all Soundtracker derivatives, including Ultimate Soundtracker, - Soundtracker v1.0 to v4.0 and V to IX, Master Soundtracker 1.0, - D.O.C-Soundtracker v2.0 to v2.3, use repeat_start in bytes (!). - Hence MOD players should default to repeat_start in bytes. The first - Soundtrackers to use repeat_start in words were Soundtracker v2.4 - (Spreadpoint), Noisetracker, and Protracker." - -[2] "Ultimate Soundtracker module format description", v0.1, by Michael - Schwendt, lines 28--31: "Years later people without knowledge of the - incompatibility between the original Soundtracker module format and - successors like Soundtracker 2.4 or Protracker damaged modules by - converting them to Protracker format." - -[3] "Amiga MOD packers described", version 4.1 (13/06/98), written by - Sylvain Chipaux (Asle/ReDoX). - -[4] "Amiga MOD packers described", version 4.1 (13/06/98), written by - Sylvain Chipaux (Asle/ReDoX). "About this loop start /4 or /2, I - cannot tell for sure because I've encountered both cases: 'Guardian - dragon' (/2) and 'Guardian dragon II' (/4). - diff --git a/docs/formats.txt b/docs/formats.txt deleted file mode 100644 index f7f5c87..0000000 --- a/docs/formats.txt +++ /dev/null @@ -1,120 +0,0 @@ - SUPPORTED MODULE FORMATS - - -Common suffix Tracker/packer Recognized variants - -Soundtracker and variants: - -MOD Sound/Noise/Protracker M.K., M!K!, M&K!, N.T., CD81 -MOD, M15 Soundtracker 2.2, UST -MOD/NT Startrekker/ADSC FLT4/8/M, EXO4/8 -MOD Digital Tracker FA04, FA06, FA08 -MOD Fast/Taketracker xCHN, xxCH -MOD His Master's Noise - -FLX Flextrax M.K., xCHN (no dsp effects) -WOW Mod's Grave M.K. - -Amiga packed formats: - -- AC1D Packer - -- FC-M Packer 1.0 -- Fuchs Tracker - -- Heatseeker mc1.0 -- Hornet Packer HRT! -- Images Music System ? -- Kefrens Sound Machine - -- Module Protector - -- NoisePacker 1.0, 2.0, 3.0 -- NoiseRunner - -- Pha Packer - -- Power Music - -- ProPacker 2.1 -- ProRunner 1.0, 2.0 -- Promizer 0.1, 1.0c, 1.8a, 2.0, 4.0 -- SKYT Packer - -- StarTrekker Packer - -- The Player 4.x, 5.0a, 6.0a, 6.1a -- Titanics Player - -- Tracker Packer 3 -MOD Unic Tracker 1.0, 2.0 -- Wanton Packer - -- XANN Packer - -- Zen Packer - - -Other Amiga tracker formats: - -DBM DigiBooster Pro DBM0 -DIGI DIGI Booster 1.4, 1.5, 1.6, 1.7 -EMOD Quadra Composer 0001 -MOD ChipTracker KRIS -MOD Protracker 3.59 PTDT -MED MED 1.12/2.10/3.00 MED2, MED3, MED4 -MED MED 3.00/OctaMED MMD0, MMD1, MMD2, MMD3 -MOD, MTN ST 2.6, Ice Tracker MTN, IT10 -OKT Oktalyzer - -SFX SoundFX 1.3, 2.0? - -Atari tracker formats: - -MOD Octalyser CD61, CD81 -DTM Digital Tracker 1.9 -GTK (*) Graoumf Tracker GTK1, GTK4 -MGT Megatracker - - -Acorn tracker formats: - -- Archimedes Tracker V1.0+++ -- Digital Symphony 0 - -PC tracker formats: - -669 Composer 669/UNIS 669 if, JN -FAR Farandole Composer 1.0 -FNK Funktracker R0, R1, R2 -IMF Imago Orpheus 1.0 -IT Impulse Tracker 1.00, 2.00, 2.14, 2.15 -LIQ Liquid Tracker 0.0, 1.0 -MDL Digitrakker 0.0, 1.0, 1.1 -MTM Multitracker 1.0 -PTM Poly Tracker 2.03 -RTM Real Tracker 1.00 -S3M Scream Tracker 3 3.00, 3.01+ -STM Scream Tracker 2 !Scream!, BMOD2STM -ULT Ultra Tracker V0001, V0002, V0003, V0004 -XM Fast Tracker II 1.02, 1.03, 1.04 - -PC packed formats: - -AMF DSMI (DMP) 0.9, 1.0, 1.1, 1.2, 1.3, 1.4 -GDM Generic Digital Music 1.0 -STX ST Music Interface Kit 1.0, 1.1 - -Game formats: - -AMF Asylum Music Format 1.0 -- Digital Illusions - -- Game Music Creator - -PSM Epic Megagames MASI epic, sinaria -J2B Galaxy Music System 5.0 - -- Galaxy Music System 4.0 - -MFP/SMP Magnetic Fields Packer - -- Novotrade Packer - -PSM Protracker Studio 0.01, 1.00 -STIM Slamtilt - -UMX Epic Games Unreal/UT IT, S3M, MOD, XM - -YM3812 (Adlib) formats: - -AMD Amusic Adlib Tracker - -RAD Reality Adlib Tracker - -HSC NEO soft/HSC-Tracker 1.5 -S3M Scream Tracker 3 3.00, 3.01+ - - -Formats marked with (*) are experimental and are known to have -replay errors and unimplemented effects. - -Format descriptions of packed modules sent by Sylvain "Asle" Chipaux. -PTM specs and info by Kilian Hekhuis. AMF specs by Miod Vallat. -Soundtracker format details by Michael Schwendt and Sylvain Chipaux. - diff --git a/docs/libxmp.3 b/docs/libxmp.3 deleted file mode 100644 index c446847..0000000 --- a/docs/libxmp.3 +++ /dev/null @@ -1,1402 +0,0 @@ -.\" Man page generated from reStructuredText. -. -.TH LIBXMP 3 "Nov 2013" "4.2" "Extended Module Player" -.SH NAME -libxmp \- A tracker module player library -. -.nr rst2man-indent-level 0 -. -.de1 rstReportMargin -\\$1 \\n[an-margin] -level \\n[rst2man-indent-level] -level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] -- -\\n[rst2man-indent0] -\\n[rst2man-indent1] -\\n[rst2man-indent2] -.. -.de1 INDENT -.\" .rstReportMargin pre: -. RS \\$1 -. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] -. nr rst2man-indent-level +1 -.\" .rstReportMargin post: -.. -.de UNINDENT -. RE -.\" indent \\n[an-margin] -.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] -.nr rst2man-indent-level -1 -.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] -.in \\n[rst2man-indent\\n[rst2man-indent-level]]u -.. -.SH INTRODUCTION -.sp -Libxmp is a module player library supporting many mainstream and obscure -module formats including Protracker MOD, Scream Tracker III S3M and -Impulse Tracker IT. Libxmp loads the module and renders the sound as -linear PCM samples in a buffer at rate and format specified by the user, -one frame at a time (standard modules usually play at 50 frames per second). -.sp -Possible applications for libxmp include stand\-alone module players, module -player plugins for other players, module information extractors, background -music replayers for games and other applications, module\-to\-mp3 renderers, etc. -.SS Concepts -.INDENT 0.0 -.IP \(bu 2 -\fBPlayer context:\fP -Most libxmp functions require a handle that identifies the module player -context. Each context is independent and multiple contexts can be defined -simultaneously. -.IP \(bu 2 -\fBSequence:\fP -Each group of positions in the order list that loops over itself, also -known as "subsong". Most modules have only one sequence, but some modules, -especially modules used in games can have multiple sequences. "Hidden -patterns" outside the main song are also listed as extra sequences, certain -module authors such as Skaven commonly place extra patterns at the end of -the module. -.IP \(bu 2 -\fBState:\fP \fI[Added in libxmp 4.2]\fP -The player can be in one of three possible states: \fIunloaded\fP, \fIloaded\fP, -or \fIplaying\fP\&. The player is in unloaded state after context creation, -changing to other states when a module is loaded or played. -.IP \(bu 2 -\fBExternal sample mixer:\fP \fI[Added in libxmp 4.2]\fP -Special sound channels can be reserved using \fIxmp_start_smix()\fP -to play module instruments or external samples. This is useful when -libxmp is used to provide background music to games or other applications -where sound effects can be played in response to events or user actions -.UNINDENT -.SS A simple example -.sp -This example loads a module, plays it at 44.1kHz and writes it to a raw -sound file: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -#include -#include -#include - -int main(int argc, char **argv) -{ - xmp_context c; - struct xmp_frame_info mi; - FILE *f; - - /* The output raw file */ - f = fopen("out.raw", "wb"); - if (f == NULL) { - fprintf(stderr, "can\(aqt open output file\en"); - exit(EXIT_FAILURE); - } - - /* Create the player context */ - c = xmp_create_context(); - - /* Load our module */ - if (xmp_load_module(c, argv[1]) != 0) { - fprintf(stderr, "can\(aqt load module\en"); - exit(EXIT_FAILURE); - } - - /* Play the module */ - xmp_start_player(c, 44100, 0); - while (xmp_play_frame(c) == 0) { - xmp_get_frame_info(c, &mi); - - if (mi.loop_count > 0) /* exit before looping */ - break; - - fwrite(mi.buffer, mi.buffer_size, 1, f); /* write audio data */ - } - xmp_end_player(c); - xmp_release_module(c); /* unload module */ - xmp_free_context(c); /* destroy the player context */ - - fclose(f); - - exit(EXIT_SUCCESS); -} -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -A player context can load and play a single module at a time. Multiple -contexts can be defined if needed. -.sp -Use \fI\%xmp_test_module()\fP to check if the file is a valid module and -retrieve the module name and type. Use \fI\%xmp_load_module()\fP to load -the module to memory. These two calls return 0 on success or <0 in case of -error. Error codes are: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -\-XMP_ERROR_INTERNAL /* Internal error */ -\-XMP_ERROR_FORMAT /* Unsupported module format */ -\-XMP_ERROR_LOAD /* Error loading file */ -\-XMP_ERROR_DEPACK /* Error depacking file */ -\-XMP_ERROR_SYSTEM /* System error */ -\-XMP_ERROR_STATE /* Incorrect player state */ -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -If a system error occurs, the specific error is set in \fBerrno\fP\&. -.sp -Parameters to \fI\%xmp_start_player()\fP are the sampling -rate (up to 48kHz) and a bitmapped integer holding one or more of the -following mixer flags: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -XMP_MIX_8BIT /* Mix to 8\-bit instead of 16 */ -XMP_MIX_UNSIGNED /* Mix to unsigned samples */ -XMP_MIX_MONO /* Mix to mono instead of stereo */ -XMP_MIX_NEAREST /* Mix using nearest neighbor interpolation */ -XMP_MIX_NOFILTER /* Disable lowpass filter */ -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -After \fI\%xmp_start_player()\fP is called, each call to \fI\%xmp_play_frame()\fP -will render an audio frame. Call \fI\%xmp_get_frame_info()\fP to retrieve the -buffer address and size. \fI\%xmp_play_frame()\fP returns 0 on success or \-1 -if replay should stop. -.sp -Use \fI\%xmp_end_player()\fP, \fI\%xmp_release_module()\fP and -\fI\%xmp_free_context()\fP to release memory and end replay. -.SS SDL example -.sp -To use libxmp with SDL, just provide a callback function that renders module -data. The module will play when \fBSDL_PauseAudio(0)\fP is called: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -#include -#include - -static void fill_audio(void *udata, unsigned char *stream, int len) -{ - xmp_play_buffer(udata, stream, len, 0); -} - -int sound_init(xmp_context ctx, int sampling_rate, int channels) -{ - SDL_AudioSpec a; - - a.freq = sampling_rate; - a.format = (AUDIO_S16); - a.channels = channels; - a.samples = 2048; - a.callback = fill_audio; - a.userdata = ctx; - - if (SDL_OpenAudio(&a, NULL) < 0) { - fprintf(stderr, "%s\en", SDL_GetError()); - return \-1; - } -} - -int main(int argc, char **argv) -{ - xmp_context ctx; - - if ((ctx = xmp_create_context()) == NULL) - return 1; - - sound_init(ctx, 44100, 2); - xmp_load_module(ctx, argv[1]); - xmp_start_player(ctx, 44100, 0); - - SDL_PauseAudio(0); - - sleep(10); // Do something important here - - SDL_PauseAudio(1); - - xmp_end_player(ctx); - xmp_release_module(ctx); - xmp_free_context(ctx); - - SDL_CloseAudio(); - return 0; -} -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -SDL callbacks run in a separate thread, so don\(aqt forget to protect sections -that manipulate module data with \fBSDL_LockAudio()\fP and \fBSDL_UnlockAudio()\fP\&. -.SH API REFERENCE -.SS Version and player information -.SS const char *xmp_version -.INDENT 0.0 -.INDENT 3.5 -A string containing the library version, such as "4.0.0". -.UNINDENT -.UNINDENT -.SS const unsigned int xmp_vercode -.INDENT 0.0 -.INDENT 3.5 -The library version encoded in a integer value. Bits 23\-16 contain the -major version number, bits 15\-8 contain the minor version number, and -bits 7\-0 contain the release number. -.UNINDENT -.UNINDENT -.SS char **xmp_get_format_list() -.INDENT 0.0 -.INDENT 3.5 -Query the list of supported module formats. -.INDENT 0.0 -.TP -.B Returns -a NULL\-terminated array of strings containing the names -of all supported module formats. -.UNINDENT -.UNINDENT -.UNINDENT -.SS Context creation -.SS xmp_context xmp_create_context() -.INDENT 0.0 -.INDENT 3.5 -Create a new player context and return an opaque handle to be used in -subsequent accesses to this context. -.INDENT 0.0 -.TP -.B \fBReturns:\fP -the player context handle. -.UNINDENT -.UNINDENT -.UNINDENT -.SS void xmp_free_context(xmp_context c) -.INDENT 0.0 -.INDENT 3.5 -Destroy a player context previously created using \fI\%xmp_create_context()\fP\&. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.SS Module loading -.SS int xmp_test_module(char *path, struct xmp_test_info *test_info) -.INDENT 0.0 -.INDENT 3.5 -Test if a file is a valid module. Testing a file does not affect the -current player context or any currently loaded module. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B path -pathname of the module to test. -.TP -.B test_info -NULL, or a pointer to a structure used to retrieve the -module title and format if the file is a valid module. -\fBstruct xmp_test_info\fP is defined as: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -struct xmp_test_info { - char name[XMP_NAME_SIZE]; /* Module title */ - char type[XMP_NAME_SIZE]; /* Module format */ -}; -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.TP -.B \fBReturns:\fP -0 if the file is a valid module, or a negative error code -in case of error. Error codes can be \fB\-XMP_ERROR_FORMAT\fP in case of an -unrecognized file format, \fB\-XMP_ERROR_DEPACK\fP if the file is compressed -and uncompression failed, or \fB\-XMP_ERROR_SYSTEM\fP in case of system error -(the system error code is set in \fBerrno\fP). -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_load_module(xmp_context c, char *path) -.INDENT 0.0 -.INDENT 3.5 -Load a module into the specified player context. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B path -pathname of the module to load. -.UNINDENT -.TP -.B \fBReturns:\fP -0 if sucessful, or a negative error code in case of error. -Error codes can be \fB\-XMP_ERROR_FORMAT\fP in case of an unrecognized file -format, \fB\-XMP_ERROR_DEPACK\fP if the file is compressed and uncompression -failed, \fB\-XMP_ERROR_LOAD\fP if the file format was recognized but the -file loading failed, or \fB\-XMP_ERROR_SYSTEM\fP in case of system error -(the system error code is set in \fBerrno\fP). -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_load_module_from_memory(xmp_context c, void *mem, long size) -.INDENT 0.0 -.INDENT 3.5 -\fI[Added in libxmp 4.2]\fP Load a module from memory into the specified -player context. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B mem -a pointer to the module file image in memory. Multi\-file modules -or compressed modules can\(aqt be loaded from memory. -.TP -.B size -the size of the module, or 0 if the size is unknown or not -specified. If size is set to 0 certain module formats won\(aqt be -recognized, the MD5 digest will not be set, and module\-specific -quirks won\(aqt be applied. -.UNINDENT -.TP -.B \fBReturns:\fP -0 if sucessful, or a negative error code in case of error. -Error codes can be \fB\-XMP_ERROR_FORMAT\fP in case of an unrecognized file -format, \fB\-XMP_ERROR_LOAD\fP if the file format was recognized but the -file loading failed, or \fB\-XMP_ERROR_SYSTEM\fP in case of system error -(the system error code is set in \fBerrno\fP). -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_load_module_from_file(xmp_context c, FILE *f, long size) -.INDENT 0.0 -.INDENT 3.5 -\fI[Added in libxmp 4.3]\fP Load a module from a stream into the specified -player context. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B f -the file stream. On return, the stream position is undefined. -.TP -.B size -the size of the module, or 0 if the size is unknown or not -specified. If size is set to 0 certain module formats won\(aqt be -recognized, the MD5 digest will not be set, and module\-specific -quirks won\(aqt be applied. -.UNINDENT -.TP -.B \fBReturns:\fP -0 if sucessful, or a negative error code in case of error. -Error codes can be \fB\-XMP_ERROR_FORMAT\fP in case of an unrecognized file -format, \fB\-XMP_ERROR_LOAD\fP if the file format was recognized but the -file loading failed, or \fB\-XMP_ERROR_SYSTEM\fP in case of system error -(the system error code is set in \fBerrno\fP). -.UNINDENT -.UNINDENT -.UNINDENT -.SS void xmp_release_module(xmp_context c) -.INDENT 0.0 -.INDENT 3.5 -Release memory allocated by a module from the specified player context. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.SS void xmp_scan_module(xmp_context c) -.INDENT 0.0 -.INDENT 3.5 -Scan the loaded module for sequences and timing. Scanning is automatically -performed by \fI\%xmp_load_module()\fP and this function should be called only -if \fI\%xmp_set_player()\fP is used to change player timing (with parameter -\fBXMP_PLAYER_VBLANK\fP) in libxmp 4.0.2 or older. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.SS void xmp_get_module_info(xmp_context c, struct xmp_module_info *info) -.INDENT 0.0 -.INDENT 3.5 -Retrieve current module data. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B info -pointer to structure containing the module data. -\fBstruct xmp_module_info\fP is defined as follows: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -struct xmp_module_info { - unsigned char md5[16]; /* MD5 message digest */ - int vol_base; /* Volume scale */ - struct xmp_module *mod; /* Pointer to module data */ - char *comment; /* Comment text, if any */ - int num_sequences; /* Number of valid sequences */ - struct xmp_sequence *seq_data; /* Pointer to sequence data */ -}; -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -Detailed module data is exposed in the \fBmod\fP field: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -struct xmp_module { - char name[XMP_NAME_SIZE]; /* Module title */ - char type[XMP_NAME_SIZE]; /* Module format */ - int pat; /* Number of patterns */ - int trk; /* Number of tracks */ - int chn; /* Tracks per pattern */ - int ins; /* Number of instruments */ - int smp; /* Number of samples */ - int spd; /* Initial speed */ - int bpm; /* Initial BPM */ - int len; /* Module length in patterns */ - int rst; /* Restart position */ - int gvl; /* Global volume */ - - struct xmp_pattern **xxp; /* Patterns */ - struct xmp_track **xxt; /* Tracks */ - struct xmp_instrument *xxi; /* Instruments */ - struct xmp_sample *xxs; /* Samples */ - struct xmp_channel xxc[64]; /* Channel info */ - unsigned char xxo[XMP_MAX_MOD_LENGTH]; /* Orders */ -}; -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -See the header file for more information about pattern and instrument -data. -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.SS Module playing -.SS int xmp_start_player(xmp_context c, int rate, int format) -.INDENT 0.0 -.INDENT 3.5 -Start playing the currently loaded module. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B rate -the sampling rate to use, in Hz (typically 44100). Valid values -range from 8kHz to 48kHz. -.TP -.B flags -bitmapped configurable player flags, one or more of the -following: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -XMP_FORMAT_8BIT /* Mix to 8\-bit instead of 16 */ -XMP_FORMAT_UNSIGNED /* Mix to unsigned samples */ -XMP_FORMAT_MONO /* Mix to mono instead of stereo */ -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.TP -.B \fBReturns:\fP -0 if sucessful, or a negative error code in case of error. -Error codes can be \fB\-XMP_ERROR_INTERNAL\fP in case of a internal player -error, \fB\-XMP_ERROR_INVALID\fP if the sampling rate is invalid, or -\fB\-XMP_ERROR_SYSTEM\fP in case of system error (the system error -code is set in \fBerrno\fP). -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_play_frame(xmp_context c) -.INDENT 0.0 -.INDENT 3.5 -Play one frame of the module. Modules usually play at 50 frames per second. -Use \fI\%xmp_get_frame_info()\fP to retrieve the buffer containing audio data. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.UNINDENT -.TP -.B \fBReturns:\fP -0 if sucessful, \fB\-XMP_END\fP if the module ended or was stopped, or -\fB\-XMP_ERROR_STATE\fP if the player is not in playing state. -.UNINDENT -.UNINDENT -.UNINDENT -.SS void xmp_get_frame_info(xmp_context c, struct xmp_frame_info *info) -.INDENT 0.0 -.INDENT 3.5 -Retrieve current frame data. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B info -pointer to structure containing current frame data. -\fBstruct xmp_frame_info\fP is defined as follows: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -struct xmp_frame_info { /* Current frame information */ - int pos; /* Current position */ - int pattern; /* Current pattern */ - int row; /* Current row in pattern */ - int num_rows; /* Number of rows in current pattern */ - int frame; /* Current frame */ - int speed; /* Current replay speed */ - int bpm; /* Current bpm */ - int time; /* Current module time in ms */ - int total_time; /* Estimated replay time in ms*/ - int frame_time; /* Frame replay time in us */ - void *buffer; /* Pointer to sound buffer */ - int buffer_size; /* Used buffer size */ - int total_size; /* Total buffer size */ - int volume; /* Current master volume */ - int loop_count; /* Loop counter */ - int virt_channels; /* Number of virtual channels */ - int virt_used; /* Used virtual channels */ - int sequence; /* Current sequence */ - - struct xmp_channel_info { /* Current channel information */ - unsigned int period; /* Sample period */ - unsigned int position; /* Sample position */ - short pitchbend; /* Linear bend from base note*/ - unsigned char note; /* Current base note number */ - unsigned char instrument; /* Current instrument number */ - unsigned char sample; /* Current sample number */ - unsigned char volume; /* Current volume */ - unsigned char pan; /* Current stereo pan */ - unsigned char reserved; /* Reserved */ - struct xmp_event event; /* Current track event */ - } channel_info[XMP_MAX_CHANNELS]; -}; -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -This function should be used to retrieve sound buffer data after -\fI\%xmp_play_frame()\fP is called. Fields \fBbuffer\fP and \fBbuffer_size\fP -contain the pointer to the sound buffer PCM data and its size. The -buffer size will be no larger than \fBXMP_MAX_FRAMESIZE\fP\&. -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_play_buffer(xmp_context c, void *buffer, int size, int loop) -.INDENT 0.0 -.INDENT 3.5 -\fI[Added in libxmp 4.1]\fP Fill the buffer with PCM data up to the specified -size. This is a convenience function that calls \fI\%xmp_play_frame()\fP -internally to fill the user\-supplied buffer \-\- don\(aqt call both functions -in the same replay loop, choose one of them. If you don\(aqt need equally -sized data chunks, \fI\%xmp_play_frame()\fP will result in better performance. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B buffer -the buffer to fill with PCM data, or NULL to reset the -internal state. -.TP -.B size -buffer size in bytes. -.TP -.B loop -stop replay when the loop counter reaches the specified -value, or 0 to disable loop checking. -.UNINDENT -.TP -.B \fBReturns:\fP -0 if sucessful, \fB\-XMP_END\fP if module was stopped or the loop counter -was reached, or \fB\-XMP_ERROR_STATE\fP if the player is not in playing -state. -.UNINDENT -.UNINDENT -.UNINDENT -.SS void xmp_end_player(xmp_context c) -.INDENT 0.0 -.INDENT 3.5 -End module replay and releases player memory. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.SS Player control -.SS int xmp_next_position(xmp_context c) -.INDENT 0.0 -.INDENT 3.5 -Skip replay to the start of the next position. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.UNINDENT -.TP -.B \fBReturns:\fP -The new position index, or \fB\-XMP_ERROR_STATE\fP if the player is not -in playing state. -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_prev_position(xmp_context c) -.INDENT 0.0 -.INDENT 3.5 -Skip replay to the start of the previous position. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.UNINDENT -.TP -.B \fBReturns:\fP -The new position index, or \fB\-XMP_ERROR_STATE\fP if the player is not -in playing state. -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_set_position(xmp_context c, int pos) -.INDENT 0.0 -.INDENT 3.5 -Skip replay to the start of the given position. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B pos -the position index to set. -.UNINDENT -.TP -.B \fBReturns:\fP -The new position index, \fB\-XMP_ERROR_INVALID\fP of the new position is -invalid or \fB\-XMP_ERROR_STATE\fP if the player is not in playing state. -.UNINDENT -.UNINDENT -.UNINDENT -.SS void xmp_stop_module(xmp_context c) -.INDENT 0.0 -.INDENT 3.5 -Stop the currently playing module. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.SS void xmp_restart_module(xmp_context c) -.INDENT 0.0 -.INDENT 3.5 -Restart the currently playing module. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_seek_time(xmp_context c, int time) -.INDENT 0.0 -.INDENT 3.5 -Skip replay to the specified time. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B time -time to seek in milliseconds. -.UNINDENT -.TP -.B \fBReturns:\fP -The new position index, or \fB\-XMP_ERROR_STATE\fP if the player is not -in playing state. -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_channel_mute(xmp_context c, int channel, int status) -.INDENT 0.0 -.INDENT 3.5 -Mute or unmute the specified channel. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B channel -the channel to mute or unmute. -.TP -.B status -0 to mute channel, 1 to unmute or \-1 to query the -current channel status. -.UNINDENT -.TP -.B \fBReturns:\fP -The previous channel status, or \fB\-XMP_ERROR_STATE\fP if the player is not -in playing state. -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_channel_vol(xmp_context c, int channel, int vol) -.INDENT 0.0 -.INDENT 3.5 -Set or retrieve the volume of the specified channel. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B channel -the channel to set or get volume. -.TP -.B vol -a value from 0\-100 to set the channel volume, or \-1 to retrieve -the current volume. -.UNINDENT -.TP -.B \fBReturns:\fP -The previous channel volume, or \fB\-XMP_ERROR_STATE\fP if the player is not -in playing state. -.UNINDENT -.UNINDENT -.UNINDENT -.SS void xmp_inject_event(xmp_context c, int channel, struct xmp_event *event) -.INDENT 0.0 -.INDENT 3.5 -Dynamically insert a new event into a playing module. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B channel -the channel to insert the new event. -.TP -.B event -the event to insert. -\fBstruct xmp_event\fP is defined as: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -struct xmp_event { - unsigned char note; /* Note number (0 means no note) */ - unsigned char ins; /* Patch number */ - unsigned char vol; /* Volume (0 to basevol) */ - unsigned char fxt; /* Effect type */ - unsigned char fxp; /* Effect parameter */ - unsigned char f2t; /* Secondary effect type */ - unsigned char f2p; /* Secondary effect parameter */ - unsigned char _flag; /* Internal (reserved) flags */ -}; -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.SS Player parameter setting -.SS int xmp_set_instrument_path(xmp_context c, char *path) -.INDENT 0.0 -.INDENT 3.5 -Set the path to retrieve external instruments or samples. Used by some -formats (such as MED2) to read sample files from a different directory -in the filesystem. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B path -the path to retrieve instrument files. -.UNINDENT -.TP -.B \fBReturns:\fP -0 if the instrument path was correctly set, or \fB\-XMP_ERROR_SYSTEM\fP -in case of error (the system error code is set in \fBerrno\fP). -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_get_player(xmp_context c, int param) -.INDENT 0.0 -.INDENT 3.5 -Retrieve current value of the specified player parameter. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B param -player parameter to get. -Valid parameters are: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -XMP_PLAYER_AMP /* Amplification factor */ -XMP_PLAYER_MIX /* Stereo mixing */ -XMP_PLAYER_INTERP /* Interpolation type */ -XMP_PLAYER_DSP /* DSP effect flags */ -XMP_PLAYER_FLAGS /* Player flags */ -XMP_PLAYER_CFLAGS /* Player flags for current module*/ -XMP_PLAYER_SMPCTL /* Control sample loading */ -XMP_PLAYER_VOLUME /* Player master volume */ -XMP_PLAYER_STATE /* Current player state*/ -XMP_PLAYER_DEFPAN /* Default pan separation */ -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -See \fBxmp_set_player\fP for the list of valid values for each parameter. -Valid states are: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -XMP_STATE_UNLOADED /* Context created */ -XMP_STATE_LOADED /* Module loaded */ -XMP_STATE_PLAYING /* Module playing */ -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.TP -.B \fBReturns:\fP -The parameter value, or \fB\-XMP_ERROR_STATE\fP if the parameter is not -\fBXMP_PLAYER_STATE\fP and the player is not in playing state. -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_set_player(xmp_context c, int param, int val) -.INDENT 0.0 -.INDENT 3.5 -Set player parameter with the specified value. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B param -player parameter to set. -Valid parameters are: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -XMP_PLAYER_AMP /* Amplification factor */ -XMP_PLAYER_MIX /* Stereo mixing */ -XMP_PLAYER_INTERP /* Interpolation type */ -XMP_PLAYER_DSP /* DSP effect flags */ -XMP_PLAYER_FLAGS /* Player flags */ -XMP_PLAYER_CFLAGS /* Player flags for current module*/ -XMP_PLAYER_SMPCTL /* Control sample loading */ -XMP_PLAYER_VOLUME /* Player master volume */ -XMP_PLAYER_DEFPAN /* Default pan separation */ -.ft P -.fi -.UNINDENT -.UNINDENT -.TP -.B val -the value to set. Valid values are: -.INDENT 7.0 -.IP \(bu 2 -Amplification factor: ranges from 0 to 3. Default value is 1. -.IP \(bu 2 -Stereo mixing: percentual left/right channel separation. Default is 70. -.IP \(bu 2 -Interpolation type: can be one of the following values: -.INDENT 2.0 -.INDENT 3.5 -.sp -.nf -.ft C -XMP_INTERP_NEAREST /* Nearest neighbor */ -XMP_INTERP_LINEAR /* Linear (default) */ -XMP_INTERP_SPLINE /* Cubic spline */ -.ft P -.fi -.UNINDENT -.UNINDENT -.IP \(bu 2 -DSP effects flags: enable or disable DSP effects. Valid effects are: -.INDENT 2.0 -.INDENT 3.5 -.sp -.nf -.ft C -XMP_DSP_LOWPASS /* Lowpass filter effect */ -XMP_DSP_ALL /* All effects */ -.ft P -.fi -.UNINDENT -.UNINDENT -.IP \(bu 2 -Player flags: tweakable player parameters. Valid flags are: -.INDENT 2.0 -.INDENT 3.5 -.sp -.nf -.ft C -XMP_FLAGS_VBLANK /* Use vblank timing */ -XMP_FLAGS_FX9BUG /* Emulate Protracker 2.x FX9 bug */ -XMP_FLAGS_FIXLOOP /* Make sample loop value / 2 */ -.ft P -.fi -.UNINDENT -.UNINDENT -.IP \(bu 2 -\fI[Added in libxmp 4.1]\fP Player flags for current module: same flags -as above but after applying module\-specific quirks (if any). -.IP \(bu 2 -\fI[Added in libxmp 4.1]\fP Control sample load. Valid values are: -.INDENT 2.0 -.INDENT 3.5 -.sp -.nf -.ft C -XMP_SMPCTL_SKIP /* Don\(aqt load samples */ -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -Disabling sample loading when loading a module allows allows -computation of module duration without decompressing and -loading large sample data, and is useful when duration information -is needed for a module that won\(aqt be played immediately. -.IP \(bu 2 -\fI[Added in libxmp 4.2]\fP Set the player master volume, in a 0\-100 scale. -.UNINDENT -.UNINDENT -.TP -.B \fBReturns:\fP -0 if parameter was correctly set, \fB\-XMP_ERROR_INVALID\fP if -parameter or values are out of the valid ranges, or \fB\-XMP_ERROR_STATE\fP -if the player is not in playing state. -.UNINDENT -.UNINDENT -.UNINDENT -.SH EXTERNAL SAMPLE MIXER API -.sp -Libxmp 4.2 includes a mini\-API that can be used to add sound effects to -games and similar applications, provided that you have a low latency sound -system. It allows module instruments or external sample files in WAV format -to be played in response to arbitrary events. -.SS Example -.sp -This example using SDL loads a module and a sound sample, plays the module -as background music, and plays the sample when a key is pressed: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -#include -#include - -static void fill_audio(void *udata, unsigned char *stream, int len) -{ - xmp_play_buffer(udata, stream, len, 0); -} - -int sound_init(xmp_context ctx, int sampling_rate, int channels) -{ - SDL_AudioSpec a; - - a.freq = sampling_rate; - a.format = (AUDIO_S16); - a.channels = channels; - a.samples = 2048; - a.callback = fill_audio; - a.userdata = ctx; - - if (SDL_OpenAudio(&a, NULL) < 0) { - fprintf(stderr, "%s\en", SDL_GetError()); - return \-1; - } -} - -int video_init() -{ - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - fprintf(stderr, "%s\en", SDL_GetError()); - return \-1; - } - if (SDL_SetVideoMode(640, 480, 8, 0) == NULL) { - fprintf(stderr, "%s\en", SDL_GetError()); - return \-1; - } - atexit(SDL_Quit); -} - -int main(int argc, char **argv) -{ - SDL_Event event; - xmp_context ctx; - - if ((ctx = xmp_create_context()) == NULL) - return 1; - - video_init(); - sound_init(ctx, 44100, 2); - - xmp_start_smix(ctx, 1, 1); - xmp_smix_load_sample(ctx, 0, "blip.wav"); - - xmp_load_module(ctx, "music.mod"); - xmp_start_player(ctx, 44100, 0); - xmp_set_player(ctx, XMP_PLAYER_VOLUME, 40); - - SDL_PauseAudio(0); - - while (1) { - if (SDL_WaitEvent(&event)) { - if (event.type == SDL_KEYDOWN) { - if (event.key.keysym.sym == SDLK_ESCAPE) - break; - xmp_smix_play_sample(ctx, 0, 60, 64, 0); - } - } - } - - SDL_PauseAudio(1); - - xmp_end_player(ctx); - xmp_release_module(ctx); - xmp_free_context(ctx); - xmp_end_smix(ctx); - - SDL_CloseAudio(); - return 0; -} -.ft P -.fi -.UNINDENT -.UNINDENT -.SS SMIX API reference -.SS int xmp_start_smix(xmp_context c, int nch, int nsmp) -.INDENT 0.0 -.INDENT 3.5 -Initialize the external sample mixer subsystem with the given number of -reserved channels and samples. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B nch -number of reserved sound mixer channels (1 to 64). -.TP -.B nsmp -number of external samples. -.UNINDENT -.TP -.B \fBReturns:\fP -0 if the external sample mixer system was correctly initialized, -\fB\-XMP_ERROR_INVALID\fP in case of invalid parameters, \fB\-XMP_ERROR_STATE\fP -if the player is already in playing state, or \fB\-XMP_ERROR_SYSTEM\fP in case -of system error (the system error code is set in \fBerrno\fP). -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_smix_play_instrument(xmp_context c, int ins, int note, int vol, int chn) -.INDENT 0.0 -.INDENT 3.5 -Play a note using an instrument from the currently loaded module in -one of the reserved sound mixer channels. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B ins -the instrument to play. -.TP -.B note -the note number to play (60 = middle C). -.TP -.B vol -the volume to use (0 to the maximum volume value used by the -current module. -.TP -.B chn -the reserved channe to use to play the instrument. -.UNINDENT -.TP -.B \fBReturns:\fP -0 if the instrument was correctly played, \fB\-XMP_ERROR_INVALID\fP in -case of invalid parameters, or \fB\-XMP_ERROR_STATE\fP if the player is not -in playing state. -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_smix_play_sample(xmp_context c, int ins, int vol, int chn) -.INDENT 0.0 -.INDENT 3.5 -Play an external sample file in one of the reserved sound channels. -The sample must have been previously loaded using -\fI\%xmp_smix_load_sample()\fP\&. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B ins -the sample to play. -.TP -.B vol -the volume to use (0 to the maximum volume value used by the -current module. -.TP -.B chn -the reserved channel to use to play the sample. -.UNINDENT -.TP -.B \fBReturns:\fP -0 if the sample was correctly played, \fB\-XMP_ERROR_INVALID\fP in -case of invalid parameters, or \fB\-XMP_ERROR_STATE\fP if the player is not -in playing state. -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_smix_channel_pan(xmp_context c, int chn, int pan) -.INDENT 0.0 -.INDENT 3.5 -Set the reserved channel pan value. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B chn -the reserved channel number. -.TP -.B pan -the pan value to set (0 to 255). -.UNINDENT -.TP -.B \fBReturns:\fP -0 if the pan value was set, or \fB\-XMP_ERROR_INVALID\fP if parameters -are invalid. -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_smix_load_sample(xmp_context c, int num, char *path) -.INDENT 0.0 -.INDENT 3.5 -Load a sound sample from a file. Samples should be in mono WAV (RIFF) -format. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B num -the slot number of the external sample to load. -.TP -.B path -pathname of the file to load. -.UNINDENT -.TP -.B \fBReturns:\fP -0 if the sample was correctly loaded, \fB\-XMP_ERROR_INVALID\fP if the -sample slot number is invalid (not reserved using \fI\%xmp_start_smix()\fP), -\fB\-XMP_ERROR_FORMAT\fP if the file format is unsupported, or -\fB\-XMP_ERROR_SYSTEM\fP in case of system error (the system error code is -set in \fBerrno\fP). -.UNINDENT -.UNINDENT -.UNINDENT -.SS int xmp_smix_release_sample(xmp_context c, int num) -.INDENT 0.0 -.INDENT 3.5 -Release memory allocated by an external sample in the specified player -context. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.TP -.B num -the sample slot number to release. -.UNINDENT -.TP -.B \fBReturns:\fP -0 if memory was correctly released, or \fB\-XMP_ERROR_INVALID\fP if the -sample slot number is invalid. -.UNINDENT -.UNINDENT -.UNINDENT -.SS void xmp_end_smix(xmp_context c) -.INDENT 0.0 -.INDENT 3.5 -Deinitialize and resease memory used by the external sample mixer subsystem. -.INDENT 0.0 -.TP -.B \fBParameters:\fP -.INDENT 7.0 -.TP -.B c -the player context handle. -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.SH AUTHOR -Claudio Matsuoka and Hipolito Carraro Jr. -.\" Generated by docutils manpage writer. -. diff --git a/docs/libxmp.html b/docs/libxmp.html deleted file mode 100644 index b23a182..0000000 --- a/docs/libxmp.html +++ /dev/null @@ -1,1719 +0,0 @@ - - - - - - -Libxmp 4.3 API documentation - - - -
-

Libxmp 4.3 API documentation

- -
-

Contents

- -
-
-

Introduction

-

Libxmp is a module player library supporting many mainstream and obscure -module formats including Protracker MOD, Scream Tracker III S3M and -Impulse Tracker IT. Libxmp loads the module and renders the sound as -linear PCM samples in a buffer at rate and format specified by the user, -one frame at a time (standard modules usually play at 50 frames per second).

-

Possible applications for libxmp include stand-alone module players, module -player plugins for other players, module information extractors, background -music replayers for games and other applications, module-to-mp3 renderers, etc.

-
-

Concepts

-
    -
  • Player context: -Most libxmp functions require a handle that identifies the module player -context. Each context is independent and multiple contexts can be defined -simultaneously.
  • -
  • Sequence: -Each group of positions in the order list that loops over itself, also -known as "subsong". Most modules have only one sequence, but some modules, -especially modules used in games can have multiple sequences. "Hidden -patterns" outside the main song are also listed as extra sequences, certain -module authors such as Skaven commonly place extra patterns at the end of -the module.
  • -
  • State: [Added in libxmp 4.2] -The player can be in one of three possible states: unloaded, loaded, -or playing. The player is in unloaded state after context creation, -changing to other states when a module is loaded or played.
  • -
  • External sample mixer: [Added in libxmp 4.2] -Special sound channels can be reserved using xmp_start_smix() -to play module instruments or external samples. This is useful when -libxmp is used to provide background music to games or other applications -where sound effects can be played in response to events or user actions
  • -
-
-
-

A simple example

-

This example loads a module, plays it at 44.1kHz and writes it to a raw -sound file:

-
-#include <stdio.h>
-#include <stdlib.h>
-#include <xmp.h>
-
-int main(int argc, char **argv)
-{
-    xmp_context c;
-    struct xmp_frame_info mi;
-    FILE *f;
-
-    /* The output raw file */
-    f = fopen("out.raw", "wb");
-    if (f == NULL) {
-        fprintf(stderr, "can't open output file\n");
-        exit(EXIT_FAILURE);
-    }
-
-    /* Create the player context */
-    c = xmp_create_context();
-
-    /* Load our module */
-    if (xmp_load_module(c, argv[1]) != 0) {
-        fprintf(stderr, "can't load module\n");
-        exit(EXIT_FAILURE);
-    }
-
-    /* Play the module */
-    xmp_start_player(c, 44100, 0);
-    while (xmp_play_frame(c) == 0) {
-        xmp_get_frame_info(c, &mi);
-
-        if (mi.loop_count > 0)    /* exit before looping */
-            break;
-
-        fwrite(mi.buffer, mi.buffer_size, 1, f);  /* write audio data */
-    }
-    xmp_end_player(c);
-    xmp_release_module(c);        /* unload module */
-    xmp_free_context(c);          /* destroy the player context */
-
-    fclose(f);
-
-    exit(EXIT_SUCCESS);
-}
-
-

A player context can load and play a single module at a time. Multiple -contexts can be defined if needed.

-

Use xmp_test_module() to check if the file is a valid module and -retrieve the module name and type. Use xmp_load_module() to load -the module to memory. These two calls return 0 on success or <0 in case of -error. Error codes are:

-
--XMP_ERROR_INTERNAL   /* Internal error */
--XMP_ERROR_FORMAT     /* Unsupported module format */
--XMP_ERROR_LOAD       /* Error loading file */
--XMP_ERROR_DEPACK     /* Error depacking file */
--XMP_ERROR_SYSTEM     /* System error */
--XMP_ERROR_STATE      /* Incorrect player state */
-
-

If a system error occurs, the specific error is set in errno.

-

Parameters to xmp_start_player() are the sampling -rate (up to 48kHz) and a bitmapped integer holding one or more of the -following mixer flags:

-
-XMP_MIX_8BIT          /* Mix to 8-bit instead of 16 */
-XMP_MIX_UNSIGNED      /* Mix to unsigned samples */
-XMP_MIX_MONO          /* Mix to mono instead of stereo */
-XMP_MIX_NEAREST       /* Mix using nearest neighbor interpolation */
-XMP_MIX_NOFILTER      /* Disable lowpass filter */
-
-

After xmp_start_player() is called, each call to xmp_play_frame() -will render an audio frame. Call xmp_get_frame_info() to retrieve the -buffer address and size. xmp_play_frame() returns 0 on success or -1 -if replay should stop.

-

Use xmp_end_player(), xmp_release_module() and -xmp_free_context() to release memory and end replay.

-
-
-

SDL example

-

To use libxmp with SDL, just provide a callback function that renders module -data. The module will play when SDL_PauseAudio(0) is called:

-
-#include <SDL/SDL.h>
-#include <xmp.h>
-
-static void fill_audio(void *udata, unsigned char *stream, int len)
-{
-    xmp_play_buffer(udata, stream, len, 0);
-}
-
-int sound_init(xmp_context ctx, int sampling_rate, int channels)
-{
-    SDL_AudioSpec a;
-
-    a.freq = sampling_rate;
-    a.format = (AUDIO_S16);
-    a.channels = channels;
-    a.samples = 2048;
-    a.callback = fill_audio;
-    a.userdata = ctx;
-
-    if (SDL_OpenAudio(&a, NULL) < 0) {
-            fprintf(stderr, "%s\n", SDL_GetError());
-            return -1;
-    }
-}
-
-int main(int argc, char **argv)
-{
-    xmp_context ctx;
-
-    if ((ctx = xmp_create_context()) == NULL)
-            return 1;
-
-    sound_init(ctx, 44100, 2);
-    xmp_load_module(ctx, argv[1]);
-    xmp_start_player(ctx, 44100, 0);
-
-    SDL_PauseAudio(0);
-
-    sleep(10);              // Do something important here
-
-    SDL_PauseAudio(1);
-
-    xmp_end_player(ctx);
-    xmp_release_module(ctx);
-    xmp_free_context(ctx);
-
-    SDL_CloseAudio();
-    return 0;
-}
-
-

SDL callbacks run in a separate thread, so don't forget to protect sections -that manipulate module data with SDL_LockAudio() and SDL_UnlockAudio().

-
-
-
-

API reference

-
-

Version and player information

-
-

const char *xmp_version

-
-A string containing the library version, such as "4.0.0".
-
-
-

const unsigned int xmp_vercode

-
-The library version encoded in a integer value. Bits 23-16 contain the -major version number, bits 15-8 contain the minor version number, and -bits 7-0 contain the release number.
-
-
-

char **xmp_get_format_list()

-
-

Query the list of supported module formats.

- --- - - - -
Returns:a NULL-terminated array of strings containing the names -of all supported module formats.
-
-
-
-
-

Context creation

-
-

xmp_context xmp_create_context()

-
-

Create a new player context and return an opaque handle to be used in -subsequent accesses to this context.

-
-
Returns:
-
the player context handle.
-
-
-
-
-

void xmp_free_context(xmp_context c)

-
-

Destroy a player context previously created using xmp_create_context().

-
-
Parameters:
-
--- - - - -
c:the player context handle.
-
-
-
-
-
-
-

Module loading

-
-

int xmp_test_module(char *path, struct xmp_test_info *test_info)

-
-

Test if a file is a valid module. Testing a file does not affect the -current player context or any currently loaded module.

-
-
Parameters:
-
--- - - - - - -
path:

pathname of the module to test.

-
test_info:

NULL, or a pointer to a structure used to retrieve the -module title and format if the file is a valid module. -struct xmp_test_info is defined as:

-
-struct xmp_test_info {
-    char name[XMP_NAME_SIZE];      /* Module title */
-    char type[XMP_NAME_SIZE];      /* Module format */
-};
-
-
-
-
Returns:
-
0 if the file is a valid module, or a negative error code -in case of error. Error codes can be -XMP_ERROR_FORMAT in case of an -unrecognized file format, -XMP_ERROR_DEPACK if the file is compressed -and uncompression failed, or -XMP_ERROR_SYSTEM in case of system error -(the system error code is set in errno).
-
-
-
-
-

int xmp_load_module(xmp_context c, char *path)

-
-

Load a module into the specified player context.

-
-
Parameters:
-
--- - - - - - -
c:the player context handle.
path:pathname of the module to load.
-
-
Returns:
-
0 if sucessful, or a negative error code in case of error. -Error codes can be -XMP_ERROR_FORMAT in case of an unrecognized file -format, -XMP_ERROR_DEPACK if the file is compressed and uncompression -failed, -XMP_ERROR_LOAD if the file format was recognized but the -file loading failed, or -XMP_ERROR_SYSTEM in case of system error -(the system error code is set in errno).
-
-
-
-
-

int xmp_load_module_from_memory(xmp_context c, void *mem, long size)

-
-

[Added in libxmp 4.2] Load a module from memory into the specified -player context.

-
-
Parameters:
-
--- - - - - - - - -
c:the player context handle.
mem:a pointer to the module file image in memory. Multi-file modules -or compressed modules can't be loaded from memory.
size:the size of the module, or 0 if the size is unknown or not -specified. If size is set to 0 certain module formats won't be -recognized, the MD5 digest will not be set, and module-specific -quirks won't be applied.
-
-
Returns:
-
0 if sucessful, or a negative error code in case of error. -Error codes can be -XMP_ERROR_FORMAT in case of an unrecognized file -format, -XMP_ERROR_LOAD if the file format was recognized but the -file loading failed, or -XMP_ERROR_SYSTEM in case of system error -(the system error code is set in errno).
-
-
-
-
-

int xmp_load_module_from_file(xmp_context c, FILE *f, long size)

-
-

[Added in libxmp 4.3] Load a module from a stream into the specified -player context.

-
-
Parameters:
-
--- - - - - - - - -
c:the player context handle.
f:the file stream. On return, the stream position is undefined.
size:the size of the module, or 0 if the size is unknown or not -specified. If size is set to 0 certain module formats won't be -recognized, the MD5 digest will not be set, and module-specific -quirks won't be applied.
-
-
Returns:
-
0 if sucessful, or a negative error code in case of error. -Error codes can be -XMP_ERROR_FORMAT in case of an unrecognized file -format, -XMP_ERROR_LOAD if the file format was recognized but the -file loading failed, or -XMP_ERROR_SYSTEM in case of system error -(the system error code is set in errno).
-
-
-
-
-

void xmp_release_module(xmp_context c)

-
-

Release memory allocated by a module from the specified player context.

-
-
Parameters:
-
--- - - - -
c:the player context handle.
-
-
-
-
-
-

void xmp_scan_module(xmp_context c)

-
-

Scan the loaded module for sequences and timing. Scanning is automatically -performed by xmp_load_module() and this function should be called only -if xmp_set_player() is used to change player timing (with parameter -XMP_PLAYER_VBLANK) in libxmp 4.0.2 or older.

-
-
Parameters:
-
--- - - - -
c:the player context handle.
-
-
-
-
-
-

void xmp_get_module_info(xmp_context c, struct xmp_module_info *info)

-
-

Retrieve current module data.

-
-
Parameters:
-
--- - - - - - -
c:

the player context handle.

-
info:

pointer to structure containing the module data. -struct xmp_module_info is defined as follows:

-
-struct xmp_module_info {
-    unsigned char md5[16];          /* MD5 message digest */
-    int vol_base;                   /* Volume scale */
-    struct xmp_module *mod;         /* Pointer to module data */
-    char *comment;                  /* Comment text, if any */
-    int num_sequences;              /* Number of valid sequences */
-    struct xmp_sequence *seq_data;  /* Pointer to sequence data */
-};
-
-

Detailed module data is exposed in the mod field:

-
-struct xmp_module {
-    char name[XMP_NAME_SIZE];       /* Module title */
-    char type[XMP_NAME_SIZE];       /* Module format */
-    int pat;                        /* Number of patterns */
-    int trk;                        /* Number of tracks */
-    int chn;                        /* Tracks per pattern */
-    int ins;                        /* Number of instruments */
-    int smp;                        /* Number of samples */
-    int spd;                        /* Initial speed */
-    int bpm;                        /* Initial BPM */
-    int len;                        /* Module length in patterns */
-    int rst;                        /* Restart position */
-    int gvl;                        /* Global volume */
-
-    struct xmp_pattern **xxp;       /* Patterns */
-    struct xmp_track **xxt;         /* Tracks */
-    struct xmp_instrument *xxi;     /* Instruments */
-    struct xmp_sample *xxs;         /* Samples */
-    struct xmp_channel xxc[64];     /* Channel info */
-    unsigned char xxo[XMP_MAX_MOD_LENGTH];  /* Orders */
-};
-
-

See the header file for more information about pattern and instrument -data.

-
-
-
-
-
-
-
-

Module playing

-
-

int xmp_start_player(xmp_context c, int rate, int format)

-
-

Start playing the currently loaded module.

-
-
Parameters:
-
--- - - - - - - - -
c:

the player context handle.

-
rate:

the sampling rate to use, in Hz (typically 44100). Valid values -range from 8kHz to 48kHz.

-
flags:

bitmapped configurable player flags, one or more of the -following:

-
-XMP_FORMAT_8BIT         /* Mix to 8-bit instead of 16 */
-XMP_FORMAT_UNSIGNED     /* Mix to unsigned samples */
-XMP_FORMAT_MONO         /* Mix to mono instead of stereo */
-
-
-
-
Returns:
-
0 if sucessful, or a negative error code in case of error. -Error codes can be -XMP_ERROR_INTERNAL in case of a internal player -error, -XMP_ERROR_INVALID if the sampling rate is invalid, or --XMP_ERROR_SYSTEM in case of system error (the system error -code is set in errno).
-
-
-
-
-

int xmp_play_frame(xmp_context c)

-
-

Play one frame of the module. Modules usually play at 50 frames per second. -Use xmp_get_frame_info() to retrieve the buffer containing audio data.

-
-
Parameters:
-
--- - - - -
c:the player context handle.
-
-
Returns:
-
0 if sucessful, -XMP_END if the module ended or was stopped, or --XMP_ERROR_STATE if the player is not in playing state.
-
-
-
-
-

void xmp_get_frame_info(xmp_context c, struct xmp_frame_info *info)

-
-

Retrieve current frame data.

-
-
Parameters:
-
--- - - - - - -
c:

the player context handle.

-
info:

pointer to structure containing current frame data. -struct xmp_frame_info is defined as follows:

-
-struct xmp_frame_info {           /* Current frame information */
-    int pos;            /* Current position */
-    int pattern;        /* Current pattern */
-    int row;            /* Current row in pattern */
-    int num_rows;       /* Number of rows in current pattern */
-    int frame;          /* Current frame */
-    int speed;          /* Current replay speed */
-    int bpm;            /* Current bpm */
-    int time;           /* Current module time in ms */
-    int total_time;     /* Estimated replay time in ms*/
-    int frame_time;     /* Frame replay time in us */
-    void *buffer;       /* Pointer to sound buffer */
-    int buffer_size;    /* Used buffer size */
-    int total_size;     /* Total buffer size */
-    int volume;         /* Current master volume */
-    int loop_count;     /* Loop counter */
-    int virt_channels;  /* Number of virtual channels */
-    int virt_used;      /* Used virtual channels */
-    int sequence;       /* Current sequence */
-
-    struct xmp_channel_info {     /* Current channel information */
-        unsigned int period;      /* Sample period */
-        unsigned int position;    /* Sample position */
-        short pitchbend;          /* Linear bend from base note*/
-        unsigned char note;       /* Current base note number */
-        unsigned char instrument; /* Current instrument number */
-        unsigned char sample;     /* Current sample number */
-        unsigned char volume;     /* Current volume */
-        unsigned char pan;        /* Current stereo pan */
-        unsigned char reserved;   /* Reserved */
-        struct xmp_event event;   /* Current track event */
-    } channel_info[XMP_MAX_CHANNELS];
-};
-
-

This function should be used to retrieve sound buffer data after -xmp_play_frame() is called. Fields buffer and buffer_size -contain the pointer to the sound buffer PCM data and its size. The -buffer size will be no larger than XMP_MAX_FRAMESIZE.

-
-
-
-
-
-
-

int xmp_play_buffer(xmp_context c, void *buffer, int size, int loop)

-
-

[Added in libxmp 4.1] Fill the buffer with PCM data up to the specified -size. This is a convenience function that calls xmp_play_frame() -internally to fill the user-supplied buffer -- don't call both functions -in the same replay loop, choose one of them. If you don't need equally -sized data chunks, xmp_play_frame() will result in better performance.

-
-
Parameters:
-
--- - - - - - - - - - -
c:the player context handle.
buffer:the buffer to fill with PCM data, or NULL to reset the -internal state.
size:buffer size in bytes.
loop:stop replay when the loop counter reaches the specified -value, or 0 to disable loop checking.
-
-
Returns:
-
0 if sucessful, -XMP_END if module was stopped or the loop counter -was reached, or -XMP_ERROR_STATE if the player is not in playing -state.
-
-
-
-
-

void xmp_end_player(xmp_context c)

-
-

End module replay and releases player memory.

-
-
Parameters:
-
--- - - - -
c:the player context handle.
-
-
-
-
-
-
-

Player control

-
-

int xmp_next_position(xmp_context c)

-
-

Skip replay to the start of the next position.

-
-
Parameters:
-
--- - - - -
c:the player context handle.
-
-
Returns:
-
The new position index, or -XMP_ERROR_STATE if the player is not -in playing state.
-
-
-
-
-

int xmp_prev_position(xmp_context c)

-
-

Skip replay to the start of the previous position.

-
-
Parameters:
-
--- - - - -
c:the player context handle.
-
-
Returns:
-
The new position index, or -XMP_ERROR_STATE if the player is not -in playing state.
-
-
-
-
-

int xmp_set_position(xmp_context c, int pos)

-
-

Skip replay to the start of the given position.

-
-
Parameters:
-
--- - - - - - -
c:the player context handle.
pos:the position index to set.
-
-
Returns:
-
The new position index, -XMP_ERROR_INVALID of the new position is -invalid or -XMP_ERROR_STATE if the player is not in playing state.
-
-
-
-
-

void xmp_stop_module(xmp_context c)

-
-

Stop the currently playing module.

-
-
Parameters:
-
--- - - - -
c:the player context handle.
-
-
-
-
-
-

void xmp_restart_module(xmp_context c)

-
-

Restart the currently playing module.

-
-
Parameters:
-
--- - - - -
c:the player context handle.
-
-
-
-
-
-

int xmp_seek_time(xmp_context c, int time)

-
-

Skip replay to the specified time.

-
-
Parameters:
-
--- - - - - - -
c:the player context handle.
time:time to seek in milliseconds.
-
-
Returns:
-
The new position index, or -XMP_ERROR_STATE if the player is not -in playing state.
-
-
-
-
-

int xmp_channel_mute(xmp_context c, int channel, int status)

-
-

Mute or unmute the specified channel.

-
-
Parameters:
-
--- - - - - - - - -
c:the player context handle.
channel:the channel to mute or unmute.
status:0 to mute channel, 1 to unmute or -1 to query the -current channel status.
-
-
Returns:
-
The previous channel status, or -XMP_ERROR_STATE if the player is not -in playing state.
-
-
-
-
-

int xmp_channel_vol(xmp_context c, int channel, int vol)

-
-

Set or retrieve the volume of the specified channel.

-
-
Parameters:
-
--- - - - - - - - -
c:the player context handle.
channel:the channel to set or get volume.
vol:a value from 0-100 to set the channel volume, or -1 to retrieve -the current volume.
-
-
Returns:
-
The previous channel volume, or -XMP_ERROR_STATE if the player is not -in playing state.
-
-
-
-
-

void xmp_inject_event(xmp_context c, int channel, struct xmp_event *event)

-
-

Dynamically insert a new event into a playing module.

-
-
Parameters:
-
--- - - - - - - - -
c:

the player context handle.

-
channel:

the channel to insert the new event.

-
event:

the event to insert. -struct xmp_event is defined as:

-
-struct xmp_event {
-    unsigned char note;   /* Note number (0 means no note) */
-    unsigned char ins;    /* Patch number */
-    unsigned char vol;    /* Volume (0 to basevol) */
-    unsigned char fxt;    /* Effect type */
-    unsigned char fxp;    /* Effect parameter */
-    unsigned char f2t;    /* Secondary effect type */
-    unsigned char f2p;    /* Secondary effect parameter */
-    unsigned char _flag;  /* Internal (reserved) flags */
-};
-
-
-
-
-
-
-
-
-

Player parameter setting

-
-

int xmp_set_instrument_path(xmp_context c, char *path)

-
-

Set the path to retrieve external instruments or samples. Used by some -formats (such as MED2) to read sample files from a different directory -in the filesystem.

-
-
Parameters:
-
--- - - - - - -
c:the player context handle.
path:the path to retrieve instrument files.
-
-
Returns:
-
0 if the instrument path was correctly set, or -XMP_ERROR_SYSTEM -in case of error (the system error code is set in errno).
-
-
-
-
-

int xmp_get_player(xmp_context c, int param)

-
-

Retrieve current value of the specified player parameter.

-
-
Parameters:
-
--- - - - - - -
c:

the player context handle.

-
param:

player parameter to get. -Valid parameters are:

-
-XMP_PLAYER_AMP      /* Amplification factor */
-XMP_PLAYER_MIX      /* Stereo mixing */
-XMP_PLAYER_INTERP   /* Interpolation type */
-XMP_PLAYER_DSP      /* DSP effect flags */
-XMP_PLAYER_FLAGS    /* Player flags */
-XMP_PLAYER_CFLAGS   /* Player flags for current module*/
-XMP_PLAYER_SMPCTL   /* Control sample loading */
-XMP_PLAYER_VOLUME   /* Player master volume */
-XMP_PLAYER_STATE    /* Current player state*/
-XMP_PLAYER_DEFPAN   /* Default pan separation */
-
-

See xmp_set_player for the list of valid values for each parameter. -Valid states are:

-
-XMP_STATE_UNLOADED  /* Context created */
-XMP_STATE_LOADED    /* Module loaded */
-XMP_STATE_PLAYING   /* Module playing */
-
-
-
-
Returns:
-
The parameter value, or -XMP_ERROR_STATE if the parameter is not -XMP_PLAYER_STATE and the player is not in playing state.
-
-
-
-
-

int xmp_set_player(xmp_context c, int param, int val)

-
-

Set player parameter with the specified value.

-
-
Parameters:
-
--- - - - - - -
param:

player parameter to set. -Valid parameters are:

-
-XMP_PLAYER_AMP      /* Amplification factor */
-XMP_PLAYER_MIX      /* Stereo mixing */
-XMP_PLAYER_INTERP   /* Interpolation type */
-XMP_PLAYER_DSP      /* DSP effect flags */
-XMP_PLAYER_FLAGS    /* Player flags */
-XMP_PLAYER_CFLAGS   /* Player flags for current module*/
-XMP_PLAYER_SMPCTL   /* Control sample loading */
-XMP_PLAYER_VOLUME   /* Player master volume */
-XMP_PLAYER_DEFPAN   /* Default pan separation */
-
-
val:

the value to set. Valid values are:

-
    -
  • Amplification factor: ranges from 0 to 3. Default value is 1.

    -
  • -
  • Stereo mixing: percentual left/right channel separation. Default is 70.

    -
  • -
  • Interpolation type: can be one of the following values:

    -
    -XMP_INTERP_NEAREST  /* Nearest neighbor */
    -XMP_INTERP_LINEAR   /* Linear (default) */
    -XMP_INTERP_SPLINE   /* Cubic spline */
    -
    -
  • -
  • DSP effects flags: enable or disable DSP effects. Valid effects are:

    -
    -XMP_DSP_LOWPASS     /* Lowpass filter effect */
    -XMP_DSP_ALL         /* All effects */
    -
    -
  • -
  • Player flags: tweakable player parameters. Valid flags are:

    -
    -XMP_FLAGS_VBLANK    /* Use vblank timing */
    -XMP_FLAGS_FX9BUG    /* Emulate Protracker 2.x FX9 bug */
    -XMP_FLAGS_FIXLOOP   /* Make sample loop value / 2 */
    -
    -
  • -
  • [Added in libxmp 4.1] Player flags for current module: same flags -as above but after applying module-specific quirks (if any).

    -
  • -
  • [Added in libxmp 4.1] Control sample load. Valid values are:

    -
    -XMP_SMPCTL_SKIP     /* Don't load samples */
    -
    -

    Disabling sample loading when loading a module allows allows -computation of module duration without decompressing and -loading large sample data, and is useful when duration information -is needed for a module that won't be played immediately.

    -
  • -
  • [Added in libxmp 4.2] Set the player master volume, in a 0-100 scale.

    -
  • -
-
-
-
Returns:
-
0 if parameter was correctly set, -XMP_ERROR_INVALID if -parameter or values are out of the valid ranges, or -XMP_ERROR_STATE -if the player is not in playing state.
-
-
-
-
-
-
-

External sample mixer API

-

Libxmp 4.2 includes a mini-API that can be used to add sound effects to -games and similar applications, provided that you have a low latency sound -system. It allows module instruments or external sample files in WAV format -to be played in response to arbitrary events.

-
-

Example

-

This example using SDL loads a module and a sound sample, plays the module -as background music, and plays the sample when a key is pressed:

-
-#include <SDL/SDL.h>
-#include <xmp.h>
-
-static void fill_audio(void *udata, unsigned char *stream, int len)
-{
-    xmp_play_buffer(udata, stream, len, 0);
-}
-
-int sound_init(xmp_context ctx, int sampling_rate, int channels)
-{
-    SDL_AudioSpec a;
-
-    a.freq = sampling_rate;
-    a.format = (AUDIO_S16);
-    a.channels = channels;
-    a.samples = 2048;
-    a.callback = fill_audio;
-    a.userdata = ctx;
-
-    if (SDL_OpenAudio(&a, NULL) < 0) {
-            fprintf(stderr, "%s\n", SDL_GetError());
-            return -1;
-    }
-}
-
-int video_init()
-{
-    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
-        fprintf(stderr, "%s\n", SDL_GetError());
-        return -1;
-    }
-    if (SDL_SetVideoMode(640, 480, 8, 0) == NULL) {
-        fprintf(stderr, "%s\n", SDL_GetError());
-        return -1;
-    }
-    atexit(SDL_Quit);
-}
-
-int main(int argc, char **argv)
-{
-    SDL_Event event;
-    xmp_context ctx;
-
-    if ((ctx = xmp_create_context()) == NULL)
-            return 1;
-
-    video_init();
-    sound_init(ctx, 44100, 2);
-
-    xmp_start_smix(ctx, 1, 1);
-    xmp_smix_load_sample(ctx, 0, "blip.wav");
-
-    xmp_load_module(ctx, "music.mod");
-    xmp_start_player(ctx, 44100, 0);
-    xmp_set_player(ctx, XMP_PLAYER_VOLUME, 40);
-
-    SDL_PauseAudio(0);
-
-    while (1) {
-        if (SDL_WaitEvent(&event)) {
-            if (event.type == SDL_KEYDOWN) {
-                if (event.key.keysym.sym == SDLK_ESCAPE)
-                    break;
-                xmp_smix_play_sample(ctx, 0, 60, 64, 0);
-            }
-        }
-    }
-
-    SDL_PauseAudio(1);
-
-    xmp_end_player(ctx);
-    xmp_release_module(ctx);
-    xmp_free_context(ctx);
-    xmp_end_smix(ctx);
-
-    SDL_CloseAudio();
-    return 0;
-}
-
-
-
-

SMIX API reference

-
-

int xmp_start_smix(xmp_context c, int nch, int nsmp)

-
-

Initialize the external sample mixer subsystem with the given number of -reserved channels and samples.

-
-
Parameters:
-
--- - - - - - - - -
c:the player context handle.
nch:number of reserved sound mixer channels (1 to 64).
nsmp:number of external samples.
-
-
Returns:
-
0 if the external sample mixer system was correctly initialized, --XMP_ERROR_INVALID in case of invalid parameters, -XMP_ERROR_STATE -if the player is already in playing state, or -XMP_ERROR_SYSTEM in case -of system error (the system error code is set in errno).
-
-
-
-
-

int xmp_smix_play_instrument(xmp_context c, int ins, int note, int vol, int chn)

-
-

Play a note using an instrument from the currently loaded module in -one of the reserved sound mixer channels.

-
-
Parameters:
-
--- - - - - - - - - - - - -
c:the player context handle.
ins:the instrument to play.
note:the note number to play (60 = middle C).
vol:the volume to use (0 to the maximum volume value used by the -current module.
chn:the reserved channe to use to play the instrument.
-
-
Returns:
-
0 if the instrument was correctly played, -XMP_ERROR_INVALID in -case of invalid parameters, or -XMP_ERROR_STATE if the player is not -in playing state.
-
-
-
-
-

int xmp_smix_play_sample(xmp_context c, int ins, int vol, int chn)

-
-

Play an external sample file in one of the reserved sound channels. -The sample must have been previously loaded using -xmp_smix_load_sample().

-
-
Parameters:
-
--- - - - - - - - - - -
c:the player context handle.
ins:the sample to play.
vol:the volume to use (0 to the maximum volume value used by the -current module.
chn:the reserved channel to use to play the sample.
-
-
Returns:
-
0 if the sample was correctly played, -XMP_ERROR_INVALID in -case of invalid parameters, or -XMP_ERROR_STATE if the player is not -in playing state.
-
-
-
-
-

int xmp_smix_channel_pan(xmp_context c, int chn, int pan)

-
-

Set the reserved channel pan value.

-
-
Parameters:
-
--- - - - - - - - -
c:the player context handle.
chn:the reserved channel number.
pan:the pan value to set (0 to 255).
-
-
Returns:
-
0 if the pan value was set, or -XMP_ERROR_INVALID if parameters -are invalid.
-
-
-
-
-

int xmp_smix_load_sample(xmp_context c, int num, char *path)

-
-

Load a sound sample from a file. Samples should be in mono WAV (RIFF) -format.

-
-
Parameters:
-
--- - - - - - - - -
c:the player context handle.
num:the slot number of the external sample to load.
path:pathname of the file to load.
-
-
Returns:
-
0 if the sample was correctly loaded, -XMP_ERROR_INVALID if the -sample slot number is invalid (not reserved using xmp_start_smix()), --XMP_ERROR_FORMAT if the file format is unsupported, or --XMP_ERROR_SYSTEM in case of system error (the system error code is -set in errno).
-
-
-
-
-

int xmp_smix_release_sample(xmp_context c, int num)

-
-

Release memory allocated by an external sample in the specified player -context.

-
-
Parameters:
-
--- - - - - - -
c:the player context handle.
num:the sample slot number to release.
-
-
Returns:
-
0 if memory was correctly released, or -XMP_ERROR_INVALID if the -sample slot number is invalid.
-
-
-
-
-

void xmp_end_smix(xmp_context c)

-
-

Deinitialize and resease memory used by the external sample mixer subsystem.

-
-
Parameters:
-
--- - - - -
c:the player context handle.
-
-
-
-
-
-
-
- - diff --git a/docs/libxmp.pdf b/docs/libxmp.pdf deleted file mode 100644 index beeae0b..0000000 Binary files a/docs/libxmp.pdf and /dev/null differ diff --git a/docs/libxmp.rst b/docs/libxmp.rst deleted file mode 100644 index 8f6eee8..0000000 --- a/docs/libxmp.rst +++ /dev/null @@ -1,1080 +0,0 @@ - -Libxmp 4.3 API documentation -============================ - -.. contents:: `Contents` - :depth: 3 - -.. raw:: pdf - - PageBreak - -Introduction ------------- - -Libxmp is a module player library supporting many mainstream and obscure -module formats including Protracker MOD, Scream Tracker III S3M and -Impulse Tracker IT. Libxmp loads the module and renders the sound as -linear PCM samples in a buffer at rate and format specified by the user, -one frame at a time (standard modules usually play at 50 frames per second). - -Possible applications for libxmp include stand-alone module players, module -player plugins for other players, module information extractors, background -music replayers for games and other applications, module-to-mp3 renderers, etc. - - -Concepts -~~~~~~~~ - -* **Player context:** - Most libxmp functions require a handle that identifies the module player - context. Each context is independent and multiple contexts can be defined - simultaneously. - -* **Sequence:** - Each group of positions in the order list that loops over itself, also - known as "subsong". Most modules have only one sequence, but some modules, - especially modules used in games can have multiple sequences. "Hidden - patterns" outside the main song are also listed as extra sequences, certain - module authors such as Skaven commonly place extra patterns at the end of - the module. - -* **State:** *[Added in libxmp 4.2]* - The player can be in one of three possible states: *unloaded*, *loaded*, - or *playing*. The player is in unloaded state after context creation, - changing to other states when a module is loaded or played. - -* **External sample mixer:** *[Added in libxmp 4.2]* - Special sound channels can be reserved using `xmp_start_smix()` - to play module instruments or external samples. This is useful when - libxmp is used to provide background music to games or other applications - where sound effects can be played in response to events or user actions - -A simple example -~~~~~~~~~~~~~~~~ - -This example loads a module, plays it at 44.1kHz and writes it to a raw -sound file:: - - #include - #include - #include - - int main(int argc, char **argv) - { - xmp_context c; - struct xmp_frame_info mi; - FILE *f; - - /* The output raw file */ - f = fopen("out.raw", "wb"); - if (f == NULL) { - fprintf(stderr, "can't open output file\n"); - exit(EXIT_FAILURE); - } - - /* Create the player context */ - c = xmp_create_context(); - - /* Load our module */ - if (xmp_load_module(c, argv[1]) != 0) { - fprintf(stderr, "can't load module\n"); - exit(EXIT_FAILURE); - } - - /* Play the module */ - xmp_start_player(c, 44100, 0); - while (xmp_play_frame(c) == 0) { - xmp_get_frame_info(c, &mi); - - if (mi.loop_count > 0) /* exit before looping */ - break; - - fwrite(mi.buffer, mi.buffer_size, 1, f); /* write audio data */ - } - xmp_end_player(c); - xmp_release_module(c); /* unload module */ - xmp_free_context(c); /* destroy the player context */ - - fclose(f); - - exit(EXIT_SUCCESS); - } - - -A player context can load and play a single module at a time. Multiple -contexts can be defined if needed. - -Use `xmp_test_module()`_ to check if the file is a valid module and -retrieve the module name and type. Use `xmp_load_module()`_ to load -the module to memory. These two calls return 0 on success or <0 in case of -error. Error codes are:: - - -XMP_ERROR_INTERNAL /* Internal error */ - -XMP_ERROR_FORMAT /* Unsupported module format */ - -XMP_ERROR_LOAD /* Error loading file */ - -XMP_ERROR_DEPACK /* Error depacking file */ - -XMP_ERROR_SYSTEM /* System error */ - -XMP_ERROR_STATE /* Incorrect player state */ - -If a system error occurs, the specific error is set in ``errno``. - -Parameters to `xmp_start_player()`_ are the sampling -rate (up to 48kHz) and a bitmapped integer holding one or more of the -following mixer flags:: - - XMP_MIX_8BIT /* Mix to 8-bit instead of 16 */ - XMP_MIX_UNSIGNED /* Mix to unsigned samples */ - XMP_MIX_MONO /* Mix to mono instead of stereo */ - XMP_MIX_NEAREST /* Mix using nearest neighbor interpolation */ - XMP_MIX_NOFILTER /* Disable lowpass filter */ - -After `xmp_start_player()`_ is called, each call to `xmp_play_frame()`_ -will render an audio frame. Call `xmp_get_frame_info()`_ to retrieve the -buffer address and size. `xmp_play_frame()`_ returns 0 on success or -1 -if replay should stop. - -Use `xmp_end_player()`_, `xmp_release_module()`_ and -`xmp_free_context()`_ to release memory and end replay. - - -SDL example -~~~~~~~~~~~ - -To use libxmp with SDL, just provide a callback function that renders module -data. The module will play when ``SDL_PauseAudio(0)`` is called:: - - #include - #include - - static void fill_audio(void *udata, unsigned char *stream, int len) - { - xmp_play_buffer(udata, stream, len, 0); - } - - int sound_init(xmp_context ctx, int sampling_rate, int channels) - { - SDL_AudioSpec a; - - a.freq = sampling_rate; - a.format = (AUDIO_S16); - a.channels = channels; - a.samples = 2048; - a.callback = fill_audio; - a.userdata = ctx; - - if (SDL_OpenAudio(&a, NULL) < 0) { - fprintf(stderr, "%s\n", SDL_GetError()); - return -1; - } - } - - int main(int argc, char **argv) - { - xmp_context ctx; - - if ((ctx = xmp_create_context()) == NULL) - return 1; - - sound_init(ctx, 44100, 2); - xmp_load_module(ctx, argv[1]); - xmp_start_player(ctx, 44100, 0); - - SDL_PauseAudio(0); - - sleep(10); // Do something important here - - SDL_PauseAudio(1); - - xmp_end_player(ctx); - xmp_release_module(ctx); - xmp_free_context(ctx); - - SDL_CloseAudio(); - return 0; - } - -SDL callbacks run in a separate thread, so don't forget to protect sections -that manipulate module data with ``SDL_LockAudio()`` and ``SDL_UnlockAudio()``. - - -.. raw:: pdf - - PageBreak - -API reference -------------- - -Version and player information -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. _xmp_version: - -const char \*xmp_version -```````````````````````` - - A string containing the library version, such as "4.0.0". - -.. _xmp_vercode: - -const unsigned int xmp_vercode -`````````````````````````````` - - The library version encoded in a integer value. Bits 23-16 contain the - major version number, bits 15-8 contain the minor version number, and - bits 7-0 contain the release number. - - -.. _xmp_get_format_list(): - -char \*\*xmp_get_format_list() -`````````````````````````````` - - Query the list of supported module formats. - - :Returns: - a NULL-terminated array of strings containing the names - of all supported module formats. - - -Context creation -~~~~~~~~~~~~~~~~ - -.. _xmp_create_context(): - -xmp_context xmp_create_context() -```````````````````````````````` - - Create a new player context and return an opaque handle to be used in - subsequent accesses to this context. - - **Returns:** - the player context handle. - -.. _xmp_free_context(): - -void xmp_free_context(xmp_context c) -```````````````````````````````````` - - Destroy a player context previously created using `xmp_create_context()`_. - - **Parameters:** - :c: - the player context handle. - - -Module loading -~~~~~~~~~~~~~~ - -.. _xmp_test_module(): - -int xmp_test_module(char \*path, struct xmp_test_info \*test_info) -`````````````````````````````````````````````````````````````````` - - Test if a file is a valid module. Testing a file does not affect the - current player context or any currently loaded module. - - **Parameters:** - :path: pathname of the module to test. - - :test_info: NULL, or a pointer to a structure used to retrieve the - module title and format if the file is a valid module. - ``struct xmp_test_info`` is defined as:: - - struct xmp_test_info { - char name[XMP_NAME_SIZE]; /* Module title */ - char type[XMP_NAME_SIZE]; /* Module format */ - }; - - **Returns:** - 0 if the file is a valid module, or a negative error code - in case of error. Error codes can be ``-XMP_ERROR_FORMAT`` in case of an - unrecognized file format, ``-XMP_ERROR_DEPACK`` if the file is compressed - and uncompression failed, or ``-XMP_ERROR_SYSTEM`` in case of system error - (the system error code is set in ``errno``). - -.. _xmp_load_module(): - -int xmp_load_module(xmp_context c, char \*path) -``````````````````````````````````````````````` - - Load a module into the specified player context. - - **Parameters:** - :c: the player context handle. - - :path: pathname of the module to load. - - **Returns:** - 0 if sucessful, or a negative error code in case of error. - Error codes can be ``-XMP_ERROR_FORMAT`` in case of an unrecognized file - format, ``-XMP_ERROR_DEPACK`` if the file is compressed and uncompression - failed, ``-XMP_ERROR_LOAD`` if the file format was recognized but the - file loading failed, or ``-XMP_ERROR_SYSTEM`` in case of system error - (the system error code is set in ``errno``). - -.. _xmp_load_module_from_memory(): - -int xmp_load_module_from_memory(xmp_context c, void \*mem, long size) -````````````````````````````````````````````````````````````````````` - - *[Added in libxmp 4.2]* Load a module from memory into the specified - player context. - - **Parameters:** - :c: the player context handle. - - :mem: a pointer to the module file image in memory. Multi-file modules - or compressed modules can't be loaded from memory. - - :size: the size of the module, or 0 if the size is unknown or not - specified. If size is set to 0 certain module formats won't be - recognized, the MD5 digest will not be set, and module-specific - quirks won't be applied. - - **Returns:** - 0 if sucessful, or a negative error code in case of error. - Error codes can be ``-XMP_ERROR_FORMAT`` in case of an unrecognized file - format, ``-XMP_ERROR_LOAD`` if the file format was recognized but the - file loading failed, or ``-XMP_ERROR_SYSTEM`` in case of system error - (the system error code is set in ``errno``). - -.. _xmp_load_module_from_file(): - -int xmp_load_module_from_file(xmp_context c, FILE \*f, long size) -````````````````````````````````````````````````````````````````` - - *[Added in libxmp 4.3]* Load a module from a stream into the specified - player context. - - **Parameters:** - :c: the player context handle. - - :f: the file stream. On return, the stream position is undefined. - - :size: the size of the module, or 0 if the size is unknown or not - specified. If size is set to 0 certain module formats won't be - recognized, the MD5 digest will not be set, and module-specific - quirks won't be applied. - - **Returns:** - 0 if sucessful, or a negative error code in case of error. - Error codes can be ``-XMP_ERROR_FORMAT`` in case of an unrecognized file - format, ``-XMP_ERROR_LOAD`` if the file format was recognized but the - file loading failed, or ``-XMP_ERROR_SYSTEM`` in case of system error - (the system error code is set in ``errno``). - -.. _xmp_release_module(): - -void xmp_release_module(xmp_context c) -`````````````````````````````````````` - - Release memory allocated by a module from the specified player context. - - **Parameters:** - :c: the player context handle. - -.. _xmp_scan_module(): - -void xmp_scan_module(xmp_context c) -``````````````````````````````````` - - Scan the loaded module for sequences and timing. Scanning is automatically - performed by `xmp_load_module()`_ and this function should be called only - if `xmp_set_player()`_ is used to change player timing (with parameter - ``XMP_PLAYER_VBLANK``) in libxmp 4.0.2 or older. - - **Parameters:** - :c: the player context handle. - -.. _xmp_get_module_info(): - -void xmp_get_module_info(xmp_context c, struct xmp_module_info \*info) -`````````````````````````````````````````````````````````````````````` - - Retrieve current module data. - - **Parameters:** - :c: the player context handle. - - :info: pointer to structure containing the module data. - ``struct xmp_module_info`` is defined as follows:: - - struct xmp_module_info { - unsigned char md5[16]; /* MD5 message digest */ - int vol_base; /* Volume scale */ - struct xmp_module *mod; /* Pointer to module data */ - char *comment; /* Comment text, if any */ - int num_sequences; /* Number of valid sequences */ - struct xmp_sequence *seq_data; /* Pointer to sequence data */ - }; - - Detailed module data is exposed in the ``mod`` field:: - - struct xmp_module { - char name[XMP_NAME_SIZE]; /* Module title */ - char type[XMP_NAME_SIZE]; /* Module format */ - int pat; /* Number of patterns */ - int trk; /* Number of tracks */ - int chn; /* Tracks per pattern */ - int ins; /* Number of instruments */ - int smp; /* Number of samples */ - int spd; /* Initial speed */ - int bpm; /* Initial BPM */ - int len; /* Module length in patterns */ - int rst; /* Restart position */ - int gvl; /* Global volume */ - - struct xmp_pattern **xxp; /* Patterns */ - struct xmp_track **xxt; /* Tracks */ - struct xmp_instrument *xxi; /* Instruments */ - struct xmp_sample *xxs; /* Samples */ - struct xmp_channel xxc[64]; /* Channel info */ - unsigned char xxo[XMP_MAX_MOD_LENGTH]; /* Orders */ - }; - - See the header file for more information about pattern and instrument - data. - - -Module playing -~~~~~~~~~~~~~~ - -.. _xmp_start_player(): - -int xmp_start_player(xmp_context c, int rate, int format) -````````````````````````````````````````````````````````` - - Start playing the currently loaded module. - - **Parameters:** - :c: the player context handle. - - :rate: the sampling rate to use, in Hz (typically 44100). Valid values - range from 8kHz to 48kHz. - - :flags: bitmapped configurable player flags, one or more of the - following:: - - XMP_FORMAT_8BIT /* Mix to 8-bit instead of 16 */ - XMP_FORMAT_UNSIGNED /* Mix to unsigned samples */ - XMP_FORMAT_MONO /* Mix to mono instead of stereo */ - - **Returns:** - 0 if sucessful, or a negative error code in case of error. - Error codes can be ``-XMP_ERROR_INTERNAL`` in case of a internal player - error, ``-XMP_ERROR_INVALID`` if the sampling rate is invalid, or - ``-XMP_ERROR_SYSTEM`` in case of system error (the system error - code is set in ``errno``). - -.. _xmp_play_frame(): - -int xmp_play_frame(xmp_context c) -````````````````````````````````` - - Play one frame of the module. Modules usually play at 50 frames per second. - Use `xmp_get_frame_info()`_ to retrieve the buffer containing audio data. - - **Parameters:** - :c: the player context handle. - - **Returns:** - 0 if sucessful, ``-XMP_END`` if the module ended or was stopped, or - ``-XMP_ERROR_STATE`` if the player is not in playing state. - -.. _xmp_get_frame_info(): - -void xmp_get_frame_info(xmp_context c, struct xmp_frame_info \*info) -```````````````````````````````````````````````````````````````````` - - Retrieve current frame data. - - **Parameters:** - :c: the player context handle. - - :info: pointer to structure containing current frame data. - ``struct xmp_frame_info`` is defined as follows:: - - struct xmp_frame_info { /* Current frame information */ - int pos; /* Current position */ - int pattern; /* Current pattern */ - int row; /* Current row in pattern */ - int num_rows; /* Number of rows in current pattern */ - int frame; /* Current frame */ - int speed; /* Current replay speed */ - int bpm; /* Current bpm */ - int time; /* Current module time in ms */ - int total_time; /* Estimated replay time in ms*/ - int frame_time; /* Frame replay time in us */ - void *buffer; /* Pointer to sound buffer */ - int buffer_size; /* Used buffer size */ - int total_size; /* Total buffer size */ - int volume; /* Current master volume */ - int loop_count; /* Loop counter */ - int virt_channels; /* Number of virtual channels */ - int virt_used; /* Used virtual channels */ - int sequence; /* Current sequence */ - - struct xmp_channel_info { /* Current channel information */ - unsigned int period; /* Sample period */ - unsigned int position; /* Sample position */ - short pitchbend; /* Linear bend from base note*/ - unsigned char note; /* Current base note number */ - unsigned char instrument; /* Current instrument number */ - unsigned char sample; /* Current sample number */ - unsigned char volume; /* Current volume */ - unsigned char pan; /* Current stereo pan */ - unsigned char reserved; /* Reserved */ - struct xmp_event event; /* Current track event */ - } channel_info[XMP_MAX_CHANNELS]; - }; - - This function should be used to retrieve sound buffer data after - `xmp_play_frame()`_ is called. Fields ``buffer`` and ``buffer_size`` - contain the pointer to the sound buffer PCM data and its size. The - buffer size will be no larger than ``XMP_MAX_FRAMESIZE``. - -.. _xmp_play_buffer(): - -int xmp_play_buffer(xmp_context c, void \*buffer, int size, int loop) -````````````````````````````````````````````````````````````````````` - - *[Added in libxmp 4.1]* Fill the buffer with PCM data up to the specified - size. This is a convenience function that calls `xmp_play_frame()`_ - internally to fill the user-supplied buffer -- don't call both functions - in the same replay loop, choose one of them. If you don't need equally - sized data chunks, `xmp_play_frame()`_ will result in better performance. - - **Parameters:** - :c: the player context handle. - - :buffer: the buffer to fill with PCM data, or NULL to reset the - internal state. - - :size: buffer size in bytes. - - :loop: stop replay when the loop counter reaches the specified - value, or 0 to disable loop checking. - - **Returns:** - 0 if sucessful, ``-XMP_END`` if module was stopped or the loop counter - was reached, or ``-XMP_ERROR_STATE`` if the player is not in playing - state. - -.. _xmp_end_player(): - -void xmp_end_player(xmp_context c) -`````````````````````````````````` - - End module replay and releases player memory. - - **Parameters:** - :c: the player context handle. - - -Player control -~~~~~~~~~~~~~~ - -.. _xmp_next_position(): - -int xmp_next_position(xmp_context c) -```````````````````````````````````` - - Skip replay to the start of the next position. - - **Parameters:** - :c: the player context handle. - - **Returns:** - The new position index, or ``-XMP_ERROR_STATE`` if the player is not - in playing state. - -.. _xmp_prev_position(): - -int xmp_prev_position(xmp_context c) -```````````````````````````````````` - - Skip replay to the start of the previous position. - - **Parameters:** - :c: the player context handle. - - **Returns:** - The new position index, or ``-XMP_ERROR_STATE`` if the player is not - in playing state. - -.. _xmp_set_position(): - -int xmp_set_position(xmp_context c, int pos) -```````````````````````````````````````````` - - Skip replay to the start of the given position. - - **Parameters:** - :c: the player context handle. - - :pos: the position index to set. - - **Returns:** - The new position index, ``-XMP_ERROR_INVALID`` of the new position is - invalid or ``-XMP_ERROR_STATE`` if the player is not in playing state. - -.. _xmp_stop_module(): - -void xmp_stop_module(xmp_context c) -``````````````````````````````````` - - Stop the currently playing module. - - **Parameters:** - :c: the player context handle. - -.. _xmp_restart_module(): - -void xmp_restart_module(xmp_context c) -`````````````````````````````````````` - - Restart the currently playing module. - - **Parameters:** - :c: the player context handle. - -.. _xmp_seek_time(): - -int xmp_seek_time(xmp_context c, int time) -`````````````````````````````````````````` - - Skip replay to the specified time. - - **Parameters:** - :c: the player context handle. - - :time: time to seek in milliseconds. - - **Returns:** - The new position index, or ``-XMP_ERROR_STATE`` if the player is not - in playing state. - -.. _xmp_channel_mute(): - -int xmp_channel_mute(xmp_context c, int channel, int status) -```````````````````````````````````````````````````````````` - - Mute or unmute the specified channel. - - **Parameters:** - :c: the player context handle. - - :channel: the channel to mute or unmute. - - :status: 0 to mute channel, 1 to unmute or -1 to query the - current channel status. - - **Returns:** - The previous channel status, or ``-XMP_ERROR_STATE`` if the player is not - in playing state. - -.. _xmp_channel_vol(): - -int xmp_channel_vol(xmp_context c, int channel, int vol) -```````````````````````````````````````````````````````` - - Set or retrieve the volume of the specified channel. - - **Parameters:** - :c: the player context handle. - - :channel: the channel to set or get volume. - - :vol: a value from 0-100 to set the channel volume, or -1 to retrieve - the current volume. - - **Returns:** - The previous channel volume, or ``-XMP_ERROR_STATE`` if the player is not - in playing state. - - -.. _xmp_inject_event(): - -void xmp_inject_event(xmp_context c, int channel, struct xmp_event \*event) -``````````````````````````````````````````````````````````````````````````` - - Dynamically insert a new event into a playing module. - - **Parameters:** - :c: the player context handle. - - :channel: the channel to insert the new event. - - :event: the event to insert. - ``struct xmp_event`` is defined as:: - - struct xmp_event { - unsigned char note; /* Note number (0 means no note) */ - unsigned char ins; /* Patch number */ - unsigned char vol; /* Volume (0 to basevol) */ - unsigned char fxt; /* Effect type */ - unsigned char fxp; /* Effect parameter */ - unsigned char f2t; /* Secondary effect type */ - unsigned char f2p; /* Secondary effect parameter */ - unsigned char _flag; /* Internal (reserved) flags */ - }; - - -Player parameter setting -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. _xmp_set_instrument_path(): - -int xmp_set_instrument_path(xmp_context c, char \*path) -``````````````````````````````````````````````````````` - - Set the path to retrieve external instruments or samples. Used by some - formats (such as MED2) to read sample files from a different directory - in the filesystem. - - **Parameters:** - :c: the player context handle. - - :path: the path to retrieve instrument files. - - **Returns:** - 0 if the instrument path was correctly set, or ``-XMP_ERROR_SYSTEM`` - in case of error (the system error code is set in ``errno``). - -.. _xmp_get_player(): - -int xmp_get_player(xmp_context c, int param) -```````````````````````````````````````````` - - Retrieve current value of the specified player parameter. - - **Parameters:** - :c: the player context handle. - - :param: player parameter to get. - Valid parameters are:: - - XMP_PLAYER_AMP /* Amplification factor */ - XMP_PLAYER_MIX /* Stereo mixing */ - XMP_PLAYER_INTERP /* Interpolation type */ - XMP_PLAYER_DSP /* DSP effect flags */ - XMP_PLAYER_FLAGS /* Player flags */ - XMP_PLAYER_CFLAGS /* Player flags for current module*/ - XMP_PLAYER_SMPCTL /* Control sample loading */ - XMP_PLAYER_VOLUME /* Player master volume */ - XMP_PLAYER_STATE /* Current player state*/ - XMP_PLAYER_DEFPAN /* Default pan separation */ - - See ``xmp_set_player`` for the list of valid values for each parameter. - Valid states are:: - - XMP_STATE_UNLOADED /* Context created */ - XMP_STATE_LOADED /* Module loaded */ - XMP_STATE_PLAYING /* Module playing */ - - **Returns:** - The parameter value, or ``-XMP_ERROR_STATE`` if the parameter is not - ``XMP_PLAYER_STATE`` and the player is not in playing state. - -.. _xmp_set_player(): - -int xmp_set_player(xmp_context c, int param, int val) -````````````````````````````````````````````````````` - - Set player parameter with the specified value. - - **Parameters:** - :param: player parameter to set. - Valid parameters are:: - - XMP_PLAYER_AMP /* Amplification factor */ - XMP_PLAYER_MIX /* Stereo mixing */ - XMP_PLAYER_INTERP /* Interpolation type */ - XMP_PLAYER_DSP /* DSP effect flags */ - XMP_PLAYER_FLAGS /* Player flags */ - XMP_PLAYER_CFLAGS /* Player flags for current module*/ - XMP_PLAYER_SMPCTL /* Control sample loading */ - XMP_PLAYER_VOLUME /* Player master volume */ - XMP_PLAYER_DEFPAN /* Default pan separation */ - - :val: the value to set. Valid values are: - - * Amplification factor: ranges from 0 to 3. Default value is 1. - - * Stereo mixing: percentual left/right channel separation. Default is 70. - - * Interpolation type: can be one of the following values:: - - XMP_INTERP_NEAREST /* Nearest neighbor */ - XMP_INTERP_LINEAR /* Linear (default) */ - XMP_INTERP_SPLINE /* Cubic spline */ - - * DSP effects flags: enable or disable DSP effects. Valid effects are:: - - XMP_DSP_LOWPASS /* Lowpass filter effect */ - XMP_DSP_ALL /* All effects */ - - * Player flags: tweakable player parameters. Valid flags are:: - - XMP_FLAGS_VBLANK /* Use vblank timing */ - XMP_FLAGS_FX9BUG /* Emulate Protracker 2.x FX9 bug */ - XMP_FLAGS_FIXLOOP /* Make sample loop value / 2 */ - - * *[Added in libxmp 4.1]* Player flags for current module: same flags - as above but after applying module-specific quirks (if any). - - * *[Added in libxmp 4.1]* Control sample load. Valid values are:: - - XMP_SMPCTL_SKIP /* Don't load samples */ - - Disabling sample loading when loading a module allows allows - computation of module duration without decompressing and - loading large sample data, and is useful when duration information - is needed for a module that won't be played immediately. - - * *[Added in libxmp 4.2]* Set the player master volume, in a 0-100 scale. - - **Returns:** - 0 if parameter was correctly set, ``-XMP_ERROR_INVALID`` if - parameter or values are out of the valid ranges, or ``-XMP_ERROR_STATE`` - if the player is not in playing state. - -.. raw:: pdf - - PageBreak - -External sample mixer API -------------------------- - -Libxmp 4.2 includes a mini-API that can be used to add sound effects to -games and similar applications, provided that you have a low latency sound -system. It allows module instruments or external sample files in WAV format -to be played in response to arbitrary events. - -Example -~~~~~~~ - -This example using SDL loads a module and a sound sample, plays the module -as background music, and plays the sample when a key is pressed:: - - #include - #include - - static void fill_audio(void *udata, unsigned char *stream, int len) - { - xmp_play_buffer(udata, stream, len, 0); - } - - int sound_init(xmp_context ctx, int sampling_rate, int channels) - { - SDL_AudioSpec a; - - a.freq = sampling_rate; - a.format = (AUDIO_S16); - a.channels = channels; - a.samples = 2048; - a.callback = fill_audio; - a.userdata = ctx; - - if (SDL_OpenAudio(&a, NULL) < 0) { - fprintf(stderr, "%s\n", SDL_GetError()); - return -1; - } - } - - int video_init() - { - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - fprintf(stderr, "%s\n", SDL_GetError()); - return -1; - } - if (SDL_SetVideoMode(640, 480, 8, 0) == NULL) { - fprintf(stderr, "%s\n", SDL_GetError()); - return -1; - } - atexit(SDL_Quit); - } - - int main(int argc, char **argv) - { - SDL_Event event; - xmp_context ctx; - - if ((ctx = xmp_create_context()) == NULL) - return 1; - - video_init(); - sound_init(ctx, 44100, 2); - - xmp_start_smix(ctx, 1, 1); - xmp_smix_load_sample(ctx, 0, "blip.wav"); - - xmp_load_module(ctx, "music.mod"); - xmp_start_player(ctx, 44100, 0); - xmp_set_player(ctx, XMP_PLAYER_VOLUME, 40); - - SDL_PauseAudio(0); - - while (1) { - if (SDL_WaitEvent(&event)) { - if (event.type == SDL_KEYDOWN) { - if (event.key.keysym.sym == SDLK_ESCAPE) - break; - xmp_smix_play_sample(ctx, 0, 60, 64, 0); - } - } - } - - SDL_PauseAudio(1); - - xmp_end_player(ctx); - xmp_release_module(ctx); - xmp_free_context(ctx); - xmp_end_smix(ctx); - - SDL_CloseAudio(); - return 0; - } - - -SMIX API reference -~~~~~~~~~~~~~~~~~~ - -.. _xmp_start_smix(): - -int xmp_start_smix(xmp_context c, int nch, int nsmp) -```````````````````````````````````````````````````` - - Initialize the external sample mixer subsystem with the given number of - reserved channels and samples. - - **Parameters:** - :c: the player context handle. - - :nch: number of reserved sound mixer channels (1 to 64). - - :nsmp: number of external samples. - - **Returns:** - 0 if the external sample mixer system was correctly initialized, - ``-XMP_ERROR_INVALID`` in case of invalid parameters, ``-XMP_ERROR_STATE`` - if the player is already in playing state, or ``-XMP_ERROR_SYSTEM`` in case - of system error (the system error code is set in ``errno``). - -.. _xmp_smix_play_instrument(): - -int xmp_smix_play_instrument(xmp_context c, int ins, int note, int vol, int chn) -```````````````````````````````````````````````````````````````````````````````` - - Play a note using an instrument from the currently loaded module in - one of the reserved sound mixer channels. - - **Parameters:** - :c: the player context handle. - - :ins: the instrument to play. - - :note: the note number to play (60 = middle C). - - :vol: the volume to use (0 to the maximum volume value used by the - current module. - - :chn: the reserved channe to use to play the instrument. - - **Returns:** - 0 if the instrument was correctly played, ``-XMP_ERROR_INVALID`` in - case of invalid parameters, or ``-XMP_ERROR_STATE`` if the player is not - in playing state. - -.. _xmp_smix_play_sample(): - -int xmp_smix_play_sample(xmp_context c, int ins, int vol, int chn) -`````````````````````````````````````````````````````````````````` - - Play an external sample file in one of the reserved sound channels. - The sample must have been previously loaded using - `xmp_smix_load_sample()`_. - - **Parameters:** - :c: the player context handle. - - :ins: the sample to play. - - :vol: the volume to use (0 to the maximum volume value used by the - current module. - - :chn: the reserved channel to use to play the sample. - - **Returns:** - 0 if the sample was correctly played, ``-XMP_ERROR_INVALID`` in - case of invalid parameters, or ``-XMP_ERROR_STATE`` if the player is not - in playing state. - -.. _xmp_smix_channel_pan(): - -int xmp_smix_channel_pan(xmp_context c, int chn, int pan) -````````````````````````````````````````````````````````` - - Set the reserved channel pan value. - - **Parameters:** - :c: the player context handle. - - :chn: the reserved channel number. - - :pan: the pan value to set (0 to 255). - - **Returns:** - 0 if the pan value was set, or ``-XMP_ERROR_INVALID`` if parameters - are invalid. - -.. _xmp_smix_load_sample(): - -int xmp_smix_load_sample(xmp_context c, int num, char \*path) -````````````````````````````````````````````````````````````` - - Load a sound sample from a file. Samples should be in mono WAV (RIFF) - format. - - **Parameters:** - :c: the player context handle. - - :num: the slot number of the external sample to load. - - :path: pathname of the file to load. - - **Returns:** - 0 if the sample was correctly loaded, ``-XMP_ERROR_INVALID`` if the - sample slot number is invalid (not reserved using `xmp_start_smix()`_), - ``-XMP_ERROR_FORMAT`` if the file format is unsupported, or - ``-XMP_ERROR_SYSTEM`` in case of system error (the system error code is - set in ``errno``). - -.. _xmp_smix_release_sample(): - -int xmp_smix_release_sample(xmp_context c, int num) -``````````````````````````````````````````````````` - - Release memory allocated by an external sample in the specified player - context. - - **Parameters:** - :c: the player context handle. - - :num: the sample slot number to release. - - **Returns:** - 0 if memory was correctly released, or ``-XMP_ERROR_INVALID`` if the - sample slot number is invalid. - -.. _xmp_end_smix(): - -void xmp_end_smix(xmp_context c) -```````````````````````````````` - - Deinitialize and resease memory used by the external sample mixer subsystem. - - **Parameters:** - :c: the player context handle. - diff --git a/docs/tracker_notes.txt b/docs/tracker_notes.txt deleted file mode 100644 index 199a398..0000000 --- a/docs/tracker_notes.txt +++ /dev/null @@ -1,478 +0,0 @@ - -MOD REPLAYING NOTES -Hipolito Carraro Jr. -Claudio Matsuoka - -Created: Sun May 16 13:43:42 EST 1999 - -Aug/Sep 2007 -- added Digitrakker 3.2 -- IT tracker fingerprint - -Jun/Jul 2009 -- More fingerprints from Storlek -- Notes on lamb's 275/263 XM tracker -- Notes on MOD2XM converted modules - - -1. Event fetch - -Here is a list of several situations where Protracker, Fast Tracker II, Scream -Tracker 3 and Impulse Tracker behave differently due to the underlying event -handling algorithm used by these trackers. - -xmp plays Protracker modules like Protracker 3.15 (marked as "standard" in -the tables). xCHN and xxCH play in FT2 style, S3M/STM/STX/PTM play in ST3 -style. - -Trackers compared: - -PT1.1 = Protracker 1.1 (Amiga Freelancers, Dec 1990) -PT1.3 = Protracker 1.3 (Amiga Freelancers, May 1992) -PT2.3 = Protracker 2.3d (Mushroom Studios, Jan 1993) -PT3.15 = Protracker 3.15 (Cryptoburners, 1992-93) -PT3.61 = Protracker 3.61 (Design/RD10, 1996) -PT4b2 = Protracker 4.0 beta 2 (Thomas Beyer et al, Feb 1997) -MED = OctaMED Professional 4.0 (Teijo Kinnunen, 1992) -MTM = MultiTracker 1.01b (Daniel Goldstein, 1993) -FT2 = Fast Tracker II 2.06 (Triton (Starbreeze Studios), 1996) -ST3 = Scream Tracker 3.21 (Future Crew, 1994) -IO10 = Imago Orpheus 1.0 (Lutz Roeder, 1994) -IT(s) = Impulse Tracker 2.14, sample mode (Jeffrey Lim) -IT(i) = Impulse Tracker 2.14, instrument mode (Jeffrey Lim) -DT32 = Digitrakker 3.2 (Jörn Mik (Prodatron), 1997) - -Protrackers downloaded from Aminet and Warlock's ADF archive and tested with -UAE 0.8.6. Startrekker 1.2, Soundtracker 2.5 and Noisetracker 1.0/ 1.2/2.0 -don't run in this version of UAE (or at least I couldn't make them run). - -Behaviors: - -Play = Play new note with new default volume -Trig = Play new note with old default volume -Switch = Play new note with current volume -LastSet = Play new note with last set volume -NewVol = Don't play sample, set new default volume -OldVol = Don't play sample, set old default volume -SetVol = Don't play sample, reset to last set volume -Cut = Stop playing sample -Cont = Continue playing sample - -Case 1: New note - - Instrument -> None Same Valid Inval -PT1.1 Play Play Play Cut -PT1.3 Play Play Play Cut -PT2.3 Switch Play Play Cut <= -PT3.15 Switch Play Play Cut <= "Standard" -PT3.61 Switch Play Play Cut <= -PT4b2 Switch Play Play Cut <= -MED Switch Play Play Cut <= -FT2 Switch Play Play Cut <= -ST3 Switch Play Play Switch -IT(s) Switch Play Play ? -IT(i) Switch Play Play Cont -DT32 Play Play Play Cut - - -Case 2: New instrument (no note) - - Instrument -> None Same Valid Inval -PT1.1 - Play Play Cut -PT1.3 - NewVol NewVol* Cut -PT2.3 - NewVol NewVol* Cut -PT3.15 - NewVol NewVol Cut <= "Standard" -PT3.61 - NewVol NewVol Cut <= -PT4b2 - NewVol NewVol Cut <= -MED - Hold Hold Cut% -FT2 - OldVol OldVol OldVol -ST3 - NewVol NewVol Cont -IT(s) - NewVol NewVol Cont -IT(i) - NewVol# Play Cont -DT32 - NewVol# NewVol# Cut - - -Case 3: Tone portamento - - Instrument -> None Same Valid Inval -PT1.1 Cont NewVol? -PT1.3 Cont NewVol NewVol* Cut -PT2.3 Cont NewVol NewVol* Cut -PT3.15 Cont NewVol NewVol Cut <= "Standard" -PT3.61 Cont NewVol NewVol Cut <= -PT4b2 Cont NewVol NewVol Cut <= -MED Cont NewVol NewVol Cut <= -FT2 Cont OldVol OldVol OldVol -ST3 Cont NewVol NewVol Cont -IT(s) Cont Play+ Play+ Cont -IT(i) @ Cont Play+ Play+ Cont -DT32 Cont NewVol NewVol Cut - - - # Don't reset envelope. - - % Any valid instrument with no note is set as Hold. When the instrument - is invalid the channel is muted until the next valid instrument. - - 00 C-2 30000 <= Play instrument 3 - 01 | 30000 \ - 02 | 20000 > Continue playing instrument 3 - 03 | 10000 / - 04 | A0000 <= Volume is set to 0 (instrument A is invalid) - 05 | 40000 <= Continue instrument 3 - - * Protracker 1.3/2.3 switches to new sample in the line after the new - instrument event. The new instrument is not played from start (i.e. a - short transient sample may not be played). This behaviour is NOT - emulated by the current version of xmp. - - 00 C-2 03 A0F <= Play instrument 03 and slide volume down - 01 --- 02 000 <= Set volume of instrument 02, playing instrument 03 - 02 --- 00 000 <= Switch to instrument 02 (weird!) - - 00 C-2 03 000 <= Play instrument 03 - 01 A-3 02 308 <= Start portamento with instrument 03 - 02 --- 00 xxx <= Switch to instrument 02 (weird!) - - @ Tone portamento works in IT, instrument mode, only while the sample is - playing. After that, the tone portamento effect is ignored and the - new note is played. - - 00 C-2 01 000 <= Start instrument 01 - 01 --- 00 000 - 02 C#2 01 G0F <= Tone portamento effect works as expected - 03 --- 00 000 - 04 --- 00 000 <= End of instrument 01 - 05 C-2 01 G0F <= Play instrument 01 again (yuck!) - - + Was NewVol in this document, but Mirko Buffoni reports that this should - be Play instead (see commit c230825c) - - -2. XM and IT envelopes - -When sustain loop is on, IT ignores the envelope loop. When the key is -released execution jumps from the current point inside the sustain loop -to the start of the envelope loop. XM envelope loops act like IT sustain -loops when the sustain point and the envelope end point are the same -(i.e. loop is active only while key is pressed). This behaviour is -correctly emulated by xmp. - - -3. Periods and replay rates - -xmp plays Protracker and Fast Tracker II modules at standard PAL rate of -7093789.2 / (428 * 2) = 8287.137 for middle C. Scream Tracker III and Impulse -Tracker play with the NTSC rate of 7159090.5 / (428 * 2) = 8363.423. Using -MED BPM = 125/33 of Protracker BPMs, the Desert Strike MMD1 plays better -with NTSC replay rate. (Claudio's note: Does that mean that the correct tempo -for MED is _not_ 125/33 of the PAL vblank rate?) - - -4. Error in the Protracker 2.1 docs - -The effect commands description in the Protracker 2.1A docs state that -effect E5x is used to set the loop start point and effect E6x is used -for loop jump. The player code shows that effect E5x is used for finetune -setting, E60 for loop set and E6x, x > 0, for loop jump. - -PT.Effects_2.1a.txt: - ... -E5- Set Loop E5x : set loop point -E6- Jump to Loop E6x : jump to loop, play x times - ... - -(Same description in Protracker V2.3A/3.01) - - -PT-Play_2.1a.s: - 1 ;************************************************** - 2 ;* ----- Protracker V2.1A Playroutine ----- * - 3 ;* Peter "CRAYON" Hanning / Mushroom Studios 1992 * - 4 ;* Vinterstigen 12, 14440 Ronninge, Sweden * - 5 ;************************************************** - 6 - ... - 802 mt_E_Commands - 803 MOVE.B n_cmdlo(A6),D0 - 804 AND.B #$F0,D0 - 805 LSR.B #4,D0 - ... - 815 CMP.B #5,D0 - 816 BEQ mt_SetFineTune - 817 CMP.B #6,D0 - 818 BEQ mt_JumpLoop - ... - 865 mt_JumpLoop - 866 TST.B mt_counter - 867 BNE mt_Return2 - 868 MOVE.B n_cmdlo(A6),D0 - 869 AND.B #$0F,D0 - 870 BEQ.S mt_SetLoop - 871 TST.B n_loopcount(A6) - 872 BEQ.S mt_jumpcnt - 873 SUBQ.B #1,n_loopcount(A6) - 874 BEQ mt_Return2 - - -5. Pattern loops - -Pattern loops are set by channel, and nesting is allowed as long as -the loops are in different tracks. The nested loop behaviour is somewhat -nonobvious as seen in the following examples. - - 00 --- 00 E60 | --- 00 E60 00 --- 00 000 | --- 00 E60 - 01 C-2 01 000 | --- 00 000 01 C-2 01 000 | --- 00 000 - 02 --- 00 E62 | --- 00 E62 02 --- 00 000 | --- 00 E62 - -In both cases the note is played three times. - - 00 --- 00 E60 | --- 00 E60 - 01 C-2 01 000 | --- 00 000 - 02 --- 00 E63 | --- 00 E62 - -In this situation the note is played twelve times. We escape the loop when -both counters are zeroed. Here's how the internal registers look like: - - Iteration => 1 2 3 4 5 6 7 8 9 A B C - Channel 1 => 3 2 1 0 3 2 1 0 3 2 1 0 - Channel 2 => 2 1 0 2 1 0 2 1 0 2 1 0 - - -If a loop end is used with no start point set, it jumps to the first line -of the pattern. If a pattern break is inside a loop and there is a loop -end in the next pattern it jumps to the row set as loop start in the -previous pattern. It is also possible to make an infinite loop in -Protracker and Fast Tracker II using nested loops in the same track: - - 00 --- 00 E60 | --- 00 000 - 01 --- 00 000 | --- 00 000 - 02 C-2 01 000 | --- 00 000 - 03 --- 00 E61 | --- 00 000 - 04 --- 00 E61 | --- 00 000 <= infinite loop - -S3M and IT set a new start point in the line after the end of the previous -loop, making the infinite loop impossible. - - -6. Effect 9 quirks - -From: Martin Willers -Subject: Incorrect Protrack-effect 0x09 -To: xmp-bugs@helllabs.org -Date: Mon, 21 Dec 1998 05:28:48 +0100 (MET) -Reply-to: M.Willers@tu-bs.de - -I've downloaded and installed the xmp-snapshot from Sun, Dec 20 today. -Don't know just how good the protrack-emulation is planned to get, but -there's a bug in the interpretation of Protracker's handling of effect 0x09 -(SetSampleOffset), that causes some MODs to play incorrectly. -Original Protracker-source has some bug in handling effect 09, in that -the sample offset given in the effect byte is added +twice+ to the current -sample offset, once before playing this instrument (as is expected), and -once again after this instrument has been played! So, if on the same channel -the same instrument is played again without resetting the instrument's -parameters (eg. when just a note period is specified, but not the instrument -number again? or the other way round? :), the offset is twice as high -as one would expect. -This can be heard very easy eg. in the (very popular) song "No Mercy" by -Alf/VTL, Position #2-#3 in the sequence. - --- - -Date: Tue, 22 Dec 1998 23:57:48 -0200 -From: Claudio Matsuoka -To: M.Willers@tu-bs.de -Subject: Re: Incorrect Protrack-effect 0x09 - -Ok, we played a bit with some custom-crafted mod to learn more about -effect 0x09. Here are the results: - -Using the "OK" sample from ST-02 - -00 C-2 01 906 PT23 : kay - ay - ay - okay <= buggy -01 --- 00 000 PT315 : kay - kay - kay - okay -02 C-2 00 000 MED : kay - kay - kay - okay -03 --- 00 000 ST3 : kay - kay - kay - okay -04 C-2 00 000 IO10 : kay - kay - kay - okay -05 --- 00 000 MTM : kay - okay - okay - okay -06 C-2 01 000 FT2 : kay - okay - okay - okay -07 --- 00 000 IT : kay - okay - okay - okay - DT32 : kay - okay - okay - okay - -So it seems that the bug was fixed somewhere between Protracker 2.3d and -3.15. The problem is that there's no way to know if the bug emulation is -desirable or not when playing M.K. mods! I believe that mods _requiring_ -this bug to be emulated are quite rare, so it will be switched using a -command line parameter or via modules.conf. - - -7. XM file format anomalies - -The official XM file format description distributed with Fast Tracker II -says "The XM module format description for XM files version $0104" and -"The current format is version $0103". The format description and actual -modules made with the tracker differ in the reserved bytes at the end of -the instrument data (2 bytes in the description and 22 in 1.04 modules) -and the sample header size field: the document says that it belongs to the -sample header data, but in XM files created by Fast Tracker II it is in -the instrument. "Braintomb" by Jazztiz/ART (jz-btomb.xm) has this field -in the sample header data. "Braintomb" is marked as 1.04 and the tracker -name field is empty (probably created using Digitrakker). - -The instrument size field is 33 for XM files created with Fast Tracker II. -"Braintomb" has 29 in this field, because the sample header size is in -the sample header structure. Modules converted with MED2XM or created with -other trackers can have the size of instrument data plus the size of the -sample header data in this field. There is a version of "" -(Counterpoint 2.0, untitled.xm) with 245 in this field. In this module the -instrument type ("always 0" according to xm.txt) is 0xda. This module was -created using an old version of ModPlug Tracker (marked as 1.04 made with -"FastTracker v 2.00", note that authentic FT2 modules are marked as -"FastTracker v2.00"). - -"ebony owl netsuke", "lightbeam", "dom" and other modules by Filip Skutela -have tracker name "FastTracker v2.00", header size 275 (authentic Fast -Tracker II modules have 276 in this field) and instrument size 263. - -Extended Module 1.02 (Vogue's "Trans atlantic" and "Dont you" remixes) and -1.03 (Vogue's "Developer 94" and "Enhanced Intuition") contains header, -instruments, patterns and samples in that order. 1.04 has header, patterns, -instruments and samples. XM 1.02 uses one byte to store the number of rows -in the pattern header, XM 1.03 and 1.04 use a 16-bit word. - -XM modules converted using MOD2XM 1.0 will always list instrument number -as 31, but the file is truncated after the last valid mod sample. These -modules are marked as "MOD2XM 1.0" with zero padding, but they can also -identify themselves as "FastTracker v2.00 ". These two variations seem -to be common in Windows cracktro loaders. - - -8. Broken sample loops in converted MOD files - -To play a sample using the 8364 Paula chip in Amiga, you must set a pointer -to the audio data in AUDxLCH (byte aligned) and the length in words in -AUDxLEN. Soundtracker uses the sample loop start in bytes and the length in -words, but Protracker uses both values in words. Some converters were not -aware of this feature and used the sample loop start in 16 bit words when -converting old Soundtracker modules to M.K., resulting in broken sample -loops. One example of broken converted M.K. mod is "Souvenir of China". - -Other formats where offsets in words are hard to detect: - -- GMC modules created with NoiseConverter have loop size / 2 . -- UNIC modules from "Guardian Dragon" have loop start / 2. Modules from - "Guardian Dragon II" have loop start / 4. -- NoisePacker v2 format is the same as NoisePacker v1 with loop start / 2. - - -9. Startrekker FLT8 format - -Multichannel variations of the standard MOD (e.g. 8CHN) have channels stored -side by side. This is NOT the case of Startrekker. Here are Bjorn Wesen's -words about it (text written in Mar 1994): - -"In regards of the Amiga StarTrekker format: It says FLT8 instead of FLT4 or - M.K., AND, the patterns are PAIRED. I thought this was the easiest 8 track - format possible, since it can be loaded in a normal 4 channel tracker if - you should want to rip sounds or patterns. So, in a 8 track FLT8 module, - patterns 00 and 01 is 'really' pattern 00. Patterns 02 and 03 together is - 'really' pattern 01. Thats it. Oh well, I didnt have the time to implement - all effect commands either, so some FLT8 modules would play back badly (I - think especially the portamento command uses a different 'scale' than the - normal portamento command, that would be hard to patch)." - -Uhm... I wonder what different scale is it. - - -10. Global volume setting - -Effect V (global volume setting) in Scream Tracker 3.21 does not affect events -in the same line where the effect is set. Fast Tracker 2.06 global volume -affects the columns to the right of the column where the effect is set (weird! --- could someone check this please?). Impulse Tracker 2.14 and Imago Orpheus -1.0 use global volume and slides as, well, global volume and slides (i.e. -affects all tracks). - -00 B-3 21 000 | --- 00 000 ST3: plays only instrument 21 -01 --- 00 000 | --- 00 G00 FT2: plays 21 and cuts 22 at row 03 -02 B-3 22 000 | --- 00 G40 IT: cuts 21 at row 01 and 22 at row 03 -03 --- 00 G00 | --- 00 000 - -Reference: Necros' "Mechanism Eight", pattern 93, channels 0 to 2, row 02. - - -11. Cut effect - -When the cut effect is used with parameter 0 (cut after 0 frames) Protracker, -Fast Tracker, Impulse Tracker and Digitrakker don't start to play the sample. -Scream Tracker and Imago Orpheus ignore the effect and don't cut the instrument. - -Subsequent note events with no instrument set are not played in Protracker. -(must check in other trackers) - -To check: cut effect with parameter > speed. - - -12. Imago Orpheus - -Error in format specs: - -The following differences have been found comparing Karsten Koch's IMF -files with the format specs for the Imago Orpheus file format version 1.00 -written by Lutz Roeder: - -- Channel status: 0x00 = channel disabled -- Envelope flags: 0 = off, 1 = on - -Other IMF notes: - -- Fine effects are 4 times finer than S3M extra fine effects -- Note values 160 (?) and 255 are key off events -- 'First effect' is the secondary effect -- In effect Mxx (0x16) xx = 0x00 is the highest cutoff frequency -- In effect Nxy (0x17) x = final cutoff value for slide, y = resonance - bit 7 = 0: Decrease cutoff frequency - bit 7 = 1: Increase cutoff frequency - bits 6-4: final cutoff frequency (0 = highest) -- Filter settings are not reset in new events! - - -12. Tracker fingerprinting - -Restart pos in M.K.: - 0x7f = Protracker or clone (including ST3) - 0x78 = ??? Possibly noisetracker - Restart pos = Noisetracker (or Fasttracker?) - Number of patterns = Soundtracker - -Noisetracker, Protracker and ST3 set the default volume of unused instruments -to 0x40 and the default loop size to 0x0002. Fasttracker sets the default -volume to 0x00 and the default loop size to 0x0000. - -S3M tracker codes: - 1 = Scream Tracker 3 - 2 = Imago Orpheus - 3 = Impulse Tracker - 4 = Schism Tracker (0x4100 = BeRoTracker) - 5 = OpenMPT (starting in 1.17) - 6 = BeRoTracker - -IT version codes: - 0214, format 0214, rsvd at 0x3c CHBI, -DEPRECATED- filenames = Chibi Tracker - 0214, format 0214, rsvd at 0x3c zero, XXXXXXXX.YYY filenames = CheeseTracker - 0216 = Impulse Tracker 2.14v3 - 0217 = Impulse Tracker 2.14v5 - 0217 and format 0200 = ModPlug Tracker 1.16 - 0888 = ModPlug Tracker 1.17 - - -13. Misc effects - -To check: (volunteers?) - -- Keyoff events with instrument set -- Vibrato depth -- Funk repeat - - diff --git a/emscripten/htdocs/backend_xmp.js b/emscripten/htdocs/backend_xmp.js index 8a3cc4e..a4fb587 100644 --- a/emscripten/htdocs/backend_xmp.js +++ b/emscripten/htdocs/backend_xmp.js @@ -9,69 +9,132 @@ window.spp_backend_state_XMP["onRuntimeInitialized"] = function() { // emscripte this.adapterCallback(); }.bind(window.spp_backend_state_XMP); -var backend_XMP = (function(Module) {var c;c||(c=typeof Module !== 'undefined' ? Module : {});var h={},k;for(k in c)c.hasOwnProperty(k)&&(h[k]=c[k]);c.arguments=[];c.thisProgram="./this.program";c.quit=function(a,b){throw b;};c.preRun=[];c.postRun=[];var n=!1,p=!1,q=!1,r=!1; -if(c.ENVIRONMENT)if("WEB"===c.ENVIRONMENT)n=!0;else if("WORKER"===c.ENVIRONMENT)p=!0;else if("NODE"===c.ENVIRONMENT)q=!0;else if("SHELL"===c.ENVIRONMENT)r=!0;else throw Error("Module['ENVIRONMENT'] value is not valid. must be one of: WEB|WORKER|NODE|SHELL.");else n="object"===typeof window,p="function"===typeof importScripts,q="object"===typeof process&&"function"===typeof require&&!n&&!p,r=!n&&!q&&!p; -if(q){var aa,ba;c.read=function(a,b){var d=t(a);d||(aa||(aa=require("fs")),ba||(ba=require("path")),a=ba.normalize(a),d=aa.readFileSync(a));return b?d:d.toString()};c.readBinary=function(a){a=c.read(a,!0);a.buffer||(a=new Uint8Array(a));assert(a.buffer);return a};1>2];a=b+a+15&-16;z[y>>2]=a;if(a=a>=A)fa(),a=!0;return a?(z[y>>2]=b,0):b}function ha(a){var b;b||(b=16);return Math.ceil(a/b)*b}var B=0;function assert(a,b){a||C("Assertion failed: "+b)} -var la={stackSave:function(){ia()},stackRestore:function(){ja()},arrayToC:function(a){var b=ka(a.length);D.set(a,b);return b},stringToC:function(a){var b=0;if(null!==a&&void 0!==a&&0!==a){var d=(a.length<<2)+1;b=ka(d);E(a,F,b,d)}return b}},ma={string:la.stringToC,array:la.arrayToC}; -function G(a,b){if("number"===typeof a){var d=!0;var e=a}else d=!1,e=a.length;var f;4==b?f=g:f=["function"===typeof oa?oa:v,ka,v,ea][void 0===b?2:b](Math.max(e,1));if(d){var g=f;assert(0==(f&3));for(a=f+(e&-4);g>2]=0;for(a=f+e;g>0]=0;return f}a.subarray||a.slice?F.set(a,f):F.set(new Uint8Array(a),f);return f} -function H(a,b){if(0===b||!a)return"";for(var d=0,e,f=0;;){e=F[a+f>>0];d|=e;if(0==e&&!b)break;f++;if(b&&f==b)break}b||(b=f);e="";if(128>d){for(;0e?d+=String.fromCharCode(e):(e-= -65536,d+=String.fromCharCode(55296|e>>10,56320|e&1023))}}else d+=String.fromCharCode(e)}} -function E(a,b,d,e){if(0=g&&(g=65536+((g&1023)<<10)|a.charCodeAt(++f)&1023);if(127>=g){if(d>=e)break;b[d++]=g}else{if(2047>=g){if(d+1>=e)break;b[d++]=192|g>>6}else{if(65535>=g){if(d+2>=e)break;b[d++]=224|g>>12}else{if(2097151>=g){if(d+3>=e)break;b[d++]=240|g>>18}else{if(67108863>=g){if(d+4>=e)break;b[d++]=248|g>>24}else{if(d+5>=e)break;b[d++]=252|g>>30;b[d++]=128|g>>24&63}b[d++]=128|g>>18&63}b[d++]=128|g>>12&63}b[d++]=128| -g>>6&63}b[d++]=128|g&63}}b[d]=0}}function ra(a){for(var b=0,d=0;d=e&&(e=65536+((e&1023)<<10)|a.charCodeAt(++d)&1023);127>=e?++b:b=2047>=e?b+2:65535>=e?b+3:2097151>=e?b+4:67108863>=e?b+5:b+6}return b}"undefined"!==typeof TextDecoder&&new TextDecoder("utf-16le");var buffer,D,F,sa,z,ta,x,da,ua,I,J,va,y;ta=x=ua=I=J=va=y=0;da=!1; -function fa(){C("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+A+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}var wa=c.TOTAL_STACK||5242880,A=c.TOTAL_MEMORY||16777216; -A>2]=a);return a}function Ja(a,b){if(0===a)a=Date.now();else if(1===a&&Ha())a=P();else return Ia(22),-1;z[b>>2]=a/1E3|0;z[b+4>>2]=a%1E3*1E6|0;return 0} -var Ka=G([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0, -1,0,3,0,1,0,2,0,1,0],2),Q=0;function R(){Q+=4;return z[Q-4>>2]}var S={};function T(a,b){Q=b;try{var d=R(),e=R(),f=R();a=0;T.c||(T.c=[null,[],[]],T.j=function(a,b){var d=T.c[a];assert(d);0===b||10===b?((1===a?c.print:c.printErr)(pa(d,0)),d.length=0):d.push(b)});for(b=0;b>2],l=z[e+(8*b+4)>>2],m=0;m>2];var d=z[b>>2]}else U.i=!0,V.USER=V.LOGNAME="web_user",V.PATH="/",V.PWD="/",V.HOME="/home/web_user",V.LANG="C.UTF-8",V._=c.thisProgram,d=v(1024),b=v(256),z[b>>2]=d,z[La>>2]=b;var e=[],f=0;for(l in a)if("string"===typeof a[l]){var g=l+"="+a[l];e.push(g);f+=g.length}if(1024>0]=f.charCodeAt(m);D[l>>0]=0;z[b+4*a>>2]=d;d+=g.length+1}z[b+ -4*e.length>>2]=0}var V={};function W(a){if(0===a)return 0;a=H(a);if(!V.hasOwnProperty(a))return 0;W.c&&Ma(W.c);a=V[a];var b=ra(a)+1,d=oa(b);d&&E(a,D,d,b);W.c=d;return W.c}function Na(a){return Math.pow(2,a)}G(Oa("GMT"),2);var X=x,Pa=x+=16,Qa=x+=16;x+=16; -function Y(){function a(a){return(a=a.toTimeString().match(/\(([A-Za-z ]+)\)$/))?a[1]:"GMT"}if(!Y.i){Y.i=!0;z[Qa>>2]=60*(new Date).getTimezoneOffset();var b=new Date(2E3,0,1),d=new Date(2E3,6,1);z[Pa>>2]=Number(b.getTimezoneOffset()!=d.getTimezoneOffset());var e=a(b),f=a(d);e=G(Oa(e),0);f=G(Oa(f),0);d.getTimezoneOffset()>2]=e,z[X+4>>2]=f):(z[X>>2]=f,z[X+4>>2]=e)}} -q?P=function(){var a=process.hrtime();return 1E3*a[0]+a[1]/1E6}:"undefined"!==typeof dateNow?P=dateNow:"object"===typeof self&&self.performance&&"function"===typeof self.performance.now?P=function(){return self.performance.now()}:"object"===typeof performance&&"function"===typeof performance.now?P=function(){return performance.now()}:P=Date.now;U(V);y=v(4);ua=I=ha(x);J=ua+wa;va=ha(J);z[y>>2]=va;da=!0;var Ra=!1;function Oa(a){var b=Array(ra(a)+1);E(a,b,0,b.length);return b} -function ca(a){for(var b=[],d=0;d>4; -f=(f&15)<<4|g>>2;var m=(g&3)<<6|l;b+=String.fromCharCode(e);64!==g&&(b+=String.fromCharCode(f));64!==l&&(b+=String.fromCharCode(m))}while(d>2]=d.position;d.g&&0===e&&0===g&&(d.g=null);return 0}catch(l){return"undefined"!==typeof FS&&l instanceof FS.a||C(l),-l.b}},___syscall145:function(a,b){Q=b;try{var d=S.f(),e=R(),f=R();return S.s(d,e,f)}catch(g){return"undefined"!==typeof FS&&g instanceof FS.a||C(g),-g.b}},___syscall146:T,___syscall195:function(a,b){Q=b;try{var d=H(R()),e=R();return S.o(FS.stat,d,e)}catch(f){return"undefined"!== -typeof FS&&f instanceof FS.a||C(f),-f.b}},___syscall197:function(a,b){Q=b;try{var d=S.f(),e=R();return S.o(FS.stat,d.path,e)}catch(f){return"undefined"!==typeof FS&&f instanceof FS.a||C(f),-f.b}},___syscall220:function(a,b){Q=b;try{var d=S.f(),e=R(),f=R();d.g||(d.g=FS.readdir(d.path));for(a=0;0>2]=l;z[e+a+4>>2]=d.position;sa[e+a+8>>1]=268; -D[e+a+10>>0]=m;E(g,F,e+a+11,256);a+=268}return a}catch(na){return"undefined"!==typeof FS&&na instanceof FS.a||C(na),-na.b}},___syscall221:function(a,b){Q=b;return 0},___syscall41:function(a,b){Q=b;try{var d=S.f();return FS.open(d.path,d.flags,0).fd}catch(e){return"undefined"!==typeof FS&&e instanceof FS.a||C(e),-e.b}},___syscall5:function(a,b){Q=b;try{var d=H(R()),e=R(),f=R();return FS.open(d,e,f).fd}catch(g){return"undefined"!==typeof FS&&g instanceof FS.a||C(g),-g.b}},___syscall54:function(a,b){Q= -b;return 0},___syscall6:function(a,b){Q=b;try{var d=S.f();FS.close(d);return 0}catch(e){return"undefined"!==typeof FS&&e instanceof FS.a||C(e),-e.b}},___unlock:function(){},_clock_gettime:Ja,_emscripten_get_now:P,_emscripten_get_now_is_monotonic:Ha,_emscripten_memcpy_big:function(a,b,d){F.set(F.subarray(b,b+d),a);return a},_getenv:W,_llvm_exp2_f32:Na,_llvm_exp2_f64:function(){return Na.apply(null,arguments)},_llvm_pow_f64:Ea,_localtime_r:function(a,b){Y();a=new Date(1E3*z[a>>2]);z[b>>2]=a.getSeconds(); -z[b+4>>2]=a.getMinutes();z[b+8>>2]=a.getHours();z[b+12>>2]=a.getDate();z[b+16>>2]=a.getMonth();z[b+20>>2]=a.getFullYear()-1900;z[b+24>>2]=a.getDay();var d=new Date(a.getFullYear(),0,1);z[b+28>>2]=(a.getTime()-d.getTime())/864E5|0;z[b+36>>2]=-(60*a.getTimezoneOffset());var e=(new Date(2E3,6,1)).getTimezoneOffset();d=d.getTimezoneOffset();a=(e!=d&&a.getTimezoneOffset()==Math.min(d,e))|0;z[b+32>>2]=a;z[b+40>>2]=z[X+(a?4:0)>>2];return b},_tzset:Y,flush_NO_FILESYSTEM:function(){var a=c._fflush;a&&a(0); -if(a=T.j){var b=T.c;b[1].length&&a(1,10);b[2].length&&a(2,10)}},DYNAMICTOP_PTR:y,tempDoublePtr:Ga,ABORT:B,STACKTOP:I,STACK_MAX:J,cttz_i8:Ka};// EMSCRIPTEN_START_ASM +var backend_XMP = (function(Module) {var e;e||(e=typeof Module !== 'undefined' ? Module : {});var aa={},k;for(k in e)e.hasOwnProperty(k)&&(aa[k]=e[k]);e.arguments=[];e.thisProgram="./this.program";e.quit=function(a,b){throw b;};e.preRun=[];e.postRun=[];var l=!1,m=!1,p=!1,ba=!1; +if(e.ENVIRONMENT)if("WEB"===e.ENVIRONMENT)l=!0;else if("WORKER"===e.ENVIRONMENT)m=!0;else if("NODE"===e.ENVIRONMENT)p=!0;else if("SHELL"===e.ENVIRONMENT)ba=!0;else throw Error("Module['ENVIRONMENT'] value is not valid. must be one of: WEB|WORKER|NODE|SHELL.");else l="object"===typeof window,m="function"===typeof importScripts,p="object"===typeof process&&"function"===typeof require&&!l&&!m,ba=!l&&!p&&!m; +if(p){var ca,ea;e.read=function(a,b){var c=q(a);c||(ca||(ca=require("fs")),ea||(ea=require("path")),a=ea.normalize(a),c=ca.readFileSync(a));return b?c:c.toString()};e.readBinary=function(a){a=e.read(a,!0);a.buffer||(a=new Uint8Array(a));assert(a.buffer);return a};1>2];a=b+a+15&-16;x[w>>2]=a;if(a=a>=z)ka(),a=!0;return a?(x[w>>2]=b,0):b}function la(a){var b;b||(b=16);return Math.ceil(a/b)*b}var ma=0;function assert(a,b){a||A("Assertion failed: "+b)} +var ra={stackSave:function(){na()},stackRestore:function(){oa()},arrayToC:function(a){var b=pa(a.length);B.set(a,b);return b},stringToC:function(a){var b=0;if(null!==a&&void 0!==a&&0!==a){var c=(a.length<<2)+1;b=pa(c);qa(a,C,b,c)}return b}},sa={string:ra.stringToC,array:ra.arrayToC}; +function ta(a,b){if("number"===typeof a){var c=!0;var d=a}else c=!1,d=a.length;var f;4==b?f=g:f=["function"===typeof ua?ua:t,pa,t,ja][void 0===b?2:b](Math.max(d,1));if(c){var g=f;assert(0==(f&3));for(a=f+(d&-4);g>2]=0;for(a=f+d;g>0]=0;return f}a.subarray||a.slice?C.set(a,f):C.set(new Uint8Array(a),f);return f} +function va(a,b){if(0===b||!a)return"";for(var c=0,d,f=0;;){d=C[a+f>>0];c|=d;if(0==d&&!b)break;f++;if(b&&f==b)break}b||(b=f);d="";if(128>c){for(;0d?c+=String.fromCharCode(d):(d-= +65536,c+=String.fromCharCode(55296|d>>10,56320|d&1023))}}else c+=String.fromCharCode(d)}} +function qa(a,b,c,d){if(!(0=h&&(h=65536+((h&1023)<<10)|a.charCodeAt(++g)&1023);if(127>=h){if(c>=d)break;b[c++]=h}else{if(2047>=h){if(c+1>=d)break;b[c++]=192|h>>6}else{if(65535>=h){if(c+2>=d)break;b[c++]=224|h>>12}else{if(2097151>=h){if(c+3>=d)break;b[c++]=240|h>>18}else{if(67108863>=h){if(c+4>=d)break;b[c++]=248|h>>24}else{if(c+5>=d)break;b[c++]=252|h>>30;b[c++]=128|h>>24&63}b[c++]=128|h>>18&63}b[c++]=128| +h>>12&63}b[c++]=128|h>>6&63}b[c++]=128|h&63}}b[c]=0;return c-f}function ya(a){for(var b=0,c=0;c=d&&(d=65536+((d&1023)<<10)|a.charCodeAt(++c)&1023);127>=d?++b:b=2047>=d?b+2:65535>=d?b+3:2097151>=d?b+4:67108863>=d?b+5:b+6}return b}"undefined"!==typeof TextDecoder&&new TextDecoder("utf-16le");var buffer,B,C,za,x,Aa,u,ia,Ba,Ca,Da,Ea,w;Aa=u=Ba=Ca=Da=Ea=w=0;ia=!1; +function ka(){A("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+z+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}var Fa=e.TOTAL_STACK||5242880,z=e.TOTAL_MEMORY||100663296; +z>2]=a);return a}function Wa(a,b){if(0===a)a=Date.now();else if(1===a&&Ua())a=F();else return Va(G.h),-1;x[b>>2]=a/1E3|0;x[b+4>>2]=a%1E3*1E6|0;return 0} +var Xa={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system", +24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed", +44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network", +65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted", +82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available", +100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle", +122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};function Ya(a,b){for(var c=0,d=a.length-1;0<=d;d--){var f=a[d];"."===f?a.splice(d,1):".."===f?(a.splice(d,1),c++):c&&(a.splice(d,1),c--)}if(b)for(;c;c--)a.unshift("..");return a}function Za(a){var b="/"===a.charAt(0),c="/"===a.substr(-1);(a=Ya(a.split("/").filter(function(a){return!!a}),!b).join("/"))||b||(a=".");a&&c&&(a+="/");return(b?"/":"")+a} +function $a(a){var b=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(a).slice(1);a=b[0];b=b[1];if(!a&&!b)return".";b&&(b=b.substr(0,b.length-1));return a+b}function ab(a){if("/"===a)return"/";var b=a.lastIndexOf("/");return-1===b?a:a.substr(b+1)}function bb(){var a=Array.prototype.slice.call(arguments,0);return Za(a.join("/"))}function H(a,b){return Za(a+"/"+b)} +function cb(){for(var a="",b=!1,c=arguments.length-1;-1<=c&&!b;c--){b=0<=c?arguments[c]:"/";if("string"!==typeof b)throw new TypeError("Arguments to path.resolve must be strings");if(!b)return"";a=b+"/"+a;b="/"===b.charAt(0)}a=Ya(a.split("/").filter(function(a){return!!a}),!b).join("/");return(b?"/":"")+a||"."}var db=[];function eb(a,b){db[a]={input:[],output:[],H:b};fb(a,gb)} +var gb={open:function(a){var b=db[a.node.rdev];if(!b)throw new I(G.X);a.tty=b;a.seekable=!1},close:function(a){a.tty.H.flush(a.tty)},flush:function(a){a.tty.H.flush(a.tty)},read:function(a,b,c,d){if(!a.tty||!a.tty.H.qa)throw new I(G.ha);for(var f=0,g=0;ga.b.length&&(a.b=J.Ea(a),a.g=a.b.length);if(!a.b||a.b.subarray){var c=a.b?a.b.length:0;c>=b||(b=Math.max(b,c*(1048576>c?2:1.125)|0),0!=c&&(b=Math.max(b,256)),c=a.b,a.b=new Uint8Array(b),0b)a.b.length=b;else for(;a.b.length=a.node.g)return 0;a=Math.min(a.node.g-f,d);assert(0<=a);if(8b)throw new I(G.h);return b},ia:function(a,b,c){J.ma(a.node,b+c);a.node.g=Math.max(a.node.g, +b+c)},ta:function(a,b,c,d,f,g,h){if(32768!==(a.node.mode&61440))throw new I(G.X);c=a.node.b;if(h&2||c.buffer!==b&&c.buffer!==b.buffer){if(0>2)}catch(c){if(!c.code)throw c; +throw new I(G[c.code]);}return b.mode},l:function(a){for(var b=[];a.parent!==a;)b.push(a.name),a=a.parent;b.push(a.j.aa.root);b.reverse();return bb.apply(null,b)},Da:function(a){a&=-2656257;var b=0,c;for(c in N.na)a&c&&(b|=N.na[c],a^=c);if(a)throw new I(G.h);return b},c:{o:function(a){a=N.l(a);try{var b=fs.lstatSync(a)}catch(c){if(!c.code)throw c;throw new I(G[c.code]);}N.T&&!b.C&&(b.C=4096);N.T&&!b.blocks&&(b.blocks=(b.size+b.C-1)/b.C|0);return{dev:b.dev,ino:b.ino,mode:b.mode,nlink:b.nlink,uid:b.uid, +gid:b.gid,rdev:b.rdev,size:b.size,atime:b.atime,mtime:b.mtime,ctime:b.ctime,C:b.C,blocks:b.blocks}},i:function(a,b){var c=N.l(a);try{void 0!==b.mode&&(fs.chmodSync(c,b.mode),a.mode=b.mode),void 0!==b.size&&fs.truncateSync(c,b.size)}catch(d){if(!d.code)throw d;throw new I(G[d.code]);}},lookup:function(a,b){var c=H(N.l(a),b);c=N.pa(c);return N.createNode(a,b,c)},K:function(a,b,c,d){a=N.createNode(a,b,c,d);b=N.l(a);try{K(a.mode)?fs.mkdirSync(b,a.mode):fs.writeFileSync(b,"",{mode:a.mode})}catch(f){if(!f.code)throw f; +throw new I(G[f.code]);}return a},rename:function(a,b,c){a=N.l(a);b=H(N.l(b),c);try{fs.renameSync(a,b)}catch(d){if(!d.code)throw d;throw new I(G[d.code]);}},unlink:function(a,b){a=H(N.l(a),b);try{fs.unlinkSync(a)}catch(c){if(!c.code)throw c;throw new I(G[c.code]);}},rmdir:function(a,b){a=H(N.l(a),b);try{fs.rmdirSync(a)}catch(c){if(!c.code)throw c;throw new I(G[c.code]);}},readdir:function(a){a=N.l(a);try{return fs.readdirSync(a)}catch(b){if(!b.code)throw b;throw new I(G[b.code]);}},symlink:function(a, +b,c){a=H(N.l(a),b);try{fs.symlinkSync(c,a)}catch(d){if(!d.code)throw d;throw new I(G[d.code]);}},readlink:function(a){var b=N.l(a);try{return b=fs.readlinkSync(b),b=qb.relative(qb.resolve(a.j.aa.root),b)}catch(c){if(!c.code)throw c;throw new I(G[c.code]);}}},f:{open:function(a){var b=N.l(a.node);try{32768===(a.node.mode&61440)&&(a.M=fs.openSync(b,N.Da(a.flags)))}catch(c){if(!c.code)throw c;throw new I(G[c.code]);}},close:function(a){try{32768===(a.node.mode&61440)&&a.M&&fs.closeSync(a.M)}catch(b){if(!b.code)throw b; +throw new I(G[b.code]);}},read:function(a,b,c,d,f){if(0===d)return 0;try{return fs.readSync(a.M,N.ja(b.buffer),c,d,f)}catch(g){throw new I(G[g.code]);}},write:function(a,b,c,d,f){try{return fs.writeSync(a.M,N.ja(b.buffer),c,d,f)}catch(g){throw new I(G[g.code]);}},v:function(a,b,c){if(1===c)b+=a.position;else if(2===c&&32768===(a.node.mode&61440))try{b+=fs.fstatSync(a.M).size}catch(d){throw new I(G[d.code]);}if(0>b)throw new I(G.h);return b}}};u+=16;u+=16;u+=16; +var rb=null,sb={},O=[],tb=1,P=null,ub=!0,Q={},I=null,pb={}; +function R(a,b){a=cb("/",a);b=b||{};if(!a)return{path:"",node:null};var c={oa:!0,da:0},d;for(d in c)void 0===b[d]&&(b[d]=c[d]);if(8>>0)%P.length}function xb(a){var b=wb(a.parent.id,a.name);a.G=P[b];P[b]=a}function M(a,b){var c;if(c=(c=yb(a,"x"))?c:a.c.lookup?0:G.U)throw new I(c,a);for(c=P[wb(a.id,b)];c;c=c.G){var d=c.name;if(c.parent.id===a.id&&d===b)return c}return a.c.lookup(a,b)} +function ob(a,b,c,d){zb||(zb=function(a,b,c,d){a||(a=this);this.parent=a;this.j=a.j;this.L=null;this.id=tb++;this.name=b;this.mode=c;this.c={};this.f={};this.rdev=d},zb.prototype={},Object.defineProperties(zb.prototype,{read:{get:function(){return 365===(this.mode&365)},set:function(a){a?this.mode|=365:this.mode&=-366}},write:{get:function(){return 146===(this.mode&146)},set:function(a){a?this.mode|=146:this.mode&=-147}},Ha:{get:function(){return K(this.mode)}},Ga:{get:function(){return 8192===(this.mode& +61440)}}}));a=new zb(a,b,c,d);xb(a);return a}function K(a){return 16384===(a&61440)}var Ab={r:0,rs:1052672,"r+":2,w:577,wx:705,xw:705,"w+":578,"wx+":706,"xw+":706,a:1089,ax:1217,xa:1217,"a+":1090,"ax+":1218,"xa+":1218};function Bb(a){var b=["r","w","rw"][a&3];a&512&&(b+="w");return b}function yb(a,b){if(ub)return 0;if(-1===b.indexOf("r")||a.mode&292){if(-1!==b.indexOf("w")&&!(a.mode&146)||-1!==b.indexOf("x")&&!(a.mode&73))return G.U}else return G.U;return 0} +function Cb(a,b){try{return M(a,b),G.fa}catch(c){}return yb(a,"wx")}function Db(a){var b=4096;for(a=a||0;a<=b;a++)if(!O[a])return a;throw new I(G.wa);}function Eb(a,b){Fb||(Fb=function(){},Fb.prototype={},Object.defineProperties(Fb.prototype,{object:{get:function(){return this.node},set:function(a){this.node=a}}}));var c=new Fb,d;for(d in a)c[d]=a[d];a=c;b=Db(b);a.fd=b;return O[b]=a}var nb={open:function(a){a.f=sb[a.node.rdev].f;a.f.open&&a.f.open(a)},v:function(){throw new I(G.P);}}; +function fb(a,b){sb[a]={f:b}}function Gb(a,b){var c="/"===b,d=!b;if(c&&rb)throw new I(G.V);if(!c&&!d){var f=R(b,{oa:!1});b=f.path;f=f.node;if(f.L)throw new I(G.V);if(!K(f.mode))throw new I(G.O);}b={type:a,aa:{},ua:b,Ia:[]};a=a.j(b);a.j=b;b.root=a;c?rb=a:f&&(f.L=b,f.j&&f.j.Ia.push(b))}function Hb(a,b,c){var d=R(a,{parent:!0}).node;a=ab(a);if(!a||"."===a||".."===a)throw new I(G.h);var f=Cb(d,a);if(f)throw new I(f);if(!d.c.K)throw new I(G.B);return d.c.K(d,a,b,c)} +function T(a,b){return Hb(a,(void 0!==b?b:511)&1023|16384,0)}function Ib(a,b,c){"undefined"===typeof c&&(c=b,b=438);return Hb(a,b|8192,c)}function Jb(a,b){if(!cb(a))throw new I(G.u);var c=R(b,{parent:!0}).node;if(!c)throw new I(G.u);b=ab(b);var d=Cb(c,b);if(d)throw new I(d);if(!c.c.symlink)throw new I(G.B);return c.c.symlink(c,b,a)} +function Kb(a){var b=R(a,{parent:!0}).node,c=ab(a),d=M(b,c);a:{try{var f=M(b,c)}catch(h){f=h.m;break a}var g=yb(b,"wx");f=g?g:K(f.mode)?G.I:0}if(f)throw new I(f);if(!b.c.unlink)throw new I(G.B);if(d.L)throw new I(G.V);try{Q.willDeletePath&&Q.willDeletePath(a)}catch(h){console.log("FS.trackingDelegate['willDeletePath']('"+a+"') threw an exception: "+h.message)}b.c.unlink(b,c);b=wb(d.parent.id,d.name);if(P[b]===d)P[b]=d.G;else for(b=P[b];b;){if(b.G===d){b.G=d.G;break}b=b.G}try{if(Q.onDeletePath)Q.onDeletePath(a)}catch(h){console.log("FS.trackingDelegate['onDeletePath']('"+ +a+"') threw an exception: "+h.message)}}function vb(a){a=R(a).node;if(!a)throw new I(G.u);if(!a.c.readlink)throw new I(G.h);return cb(S(a.parent),a.c.readlink(a))}function Lb(a,b){var c;"string"===typeof a?c=R(a,{J:!0}).node:c=a;if(!c.c.i)throw new I(G.B);c.c.i(c,{mode:b&4095|c.mode&-4096,timestamp:Date.now()})} +function Mb(a,b,c,d){if(""===a)throw new I(G.u);if("string"===typeof b){var f=Ab[b];if("undefined"===typeof f)throw Error("Unknown file open mode: "+b);b=f}c=b&64?("undefined"===typeof c?438:c)&4095|32768:0;if("object"===typeof a)var g=a;else{a=Za(a);try{g=R(a,{J:!(b&131072)}).node}catch(n){}}f=!1;if(b&64)if(g){if(b&128)throw new I(G.fa);}else g=Hb(a,c,0),f=!0;if(!g)throw new I(G.u);8192===(g.mode&61440)&&(b&=-513);if(b&65536&&!K(g.mode))throw new I(G.O);if(!f&&(c=g?40960===(g.mode&61440)?G.W:K(g.mode)&& +("r"!==Bb(b)||b&512)?G.I:yb(g,Bb(b)):G.u))throw new I(c);if(b&512){c=g;var h;"string"===typeof c?h=R(c,{J:!0}).node:h=c;if(!h.c.i)throw new I(G.B);if(K(h.mode))throw new I(G.I);if(32768!==(h.mode&61440))throw new I(G.h);if(c=yb(h,"w"))throw new I(c);h.c.i(h,{size:0,timestamp:Date.now()})}b&=-641;d=Eb({node:g,path:S(g),flags:b,seekable:!0,position:0,f:g.f,Na:[],error:!1},d);d.f.open&&d.f.open(d);!e.logReadFiles||b&1||(Nb||(Nb={}),a in Nb||(Nb[a]=1,e.printErr("read file: "+a)));try{Q.onOpenFile&&(g= +0,1!==(b&2097155)&&(g|=1),0!==(b&2097155)&&(g|=2),Q.onOpenFile(a,g))}catch(n){console.log("FS.trackingDelegate['onOpenFile']('"+a+"', flags) threw an exception: "+n.message)}return d}function Ob(a){a.D&&(a.D=null);try{a.f.close&&a.f.close(a)}catch(b){throw b;}finally{O[a.fd]=null}}function Pb(a,b,c){if(!a.seekable||!a.f.v)throw new I(G.P);a.position=a.f.v(a,b,c);a.Na=[];return a.position} +function Qb(a,b,c,d,f,g){if(0>d||0>f)throw new I(G.h);if(0===(a.flags&2097155))throw new I(G.N);if(K(a.node.mode))throw new I(G.I);if(!a.f.write)throw new I(G.h);a.flags&1024&&(f=Pb(a,0,2));var h=!0;if("undefined"===typeof f)f=a.position,h=!1;else if(!a.seekable)throw new I(G.P);b=a.f.write(a,b,c,d,f,g);h||(a.position+=b);try{if(a.path&&Q.onWriteToFile)Q.onWriteToFile(a.path)}catch(n){console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: "+n.message)}return b} +function Rb(){I||(I=function(a,b){this.node=b;this.La=function(a){this.m=a;for(var b in G)if(G[b]===a){this.code=b;break}};this.La(a);this.message=Xa[a];this.stack&&Object.defineProperty(this,"stack",{value:Error().stack,writable:!0})},I.prototype=Error(),I.prototype.constructor=I,[G.u].forEach(function(a){pb[a]=new I(a);pb[a].stack=""}))}var Sb;function Tb(a,b){var c=0;a&&(c|=365);b&&(c|=146);return c} +function Ub(a,b,c,d){a=H("string"===typeof a?a:S(a),b);return T(a,Tb(c,d))}function Vb(a,b){a="string"===typeof a?a:S(a);for(b=b.split("/").reverse();b.length;){var c=b.pop();if(c){var d=H(a,c);try{T(d)}catch(f){}a=d}}return d}function Wb(a,b,c,d){a=H("string"===typeof a?a:S(a),b);c=Tb(c,d);return Hb(a,(void 0!==c?c:438)&4095|32768,0)} +function Xb(a,b,c,d,f,g){a=b?H("string"===typeof a?a:S(a),b):a;d=Tb(d,f);f=Hb(a,(void 0!==d?d:438)&4095|32768,0);if(c){if("string"===typeof c){a=Array(c.length);b=0;for(var h=c.length;bthis.length-1||0>a)){var b=a%this.chunkSize;return this.ra(a/this.chunkSize|0)[b]}};g.prototype.Ka=function(a){this.ra=a};g.prototype.ka=function(){var a=new XMLHttpRequest;a.open("HEAD",c,!1);a.send(null);if(!(200<=a.status&&300>a.status||304===a.status))throw Error("Couldn't load "+c+". Status: "+a.status);var b=Number(a.getResponseHeader("Content-length")),d,f=(d=a.getResponseHeader("Accept-Ranges"))&&"bytes"=== +d;a=(d=a.getResponseHeader("Content-Encoding"))&&"gzip"===d;var g=1048576;f||(g=b);var h=this;h.Ka(function(a){var d=a*g,f=(a+1)*g-1;f=Math.min(f,b-1);if("undefined"===typeof h.S[a]){var n=h.S;if(d>f)throw Error("invalid range ("+d+", "+f+") or no bytes requested!");if(f>b-1)throw Error("only "+b+" bytes available! programmer error!");var r=new XMLHttpRequest;r.open("GET",c,!1);b!==g&&r.setRequestHeader("Range","bytes="+d+"-"+f);"undefined"!=typeof Uint8Array&&(r.responseType="arraybuffer");r.overrideMimeType&& +r.overrideMimeType("text/plain; charset=x-user-defined");r.send(null);if(!(200<=r.status&&300>r.status||304===r.status))throw Error("Couldn't load "+c+". Status: "+r.status);d=void 0!==r.response?new Uint8Array(r.response||[]):kb(r.responseText||"",!0);n[a]=d}if("undefined"===typeof h.S[a])throw Error("doXHR failed!");return h.S[a]});if(a||!b)g=b=1,g=b=this.ra(0).length,console.log("LazyFiles on gzip forces download of the whole file when length is accessed");this.Aa=b;this.za=g;this.$=!0};if("undefined"!== +typeof XMLHttpRequest){if(!m)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var h=new g;Object.defineProperties(h,{length:{get:function(){this.$||this.ka();return this.Aa}},chunkSize:{get:function(){this.$||this.ka();return this.za}}});var n=void 0}else n=c,h=void 0;var v=Wb(a,b,d,f);h?v.b=h:n&&(v.b=null,v.url=n);Object.defineProperties(v,{g:{get:function(){return this.b.length}}});var y={};Object.keys(v.f).forEach(function(a){var b= +v.f[a];y[a]=function(){if(!Zb(v))throw new I(G.A);return b.apply(null,arguments)}});y.read=function(a,b,c,d,f){if(!Zb(v))throw new I(G.A);a=a.node.b;if(f>=a.length)return 0;d=Math.min(a.length-f,d);assert(0<=d);if(a.slice)for(var g=0;g>2]}function X(){var a=O[W()];if(!a)throw new I(G.N);return a} +var bc=ta([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2, +0,1,0,3,0,1,0,2,0,1,0],2),cc=u;u+=16; +function dc(a){if(dc.Z){var b=x[cc>>2];var c=x[b>>2]}else dc.Z=!0,Y.USER=Y.LOGNAME="web_user",Y.PATH="/",Y.PWD="/",Y.HOME="/home/web_user",Y.LANG="C.UTF-8",Y._=e.thisProgram,c=t(1024),b=t(256),x[b>>2]=c,x[cc>>2]=b;var d=[],f=0;for(h in a)if("string"===typeof a[h]){var g=h+"="+a[h];d.push(g);f+=g.length}if(1024>0]=f.charCodeAt(n);B[h>>0]=0;x[b+4*a>>2]=c;c+=g.length+ +1}x[b+4*d.length>>2]=0}var Y={};function ec(a){if(0===a)return 0;a=va(a);if(!Y.hasOwnProperty(a))return 0;ec.R&&fc(ec.R);a=Y[a];var b=ya(a)+1,c=ua(b);c&&qa(a,B,c,b);ec.R=c;return ec.R}function hc(a){return Math.pow(2,a)}ta(kb("GMT"),2);var ic=u,jc=u+=16,kc=u+=16;u+=16; +function lc(){function a(a){return(a=a.toTimeString().match(/\(([A-Za-z ]+)\)$/))?a[1]:"GMT"}if(!lc.Z){lc.Z=!0;x[kc>>2]=60*(new Date).getTimezoneOffset();var b=new Date(2E3,0,1),c=new Date(2E3,6,1);x[jc>>2]=Number(b.getTimezoneOffset()!=c.getTimezoneOffset());var d=a(b),f=a(c);d=ta(kb(d),0);f=ta(kb(f),0);c.getTimezoneOffset()>2]=d,x[ic+4>>2]=f):(x[ic>>2]=f,x[ic+4>>2]=d)}} +p?F=function(){var a=process.hrtime();return 1E3*a[0]+a[1]/1E6}:"undefined"!==typeof dateNow?F=dateNow:"object"===typeof self&&self.performance&&"function"===typeof self.performance.now?F=function(){return self.performance.now()}:"object"===typeof performance&&"function"===typeof performance.now?F=function(){return performance.now()}:F=Date.now;Rb();P=Array(4096);Gb(J,"/");T("/tmp");T("/home");T("/home/web_user"); +(function(){T("/dev");fb(259,{read:function(){return 0},write:function(a,b,f,g){return g}});Ib("/dev/null",259);eb(1280,lb);eb(1536,mb);Ib("/dev/tty",1280);Ib("/dev/tty1",1536);if("undefined"!==typeof crypto){var a=new Uint8Array(1);var b=function(){crypto.getRandomValues(a);return a[0]}}else b=p?function(){return require("crypto").randomBytes(1)[0]}:function(){return 256*Math.random()|0};U("/dev","random",b);U("/dev","urandom",b);T("/dev/shm");T("/dev/shm/tmp")})();T("/proc");T("/proc/self");T("/proc/self/fd"); +Gb({j:function(){var a=ob("/proc/self","fd",16895,73);a.c={lookup:function(a,c){var b=O[+c];if(!b)throw new I(G.N);a={parent:null,j:{ua:"fake"},c:{readlink:function(){return b.path}}};return a.parent=a}};return a}},"/proc/self/fd"); +Ia.unshift(function(){if(!e.noFSInit&&!Sb){assert(!Sb,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");Sb=!0;Rb();e.stdin=e.stdin;e.stdout=e.stdout;e.stderr=e.stderr;e.stdin?U("/dev","stdin",e.stdin):Jb("/dev/tty","/dev/stdin");e.stdout?U("/dev","stdout",null,e.stdout):Jb("/dev/tty","/dev/stdout");e.stderr?U("/dev","stderr",null,e.stderr):Jb("/dev/tty1","/dev/stderr");var a= +Mb("/dev/stdin","r");assert(0===a.fd,"invalid handle for stdin ("+a.fd+")");a=Mb("/dev/stdout","w");assert(1===a.fd,"invalid handle for stdout ("+a.fd+")");a=Mb("/dev/stderr","w");assert(2===a.fd,"invalid handle for stderr ("+a.fd+")")}});Ja.push(function(){ub=!1});Ka.push(function(){Sb=!1;var a=e._fflush;a&&a(0);for(a=0;a>2]=Ea;ia=!0;var mc=!1;function kb(a,b){var c=Array(ya(a)+1);a=qa(a,c,0,c.length);b&&(c.length=a);return c} +function ha(a){for(var b=[],c=0;c>4; +f=(f&15)<<4|g>>2;var n=(g&3)<<6|h;b+=String.fromCharCode(d);64!==g&&(b+=String.fromCharCode(f));64!==h&&(b+=String.fromCharCode(n))}while(c>2]=c.position;c.D&&0===d&&0===g&&(c.D=null);return 0}catch(h){return"undefined"!==typeof FS&&h instanceof I||A(h),-h.m}},___syscall145:function(a,b){V=b;try{var c=X(),d=W();a:{var f=W();for(b=a=0;b>2],h=c,n=x[d+ +8*b>>2],v=g,y=void 0,r=B;if(0>v||0>y)throw new I(G.h);if(1===(h.flags&2097155))throw new I(G.N);if(K(h.node.mode))throw new I(G.I);if(!h.f.read)throw new I(G.h);var L=!0;if("undefined"===typeof y)y=h.position,L=!1;else if(!h.seekable)throw new I(G.P);var hb=h.f.read(h,r,n,v,y);L||(h.position+=hb);var ib=hb;if(0>ib){var da=-1;break a}a+=ib;if(ib>2],x[d+(8*b+4)>>2],void 0);if(0>g){var h=-1;break a}a+=g}h=a}return h}catch(n){return"undefined"!==typeof FS&&n instanceof I||A(n),-n.m}},___syscall195:function(a,b){V=b;try{var c=va(W());a:{var d=W();try{var f=R(c,{J:!0}).node;if(!f)throw new I(G.u);if(!f.c.o)throw new I(G.B);var g=f.c.o(f)}catch(n){if(n&&n.node&&Za(c)!==Za(S(n.node))){var h=-G.O;break a}throw n;}x[d>>2]=g.dev;x[d+4>>2]=0;x[d+8>>2]=g.ino;x[d+12>>2]=g.mode;x[d+16>>2]=g.nlink;x[d+20>>2]= +g.uid;x[d+24>>2]=g.gid;x[d+28>>2]=g.rdev;x[d+32>>2]=0;x[d+36>>2]=g.size;x[d+40>>2]=4096;x[d+44>>2]=g.blocks;x[d+48>>2]=g.atime.getTime()/1E3|0;x[d+52>>2]=0;x[d+56>>2]=g.mtime.getTime()/1E3|0;x[d+60>>2]=0;x[d+64>>2]=g.ctime.getTime()/1E3|0;x[d+68>>2]=0;x[d+72>>2]=g.ino;h=0}return h}catch(n){return"undefined"!==typeof FS&&n instanceof I||A(n),-n.m}},___syscall220:function(a,b){V=b;try{var c=X(),d=W(),f=W();if(!c.D){var g=R(c.path,{J:!0}).node;if(!g.c.readdir)throw new I(G.O);var h=g.c.readdir(g);c.D= +h}for(a=0;0>2]=v;x[d+a+4>>2]=c.position;za[d+a+8>>1]=268;B[d+a+10>>0]=y;qa(n,C,d+a+11,256);a+=268}return a}catch(L){return"undefined"!==typeof FS&&L instanceof I||A(L),-L.m}},___syscall221:function(a,b){V=b;try{var c=X();switch(W()){case 0:var d=W();return 0>d?-G.h:Mb(c.path,c.flags,0,d).fd;case 1:case 2:return 0;case 3:return c.flags; +case 4:return d=W(),c.flags|=d,0;case 12:case 12:return d=W(),za[d+0>>1]=2,0;case 13:case 14:case 13:case 14:return 0;case 16:case 8:return-G.h;case 9:return Va(G.h),-1;default:return-G.h}}catch(f){return"undefined"!==typeof FS&&f instanceof I||A(f),-f.m}},___syscall5:function(a,b){V=b;try{var c=va(W()),d=W(),f=W();return Mb(c,d,f).fd}catch(g){return"undefined"!==typeof FS&&g instanceof I||A(g),-g.m}},___syscall54:function(a,b){V=b;try{var c=X(),d=W();switch(d){case 21509:case 21505:return c.tty? +0:-G.F;case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:return c.tty?0:-G.F;case 21519:if(!c.tty)return-G.F;var f=W();return x[f>>2]=0;case 21520:return c.tty?-G.h:-G.F;case 21531:a=f=W();if(!c.f.Fa)throw new I(G.F);return c.f.Fa(c,d,a);case 21523:return c.tty?0:-G.F;default:A("bad ioctl syscall "+d)}}catch(g){return"undefined"!==typeof FS&&g instanceof I||A(g),-g.m}},___syscall6:function(a,b){V=b;try{var c=X();Ob(c);return 0}catch(d){return"undefined"!==typeof FS&&d instanceof I|| +A(d),-d.m}},___unlock:function(){},_clock_gettime:Wa,_emscripten_get_now:F,_emscripten_get_now_is_monotonic:Ua,_emscripten_memcpy_big:function(a,b,c){C.set(C.subarray(b,b+c),a);return a},_getenv:ec,_llvm_exp2_f32:hc,_llvm_exp2_f64:function(){return hc.apply(null,arguments)},_localtime_r:function(a,b){lc();a=new Date(1E3*x[a>>2]);x[b>>2]=a.getSeconds();x[b+4>>2]=a.getMinutes();x[b+8>>2]=a.getHours();x[b+12>>2]=a.getDate();x[b+16>>2]=a.getMonth();x[b+20>>2]=a.getFullYear()-1900;x[b+24>>2]=a.getDay(); +var c=new Date(a.getFullYear(),0,1);x[b+28>>2]=(a.getTime()-c.getTime())/864E5|0;x[b+36>>2]=-(60*a.getTimezoneOffset());var d=(new Date(2E3,6,1)).getTimezoneOffset();c=c.getTimezoneOffset();a=(d!=c&&a.getTimezoneOffset()==Math.min(c,d))|0;x[b+32>>2]=a;x[b+40>>2]=x[ic+(a?4:0)>>2];return b},_tzset:lc,DYNAMICTOP_PTR:w,tempDoublePtr:Ta,ABORT:ma,STACKTOP:Ca,STACK_MAX:Da,cttz_i8:bc};// EMSCRIPTEN_START_ASM var Z=(/** @suppress {uselessCode} */ function(global,env,buffer) { -"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.DYNAMICTOP_PTR|0;var j=env.tempDoublePtr|0;var k=env.ABORT|0;var l=env.STACKTOP|0;var m=env.STACK_MAX|0;var n=env.cttz_i8|0;var o=0;var p=0;var q=0;var r=0;var s=global.NaN,t=global.Infinity;var u=0,v=0,w=0,x=0,y=0.0;var z=0;var A=global.Math.floor;var B=global.Math.abs;var C=global.Math.sqrt;var D=global.Math.pow;var E=global.Math.cos;var F=global.Math.sin;var G=global.Math.tan;var H=global.Math.acos;var I=global.Math.asin;var J=global.Math.atan;var K=global.Math.atan2;var L=global.Math.exp;var M=global.Math.log;var N=global.Math.ceil;var O=global.Math.imul;var P=global.Math.min;var Q=global.Math.max;var R=global.Math.clz32;var S=env.abort;var T=env.assert;var U=env.enlargeMemory;var V=env.getTotalMemory;var W=env.abortOnCannotGrowMemory;var X=env.invoke_ii;var Y=env.invoke_iii;var Z=env.invoke_iiii;var _=env.invoke_iiiii;var $=env.invoke_vii;var aa=env.invoke_viii;var ba=env.invoke_viiii;var ca=env.invoke_viiiiii;var da=env.___assert_fail;var ea=env.___buildEnvironment;var fa=env.___clock_gettime;var ga=env.___lock;var ha=env.___setErrNo;var ia=env.___syscall10;var ja=env.___syscall140;var ka=env.___syscall145;var la=env.___syscall146;var ma=env.___syscall195;var na=env.___syscall197;var oa=env.___syscall220;var pa=env.___syscall221;var qa=env.___syscall41;var ra=env.___syscall5;var sa=env.___syscall54;var ta=env.___syscall6;var ua=env.___unlock;var va=env._clock_gettime;var wa=env._emscripten_get_now;var xa=env._emscripten_get_now_is_monotonic;var ya=env._emscripten_memcpy_big;var za=env._getenv;var Aa=env._llvm_exp2_f32;var Ba=env._llvm_exp2_f64;var Ca=env._llvm_pow_f64;var Da=env._localtime_r;var Ea=env._tzset;var Fa=env.flush_NO_FILESYSTEM;var Ga=0.0; +"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.DYNAMICTOP_PTR|0;var j=env.tempDoublePtr|0;var k=env.ABORT|0;var l=env.STACKTOP|0;var m=env.STACK_MAX|0;var n=env.cttz_i8|0;var o=0;var p=0;var q=0;var r=0;var s=global.NaN,t=global.Infinity;var u=0,v=0,w=0,x=0,y=0.0;var z=0;var A=global.Math.floor;var B=global.Math.abs;var C=global.Math.sqrt;var D=global.Math.pow;var E=global.Math.cos;var F=global.Math.sin;var G=global.Math.tan;var H=global.Math.acos;var I=global.Math.asin;var J=global.Math.atan;var K=global.Math.atan2;var L=global.Math.exp;var M=global.Math.log;var N=global.Math.ceil;var O=global.Math.imul;var P=global.Math.min;var Q=global.Math.max;var R=global.Math.clz32;var S=env.abort;var T=env.assert;var U=env.enlargeMemory;var V=env.getTotalMemory;var W=env.abortOnCannotGrowMemory;var X=env.invoke_ii;var Y=env.invoke_iii;var Z=env.invoke_iiii;var _=env.invoke_iiiii;var $=env.invoke_vii;var aa=env.invoke_viiiiiiiii;var ba=env.___buildEnvironment;var ca=env.___clock_gettime;var da=env.___lock;var ea=env.___setErrNo;var fa=env.___syscall10;var ga=env.___syscall140;var ha=env.___syscall145;var ia=env.___syscall146;var ja=env.___syscall195;var ka=env.___syscall220;var la=env.___syscall221;var ma=env.___syscall5;var na=env.___syscall54;var oa=env.___syscall6;var pa=env.___unlock;var qa=env._clock_gettime;var ra=env._emscripten_get_now;var sa=env._emscripten_get_now_is_monotonic;var ta=env._emscripten_memcpy_big;var ua=env._getenv;var va=env._llvm_exp2_f32;var wa=env._llvm_exp2_f64;var xa=env._localtime_r;var ya=env._tzset;var za=0.0; // EMSCRIPTEN_START_FUNCS -function ze(f,g,i){f=f|0;g=g|0;i=i|0;var j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0;V=l;l=l+1504|0;y=V+8|0;x=V;k=V+1452|0;S=V+664|0;R=V+656|0;T=V+120|0;P=V+96|0;Q=V+12|0;_l(g,i,0)|0;Zl(k,4,1,g)|0;j=a[k+3>>0]|0;c[k+4>>2]=Xl(g)|0;m=Xl(g)|0;Pl(g)|0;Pl(g)|0;w=Xl(g)|0;Xl(g)|0;I=Xl(g)|0;Xl(g)|0;s=Xl(g)|0;Xl(g)|0;b[k+40>>1]=Pl(g)|0;b[k+42>>1]=Pl(g)|0;b[k+44>>1]=Pl(g)|0;b[k+46>>1]=Pl(g)|0;b[k+48>>1]=Pl(g)|0;a[k+50>>0]=Kl(g)|0;a[k+51>>0]=Kl(g)|0;_l(g,m+i|0,0)|0;m=Pl(g)|0;k=0;do{b[S+(k<<3)>>1]=m;b[S+(k<<3)+2>>1]=Pl(g)|0;a[S+(k<<3)+4>>0]=Kl(g)|0;a[S+(k<<3)+5>>0]=Kl(g)|0;a[S+(k<<3)+6>>0]=Kl(g)|0;a[S+(k<<3)+7>>0]=Il(g)|0;k=k+1|0;m=Pl(g)|0}while((k|0)!=63);u=j<<24>>24;M=u+-48|0;r=S+504|0;b[r>>1]=m;b[S+506>>1]=Pl(g)|0;L=Xl(g)|0;Xl(g)|0;N=Xl(g)|0;b[S+520>>1]=Pl(g)|0;b[S+522>>1]=Pl(g)|0;U=Xl(g)|0;c[S+528>>2]=Xl(g)|0;b[S+532>>1]=Pl(g)|0;b[S+534>>1]=Pl(g)|0;a[S+536>>0]=Kl(g)|0;a[S+537>>0]=Kl(g)|0;b[S+538>>1]=Pl(g)|0;a[S+540>>0]=Kl(g)|0;_l(g,223,1)|0;n=S+764|0;b[n>>1]=Pl(g)|0;H=S+766|0;a[H>>0]=Kl(g)|0;j=S+767|0;a[j>>0]=Kl(g)|0;o=S+768|0;a[o>>0]=Kl(g)|0;p=S+769|0;a[p>>0]=Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;Kl(g)|0;a[S+786>>0]=Kl(g)|0;q=S+787|0;a[q>>0]=Kl(g)|0;_l(g,L+i|0,0)|0;_l(g,(Xl(g)|0)+i|0,0)|0;_l(g,32,1)|0;Xl(g)|0;Xl(g)|0;L=Pl(g)|0;m=f+156|0;c[m>>2]=L&65535;if(L<<16>>16){k=0;do{a[f+952+k>>0]=Pl(g)|0;k=k+1|0}while((k|0)<(c[m>>2]|0))}c[f+1264>>2]=8363;G=d[j>>0]|0;F=f+1280|0;c[F>>2]=(G&32|0?0:192)|c[F>>2];G=G&64;F=d[o>>0]|0;h[f+1256>>3]=2.64;ue(f,G,e[n>>1]|0,F&32,(F&31)+1|0);c[f+148>>2]=d[p>>0];F=f+128|0;c[F>>2]=e[r>>1];J=a[q>>0]|0;K=f+140|0;c[K>>2]=J&255;c[f+160>>2]=0;L=f+136|0;c[L>>2]=0;a[f>>0]=0;n=f+144|0;c[n>>2]=0;if(J<<24>>24){k=I+i|0;m=0;do{_l(g,k+(m<<2)|0,0)|0;j=Xl(g)|0;if(j|0){_l(g,j+i|0,0)|0;Xl(g)|0;if((Pl(g)|0)<<16>>16==-1){_l(g,14,1)|0;j=(Pl(g)|0)&65535}else j=1;c[n>>2]=(c[n>>2]|0)+j}m=m+1|0}while((m|0)<(c[K>>2]|0))}j=Q+8|0;b[j>>1]=0;k=Q+10|0;b[k>>1]=0;m=Q+24|0;b[m>>1]=0;p=Q+26|0;b[p>>1]=0;J=(s|0)!=0;if(J){_l(g,s+i|0,0)|0;Xl(g)|0;t=Xl(g)|0;q=Pl(g)|0;b[j>>1]=q;r=Pl(g)|0;b[k>>1]=r;Xl(g)|0;Xl(g)|0;s=Xl(g)|0;n=Pl(g)|0;b[m>>1]=n;o=Pl(g)|0;b[p>>1]=o;Xl(g)|0;Xl(g)|0;Xl(g)|0;Xl(g)|0;E=Xl(g)|0;j=Xl(g)|0;c[Q+48>>2]=j;Xl(g)|0;k=Xl(g)|0;_l(g,E+i|0,0)|0;if(j|0){m=0;do{a[f+m>>0]=Kl(g)|0;E=m;m=m+1|0}while(!((E|0)>62|m>>>0>=j>>>0))}if(k){_l(g,k+i|0,0)|0;ve(g,f)}}else{n=0;o=0;q=0;r=0;t=0;s=0}j=c[F>>2]|0;if((j|0)>0){k=w+i|0;m=0;do{_l(g,k+(m<<2)|0,0)|0;j=Xl(g)|0;if(j|0?(_l(g,j+i|0,0)|0,v=Pl(g)|0,Pl(g)|0,v=v&65535,(v|0)>(c[L>>2]|0)):0)c[L>>2]=v;m=m+1|0;j=c[F>>2]|0}while((m|0)<(j|0))}c[f+132>>2]=O(c[L>>2]|0,j)|0;j=(M|0)==2;if(j)Eb(f,20530,x);else{c[y>>2]=u;Eb(f,20546,y)}if((pb(f)|0)<0){f=-1;l=V;return f|0}a:do if((c[F>>2]|0)>0){C=w+i|0;D=f+168|0;E=f+172|0;B=j?12:244;A=0;while(1){_l(g,C+(A<<2)|0,0)|0;j=Xl(g)|0;if(j|0){_l(g,j+i|0,0)|0;j=Pl(g)|0;z=Pl(g)|0;Xl(g)|0;if((tb(f,A,(z&65535)+1|0)|0)<0){j=-1;break}k=c[D>>2]|0;if((c[c[k+(A<<2)>>2]>>2]|0)>0){z=j&65535;y=j<<16>>16==0;x=0;do{if(!y){w=0;do{j=Kl(g)|0;p=Kl(g)|0;u=Kl(g)|0;v=Kl(g)|0;k=c[(c[E>>2]|0)+(c[(c[(c[D>>2]|0)+(A<<2)>>2]|0)+4+(w<<2)>>2]<<2)>>2]|0;m=k+4+(x<<3)|0;j=j&127;a[m>>0]=j;if(!(j<<24>>24))j=0;else{j=(j&255)+B+(d[H>>0]|0)&255;j=(j&255)>120?0:j;a[m>>0]=j}p=p&63;a[k+4+(x<<3)+1>>0]=p;if(p<<24>>24!=0&j<<24>>24==0)a[k+4+(x<<3)+5>>0]=-79;a[k+4+(x<<3)+3>>0]=u;a[k+4+(x<<3)+4>>0]=v;ne(m,G);w=w+1|0}while((w|0)!=(z|0));k=c[D>>2]|0}x=x+1|0}while((x|0)<(c[c[k+(A<<2)>>2]>>2]|0))}}A=A+1|0;if((A|0)>=(c[F>>2]|0))break a}l=V;return j|0}while(0);if(Nj(f)|0){f=-1;l=V;return f|0}if((nb(f)|0)<0){f=-1;l=V;return f|0}b:do if((c[K>>2]|0)>0){u=I+i|0;B=R+4|0;D=f+176|0;x=P+3|0;v=P+1|0;A=P+2|0;w=P+4|0;z=P+5|0;C=T+20|0;y=0;j=0;c:while(1){_l(g,u+(y<<2)|0,0)|0;k=Xl(g)|0;d:do if(k){m=k+i|0;_l(g,m,0)|0;c[R>>2]=Xl(g)|0;p=Pl(g)|0;b[B>>1]=p;k=$l(g)|0;if(J){if((y|0)<(n&65535|0)){I=c[D>>2]|0;_l(g,(O(o&65535,y)|0)+s|0,0)|0;Zl(I+(y*764|0)|0,40,1,g)|0}a[x>>0]=0;if((y|0)<(q&65535|0)?(_l(g,(O(r&65535,y)|0)+t|0,0)|0,a[P>>0]=Kl(g)|0,a[v>>0]=Kl(g)|0,a[A>>0]=Kl(g)|0,a[x>>0]=Kl(g)|0,(r&65535)>4):0){a[w>>0]=Kl(g)|0;a[z>>0]=Kl(g)|0}}else a[x>>0]=0;_l(g,k,0)|0;k=p<<16>>16;switch(p<<16>>16){case -2:{if((qe(g,f,y,j,T,P,S+(y<<3)|0)|0)<0){j=-1;k=74;break c}if(!(pe(f,y,T)|0)){j=j+1|0;break d}else{j=-1;k=74;break c}}case -1:{k=re(g,f,y,j,T,P,S+(y<<3)|0)|0;if((k|0)>0)break d;if((k|0)<0){j=-1;k=74;break c}j=(e[C>>1]|0)+j|0;if(!(pe(f,y,T)|0))break d;else{j=-1;k=74;break c}}default:{if((p+-1&65535)<6){k=c[2308+(k+-1<<2)>>2]|0;_l(g,m+6|0,0)|0;m=te(g,f,y,j,R,k,P,S+(y<<3)|0)|0;k=(m|0)<0?0:k}else{if(!(p<<16>>16==0&(k&-49|0)==0))break d;_l(g,m+6|0,0)|0;m=se(g,f,y,j,R,Q,P,S+(y<<3)|0,M)|0;k=m>>>31^1}if(!(m>>31&-76)){j=k+j|0;break d}else{j=-1;k=74;break c}}}}while(0);y=y+1|0;if((y|0)>=(c[K>>2]|0))break b}if((k|0)==74){l=V;return j|0}}while(0);_l(g,N+i|0,0)|0;j=c[L>>2]|0;if((j|0)>0){k=0;do{c[f+184+(k*12|0)+4>>2]=(Kl(g)|0)&255;k=k+1|0;j=c[L>>2]|0}while((k|0)<(j|0))}if(!U){if((j|0)>0){j=0;do{c[f+184+(j*12|0)>>2]=128;j=j+1|0}while((j|0)<(c[L>>2]|0))}}else{_l(g,U+i|0,0)|0;if((c[L>>2]|0)>0){j=0;do{i=(Il(g)|0)<<24>>24<<3;c[f+184+(j*12|0)>>2]=((i|0)<127?i:127)+128;j=j+1|0}while((j|0)<(c[L>>2]|0))}}c[f+1284>>2]=4;f=0;l=V;return f|0}function Ae(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+16|0;c=d;if(((Zl(c,1,4,a)|0)>>>0>=4?(en(c,20595,4)|0)==0:0)?(Kl(a)|0)<<24>>24==32:0){xb(a,b,32);c=0}else c=-1;l=d;return c|0}function Be(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0;db=l;l=l+608|0;p=db;$a=db+500|0;v=db+368|0;ab=db+12|0;o=db+575|0;i=db+542|0;_l(g,h,0)|0;if((Ce(g,$a,20595)|0)<0){cb=-1;l=db;return cb|0}x=b[$a+38>>1]|0;m=x&65535;Zl(o,1,20,g)|0;a[o+20>>0]=0;Zl(i,1,32,g)|0;a[i+32>>0]=0;t=v+52|0;b[t>>1]=Ml(g)|0;n=v+54|0;a[n>>0]=Kl(g)|0;q=v+55|0;a[q>>0]=Kl(g)|0;k=v+56|0;b[k>>1]=Ml(g)|0;j=v+58|0;b[j>>1]=Ml(g)|0;r=v+60|0;a[r>>0]=Kl(g)|0;s=v+61|0;a[s>>0]=Kl(g)|0;Zl(v+62|0,32,1,g)|0;u=v+96|0;c[u>>2]=Vl(g)|0;_a=(x&65535)>273;if(_a)_l(g,32,1)|0;if(b[k>>1]|0){i=0;do{a[f+952+i>>0]=Ml(g)|0;i=i+1|0}while((i|0)<(e[k>>1]|0))}Za=$a+5|0;yo(f,Za,20)|0;c[p>>2]=o;c[p+4>>2]=m>>>8;c[p+8>>2]=m&255;ao(f+64|0,64,20600,p);c[f+156>>2]=e[k>>1];Ya=e[j>>1]|0;w=f+128|0;c[w>>2]=Ya;Wa=a[n>>0]|0;Xa=Wa&255;j=f+136|0;c[j>>2]=Xa;c[f+132>>2]=O(Xa,Ya)|0;Ya=f+140|0;c[Ya>>2]=d[q>>0];c[f+148>>2]=d[r>>0];c[f+152>>2]=d[s>>0];Xa=f+1280|0;c[Xa>>2]=b[t>>1]<<12&4096|c[Xa>>2];if(Wa<<24>>24){i=0;do{c[f+184+(i*12|0)>>2]=d[v+62+i>>0];i=i+1|0}while((i|0)<(c[j>>2]|0))}if((pb(f)|0)<0){cb=-1;l=db;return cb|0}Wa=$a+40|0;i=(e[Wa>>1]|0)+42+(c[u>>2]|0)|0;Va=(c[w>>2]|0)>0;_l(g,i+h|0,0)|0;a:do if(Va){t=f+172|0;s=f+168|0;r=0;while(1){if((Ce(g,$a,20615)|0)<0){i=-1;j=64;break}Ml(g)|0;k=Kl(g)|0;j=Ml(g)|0;q=Vl(g)|0;i=i+42+q+(e[Wa>>1]|0)|0;q=j&65535;if((tb(f,r,q)|0)<0){i=-1;j=64;break}if(j<<16>>16){p=k&255;n=k<<24>>24!=0;o=0;do{j=Kl(g)|0;if(n&j<<24>>24!=0){m=j&255;k=0;while(1){if(!(m&1))j=(c[t>>2]|0)+(c[(c[(c[s>>2]|0)+(r<<2)>>2]|0)+4+(k<<2)>>2]<<2)|0;else{k=(Kl(g)|0)&255;j=(c[t>>2]|0)+(c[(c[(c[s>>2]|0)+(r<<2)>>2]|0)+4+(k<<2)>>2]<<2)|0}j=c[j>>2]|0;if(m&2|0){Va=(Kl(g)|0)&255;a[j+4+(o<<3)>>0]=(Va+1&255|0)==255?-127:Va+13&255}if(m&4|0)a[j+4+(o<<3)+1>>0]=Kl(g)|0;if(m&8|0)a[j+4+(o<<3)+3>>0]=Kl(g)|0;if(m&16|0)a[j+4+(o<<3)+4>>0]=Kl(g)|0;if(m&32|0)a[j+4+(o<<3)+5>>0]=Kl(g)|0;if(m&64|0)a[j+4+(o<<3)+6>>0]=Kl(g)|0;k=k+1|0;j=Kl(g)|0;if(!((k|0)<(p|0)&j<<24>>24!=0))break;else m=j&255}}o=o+1|0}while((o|0)!=(q|0))}r=r+1|0;Va=(r|0)<(c[w>>2]|0);_l(g,i+h|0,0)|0;if(!Va)break a}if((j|0)==64){l=db;return i|0}}while(0);Va=f+144|0;c[Va>>2]=1024;if((nb(f)|0)<0){cb=-1;l=db;return cb|0}b:do if((c[Ya>>2]|0)>0){Ua=f+176|0;Ea=ab+2|0;Da=ab+4|0;La=ab+124|0;Na=ab+224|0;Ja=ab+225|0;Ha=ab+226|0;Fa=ab+228|0;Ma=ab+232|0;Oa=ab+332|0;Ka=ab+333|0;Ia=ab+334|0;Ga=ab+336|0;Qa=ab+340|0;Sa=ab+341|0;Pa=ab+342|0;Ra=ab+343|0;Ta=ab+344|0;x=(x&65535)>271;D=ab+346|0;B=ab+347|0;E=ab+348|0;C=ab+349|0;F=ab+350|0;A=ab+351|0;z=ab+352|0;G=ab+353|0;ea=f+180|0;H=ab+128|0;fa=ab+132|0;I=ab+136|0;ga=ab+140|0;L=ab+144|0;ja=ab+148|0;M=ab+152|0;ka=ab+156|0;N=ab+160|0;la=ab+164|0;P=ab+168|0;ma=ab+172|0;Q=ab+176|0;na=ab+180|0;R=ab+184|0;oa=ab+188|0;S=ab+192|0;pa=ab+196|0;T=ab+200|0;qa=ab+204|0;J=ab+208|0;ha=ab+212|0;K=ab+216|0;ia=ab+220|0;U=ab+236|0;ra=ab+240|0;V=ab+244|0;sa=ab+248|0;Y=ab+252|0;va=ab+256|0;Z=ab+260|0;wa=ab+264|0;_=ab+268|0;xa=ab+272|0;$=ab+276|0;ya=ab+280|0;aa=ab+284|0;za=ab+288|0;ba=ab+292|0;Aa=ab+296|0;ca=ab+300|0;Ba=ab+304|0;da=ab+308|0;Ca=ab+312|0;W=ab+316|0;ta=ab+320|0;X=ab+324|0;ua=ab+328|0;y=0;i=0;c:while(1){n=c[Ua>>2]|0;if((Ce(g,$a,20620)|0)<0){i=-1;j=64;break}vb(c[Ua>>2]|0,y,Za,32);if(b[Wa>>1]|0){a[ab>>0]=Kl(g)|0;b[Ea>>1]=Ml(g)|0;Zl(Da,120,1,g)|0;a[La>>0]=Kl(g)|0;c[H>>2]=Vl(g)|0;c[fa>>2]=Vl(g)|0;c[I>>2]=Vl(g)|0;c[ga>>2]=Vl(g)|0;c[L>>2]=Vl(g)|0;c[ja>>2]=Vl(g)|0;c[M>>2]=Vl(g)|0;c[ka>>2]=Vl(g)|0;c[N>>2]=Vl(g)|0;c[la>>2]=Vl(g)|0;c[P>>2]=Vl(g)|0;c[ma>>2]=Vl(g)|0;c[Q>>2]=Vl(g)|0;c[na>>2]=Vl(g)|0;c[R>>2]=Vl(g)|0;c[oa>>2]=Vl(g)|0;c[S>>2]=Vl(g)|0;c[pa>>2]=Vl(g)|0;c[T>>2]=Vl(g)|0;c[qa>>2]=Vl(g)|0;c[J>>2]=Vl(g)|0;c[ha>>2]=Vl(g)|0;c[K>>2]=Vl(g)|0;c[ia>>2]=Vl(g)|0;a[Na>>0]=Kl(g)|0;a[Ja>>0]=Kl(g)|0;a[Ha>>0]=Kl(g)|0;b[Fa>>1]=Ml(g)|0;a[Ma>>0]=Kl(g)|0;c[U>>2]=Vl(g)|0;c[ra>>2]=Vl(g)|0;c[V>>2]=Vl(g)|0;c[sa>>2]=Vl(g)|0;c[Y>>2]=Vl(g)|0;c[va>>2]=Vl(g)|0;c[Z>>2]=Vl(g)|0;c[wa>>2]=Vl(g)|0;c[_>>2]=Vl(g)|0;c[xa>>2]=Vl(g)|0;c[$>>2]=Vl(g)|0;c[ya>>2]=Vl(g)|0;c[aa>>2]=Vl(g)|0;c[za>>2]=Vl(g)|0;c[ba>>2]=Vl(g)|0;c[Aa>>2]=Vl(g)|0;c[ca>>2]=Vl(g)|0;c[Ba>>2]=Vl(g)|0;c[da>>2]=Vl(g)|0;c[Ca>>2]=Vl(g)|0;c[W>>2]=Vl(g)|0;c[ta>>2]=Vl(g)|0;c[X>>2]=Vl(g)|0;c[ua>>2]=Vl(g)|0;a[Oa>>0]=Kl(g)|0;a[Ka>>0]=Kl(g)|0;a[Ia>>0]=Kl(g)|0;b[Ga>>1]=Ml(g)|0;a[Qa>>0]=Kl(g)|0;a[Sa>>0]=Kl(g)|0;a[Pa>>0]=Kl(g)|0;a[Ra>>0]=Kl(g)|0;b[Ta>>1]=Ml(g)|0;if(x){a[D>>0]=Kl(g)|0;a[B>>0]=Kl(g)|0;a[E>>0]=Kl(g)|0;a[C>>0]=Kl(g)|0}if(_a){a[F>>0]=Kl(g)|0;a[A>>0]=Kl(g)|0;a[z>>0]=Kl(g)|0;a[G>>0]=Kl(g)|0}w=a[ab>>0]|0;h=n+(y*764|0)+36|0;w=((w&255)<16?w:16)&255;c[h>>2]=w;if((ob(f,y,w)|0)<0){i=-1;j=64;break}else j=0;do{a[n+(y*764|0)+512+(j<<1)>>0]=a[ab+4+j>>0]|0;j=j+1|0}while((j|0)!=120);c[n+(y*764|0)+40>>2]=e[Ta>>1];w=a[La>>0]|0;k=n+(y*764|0)+48|0;c[k>>2]=w&255;c[n+(y*764|0)+56>>2]=d[Na>>0];c[n+(y*764|0)+64>>2]=d[Ja>>0];c[n+(y*764|0)+68>>2]=d[Ha>>0];c[n+(y*764|0)+44>>2]=e[Fa>>1];j=d[Ma>>0]|0;m=n+(y*764|0)+204|0;c[m>>2]=j;c[n+(y*764|0)+212>>2]=d[Oa>>0];c[n+(y*764|0)+220>>2]=d[Ka>>0];c[n+(y*764|0)+224>>2]=d[Ia>>0];c[n+(y*764|0)+200>>2]=e[Ga>>1];if(w<<24>>24){j=0;do{w=j<<1;b[n+(y*764|0)+72+(w<<1)>>1]=c[ab+128+(j<<3)>>2];b[n+(y*764|0)+72+((w|1)<<1)>>1]=(c[ab+128+(j<<3)+4>>2]|0)/2|0;j=j+1|0}while((j|0)<(c[k>>2]|0));j=c[m>>2]|0}if((j|0)>0){j=0;do{w=j<<1;b[n+(y*764|0)+228+(w<<1)>>1]=c[ab+236+(j<<3)>>2];b[n+(y*764|0)+228+((w|1)<<1)>>1]=((c[ab+236+(j<<3)+4>>2]|0)/2|0)+32;j=j+1|0}while((j|0)<(c[m>>2]|0))}if((c[h>>2]|0)>0){w=n+(y*764|0)+756|0;v=0;do{j=c[w>>2]|0;if((Ce(g,$a,20625)|0)<0){i=-1;j=64;break c}q=Ml(g)|0;p=Kl(g)|0;o=Kl(g)|0;r=Vl(g)|0;u=Vl(g)|0;s=Vl(g)|0;t=Vl(g)|0;eb=Vl(g)|0;m=Kl(g)|0;k=Kl(g)|0;n=j+(v<<6)+12|0;mi(eb,n,j+(v<<6)+16|0);c[n>>2]=48-(m&255)+(c[n>>2]|0);c[j+(v<<6)>>2]=(O(o&255,p&255)|0)>>>6;c[j+(v<<6)+8>>2]=(k<<24>>24<<1)+128;c[j+(v<<6)+20>>2]=a[Qa>>0];c[j+(v<<6)+24>>2]=a[Pa>>0];c[j+(v<<6)+28>>2]=a[Ra>>0];c[j+(v<<6)+32>>2]=a[Sa>>0];c[j+(v<<6)+40>>2]=i;k=c[Va>>2]|0;j=c[ea>>2]|0;if((i|0)>=(k|0)){j=ub(j,Va,(k*3|0)/2|0)|0;c[ea>>2]=j;if(!j){i=-1;j=64;break c}}p=j+(i*52|0)|0;wb(p,Za,32)|0;m=j+(i*52|0)+32|0;c[m>>2]=r;o=j+(i*52|0)+36|0;c[o>>2]=s;n=j+(i*52|0)+40|0;c[n>>2]=t;k=j+(i*52|0)+44|0;c[k>>2]=0;if(!(q&2))j=0;else{c[k>>2]=1;c[m>>2]=r>>1;c[o>>2]=s>>1;c[n>>2]=t>>1;j=1}c[k>>2]=((u&255|0)==2?4:0)|(u&3|0?2:0)|j;if((Ub(f,g,1,p,0)|0)<0){i=-1;j=64;break c}v=v+1|0;i=i+1|0}while((v|0)<(c[h>>2]|0))}}else a[ab>>0]=0;y=y+1|0;if((y|0)>=(c[Ya>>2]|0)){bb=i;cb=ea;break b}}if((j|0)==64){l=db;return i|0}}else{bb=0;cb=f+180|0}while(0);eb=ub(c[cb>>2]|0,Va,bb)|0;c[cb>>2]=eb;if(!eb){eb=-1;l=db;return eb|0}c[Xa>>2]=c[Xa>>2]|704643104;c[f+1284>>2]=1;eb=0;l=db;return eb|0}function Ce(c,d,e){c=c|0;d=d|0;e=e|0;Zl(d,4,1,c)|0;if(en(e,d,4)|0){e=-1;return e|0}e=Kl(c)|0;a[d+4>>0]=e;if(e<<24>>24!=32){e=-1;return e|0}Zl(d+5|0,32,1,c)|0;a[d+37>>0]=Kl(c)|0;b[d+38>>1]=Ml(c)|0;b[d+40>>1]=Ml(c)|0;e=0;return e|0}function De(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)!=1143886894){b=-1;return b|0}Xl(a)|0;Pl(a)|0;Pl(a)|0;Pl(a)|0;Pl(a)|0;Pl(a)|0;Xl(a)|0;xb(a,b,32);b=0;return b|0}function Ee(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=l;l=l+32|0;e=f;_l(b,d,0)|0;c[e+4>>2]=0;c[e>>2]=0;d=Fb()|0;if(!d){a=-1;l=f;return a|0}g=Jb(d,20646,34)|0;g=Jb(d,20651,35)|0|g;g=g|(Jb(d,21298,36)|0);g=g|(Jb(d,21303,37)|0);g=g|(Jb(d,20656,38)|0);if(g|(Jb(d,20661,39)|0)|0){g=-1;l=f;return g|0}g=Gb(d,a,b,e)|0;Mb(d);if((g|0)<0){g=-1;l=f;return g|0}d=c[e+12>>2]|0;e=a+128|0;if((d|0)>=(c[e>>2]|0)){g=0;l=f;return g|0}while(1){if((tb(a,d,64)|0)<0){d=-1;e=7;break}d=d+1|0;if((d|0)>=(c[e>>2]|0)){d=0;e=7;break}}if((e|0)==7){l=f;return d|0}return 0}function Fe(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=l;l=l+16|0;Pl(d)|0;Pl(d)|0;Pl(d)|0;c[a+148>>2]=(Pl(d)|0)&65535;e=Pl(d)|0;if(e<<16>>16)c[a+152>>2]=e&65535;Xl(d)|0;Zl(a,32,1,d)|0;Eb(a,20666,b);l=b;return 0}function Ge(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0;c[b+156>>2]=(Pl(e)|0)&65535;c[b+160>>2]=(Pl(e)|0)&65535;Xl(e)|0;f=0;d=0;do{g=Kl(e)|0;a[b+952+f>>0]=g;g=g&255;d=(g|0)>(d|0)?g:d;f=f+1|0}while((f|0)!=128);c[b+128>>2]=d+1;return 0}function He(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=a+136|0;c[b>>2]=(Pl(d)|0)&65535;c[e+8>>2]=(Pl(d)|0)&65535;c[a+132>>2]=O(c[a+128>>2]|0,c[b>>2]|0)|0;return 0}function Ie(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0;j=l;l=l+32|0;g=j;i=(Pl(d)|0)&65535;c[a+144>>2]=i;f=a+140|0;c[f>>2]=i;if((nb(a)|0)<0){a=-1;l=j;return a|0}if((c[f>>2]|0)<=0){a=0;l=j;return a|0}i=a+180|0;h=a+176|0;b=0;while(1){if((ob(a,b,1)|0)<0){e=-1;b=8;break}Xl(d)|0;e=Xl(d)|0;c[(c[i>>2]|0)+(b*52|0)+32>>2]=e;c[(c[h>>2]|0)+(b*764|0)+36>>2]=(e|0)!=0&1;e=(Il(d)|0)<<24>>24;k=(Kl(d)|0)&255;m=c[(c[h>>2]|0)+(b*764|0)+756>>2]|0;c[m>>2]=k;c[m+8>>2]=128;m=Xl(d)|0;c[(c[i>>2]|0)+(b*52|0)+36>>2]=m;m=Xl(d)|0;k=c[i>>2]|0;c[k+(b*52|0)+40>>2]=m+-1+(c[k+(b*52|0)+36>>2]|0);c[k+(b*52|0)+44>>2]=(m|0)>2?2:0;Zl(g,22,1,d)|0;vb(c[h>>2]|0,b,g,22);if(((Pl(d)|0)&255)>8){m=c[i>>2]|0;k=m+(b*52|0)+44|0;c[k>>2]=c[k>>2]|1;k=m+(b*52|0)+32|0;c[k>>2]=c[k>>2]>>1;k=m+(b*52|0)+36|0;c[k>>2]=c[k>>2]>>1;m=m+(b*52|0)+40|0;c[m>>2]=c[m>>2]>>1}Xl(d)|0;k=Xl(d)|0;m=c[(c[h>>2]|0)+(b*764|0)+756>>2]|0;mi(k,m+12|0,m+16|0);m=c[(c[h>>2]|0)+(b*764|0)+756>>2]|0;k=m+16|0;c[k>>2]=(c[k>>2]|0)+e;c[m+40>>2]=b;b=b+1|0;if((b|0)>=(c[f>>2]|0)){e=0;b=8;break}}if((b|0)==8){l=j;return e|0}return 0}function Je(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if(!(c[f>>2]|0)){c[f>>2]=1;f=f+12|0;c[f>>2]=0;if((pb(b)|0)<0){e=-1;return e|0}}else f=f+12|0;Xl(e)|0;n=(Pl(e)|0)&65535;g=Pl(e)|0;o=g&65535;d=c[f>>2]|0;a:do if((d|0)<=(n|0)){while(1){if((tb(b,d,o)|0)<0){f=-1;break}if((d|0)<(n|0))d=d+1|0;else break a}return f|0}while(0);c[f>>2]=n+1;if(!(g<<16>>16)){e=0;return e|0}l=b+136|0;m=b+172|0;k=b+168|0;f=c[l>>2]|0;j=0;do{if((f|0)>0){i=0;do{f=c[(c[m>>2]|0)+(c[(c[(c[k>>2]|0)+(n<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0;d=Kl(e)|0;g=Kl(e)|0;b=Kl(e)|0;h=Kl(e)|0;if(d<<24>>24){d=d+-1&255;a[f+4+(j<<3)>>0]=(d&15)+12+((d>>>4)*12|0)}a[f+4+(j<<3)+2>>0]=(g&255)>>>2;b=b&255;a[f+4+(j<<3)+1>>0]=(g&255)<<4&48|b>>>4;a[f+4+(j<<3)+3>>0]=b&15;a[f+4+(j<<3)+4>>0]=h;i=i+1|0;f=c[l>>2]|0}while((i|0)<(f|0))}j=j+1|0}while((j|0)!=(o|0));f=0;return f|0}function Ke(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=e+4|0;if(!(c[f>>2]|0)){c[f>>2]=1;c[e+16>>2]=0}if((b|0)>2){e=e+16|0;if((Ub(a,d,64,(c[a+180>>2]|0)+((c[(c[(c[a+176>>2]|0)+((c[e>>2]|0)*764|0)+756>>2]|0)+40>>2]|0)*52|0)|0,0)|0)<=-1){a=-1;return a|0}}else e=e+16|0;c[e>>2]=(c[e>>2]|0)+1;a=0;return a|0}function Le(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)!=1313800192){b=-1;return b|0}xb(a,b,(Kl(a)|0)&255);b=0;return b|0}function Me(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+16|0;_l(d,e,0)|0;Xl(d)|0;Eb(b,20704,t);s=Kl(d)|0;f=s&255;if(s<<24>>24){g=0;do{e=Kl(d)|0;if((g|0)<64)a[b+g>>0]=e;g=g+1|0}while((g|0)!=(f|0))}Ml(d)|0;Ml(d)|0;Ml(d)|0;Ml(d)|0;Kl(d)|0;r=b+128|0;c[r>>2]=(Kl(d)|0)&255;Kl(d)|0;s=(Kl(d)|0)&255;q=b+136|0;c[q>>2]=s;c[b+132>>2]=O(c[r>>2]|0,s)|0;Kl(d)|0;Ml(d)|0;Ml(d)|0;Kl(d)|0;c[b+144>>2]=63;s=b+140|0;c[s>>2]=63;e=0;do{f=Kl(d)|0;if(f<<24>>24==-1)break;a[b+952+e>>0]=f;e=e+1|0}while((e|0)<256);_l(d,255-e|0,1)|0;c[b+156>>2]=e;if((nb(b)|0)<0){b=-1;l=t;return b|0}a:do if((c[s>>2]|0)>0){j=b+176|0;k=b+180|0;i=0;while(1){if((ob(b,i,1)|0)<0){e=-1;break}p=Kl(d)|0;f=p&255;if(p<<24>>24){g=0;h=0;do{e=Kl(d)|0;g=e<<24>>24==32?g:1;if((h|0)<32)a[(c[j>>2]|0)+(i*764|0)+h>>0]=e;h=h+1|0}while((h|0)!=(f|0));if(!g)m=17}else m=17;if((m|0)==17){m=0;a[(c[j>>2]|0)+(i*764|0)>>0]=0}Vl(d)|0;Vl(d)|0;g=(Kl(d)|0)&255;c[c[(c[j>>2]|0)+(i*764|0)+756>>2]>>2]=g;g=(Ml(d)|0)&65535;f=(Ml(d)|0)&65535;c[(c[k>>2]|0)+(i*52|0)+32>>2]=f;f=(Ml(d)|0)&65535;c[(c[k>>2]|0)+(i*52|0)+36>>2]=f;f=(Ml(d)|0)&65535;c[(c[k>>2]|0)+(i*52|0)+40>>2]=f;Vl(d)|0;Ml(d)|0;f=c[k>>2]|0;e=c[j>>2]|0;if((c[f+(i*52|0)+32>>2]|0)>0)c[e+(i*764|0)+36>>2]=1;c[f+(i*52|0)+44>>2]=(c[f+(i*52|0)+40>>2]|0)>0?2:0;o=c[e+(i*764|0)+756>>2]|0;p=o+16|0;c[p>>2]=0;c[o+8>>2]=128;c[o+40>>2]=i;mi(((g*8363|0)>>>0)/8448|0,o+12|0,p);i=i+1|0;if((i|0)>=(c[s>>2]|0))break a}l=t;return e|0}while(0);if((pb(b)|0)<0){b=-1;l=t;return b|0}b:do if((c[r>>2]|0)>0){o=b+168|0;p=b+172|0;n=0;while(1){if((tb(b,n,64)|0)<0){e=-1;break}e=c[o>>2]|0;if((c[c[e+(n<<2)>>2]>>2]|0)>0){f=c[q>>2]|0;m=0;do{if((f|0)>0){g=0;while(1){e=c[(c[p>>2]|0)+(c[(c[e+(n<<2)>>2]|0)+4+(g<<2)>>2]<<2)>>2]|0;h=Vl(d)|0;f=h&63;i=h>>>6&127;j=h>>>13&127;k=h>>>20&15;if((f|0)!=63)a[e+4+(m<<3)>>0]=f+36;if((i|0)!=127)a[e+4+(m<<3)+1>>0]=i+1;if((j|0)!=127)a[e+4+(m<<3)+2>>0]=j;if((k|0)!=15){a[e+4+(m<<3)+3>>0]=a[20719+k>>0]|0;a[e+4+(m<<3)+4>>0]=h>>>24}g=g+1|0;f=c[q>>2]|0;if((g|0)>=(f|0))break;e=c[o>>2]|0}e=c[o>>2]|0}m=m+1|0}while((m|0)<(c[c[e+(n<<2)>>2]>>2]|0))}n=n+1|0;if((n|0)>=(c[r>>2]|0))break b}l=t;return e|0}while(0);e=c[s>>2]|0;c:do if((e|0)>0){h=b+180|0;g=0;while(1){f=c[h>>2]|0;if(c[f+(g*52|0)+32>>2]|0){if((Ub(b,d,2,f+(g*52|0)|0,0)|0)<0){e=-1;break}e=c[s>>2]|0}g=g+1|0;if((g|0)>=(e|0))break c}l=t;return e|0}while(0);d=b+1280|0;c[d>>2]=c[d>>2]|293601825;c[b+1284>>2]=2;b=0;l=t;return b|0}function Ne(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;if((Xl(a)|0)!=1297437528){b=-1;return b|0}Vl(a)|0;a:do if(!(am(a)|0)){while(1){d=Xl(a)|0;c=Vl(a)|0;if((d|0)==1296974157)break;_l(a,c,1)|0;if(am(a)|0)break a}xb(a,b,32);d=0;return d|0}while(0);xb(a,b,0);d=0;return d|0}function Oe(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;f=l;l=l+112|0;e=f;_l(b,d,0)|0;Xl(b)|0;Xl(b)|0;c[e>>2]=0;c[e+4>>2]=0;c[e+8>>2]=0;c[e+12>>2]=0;c[e+16>>2]=0;d=Fb()|0;if(!d){a=-1;l=f;return a|0}Jb(d,20753,40)|0;Jb(d,20758,41)|0;Jb(d,20763,42)|0;Jb(d,20768,43)|0;Jb(d,20773,44)|0;Jb(d,20778,45)|0;Jb(d,20783,46)|0;Jb(d,20788,47)|0;Jb(d,20793,48)|0;Jb(d,21298,49)|0;Jb(d,20798,50)|0;Qb(d,1);b=(Gb(d,a,b,e)|0)<0;Mb(d);if(b){a=-1;l=f;return a|0}d=a+136|0;if((c[d>>2]|0)>0)e=0;else{a=0;l=f;return a|0}do{c[a+184+(e*12|0)>>2]=(((e+3|0)/2|0|0)%2|0)*255;e=e+1|0}while((e|0)<(c[d>>2]|0));d=0;l=f;return d|0}function Pe(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=(Kl(d)|0)&255;c[e>>2]=((b>>>4)*10|0)+(b&15);b=(Kl(d)|0)&255;c[e>>2]=((b&15)*100|0)+(c[e>>2]|0)+((b>>>4)*1e3|0);b=(Kl(d)|0)&255;c[e+4>>2]=((b>>>4)*10|0)+(b&15);b=(Kl(d)|0)&255;c[e+8>>2]=((b>>>4)*10|0)+(b&15);return 0}function Qe(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;c[a+136>>2]=Vl(d)|0;return 0}function Re(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0;h=f+28|0;Zl(h,1,8,e)|0;g=b+136|0;f=c[g>>2]|0;if((f|0)>0)e=0;else return 0;do{d=a[h+e>>0]|0;if((d+-1&255)<7){c[b+184+(e*12|0)>>2]=((d&255)*42|0)+-40;f=c[g>>2]|0}e=e+1|0}while((e|0)<(f|0));return 0}function Se(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;Zl(a,1,32,c)|0;return 0}function Te(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return 0}function Ue(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;c[a+156>>2]=Vl(d)|0;return 0}function Ve(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;c[a+128>>2]=Vl(d)|0;return 0}function We(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;Zl(d+36|0,1,64,c)|0;return 0}function Xe(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;b=l;l=l+16|0;Zl(a+952|0,1,128,c)|0;Eb(a,20734,b);l=b;return 0}function Ye(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0;e=g+12|0;if(!(c[e>>2]|0)){c[e>>2]=1;e=g+24|0;c[e>>2]=0;c[b+132>>2]=O(c[b+136>>2]|0,c[b+128>>2]|0)|0;if((pb(b)|0)<0){f=-1;return f|0}}else e=g+24|0;m=c[e>>2]|0;j=g+36+m|0;if((tb(b,m,d[j>>0]|0)|0)<0){f=-1;return f|0}g=a[j>>0]|0;if(g<<24>>24){k=b+136|0;l=b+172|0;i=b+168|0;b=c[k>>2]|0;h=0;do{if((b|0)>0){g=0;do{n=c[(c[l>>2]|0)+(c[(c[(c[i>>2]|0)+(m<<2)>>2]|0)+4+(g<<2)>>2]<<2)>>2]|0;b=n+4+(h<<3)|0;a[n+4+(h<<3)+4>>0]=Kl(f)|0;a[n+4+(h<<3)+3>>0]=Kl(f)|0;a[n+4+(h<<3)+1>>0]=Kl(f)|0;n=Kl(f)|0;a[b>>0]=n<<24>>24==0?0:(n&255)+48&255;_e(b);g=g+1|0;b=c[k>>2]|0}while((g|0)<(b|0));g=a[j>>0]|0}h=h+1|0}while((h|0)<(g&255|0))}c[e>>2]=(c[e>>2]|0)+1;n=0;return n|0}function Ze(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;b=e+16|0;do if(!(c[b>>2]|0)){c[a+140>>2]=36;c[a+144>>2]=36;if((nb(a)|0)<0){a=-1;return a|0}else{c[b>>2]=1;b=e+20|0;c[b>>2]=0;e=0;break}}else{b=e+20|0;e=c[b>>2]|0;if((e|0)>35){a=0;return a|0}}while(0);g=a+176|0;c[(c[g>>2]|0)+(e*764|0)+36>>2]=1;if((ob(a,e,1)|0)<0){a=-1;return a|0}Vl(d)|0;f=Vl(d)|0;if((f|0)<32)Zl((c[g>>2]|0)+(e*764|0)|0,1,f,d)|0;Vl(d)|0;Vl(d)|0;h=(Vl(d)|0)&255;c[c[(c[g>>2]|0)+(e*764|0)+756>>2]>>2]=h;Vl(d)|0;Vl(d)|0;h=Vl(d)|0;f=a+180|0;c[(c[f>>2]|0)+(e*52|0)+32>>2]=h;Vl(d)|0;Vl(d)|0;h=Vl(d)|0;c[(c[f>>2]|0)+(e*52|0)+36>>2]=h;Vl(d)|0;Vl(d)|0;h=Vl(d)|0;c[(c[f>>2]|0)+(e*52|0)+40>>2]=h;Vl(d)|0;Vl(d)|0;Vl(d)|0;h=c[(c[g>>2]|0)+(e*764|0)+756>>2]|0;c[h+40>>2]=e;c[h+8>>2]=128;c[a+1276>>2]=20;c[a+1268>>2]=255;f=c[f>>2]|0;h=f+(e*52|0)+40|0;g=c[h>>2]|0;if((g|0)<=2){if((g|0)==2?(c[f+(e*52|0)+36>>2]|0)>0:0){c[f+(e*52|0)+44>>2]=2;c[h>>2]=c[f+(e*52|0)+32>>2]}}else{c[f+(e*52|0)+44>>2]=2;c[h>>2]=g+(c[f+(e*52|0)+36>>2]|0)}if((Ub(a,d,128,f+(e*52|0)|0,0)|0)<0){a=-1;return a|0}c[b>>2]=(c[b>>2]|0)+1;a=0;return a|0}function _e(b){b=b|0;var c=0,d=0;d=b+3|0;do switch(a[d>>0]|0){case 0:{a[d>>0]=0;return}case 1:{a[d>>0]=1;return}case 2:{a[d>>0]=2;return}case 3:{a[d>>0]=3;return}case 11:{a[d>>0]=13;return}case 12:{c=b+4|0;b=a[c>>0]|0;if((b&255)<65){a[d>>0]=12;b=a[20803+(b&255)>>0]|0}else{a[d>>0]=0;b=0}a[c>>0]=b;return}case 25:case 14:{c=b+4|0;b=a[c>>0]|0;if((b+-1&255)<7){a[d>>0]=8;a[c>>0]=((b&255)*42|0)+216;return}else{a[c>>0]=0;a[d>>0]=0;return}}case 16:{a[d>>0]=-96;return}case 17:{a[d>>0]=-95;return}case 19:{a[d>>0]=11;return}case 21:{a[b+4>>0]=0;a[d>>0]=0;return}case 28:{a[d>>0]=15;return}case 31:{a[d>>0]=12;return}default:{a[b+4>>0]=0;a[d>>0]=0;return}}while(0)}function $e(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;if(c[a>>2]|0){b=-1;return b|0}e=Xl(a)|0;if((e|0)!=33624851|(Xl(a)|0)!=336724235){b=-1;return b|0}if(((Kl(a)|0)&255)>1){b=-1;return b|0}Kl(a)|0;Ml(a)|0;Ml(a)|0;Rl(a)|0;d=Kl(a)|0;e=0;do{if(d<<24>>24>-1)Rl(a)|0;e=e+1|0;d=Kl(a)|0}while((e|0)!=63);xb(a,b,d&255);b=0;return b|0}function af(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;w=l;l=l+400|0;u=w;t=w+128|0;q=w+384|0;_l(e,f,0)|0;_l(e,8,1)|0;Kl(e)|0;Eb(b,20868,u);s=b+136|0;c[s>>2]=(Kl(e)|0)&255;p=(Ml(e)|0)&65535;c[b+128>>2]=p;m=b+156|0;c[m>>2]=p;p=b+132|0;c[p>>2]=(Ml(e)|0)&65535;Rl(e)|0;c[b+144>>2]=63;r=b+140|0;c[r>>2]=63;if((nb(b)|0)<0){b=-1;l=w;return b|0}a:do if((c[r>>2]|0)>0){h=b+180|0;g=b+176|0;f=0;while(1){if((ob(b,f,1)|0)<0){f=-1;break}o=(Kl(e)|0)&255;c[t+(f<<2)>>2]=o;if(!(o&128)){o=(Rl(e)|0)<<1;c[(c[h>>2]|0)+(f*52|0)+32>>2]=o;c[(c[g>>2]|0)+(f*764|0)+36>>2]=1}f=f+1|0;if((f|0)>=(c[r>>2]|0))break a}l=w;return f|0}while(0);Zl(b,1,(Kl(e)|0)&255,e)|0;Zl(q,1,8,e)|0;c[p>>2]=(c[p>>2]|0)+1;if((pb(b)|0)<0){b=-1;l=w;return b|0}f=Kl(e)|0;if((f&255)>1){b=-1;l=w;return b|0}g=O(c[m>>2]<<1,c[s>>2]|0)|0;k=Om(g)|0;if(!k){b=-1;l=w;return b|0}if(f<<24>>24){if(!(fb(c[e+4>>2]|0,k,g,g)|0)){Pm(k);b=-1;l=w;return b|0}}else Zl(k,1,g,e)|0;b:do if((c[m>>2]|0)>0){j=b+168|0;i=0;while(1){if((qb(b,i)|0)<0)break;h=c[(c[j>>2]|0)+(i<<2)>>2]|0;c[h>>2]=64;f=c[s>>2]|0;if((f|0)>0){g=0;do{o=k+((O(f,i)|0)+g<<1)|0;o=bf(a[o>>0]|0,a[o+1>>0]|0)|0;f=h+4+(g<<2)|0;c[f>>2]=o;if((o|0)==4096)c[f>>2]=(c[p>>2]|0)+-1;g=g+1|0;f=c[s>>2]|0}while((g|0)<(f|0))}a[b+952+i>>0]=i;i=i+1|0;if((i|0)>=(c[m>>2]|0))break b}Pm(k);b=-1;l=w;return b|0}while(0);Pm(k);f=Kl(e)|0;if((f&255)>1){b=-1;l=w;return b|0}g=(c[p>>2]<<8)+-256|0;o=Om(g)|0;if(!o){b=-1;l=w;return b|0}if(f<<24>>24){if(!(fb(c[e+4>>2]|0,o,g,g)|0)){Pm(o);b=-1;l=w;return b|0}}else Zl(o,1,g,e)|0;c:do if((c[p>>2]|0)>1){n=b+172|0;f=0;while(1){if((rb(b,f,64)|0)<0)break;h=c[n>>2]|0;g=c[h+(f<<2)>>2]|0;if((c[g>>2]|0)>0){m=f<<6;k=0;do{i=g+4+(k<<3)|0;j=cf(o+(k+m<<2)|0)|0;x=j&63;a[i>>0]=(x|0)==0?0:x+48&255;a[g+4+(k<<3)+1>>0]=j>>>6&127;x=j>>>14;y=x&63;g=g+4+(k<<3)+3|0;a[g>>0]=y;if(!((d[q+(y>>>3)>>0]|0)&1<<(x&7)))a[g>>0]=0;else{df(i,j>>>20);h=c[n>>2]|0}k=k+1|0;g=c[h+(f<<2)>>2]|0}while((k|0)<(c[g>>2]|0))}f=f+1|0;if((f|0)>=((c[p>>2]|0)+-1|0))break c}Pm(o);y=-1;l=w;return y|0}else f=0;while(0);Pm(o);if((rb(b,f,64)|0)<0){y=-1;l=w;return y|0}d:do if((c[r>>2]|0)>0){m=b+180|0;k=b+176|0;i=e+4|0;j=0;while(1){f=u;g=f+128|0;do{a[f>>0]=0;f=f+1|0}while((f|0)<(g|0));y=c[t+(j<<2)>>2]|0;Zl(u,1,y&127,e)|0;vb(c[k>>2]|0,j,u,32);if(!(y&128)){h=(Rl(e)|0)<<1;c[(c[m>>2]|0)+(j*52|0)+36>>2]=h;h=(Rl(e)|0)<<1;f=c[m>>2]|0;g=f+(j*52|0)+44|0;if((h|0)>2)c[g>>2]=c[g>>2]|2;c[f+(j*52|0)+40>>2]=(c[f+(j*52|0)+36>>2]|0)+h;y=(Kl(e)|0)&255;x=c[(c[k>>2]|0)+(j*764|0)+756>>2]|0;c[x>>2]=y;c[x+8>>2]=128;x=((Kl(e)|0)&255)<<28>>24;y=c[(c[k>>2]|0)+(j*764|0)+756>>2]|0;c[y+16>>2]=x;c[y+40>>2]=j;if(c[(c[m>>2]|0)+(j*52|0)+32>>2]|0){g=Kl(e)|0;do if((g&255)>1){co(20885,32,1,7508);f=c[m>>2]|0;v=53}else{f=c[m>>2]|0;if(g<<24>>24!=1){v=53;break}f=f+(j*52|0)+32|0;y=Om(c[f>>2]|0)|0;f=c[f>>2]|0;fb(c[i>>2]|0,y,f,f)|0;f=Ub(b,0,17,(c[m>>2]|0)+(j*52|0)|0,y)|0;Pm(y)}while(0);if((v|0)==53){v=0;f=Ub(b,e,128,f+(j*52|0)|0,0)|0}if((f|0)<0){f=-1;break}}else v=54}else v=54;if((v|0)==54)v=0;j=j+1|0;if((j|0)>=(c[r>>2]|0))break d}l=w;return f|0}while(0);if((c[s>>2]|0)>0)f=0;else{y=0;l=w;return y|0}do{c[b+184+(f*12|0)>>2]=(((f+3|0)/2|0|0)%2|0)*255;f=f+1|0}while((f|0)<(c[s>>2]|0));f=0;l=w;return f|0}function bf(a,b){a=a|0;b=b|0;return (b&255)<<8|a&255|0}function cf(a){a=a|0;return (d[a+1>>0]|0)<<8|(d[a>>0]|0)|(d[a+2>>0]|0)<<16|(d[a+3>>0]|0)<<24|0}function df(b,c){b=b|0;c=c|0;var d=0,e=0;d=b+3|0;e=a[d>>0]|0;do switch(e<<24>>24){case 2:case 1:case 0:{a[b+4>>0]=c;d=c>>8;if(!d)return;a[b+5>>0]=-96;a[b+6>>0]=d;return}case 7:case 4:case 3:{a[b+4>>0]=c;return}case 6:case 5:{a[b+4>>0]=c;if(c|0)return;a[d>>0]=(e&255)+254;return}case 9:{a[b+4>>0]=c>>>1;return}case 10:{if(!(c&255))a[d>>0]=0;else a[b+4>>0]=c;a[b+5>>0]=14;a[b+6>>0]=c>>>8&15|16;return}case 15:case 13:case 12:case 11:{a[b+4>>0]=c;return}case 19:{a[d>>0]=14;a[b+4>>0]=c&15|48;return}case 20:{a[d>>0]=14;a[b+4>>0]=c&15|64;return}case 21:{a[d>>0]=14;a[b+4>>0]=c&15|80;return}case 22:{a[d>>0]=14;a[b+4>>0]=c&15|96;return}case 23:{a[d>>0]=14;a[b+4>>0]=c&15|112;return}case 25:if((c|0)<16){a[d>>0]=14;a[b+4>>0]=c&15|144;return}else{a[d>>0]=0;return}case 27:case 26:case 18:case 17:{if(((c&255)+-1|0)>>>0<15){a[d>>0]=14;a[b+4>>0]=(e<<24>>24==17|e<<24>>24==26?16:32)|c&15}else a[d>>0]=0;d=c>>8;if(!d)return;a[b+5>>0]=14;a[b+6>>0]=((e+-17&255)<2?160:176)|d;return}case 28:{a[d>>0]=14;a[b+4>>0]=c&15|192;return}case 29:{a[d>>0]=14;a[b+4>>0]=c&15|208;return}case 30:{a[d>>0]=14;a[b+4>>0]=c&15|224;return}case 31:{a[d>>0]=0;return}case 32:{a[d>>0]=0;a[b+4>>0]=c;d=c>>8;if(!d)return;a[b+5>>0]=-95;a[b+6>>0]=d;return}case 33:{a[d>>0]=1;a[b+4>>0]=c;d=c>>8;if(!d)return;a[b+5>>0]=-95;a[b+6>>0]=d;return}case 34:{a[d>>0]=2;a[b+4>>0]=c;d=c>>8;if(!d)return;a[b+5>>0]=-95;a[b+6>>0]=d;return}case 47:{if((c+-256|0)>>>0>=1793)return;a[d>>0]=15;a[b+4>>0]=(c+4|0)>>>3;return}default:{a[d>>0]=0;return}}while(0)}function ef(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)==1296385026){xb(a,b,0);a=0}else a=-1;return a|0}function ff(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;x=l;l=l+4736|0;v=x+4096|0;u=x;f=x+4696|0;q=x+4440|0;r=x+4184|0;t=x+4104|0;_l(d,e,0)|0;if((Xl(d)|0)!=1296385026){w=-1;l=x;return w|0}Eb(b,20918,u);c[b+144>>2]=32;c[b+140>>2]=32;if((nb(b)|0)<0){w=-1;l=x;return w|0}Zl(f,1,40,d)|0;o=b+176|0;e=0;do{Zl(f,1,40,d)|0;vb(c[o>>2]|0,e,f,32);if((ob(b,e,1)|0)<0){s=-1;w=36;break}e=e+1|0}while((e|0)<31);if((w|0)==36){l=x;return s|0}Kl(d)|0;e=0;do{m=(Kl(d)|0)&255;n=c[(c[o>>2]|0)+(e*764|0)+756>>2]|0;c[n>>2]=m;c[n+8>>2]=128;c[n+16>>2]=0;c[n+40>>2]=e;e=e+1|0}while((e|0)!=31);Pl(d)|0;n=b+180|0;e=Pl(d)|0;f=0;do{c[(c[n>>2]|0)+(f*52|0)+36>>2]=e&65535;f=f+1|0;e=Pl(d)|0}while((f|0)!=31);e=0;do{k=Pl(d)|0;m=c[n>>2]|0;c[m+(e*52|0)+40>>2]=(c[m+(e*52|0)+36>>2]|0)+(k&65535);c[m+(e*52|0)+44>>2]=(k&65535)>1?2:0;e=e+1|0}while((e|0)!=31);k=b+136|0;c[k>>2]=4;m=(Pl(d)|0)&65535;i=b+128|0;c[i>>2]=m;c[b+132>>2]=O(c[k>>2]|0,m)|0;Zl(b+952|0,1,100,d)|0;c[b+156>>2]=(Pl(d)|0)&65535;c[b+148>>2]=192/(((Pl(d)|0)&65535)>>>0)|0;Pl(d)|0;m=Pl(d)|0;Xl(d)|0;_l(d,16,1)|0;if(m<<16>>16==6){m=b+1280|0;c[m>>2]=c[m>>2]|192}if((pb(b)|0)<0){w=-1;l=x;return w|0}a:do if((c[i>>2]|0)>0){m=b+172|0;k=b+168|0;f=0;while(1){if((tb(b,f,64)|0)<0){s=-1;break}Xl(d)|0;g=0;do{h=0;do{j=c[(c[m>>2]|0)+(c[(c[(c[k>>2]|0)+(f<<2)>>2]|0)+4+(h<<2)>>2]<<2)>>2]|0;a[j+4+(g<<3)>>0]=ki((Pl(d)|0)&65535)|0;y=Kl(d)|0;a[j+4+(g<<3)+1>>0]=(y&255)>>>4;e=j+4+(g<<3)+3|0;a[e>>0]=y&15;a[j+4+(g<<3)+4>>0]=Kl(d)|0;j=(a[e>>0]|0)+-13<<24>>24;if((j&255)<3)a[e>>0]=789002>>>((j&255)<<3&16777215);h=h+1|0}while((h|0)!=4);g=g+1|0}while((g|0)!=64);f=f+1|0;if((f|0)>=(c[i>>2]|0))break a}l=x;return s|0}while(0);k=t+36|0;i=b+6548|0;h=0;while(1){Db(c[i>>2]|0,q);m=(Cb(q,(c[o>>2]|0)+(h*764|0)|0,r)|0)!=0;if(m?(c[v>>2]=q,c[v+4>>2]=r,ao(u,4096,20932,v),p=bm(u,21621)|0,(p|0)!=0):0){fm(p,t)|0;c[(c[n>>2]|0)+(h*52|0)+32>>2]=c[k>>2];j=p}else j=0;e=c[n>>2]|0;f=c[e+(h*52|0)+32>>2]|0;g=c[o>>2]|0;if((f|0)>0)c[g+(h*764|0)+36>>2]=1;if(!(Zn(g+(h*764|0)|0)|0)){if(!((f|0)==0|m^1))w=33}else if(m)w=33;if((w|0)==33?(w=0,y=Ub(b,j,0,e+(h*52|0)|0,0)|0,dm(j),(y|0)<=-1):0)break;h=h+1|0;if((h|0)>=31){s=0;w=36;break}}if((w|0)==36){l=x;return s|0}y=-1;l=x;return y|0}function gf(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)==1296385027){xb(a,b,0);a=0}else a=-1;return a|0}function hf(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0;n=l;l=l+48|0;g=n;_l(d,e,0)|0;Xl(d)|0;Eb(b,20938,g);c[b+144>>2]=32;c[b+140>>2]=32;if((nb(b)|0)<0){b=-1;l=n;return b|0}m=b+176|0;e=0;do{f=0;do{k=Kl(d)|0;a[g+f>>0]=k;f=f+1|0}while(k<<24>>24!=0&(f|0)<40);vb(c[m>>2]|0,e,g,32);if((ob(b,e,1)|0)<=-1){h=-1;i=56;break}e=e+1|0}while((e|0)<32);if((i|0)==56){l=n;return h|0}f=0;g=Xl(d)|0;while(1){if((g|0)<0)e=(Kl(d)|0)&255;else e=0;k=c[(c[m>>2]|0)+(f*764|0)+756>>2]|0;c[k>>2]=e;c[k+8>>2]=128;c[k+16>>2]=0;c[k+40>>2]=f;f=f+1|0;if((f|0)==32)break;else g=g<<1}k=b+180|0;f=0;g=Xl(d)|0;while(1){if((g|0)<0)e=(Pl(d)|0)&65535;else e=0;c[(c[k>>2]|0)+(f*52|0)+36>>2]=e;f=f+1|0;if((f|0)==32)break;else g=g<<1}f=0;g=Xl(d)|0;while(1){if((g|0)<0)e=(Pl(d)|0)&65535;else e=0;j=c[k>>2]|0;i=(c[j+(f*52|0)+36>>2]|0)+e|0;c[j+(f*52|0)+32>>2]=i;c[j+(f*52|0)+40>>2]=i;c[j+(f*52|0)+44>>2]=e>>>0>1?2:0;f=f+1|0;if((f|0)==32)break;else g=g<<1}e=b+136|0;c[e>>2]=4;i=(Pl(d)|0)&65535;j=b+128|0;c[j>>2]=i;c[b+132>>2]=O(c[e>>2]|0,i)|0;i=(Pl(d)|0)&65535;c[b+156>>2]=i;Zl(b+952|0,1,i,d)|0;i=Pl(d)|0;e=i&65535;f=b+148|0;c[f>>2]=e;if((i&65535)>10){c[b+152>>2]=((e*125|0)>>>0)/33|0;c[f>>2]=6}g=Il(d)|0;Kl(d)|0;h=Pl(d)|0;Xl(d)|0;_l(d,16,1)|0;e=0;f=Xl(d)|0;while(1){if((f|0)<0)Kl(d)|0;e=e+1|0;if((e|0)==32)break;else f=f<<1}e=0;f=Xl(d)|0;while(1){if((f|0)<0)Kl(d)|0;e=e+1|0;if((e|0)==32)break;else f=f<<1}e=g<<24>>24;if(h<<16>>16==6){i=b+1280|0;c[i>>2]=c[i>>2]|192}i=c[m>>2]|0;c[(c[i+756>>2]|0)+12>>2]=e;c[(c[i+1520>>2]|0)+12>>2]=e;c[(c[i+2284>>2]|0)+12>>2]=e;c[(c[i+3048>>2]|0)+12>>2]=e;c[(c[i+3812>>2]|0)+12>>2]=e;c[(c[i+4576>>2]|0)+12>>2]=e;c[(c[i+5340>>2]|0)+12>>2]=e;c[(c[i+6104>>2]|0)+12>>2]=e;c[(c[i+6868>>2]|0)+12>>2]=e;c[(c[i+7632>>2]|0)+12>>2]=e;c[(c[i+8396>>2]|0)+12>>2]=e;c[(c[i+9160>>2]|0)+12>>2]=e;c[(c[i+9924>>2]|0)+12>>2]=e;c[(c[i+10688>>2]|0)+12>>2]=e;c[(c[i+11452>>2]|0)+12>>2]=e;c[(c[i+12216>>2]|0)+12>>2]=e;c[(c[i+12980>>2]|0)+12>>2]=e;c[(c[i+13744>>2]|0)+12>>2]=e;c[(c[i+14508>>2]|0)+12>>2]=e;c[(c[i+15272>>2]|0)+12>>2]=e;c[(c[i+16036>>2]|0)+12>>2]=e;c[(c[i+16800>>2]|0)+12>>2]=e;c[(c[i+17564>>2]|0)+12>>2]=e;c[(c[i+18328>>2]|0)+12>>2]=e;c[(c[i+19092>>2]|0)+12>>2]=e;c[(c[i+19856>>2]|0)+12>>2]=e;c[(c[i+20620>>2]|0)+12>>2]=e;c[(c[i+21384>>2]|0)+12>>2]=e;c[(c[i+22148>>2]|0)+12>>2]=e;c[(c[i+22912>>2]|0)+12>>2]=e;c[(c[i+23676>>2]|0)+12>>2]=e;c[(c[i+24440>>2]|0)+12>>2]=e;if((pb(b)|0)<0){b=-1;l=n;return b|0}a:do if((c[j>>2]|0)>0){i=0;while(1){if((tb(b,i,64)|0)<0){h=-1;i=56;break}Kl(d)|0;e=Kl(d)|0;h=(Pl(d)|0)&65535;g=Qm(1,h+16|0)|0;if(!g){h=-1;i=56;break}f=e&255;if(!(f&16))if(!(f&1))e=Xl(d)|0;else e=-1;else e=0;c[g>>2]=e;if(!(f&32))if(!(f&2))e=Xl(d)|0;else e=-1;else e=0;c[g+4>>2]=e;if(!(f&64))if(!(f&4))e=Xl(d)|0;else e=-1;else e=0;c[g+8>>2]=e;if(!(f&128))if(!(f&8))e=Xl(d)|0;else e=-1;else e=0;c[g+12>>2]=e;Zl(g+16|0,1,h,d)|0;h=jf(b,i&65535,g)|0;Pm(g);i=i+1|0;if((h|0)<=-1){h=-1;i=56;break}if((i|0)>=(c[j>>2]|0))break a}if((i|0)==56){l=n;return h|0}}while(0);e=0;f=Xl(d)|0;while(1){if((f|0)<=-1){c[(c[m>>2]|0)+(e*764|0)+36>>2]=1;j=Xl(d)|0;c[(c[k>>2]|0)+(e*52|0)+32>>2]=j;if(!j)c[(c[m>>2]|0)+(e*764|0)+36>>2]=0;if((Pl(d)|0)<<16>>16==0?(Ub(b,d,0,(c[k>>2]|0)+(e*52|0)|0,0)|0)<0:0){h=-1;i=56;break}}e=e+1|0;if((e|0)>=32){h=0;i=56;break}else f=f<<1}if((i|0)==56){l=n;return h|0}return 0}function jf(d,e,f){d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;z=l;l=l+32|0;h=z+12|0;x=z+8|0;g=z+4|0;w=z;v=z+16|0;c[h>>2]=c[f>>2];c[x>>2]=c[f+4>>2];c[g>>2]=c[f+8>>2];c[w>>2]=c[f+12>>2];b[v>>1]=0;o=f+16|0;n=c[d+136>>2]|0;y=Qm(3,256)|0;if(!y){y=-1;l=z;return y|0}q=((n|0)/4|0)&255;s=16-n|0;p=(n|0)>0;r=n*3|0;m=0;k=y;while(1){j=(m|0)==32;g=j?w:g;h=j?x:h;if((c[h>>2]|0)<0?(t=kf(o,v,q)|0,p):0){f=0;i=(t&65535)<>0]=kf(o,v,2)|0;a[j+1>>0]=((lf(o,v)|0)&255)<<4}f=f+1<<24>>24;if((f&255|0)>=(n|0))break;else{i=i<<1&131070;j=j+3|0}}}if((c[g>>2]|0)<0?(u=kf(o,v,q)|0,p):0){f=0;i=(u&65535)<>0]=a[A>>0]|B;a[j+2>>0]=kf(o,v,2)|0}f=f+1<<24>>24;if((f&255|0)>=(n|0))break;else{i=i<<1&131070;j=j+3|0}}}c[h>>2]=c[h>>2]<<1;c[g>>2]=c[g>>2]<<1;m=m+1|0;if((m|0)==64)break;else k=k+r|0}o=c[d+172>>2]|0;h=c[(c[d+168>>2]|0)+((e&65535)<<2)>>2]|0;k=0;do{n=k*12|0;m=0;do{f=c[o+(c[h+4+(m<<2)>>2]<<2)>>2]|0;g=(m*3|0)+n|0;B=a[y+g>>0]|0;a[f+4+(k<<3)>>0]=B<<24>>24==0?0:(B&255)+48&255;B=a[y+(g+1)>>0]|0;j=(B&255)>>>4;a[f+4+(k<<3)+1>>0]=j<<24>>24==0?0:j+1<<24>>24;j=f+4+(k<<3)+3|0;a[j>>0]=B&15;g=a[y+(g+2)>>0]|0;i=f+4+(k<<3)+4|0;a[i>>0]=g;a:do switch(B&15){case 4:case 3:case 2:case 1:case 0:break;case 12:{B=g&255;a[i>>0]=((B>>>4)*10|0)+(B&15);break}case 13:{a[j>>0]=10;break}case 15:switch(g<<24>>24){case 0:{a[j>>0]=13;break a}case -1:{a[j>>0]=0;a[i>>0]=0;a[f+4+(k<<3)+2>>0]=1;break a}case -2:{a[j>>0]=0;a[i>>0]=0;break a}case -15:{a[j>>0]=14;a[i>>0]=-109;break a}case -14:{a[j>>0]=14;a[i>>0]=-61;break a}case -13:{a[j>>0]=14;a[i>>0]=-45;break a}default:{if((g&255)<=10)break a;a[j>>0]=-85;a[i>>0]=(((g&255)*125|0)>>>0)/33|0;break a}}default:{a[j>>0]=0;a[i>>0]=0}}while(0);m=m+1|0}while((m|0)!=4);k=k+1|0}while((k|0)!=64);Pm(y);B=0;l=z;return B|0}function kf(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;if(!(c<<24>>24)){b=0;return b|0}else d=0;do{c=c+-1<<24>>24;d=(lf(a,b)|0)&255|d<<4&1048560}while(c<<24>>24!=0);b=d&65535;return b|0}function lf(c,d){c=c|0;d=d|0;var e=0;e=b[d>>1]|0;c=a[c+((e&65535)>>>1&65535)>>0]|0;b[d>>1]=e+1<<16>>16;return ((e&1)==0?(c&255)>>>4:c&15)|0}function mf(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)==1296385028){xb(a,b,0);a=0}else a=-1;return a|0}function nf(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0;P=l;l=l+4736|0;L=P;r=P+4712|0;N=P+3688|0;K=P+616|0;H=P+584|0;G=P+552|0;I=P+536|0;_l(g,h,0)|0;Xl(g)|0;k=$l(g)|0;_l(g,0,2)|0;a:do if(($l(g)|0)>2e3){_l(g,-1024,1)|0;Zl(N,1,1024,g)|0;i=0;while(1){j=N+i|0;i=i+1|0;if(!(en(j,20966,8)|0))break;if((i|0)>=1013){q=2;i=10;break a}}q=d[j+10>>0]|0;i=d[j+11>>0]|0}else{q=2;i=10}while(0);_l(g,k+h|0,0)|0;c[L>>2]=q;c[L+4>>2]=i;ao(f+64|0,64,20975,L);i=Kl(g)|0;if(!(i<<24>>24)){k=0;j=0;i=0}else{j=0;k=0;h=i&255;m=0;i=0;while(1){if(h&128){j=_o(j|0,k|0,8)|0;k=z;j=(Kl(g)|0)&255|j;i=i+1|0}m=m+1|0;h=h<<1;if(!((h&255)<<24>>24!=0&(m|0)<8))break;else h=h&254}}j=_o(j|0,k|0,8-i<<3|0)|0;i=z;cp(K|0,0,3072)|0;if((j|0)==0&(i|0)==0)J=0;else{p=0;k=0;do{o=p;p=p+1|0;if(!((i|0)>0|(i|0)==0&j>>>0>0)){n=Kl(g)|0;J=Kl(g)|0;k=J&255;if(!(J<<24>>24))k=0;else{h=0;do{a[L+h>>0]=Kl(g)|0;h=h+1|0}while((h|0)!=(k|0))}a[L+k>>0]=0;m=K+(o*48|0)+40|0;c[m>>2]=64;k=n&255;if(!(k&1))c[K+(o*48|0)+32>>2]=((Pl(g)|0)&65535)<<1;if(!(k&2))h=((Pl(g)|0)&65535)<<1;else h=0;if(!(k&4))Kl(g)|0;if(!(k&8))Kl(g)|0;if(!(k&48))c[m>>2]=(Kl(g)|0)&255;if(!(k&64))c[K+(o*48|0)+44>>2]=(Il(g)|0)<<24>>24;c[K+(o*48|0)+36>>2]=(c[K+(o*48|0)+32>>2]|0)+(h&65534);wb(K+(o*48|0)|0,L,32)|0;k=p}j=_o(j|0,i|0,1)|0;i=z}while(((j|0)!=0|(i|0)!=0)&(p|0)<64);J=k}D=f+128|0;c[D>>2]=(Pl(g)|0)&65535;C=Pl(g)|0;i=C&65535;c[f+156>>2]=i;if((C&65535)>256){f=-1;l=P;return f|0}Zl(f+952|0,1,i,g)|0;C=Pl(g)|0;i=C&65535;if((C&65535)<11){k=f+148|0;c[k>>2]=i;i=125}else{i=((i*125|0)>>>0)/33|0;k=f+148|0}c[f+152>>2]=i;j=(Il(g)|0)<<24>>24;Il(g)|0;i=(Il(g)|0)<<24>>24;c[k>>2]=(Kl(g)|0)&255;if(!(i&32)){C=f+1280|0;c[C>>2]=c[C>>2]|192}if((q|0)==2)c[k>>2]=6-(i>>>5&1);_l(g,20,1)|0;Zl(r,1,16,g)|0;Kl(g)|0;i=0;do{C=K+(i*48|0)+44|0;c[C>>2]=(c[C>>2]|0)+j;i=i+1|0}while((i|0)!=64);C=f+136|0;c[C>>2]=0;h=$l(g)|0;i=c[D>>2]|0;if((i|0)>0){k=0;do{i=(Kl(g)|0)&255;j=(Kl(g)|0)&255;if((j|0)>(c[C>>2]|0))c[C>>2]=j;Kl(g)|0;_l(g,i+-4+((Pl(g)|0)&65535)|0,1)|0;k=k+1|0;i=c[D>>2]|0}while((k|0)<(i|0))}c[f+132>>2]=O(c[C>>2]|0,i)|0;if((pb(f)|0)<0){f=-1;l=P;return f|0}_l(g,h,0)|0;b:do if((c[D>>2]|0)>0){B=f+172|0;A=f+168|0;y=0;while(1){n=(Kl(g)|0)&255;m=$l(g)|0;o=Kl(g)|0;x=o&255;if((x|0)>(c[C>>2]|0))break;h=(Kl(g)|0)&255;j=Pl(g)|0;i=h>>>6;k=0;while(1){a[L+k>>0]=Kl(g)|0;if((k|0)==(i|0))break;else k=k+1|0}w=j&65535;if((tb(f,y,h+1|0)|0)<0)break;c[H>>2]=0;c[H+4>>2]=0;c[H+8>>2]=0;c[H+12>>2]=0;c[H+16>>2]=0;c[H+20>>2]=0;c[H+24>>2]=0;c[H+28>>2]=0;c[G>>2]=0;c[G+4>>2]=0;c[G+8>>2]=0;c[G+12>>2]=0;c[G+16>>2]=0;c[G+20>>2]=0;c[G+24>>2]=0;c[G+28>>2]=0;v=(h>>>5)+1|0;h=0;do{j=d[L+((h|0)/2|0)>>0]|0;k=((h|0)%2|0)<<2;if(!(j&128>>>k))if(!(j&64>>>k))i=Xl(g)|0;else i=0;else i=-1;c[H+(h<<2)>>2]=i;if(!(j&32>>>k))if(!(j&16>>>k))i=Xl(g)|0;else i=0;else i=-1;c[G+(h<<2)>>2]=i;h=h+1|0}while((h|0)!=(v|0));u=m+n|0;_l(g,u,0)|0;of(g,I);q=o<<24>>24==0;t=0;do{s=t<<5;o=H+(t<<2)|0;p=G+(t<<2)|0;m=c[o>>2]|0;r=0;do{n=r+s|0;if((m|0)<0?(E=pf(I,x)|0,!q):0){j=E&65535;k=0;while(1){i=c[(c[B>>2]|0)+(c[(c[(c[A>>2]|0)+(y<<2)>>2]|0)+4+(k<<2)>>2]<<2)>>2]|0;if(j&32768|0){h=qf(I)|0;Q=h>>>4;a[i+4+(n<<3)>>0]=(Q&255)<<24>>24==0?0:Q+48&255;a[i+4+(n<<3)+1>>0]=h&15}k=k+1|0;if((k|0)==(x|0))break;else j=j<<1}}i=c[p>>2]|0;if((i|0)<0?(F=pf(I,x)|0,!q):0){k=F&65535;h=0;while(1){j=c[(c[B>>2]|0)+(c[(c[(c[A>>2]|0)+(y<<2)>>2]|0)+4+(h<<2)>>2]<<2)>>2]|0;if(k&32768|0){Q=qf(I)|0;a[j+4+(n<<3)+3>>0]=Q>>>8;a[j+4+(n<<3)+4>>0]=Q;rf(j+4+(n<<3)|0)}h=h+1|0;if((h|0)==(x|0))break;else k=k<<1}}m=m<<1;c[p>>2]=i<<1;r=r+1|0}while((r|0)!=32);c[o>>2]=m;t=t+1|0}while((t|0)!=(v|0));_l(g,w+u|0,0)|0;y=y+1|0;if((y|0)>=(c[D>>2]|0))break b}Q=-1;l=P;return Q|0}while(0);c[f+140>>2]=J;if(Nj(f)|0){Q=-1;l=P;return Q|0}i=Xl(g)|0;do if((i|0)==1296385110){c[f+144>>2]=0;if((nb(f)|0)<0){Q=-1;l=P;return Q|0}else{_l(g,-4,1)|0;break}}else{q=_o(Xl(g)|0,i|0,1)|0;p=z;o=$l(g)|0;if((q|0)==0&(p|0)==0)i=0;else{h=p;m=q;n=0;i=0;do{if(!((h|0)>0|(h|0)==0&m>>>0>0)){j=Xl(g)|0;Q=Pl(g)|0;k=$l(g)|0;switch(Q<<16>>16){case 0:case -2:{i=i+1|0;break}case -1:{_l(g,20,1)|0;i=((Pl(g)|0)&65535)+i|0;break}default:{}}_l(g,k+j|0,0)|0}n=n+1|0;m=_o(m|0,h|0,1)|0;h=z}while(((m|0)!=0|(h|0)!=0)&(n|0)<64)}_l(g,o,0)|0;c[f+144>>2]=i;if((nb(f)|0)<0){Q=-1;l=P;return Q|0}c:do if(((q|0)!=0|(p|0)!=0)&(J|0)>0){B=f+176|0;t=L+10|0;u=L+12|0;w=L+14|0;A=L+16|0;v=L+18|0;y=L+19|0;x=L+20|0;r=L+22|0;s=L+150|0;C=f+180|0;o=0;i=0;d:while(1){e:do if((p|0)>0|(p|0)==0&q>>>0>0)M=113;else{h=c[B>>2]|0;k=h+(o*764|0)|0;n=Xl(g)|0;Q=Pl(g)|0;yo(k,K+(o*48|0)|0,32)|0;switch(Q<<16>>16){case -2:{j=$l(g)|0;Xl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;b[t>>1]=Pl(g)|0;b[u>>1]=Pl(g)|0;b[w>>1]=Pl(g)|0;b[A>>1]=Pl(g)|0;a[v>>0]=Kl(g)|0;a[y>>0]=Kl(g)|0;b[x>>1]=Pl(g)|0;Zl(r,1,e[w>>1]|0,g)|0;Zl(s,1,e[A>>1]|0,g)|0;_l(g,(Xl(g)|0)+j|0,0)|0;j=Xl(g)|0;Pl(g)|0;if(Jj(k)|0)break d;c[h+(o*764|0)+36>>2]=1;if((ob(f,o,1)|0)<0)break d;Q=c[h+(o*764|0)+756>>2]|0;I=c[h+(o*764|0)+760>>2]|0;c[I+4>>2]=d[v>>0];c[I+8>>2]=d[y>>0];c[Q+8>>2]=128;c[Q>>2]=c[K+(o*48|0)+40>>2];c[Q+12>>2]=c[K+(o*48|0)+44>>2];c[Q+40>>2]=i;c[Q+16>>2]=0;Q=c[C>>2]|0;c[Q+(i*52|0)+32>>2]=j;c[Q+(i*52|0)+36>>2]=c[K+(o*48|0)+32>>2];I=c[K+(o*48|0)+36>>2]|0;c[Q+(i*52|0)+40>>2]=I;c[Q+(i*52|0)+44>>2]=(I|0)>2?2:0;if((Ub(f,g,0,Q+(i*52|0)|0,0)|0)<0)break d;if(!(pe(f,o,L)|0)){i=i+1|0;break e}else{i=-1;M=125;break d}}case -1:{m=$l(g)|0;Xl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;b[t>>1]=Pl(g)|0;b[u>>1]=Pl(g)|0;b[w>>1]=Pl(g)|0;b[A>>1]=Pl(g)|0;a[v>>0]=Kl(g)|0;a[y>>0]=Kl(g)|0;b[x>>1]=Pl(g)|0;Zl(r,1,e[w>>1]|0,g)|0;Zl(s,1,e[A>>1]|0,g)|0;j=b[x>>1]|0;if(j<<16>>16==-1){M=113;break e}if((j&65535)>64)break d;if(j<<16>>16){j=0;do{c[L+280+(j<<2)>>2]=Xl(g)|0;j=j+1|0}while((j|0)<(e[x>>1]|0))}if(Jj((c[B>>2]|0)+(o*764|0)|0)|0)break d;Q=e[x>>1]|0;c[(c[B>>2]|0)+(o*764|0)+36>>2]=Q;if((ob(f,o,Q)|0)<0)break d;Q=c[h+(o*764|0)+760>>2]|0;c[Q+4>>2]=d[v>>0];c[Q+8>>2]=d[y>>0];if(b[x>>1]|0){k=h+(o*764|0)+756|0;j=0;do{Q=c[k>>2]|0;c[Q+(j<<6)+8>>2]=128;c[Q+(j<<6)>>2]=64;c[Q+(j<<6)+12>>2]=-24;c[Q+(j<<6)+40>>2]=i;c[Q+(j<<6)+16>>2]=0;_l(g,(c[L+280+(j<<2)>>2]|0)+m|0,0)|0;Q=c[C>>2]|0;I=((Pl(g)|0)&65535)<<1;c[Q+(i*52|0)+32>>2]=I;c[Q+(i*52|0)+36>>2]=0;c[Q+(i*52|0)+40>>2]=I;c[Q+(i*52|0)+44>>2]=2;if((Ub(f,g,0,Q+(i*52|0)|0,0)|0)<0)break d;i=i+1|0;j=j+1|0}while((j|0)<(e[x>>1]|0))}if(pe(f,o,L)|0)break d;_l(g,m+n|0,0)|0;M=113;break e}case 0:{c[h+(o*764|0)+36>>2]=1;if((ob(f,o,1)|0)<0)break d;Q=c[h+(o*764|0)+756>>2]|0;c[Q>>2]=c[K+(o*48|0)+40>>2];c[Q+8>>2]=128;c[Q+12>>2]=c[K+(o*48|0)+44>>2];c[Q+40>>2]=i;Q=c[C>>2]|0;c[Q+(i*52|0)+32>>2]=n;c[Q+(i*52|0)+36>>2]=c[K+(o*48|0)+32>>2];I=c[K+(o*48|0)+36>>2]|0;c[Q+(i*52|0)+40>>2]=I;c[Q+(i*52|0)+44>>2]=(I|0)>2?2:0;if((Ub(f,g,0,Q+(i*52|0)|0,0)|0)<0)break d;a[h+(o*764|0)+513>>0]=48;a[h+(o*764|0)+515>>0]=48;a[h+(o*764|0)+517>>0]=48;a[h+(o*764|0)+519>>0]=48;a[h+(o*764|0)+521>>0]=48;a[h+(o*764|0)+523>>0]=48;a[h+(o*764|0)+525>>0]=48;a[h+(o*764|0)+527>>0]=48;a[h+(o*764|0)+529>>0]=48;a[h+(o*764|0)+531>>0]=48;a[h+(o*764|0)+533>>0]=48;a[h+(o*764|0)+535>>0]=48;a[h+(o*764|0)+537>>0]=36;a[h+(o*764|0)+539>>0]=36;a[h+(o*764|0)+541>>0]=36;a[h+(o*764|0)+543>>0]=36;a[h+(o*764|0)+545>>0]=36;a[h+(o*764|0)+547>>0]=36;a[h+(o*764|0)+549>>0]=36;a[h+(o*764|0)+551>>0]=36;a[h+(o*764|0)+553>>0]=36;a[h+(o*764|0)+555>>0]=36;a[h+(o*764|0)+557>>0]=36;a[h+(o*764|0)+559>>0]=36;a[h+(o*764|0)+561>>0]=24;a[h+(o*764|0)+563>>0]=24;a[h+(o*764|0)+565>>0]=24;a[h+(o*764|0)+567>>0]=24;a[h+(o*764|0)+569>>0]=24;a[h+(o*764|0)+571>>0]=24;a[h+(o*764|0)+573>>0]=24;a[h+(o*764|0)+575>>0]=24;a[h+(o*764|0)+577>>0]=24;a[h+(o*764|0)+579>>0]=24;a[h+(o*764|0)+581>>0]=24;a[h+(o*764|0)+583>>0]=24;a[h+(o*764|0)+585>>0]=12;a[h+(o*764|0)+587>>0]=12;a[h+(o*764|0)+589>>0]=12;a[h+(o*764|0)+591>>0]=12;a[h+(o*764|0)+593>>0]=12;a[h+(o*764|0)+595>>0]=12;a[h+(o*764|0)+597>>0]=12;a[h+(o*764|0)+599>>0]=12;a[h+(o*764|0)+601>>0]=12;a[h+(o*764|0)+603>>0]=12;a[h+(o*764|0)+605>>0]=12;a[h+(o*764|0)+607>>0]=12;a[h+(o*764|0)+609>>0]=0;a[h+(o*764|0)+611>>0]=0;a[h+(o*764|0)+613>>0]=0;a[h+(o*764|0)+615>>0]=0;a[h+(o*764|0)+617>>0]=0;a[h+(o*764|0)+619>>0]=0;a[h+(o*764|0)+621>>0]=0;a[h+(o*764|0)+623>>0]=0;a[h+(o*764|0)+625>>0]=0;a[h+(o*764|0)+627>>0]=0;a[h+(o*764|0)+629>>0]=0;a[h+(o*764|0)+631>>0]=0;a[h+(o*764|0)+633>>0]=0;a[h+(o*764|0)+635>>0]=0;a[h+(o*764|0)+637>>0]=0;a[h+(o*764|0)+639>>0]=0;a[h+(o*764|0)+641>>0]=0;a[h+(o*764|0)+643>>0]=0;a[h+(o*764|0)+645>>0]=0;a[h+(o*764|0)+647>>0]=0;a[h+(o*764|0)+649>>0]=0;a[h+(o*764|0)+651>>0]=0;a[h+(o*764|0)+653>>0]=0;a[h+(o*764|0)+655>>0]=0;a[h+(o*764|0)+657>>0]=0;a[h+(o*764|0)+659>>0]=0;a[h+(o*764|0)+661>>0]=0;a[h+(o*764|0)+663>>0]=0;a[h+(o*764|0)+665>>0]=0;a[h+(o*764|0)+667>>0]=0;a[h+(o*764|0)+669>>0]=0;a[h+(o*764|0)+671>>0]=0;a[h+(o*764|0)+673>>0]=0;a[h+(o*764|0)+675>>0]=0;a[h+(o*764|0)+677>>0]=0;a[h+(o*764|0)+679>>0]=0;a[h+(o*764|0)+681>>0]=-12;a[h+(o*764|0)+683>>0]=-12;a[h+(o*764|0)+685>>0]=-12;a[h+(o*764|0)+687>>0]=-12;a[h+(o*764|0)+689>>0]=-12;a[h+(o*764|0)+691>>0]=-12;a[h+(o*764|0)+693>>0]=-12;a[h+(o*764|0)+695>>0]=-12;a[h+(o*764|0)+697>>0]=-12;a[h+(o*764|0)+699>>0]=-12;a[h+(o*764|0)+701>>0]=-12;a[h+(o*764|0)+703>>0]=-12;a[h+(o*764|0)+705>>0]=-24;a[h+(o*764|0)+707>>0]=-24;a[h+(o*764|0)+709>>0]=-24;a[h+(o*764|0)+711>>0]=-24;a[h+(o*764|0)+713>>0]=-24;a[h+(o*764|0)+715>>0]=-24;a[h+(o*764|0)+717>>0]=-24;a[h+(o*764|0)+719>>0]=-24;a[h+(o*764|0)+721>>0]=-24;a[h+(o*764|0)+723>>0]=-24;a[h+(o*764|0)+725>>0]=-24;a[h+(o*764|0)+727>>0]=-24;i=i+1|0;M=113;break e}default:{_l(g,n,1)|0;M=113;break e}}}while(0);if((M|0)==113)M=0;o=o+1|0;q=_o(q|0,p|0,1)|0;p=z;if(!(((q|0)!=0|(p|0)!=0)&(o|0)<(J|0)))break c}if((M|0)==125){l=P;return i|0}Q=-1;l=P;return Q|0}while(0);Pl(g)|0}while(0);f:do if(!(am(g)|0))do{i=Xl(g)|0;if((i|0)<0)break f;j=Xl(g)|0;if((j|0)<0)break f;k=$l(g)|0;g:do if((i|0)<1296385110){switch(i|0){case 1095650895:break;default:break g}Q=(j|0)<1023?j:1023;Zl(N,1,Q,g)|0;a[N+Q>>0]=0}else{switch(i|0){case 1296385110:break;default:break g}Xl(g)|0}while(0);_l(g,k+j|0,0)|0}while(!(am(g)|0));while(0);c[f+1284>>2]=4;Q=0;l=P;return Q|0}function of(b,d){b=b|0;d=d|0;c[d>>2]=b;a[d+8>>0]=0;c[d+4>>2]=0;return}function pf(a,b){a=a|0;b=b|0;if((b|0)<5){a=(sf(a)|0)<<12&65535;return a|0}if((b|0)<9){a=(tf(a)|0)<<8&65535;return a|0}if((b|0)<13){a=(qf(a)|0)<<4&65535;return a|0}else{a=uf(a)|0;return a|0}return 0}function qf(a){a=a|0;var b=0,c=0;b=sf(a)|0;c=sf(a)|0;return c<<4|b<<8|(sf(a)|0)|0}function rf(b){b=b|0;var c=0,e=0,f=0;f=b+3|0;switch(a[f>>0]|0){case 12:{f=b+4|0;e=d[f>>0]|0;a[f>>0]=((e>>>4)*10|0)+(e&15);return}case 13:{a[f>>0]=10;return}case 15:{e=b+4|0;c=a[e>>0]|0;switch(c<<24>>24){case 0:{a[f>>0]=13;return}case -1:{a[f>>0]=0;a[e>>0]=0;a[b+2>>0]=1;return}case -15:{a[f>>0]=14;a[e>>0]=-109;return}case -14:{a[f>>0]=14;a[e>>0]=-61;return}case -13:{a[f>>0]=14;a[e>>0]=-45;return}default:{if((c&255)>240){a[f>>0]=0;a[e>>0]=0;return}if((c&255)<=10)return;a[f>>0]=-85;a[e>>0]=(((c&255)*125|0)>>>0)/33|0;return}}}case 4:case 3:case 2:case 1:case 0:return;default:{a[f>>0]=0;a[b+4>>0]=0;return}}}function sf(b){b=b|0;var d=0,e=0;e=b+4|0;d=(c[e>>2]|0)==0;c[e>>2]=d&1;if(d){e=Kl(c[b>>2]|0)|0;a[b+8>>0]=e;e=(e&255)>>>4;return e|0}else{e=a[b+8>>0]&15;return e|0}return 0}function tf(a){a=a|0;var b=0;b=sf(a)|0;return b<<4|(sf(a)|0)|0}function uf(a){a=a|0;var b=0,c=0,d=0;c=sf(a)|0;d=sf(a)|0;b=sf(a)|0;return (d<<8|c<<12|b<<4|(sf(a)|0))&65535|0}function vf(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)!=1145195824){b=-1;return b|0}_l(a,12,1)|0;xb(a,b,44);b=0;return b|0}function wf(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0;i=l;l=l+64|0;h=i;g=i+12|0;f=i+8|0;_l(b,d,0)|0;Xl(b)|0;c[f>>2]=0;d=Pl(b)|0;_l(b,10,1)|0;Zl(g,1,44,b)|0;e=Fb()|0;if(!e){a=-1;l=i;return a|0}j=Jb(e,21008,51)|0;j=Jb(e,21013,52)|0|j;j=j|(Jb(e,21303,53)|0);j=j|(Jb(e,21298,54)|0);j=j|(Jb(e,21018,55)|0);if(j|(Jb(e,21023,56)|0)|0){j=-1;l=i;return j|0}yo(a,g,64)|0;j=d&65535;c[h>>2]=j>>>8;c[h+4>>2]=j&255;ao(a+64|0,64,21028,h);j=(Gb(e,a,b,f)|0)<0;Mb(e);if(j){j=-1;l=i;return j|0}d=a+136|0;if((c[d>>2]|0)>0)e=0;else{j=0;l=i;return j|0}do{c[a+184+(e*12|0)>>2]=128;e=e+1|0}while((e|0)<(c[d>>2]|0));d=0;l=i;return d|0}function xf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;c[a+140>>2]=(Pl(d)|0)&65535;c[a+144>>2]=(Pl(d)|0)&65535;Pl(d)|0;e=a+128|0;c[e>>2]=(Pl(d)|0)&65535;b=(Pl(d)|0)&65535;c[a+136>>2]=b;c[a+132>>2]=O(c[e>>2]|0,b)|0;return (nb(a)|0)>>31|0}function yf(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0;g=l;l=l+64|0;if(c[f>>2]|0){l=g;return 0}c[f>>2]=1;Zl(g,44,1,e)|0;d=Pl(e)|0;f=b+156|0;c[f>>2]=d&65535;if(!(d<<16>>16)){l=g;return 0}else d=0;do{a[b+952+d>>0]=Pl(e)|0;d=d+1|0}while((d|0)<(c[f>>2]|0));l=g;return 0}function zf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0;k=l;l=l+64|0;e=k;i=a+176|0;g=a+140|0;if((c[g>>2]|0)<=0){a=0;l=k;return a|0}h=a+144|0;j=a+180|0;f=0;while(1){c[(c[i>>2]|0)+(f*764|0)+36>>2]=1;if((ob(a,f,1)|0)<0){e=-1;b=8;break}Zl(e,30,1,d)|0;vb(c[i>>2]|0,f,e,30);m=Pl(d)|0;b=m&65535;if(m<<16>>16?(b|0)<=(c[h>>2]|0):0){m=b+-1|0;c[(c[(c[i>>2]|0)+(f*764|0)+756>>2]|0)+40>>2]=m;b=(Pl(d)|0)&65535;c[c[(c[i>>2]|0)+(f*764|0)+756>>2]>>2]=b;b=Xl(d)|0;o=Xl(d)|0;n=c[j>>2]|0;c[n+(m*52|0)+36>>2]=o;n=c[n+(f*52|0)+36>>2]|0;n=(Xl(d)|0)+n|0;c[(c[j>>2]|0)+(m*52|0)+40>>2]=n;n=((Pl(d)|0)<<16>>16)+128|0;c[(c[(c[i>>2]|0)+(f*764|0)+756>>2]|0)+8>>2]=(n|0)<255?n:255;n=(Pl(d)|0)&65535;c[(c[j>>2]|0)+(m*52|0)+44>>2]=(n&3|0?2:0)|n<<1&4;m=c[(c[i>>2]|0)+(f*764|0)+756>>2]|0;mi(b,m+12|0,m+16|0)}f=f+1|0;if((f|0)>=(c[g>>2]|0)){e=0;b=8;break}}if((b|0)==8){l=k;return e|0}return 0}function Af(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;s=l;l=l+16|0;m=s;if((pb(b)|0)<0){u=-1;l=s;return u|0}o=b+128|0;if((c[o>>2]|0)<=0){u=0;l=s;return u|0}k=b+136|0;q=b+168|0;r=b+172|0;n=0;while(1){if((tb(b,n,(Pl(e)|0)&65535)|0)<0){f=-1;u=36;break}f=Xl(e)|0;a:do if((f|0)>0){p=0;while(1){while(1){d=Kl(e)|0;g=d&255;if((f|0)==1)break a;if(!(d<<24>>24))break;d=g+-1|0;i=(Kl(e)|0)&255;h=f+-2|0;if((h|0)<1)break a;if((g|0)<=(c[k>>2]|0)?(t=c[(c[q>>2]|0)+(n<<2)>>2]|0,(p|0)<(c[t>>2]|0)):0)j=(c[(c[r>>2]|0)+(c[t+4+(d<<2)>>2]<<2)>>2]|0)+4+(p<<3)|0;else j=m;if(i&1){h=(Kl(e)|0)&255;a[j>>0]=(h&15)+13+((h>>>4)*12|0);f=f+-3|0;if((f|0)<1)break a}else f=h;if(i&2){a[j+1>>0]=Kl(e)|0;if((f|0)<2)break a;else f=f+-1|0}if(i&4){a[j+3>>0]=Kl(e)|0;if((f|0)<2)break a;else f=f+-1|0}if(i&8){a[j+4>>0]=Kl(e)|0;if((f|0)<2)break a;else f=f+-1|0}if(i&16){a[j+5>>0]=Kl(e)|0;if((f|0)<2)break a;else f=f+-1|0}if(i&32){a[j+6>>0]=Kl(e)|0;if((f|0)<2)break a;else f=f+-1|0}g=j+3|0;d=a[g>>0]|0;if(d<<24>>24!=28){if((d&255)>28)u=29}else{a[g>>0]=-85;u=29}if((u|0)==29){u=0;a[j+6>>0]=0;a[g>>0]=0}g=j+5|0;d=a[g>>0]|0;if(d<<24>>24!=28){if((d&255)>28)u=33}else{a[g>>0]=-85;u=33}if((u|0)==33){u=0;a[j+6>>0]=0;a[g>>0]=0}if((f|0)<=0)break a}if((f|0)>1){p=p+1|0;f=f+-1|0}else break}}while(0);n=n+1|0;if((n|0)>=(c[o>>2]|0)){f=0;u=36;break}}if((u|0)==36){l=s;return f|0}return 0}function Bf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;j=a+144|0;if((c[j>>2]|0)<=0){a=0;return a|0}k=a+180|0;h=0;while(1){b=Xl(d)|0;f=Xl(d)|0;e=c[k>>2]|0;i=e+(h*52|0)+32|0;c[i>>2]=f;g=e+(h*52|0)+44|0;if(b&2|0)c[g>>2]=c[g>>2]|1;if(!(b&4)){if((Ub(a,d,64,e+(h*52|0)|0,0)|0)<0){e=-1;b=9;break}}else{g=f<<2;c[i>>2]=g;_l(d,g,1)|0}h=h+1|0;if((h|0)>=(c[j>>2]|0)){e=0;b=9;break}}if((b|0)==9)return e|0;return 0}function Cf(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0;g=Pl(e)|0;h=g&65535;if(!(g<<16>>16))return 0;g=a+176|0;f=0;do{a=((Pl(e)|0)&65535)+-1|0;d=(Kl(e)|0)&7;c[(c[g>>2]|0)+(a*764|0)+44>>2]=d;d=(Kl(e)|0)&255;c[(c[g>>2]|0)+(a*764|0)+48>>2]=d;d=(Kl(e)|0)&255;c[(c[g>>2]|0)+(a*764|0)+56>>2]=d;d=(Kl(e)|0)&255;c[(c[g>>2]|0)+(a*764|0)+64>>2]=d;d=(Kl(e)|0)&255;c[(c[g>>2]|0)+(a*764|0)+68>>2]=d;Kl(e)|0;d=0;do{j=Pl(e)|0;i=d<<1;b[(c[g>>2]|0)+(a*764|0)+72+(i<<1)>>1]=j;j=Pl(e)|0;b[(c[g>>2]|0)+(a*764|0)+72+((i|1)<<1)>>1]=j;d=d+1|0}while((d|0)!=32);f=f+1|0}while((f|0)!=(h|0));return 0}function Df(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=l;l=l+1504|0;c=d;if((Zl(c,1,1500,a)|0)>>>0<1500){e=-1;l=d;return e|0}if((gj(c)|0)==-1048368482){a=c;c=0}else{e=-1;l=d;return e|0}while(1){b=gj(a)|0;if((b|0)==1229803597|(en(a,21072,16)|0)==0)break;if((c|0)>44&(b|0)==1396920909){e=5;break}if((c|0)>1080&(b|0)==1294879534){e=7;break}c=c+1|0;if((c|0)<1500)a=a+1|0;else{c=-1;break}}if((e|0)==5)c=c+-44|0;else if((e|0)==7)c=c+-1080|0;e=c>>31;l=d;return e|0}function Ef(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0;g=l;l=l+1504|0;e=g;_l(b,c,0)|0;Zl(e,1,1500,b)|0;c=0;while(1){d=gj(e)|0;if(!(en(e,21072,16)|0)){f=3;break}if((d|0)==1229803597){f=5;break}if((c|0)>44&(d|0)==1396920909){f=7;break}if((c|0)>1080&(d|0)==1294879534){f=9;break}c=c+1|0;if((c|0)<1500)e=e+1|0;else{c=-1;break}}if((f|0)==3)c=cc(a,b,c)|0;else if((f|0)==5)c=hd(a,b,c)|0;else if((f|0)==7)c=jc(a,b,c+-44|0)|0;else if((f|0)==9)c=gc(a,b,c+-1080|0)|0;l=g;return c|0}function Ff(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)!=1195658750){b=-1;return b|0}_l(a,c+71|0,0)|0;if((Xl(a)|0)!=1196246611){b=-1;return b|0}_l(a,c+4|0,0)|0;xb(a,b,32);b=0;return b|0}function Gf(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;u=l;l=l+96|0;k=u+16|0;j=u;q=u+64|0;m=u+32|0;_l(d,e,0)|0;Xl(d)|0;Zl(b,1,32,d)|0;_l(d,32,1)|0;_l(d,7,1)|0;f=(Kl(d)|0)&255;i=(Kl(d)|0)&255;t=Ml(d)|0;g=(Kl(d)|0)&255;h=(Kl(d)|0)&255;if(!(t<<16>>16)){c[j>>2]=f;c[j+4>>2]=i;c[j+8>>2]=g;c[j+12>>2]=h;Eb(b,21111,j)}else{c[k>>2]=f;c[k+4>>2]=i;c[k+8>>2]=g;c[k+12>>2]=h;Eb(b,21138,k)}Zl(m,32,1,d)|0;h=0;do{g=m+h|0;f=a[g>>0]|0;switch(f<<24>>24){case -1:{a[g>>0]=8;c[b+184+(h*12|0)+4>>2]=0;f=b+184+(h*12|0)+8|0;c[f>>2]=c[f>>2]|2;f=8;break}case 16:{a[g>>0]=8;f=8;break}default:{}}c[b+184+(h*12|0)>>2]=(f&255)<<4;h=h+1|0}while((h|0)!=32);c[b+164>>2]=(Kl(d)|0)&255;c[b+148>>2]=(Kl(d)|0)&255;c[b+152>>2]=(Kl(d)|0)&255;Ml(d)|0;o=Vl(d)|0;h=b+156|0;c[h>>2]=((Kl(d)|0)&255)+1;p=Vl(d)|0;s=b+128|0;c[s>>2]=((Kl(d)|0)&255)+1;f=Vl(d)|0;r=Vl(d)|0;n=((Kl(d)|0)&255)+1|0;c[b+144>>2]=n;t=b+140|0;c[t>>2]=n;_l(d,o+e|0,0)|0;if((c[h>>2]|0)>0){g=0;do{a[b+952+g>>0]=Kl(d)|0;g=g+1|0}while((g|0)<(c[h>>2]|0))}_l(d,f+e|0,0)|0;if((nb(b)|0)<0){b=-1;l=u;return b|0}a:do if((c[t>>2]|0)>0){o=b+180|0;n=b+176|0;k=0;while(1){if((ob(b,k,1)|0)<0){f=-1;break}Zl(q,32,1,d)|0;vb(c[n>>2]|0,k,q,32);_l(d,12,1)|0;Kl(d)|0;i=Vl(d)|0;c[(c[o>>2]|0)+(k*52|0)+32>>2]=i;i=Vl(d)|0;c[(c[o>>2]|0)+(k*52|0)+36>>2]=i;i=Vl(d)|0;c[(c[o>>2]|0)+(k*52|0)+40>>2]=i;i=(Kl(d)|0)&255;g=(Ml(d)|0)&65535;m=(Kl(d)|0)&255;j=Kl(d)|0;f=c[(c[n>>2]|0)+(k*764|0)+756>>2]|0;c[f>>2]=m>>>0<64?m:64;c[f+8>>2]=(j&255)>15?128:(j&255)<<4;mi(g,f+12|0,f+16|0);f=c[n>>2]|0;c[(c[f+(k*764|0)+756>>2]|0)+40>>2]=k;g=c[o>>2]|0;j=g+(k*52|0)+44|0;c[j>>2]=0;m=g+(k*52|0)+32|0;h=c[m>>2]|0;if((h|0)>0)c[f+(k*764|0)+36>>2]=1;if(!(i&1))f=1;else{c[j>>2]=2;f=3}if(i&2|0){c[j>>2]=f;c[m>>2]=h>>1;m=g+(k*52|0)+36|0;c[m>>2]=c[m>>2]>>1;m=g+(k*52|0)+40|0;c[m>>2]=c[m>>2]>>1}k=k+1|0;if((k|0)>=(c[t>>2]|0))break a}l=u;return f|0}while(0);m=p+e|0;_l(d,m,0)|0;k=b+136|0;c[k>>2]=0;f=c[s>>2]|0;if((f|0)>0){j=0;do{f=Ml(d)|0;b:do if((f&65535)>2){f=(f&65535)+-2|0;while(1){while(1){q=Kl(d)|0;i=q&255;h=f+-1|0;if(!(q<<24>>24))break;g=i&31;if((c[k>>2]|0)<=(g|0))c[k>>2]=g+1;if(!(i&32))f=h;else{Kl(d)|0;Kl(d)|0;f=f+-3|0}if(i&64)do{g=(Kl(d)|0)&255;if((g&192|0)==192)f=f+-1|0;else{Kl(d)|0;f=f+-2|0}}while((g&32|0)!=0);if((f|0)<=0)break b}if((f|0)>1)f=h;else break}}while(0);j=j+1|0;f=c[s>>2]|0}while((j|0)<(f|0));g=c[k>>2]|0}else g=0;c[b+132>>2]=O(g,f)|0;if((pb(b)|0)<0){b=-1;l=u;return b|0}_l(d,m,0)|0;c:do if((c[s>>2]|0)>0){q=b+172|0;p=b+168|0;o=0;while(1){if((tb(b,o,64)|0)<0){f=-1;break}f=Ml(d)|0;d:do if((f&65535)>2){f=(f&65535)+-2|0;n=0;while(1){while(1){m=Kl(d)|0;h=m&255;g=f+-1|0;if(!(m<<24>>24))break;i=c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+((h&31)<<2)>>2]<<2)>>2]|0;if(!(h&32))f=g;else{m=(Kl(d)|0)&255;a[i+4+(n<<3)>>0]=(m&15)+12+((m>>>4&7)*12|0);a[i+4+(n<<3)+1>>0]=Kl(d)|0;f=f+-3|0}e:do if(h&64){m=i+4+(n<<3)+3|0;k=i+4+(n<<3)+4|0;j=i+4+(n<<3)+5|0;h=i+4+(n<<3)+6|0;while(1){i=Kl(d)|0;g=i&255;switch((i&255)>>>6&3){case 0:{a[m>>0]=g&31;a[k>>0]=Kl(d)|0;Hf(m,k);f=f+-2|0;break}case 1:{a[j>>0]=g&31;a[h>>0]=Kl(d)|0;Hf(j,h);f=f+-2|0;break}case 2:{Kl(d)|0;f=f+-2|0;break}default:f=f+-1|0}if(!(g&32))break e}}while(0);if((f|0)<=0)break d}if((f|0)>1){f=g;n=n+1|0}else break}}while(0);o=o+1|0;if((o|0)>=(c[s>>2]|0))break c}l=u;return f|0}while(0);_l(d,r+e|0,0)|0;g=b+180|0;if((c[t>>2]|0)>0)f=0;else{b=0;l=u;return b|0}while(1){if((Ub(b,d,2,(c[g>>2]|0)+(f*52|0)|0,0)|0)<0){f=-1;g=62;break}f=f+1|0;if((f|0)>=(c[t>>2]|0)){f=0;g=62;break}}if((g|0)==62){l=u;return f|0}return 0}function Hf(b,c){b=b|0;c=c|0;do switch(a[b>>0]|0){case 0:{a[c>>0]=0;break}case 15:case 14:case 13:case 12:case 11:case 10:case 9:case 7:case 6:case 5:case 4:case 3:case 2:case 1:break;case 8:{a[b>>0]=29;break}case 16:{a[b>>0]=-76;break}case 17:{a[c>>0]=0;a[b>>0]=0;break}case 18:{a[b>>0]=27;break}case 19:{a[b>>0]=16;break}case 20:{a[b>>0]=-84;break}case 30:{a[c>>0]=0;a[b>>0]=0;break}case 31:{a[b>>0]=-85;break}default:{a[c>>0]=0;a[b>>0]=0}}while(0);return}function If(a,b,d){a=a|0;b=b|0;d=d|0;if(c[a>>2]|0){b=-1;return b|0}b=Kf(c[a+4>>2]|0)|0;return b|0}function Jf(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+5216|0;q=w+8|0;p=w;r=w+16|0;t=w+5200|0;o=w+12|0;v=w+1104|0;ol(v);k=v+(Zn(v)|0)|0;i=21186;j=k+11|0;do{a[k>>0]=a[i>>0]|0;k=k+1|0;i=i+1|0}while((k|0)<(j|0));i=No(v)|0;if((i|0)<0){v=-1;l=w;return v|0}if((lg(Eo(c[g+4>>2]|0)|0,i,o)|0)<0){Kn(i);xo(v);v=-1;l=w;return v|0}u=em(i)|0;if(!u){Kn(i);xo(v);v=-1;l=w;return v|0}_l(u,h,0)|0;Zl(r,20,1,u)|0;i=0;do{Zl(r+20+(i*30|0)|0,22,1,u)|0;b[r+20+(i*30|0)+22>>1]=Pl(u)|0;a[r+20+(i*30|0)+24>>0]=Kl(u)|0;a[r+20+(i*30|0)+25>>0]=Kl(u)|0;b[r+20+(i*30|0)+26>>1]=Pl(u)|0;b[r+20+(i*30|0)+28>>1]=Pl(u)|0;i=i+1|0}while((i|0)!=31);i=r+950|0;a[i>>0]=Kl(u)|0;g=r+951|0;a[g>>0]=Kl(u)|0;h=r+952|0;Zl(h,128,1,u)|0;s=r+1080|0;Zl(s,4,1,u)|0;a:do if(!(en(s,21197,4)|0)){n=f+140|0;c[n>>2]=31;s=f+144|0;c[s>>2]=31;m=f+136|0;c[m>>2]=4;c[f+156>>2]=d[i>>0];c[f+160>>2]=d[g>>0];k=f+952|0;i=h;j=k+128|0;do{b[k>>1]=b[i>>1]|0;k=k+2|0;i=i+2|0}while((k|0)<(j|0));k=f+128|0;h=4;j=0;do{g=f+952+j|0;i=a[g>>0]|0;if((h|0)>4){i=(i&255)>>>1;a[g>>0]=i}g=i&255;i=c[k>>2]|0;if((g|0)>(i|0)){c[k>>2]=g;i=g}j=j+1|0;h=c[m>>2]|0}while((j|0)!=128);m=i+1|0;c[k>>2]=m;c[f+132>>2]=O(m,h)|0;c[p>>2]=r;ao(f,64,21202,p);c[q>>2]=c[o>>2];ao(f+64|0,64,21202,q);if((nb(f)|0)<0){v=-1;l=w;return v|0}b:do if((c[n>>2]|0)>0){j=f+180|0;h=f+176|0;g=0;while(1){if((ob(f,g,1)|0)<0){i=-1;break}q=b[r+20+(g*30|0)+22>>1]|0;i=c[j>>2]|0;c[i+(g*52|0)+32>>2]=(q&65535)<<1;o=e[r+20+(g*30|0)+26>>1]<<1;c[i+(g*52|0)+36>>2]=o;p=b[r+20+(g*30|0)+28>>1]|0;c[i+(g*52|0)+40>>2]=((p&65535)<<1)+o;c[i+(g*52|0)+44>>2]=(p&65535)>1?2:0;i=c[h>>2]|0;p=c[i+(g*764|0)+756>>2]|0;c[p+16>>2]=d[r+20+(g*30|0)+24>>0]<<28>>24;c[p>>2]=a[r+20+(g*30|0)+25>>0];c[p+8>>2]=128;c[p+40>>2]=g;c[i+(g*764|0)+40>>2]=4095;if(q<<16>>16)c[i+(g*764|0)+36>>2]=1;vb(i,g,r+20+(g*30|0)|0,22);g=g+1|0;if((g|0)>=(c[n>>2]|0))break b}l=w;return i|0}while(0);if((pb(f)|0)<0){v=-1;l=w;return v|0}c:do if((c[k>>2]|0)>0){j=f+172|0;h=f+168|0;i=0;while(1){if((tb(f,i,64)|0)<0){i=-1;break}else g=0;do{r=(c[(c[j>>2]|0)+(c[(c[(c[h>>2]|0)+(i<<2)>>2]|0)+4+(((g|0)%4|0)<<2)>>2]<<2)>>2]|0)+4+(((g|0)/4|0)<<3)|0;Zl(t,1,4,u)|0;Bb(r,t);g=g+1|0}while((g|0)!=256);i=i+1|0;if((i|0)>=(c[k>>2]|0))break c}l=w;return i|0}while(0);t=f+1280|0;c[t>>2]=c[t>>2]|8192;if((c[s>>2]|0)>0){g=f+180|0;i=0;do{if((Ub(f,u,0,(c[g>>2]|0)+(i*52|0)|0,0)|0)<0)break a;i=i+1|0}while((i|0)<(c[s>>2]|0))}dm(u);xo(v);v=0;l=w;return v|0}while(0);dm(u);xo(v);v=-1;l=w;return v|0}function Kf(a){a=a|0;var b=0,c=0,d=0,e=0,f=0;c=Qm(1,65536)|0;if(!c){a=-1;return a|0}Go(c,65536,1,a)|0;b=mg(c,65536)|0;a:do if((b|0)>0){f=c;e=65536;while(1){d=e;e=b+e|0;c=Rm(f,e)|0;if(!c)break;Go(c+d|0,b,1,a)|0;b=mg(c,e)|0;if((b|0)<=0)break a;else f=c}Pm(f);a=-1;return a|0}while(0);Pm(c);a=((b|0)!=0)<<31>>31;return a|0}function Lf(a,b,c){a=a|0;b=b|0;c=c|0;if(((Xl(a)|0)==1380533830?(Xl(a)|0,(Xl(a)|0)==1095573536):0)?(Xl(a)|0)==1229867348:0){Xl(a)|0;xb(a,b,64);a=0}else a=-1;return a|0}function Mf(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0;m=l;l=l+64|0;k=m;_l(b,e,0)|0;Xl(b)|0;Xl(b)|0;Xl(b)|0;g=$l(b)|0;h=a+140|0;c[h>>2]=0;i=a+144|0;c[i>>2]=0;f=Fb()|0;if(!f){a=-1;l=m;return a|0}j=Jb(f,21235,57)|0;j=Jb(f,21293,58)|0|j;j=j|(Jb(f,21298,59)|0);if(j|(Jb(f,21303,60)|0)|0){a=-1;l=m;return a|0}Qb(f,1);Qb(f,16);Qb(f,4);j=(Gb(f,a,b,k)|0)<0;Mb(f);if(j){a=-1;l=m;return a|0}j=a+136|0;c[a+132>>2]=O(c[j>>2]|0,c[a+128>>2]|0)|0;c[i>>2]=c[h>>2];if((nb(a)|0)<0){a=-1;l=m;return a|0}if((pb(a)|0)<0){a=-1;l=m;return a|0}_l(b,g+e|0,0)|0;f=Fb()|0;if(!f){a=-1;l=m;return a|0}e=Jb(f,21298,61)|0;if(Jb(f,21303,62)|0|e|0){a=-1;l=m;return a|0}Qb(f,1);Qb(f,16);Qb(f,4);b=(Gb(f,a,b,k)|0)<0;Mb(f);if(b){a=-1;l=m;return a|0}if((c[j>>2]|0)>0){f=0;do{c[a+184+(f*12|0)>>2]=(d[k+f>>0]|0)<<1;f=f+1|0}while((f|0)<(c[j>>2]|0))}k=a+1280|0;c[k>>2]=c[k>>2]|704643104;c[a+1284>>2]=1;a=0;l=m;return a|0}function Nf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;b=l;l=l+80|0;f=b+8|0;Zl(f,1,64,d)|0;yo(a,f,64)|0;Eb(a,21240,b);if(!((Kl(d)|0)&1)){f=a+1280|0;c[f>>2]=c[f>>2]|4096}c[a+136>>2]=(Kl(d)|0)&255;c[a+148>>2]=(Kl(d)|0)&255;c[a+152>>2]=(Kl(d)|0)&255;Ml(d)|0;Ml(d)|0;Kl(d)|0;Zl(e,1,64,d)|0;l=b;return 0}function Of(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;d=b+156|0;c[d>>2]=((Kl(e)|0)&255)+1;f=0;do{a[b+952+f>>0]=Kl(e)|0;f=f+1|0}while((f|0)<(c[d>>2]|0));return 0}function Pf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;e=(Kl(d)|0)&255;d=a+128|0;if((e|0)<(c[d>>2]|0))return 0;c[d>>2]=e+1;return 0}function Qf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;Xl(d)|0;Kl(d)|0;e=(Kl(d)|0)&255;d=a+140|0;if((e|0)<(c[d>>2]|0))return 0;c[d>>2]=e+1;return 0}function Rf(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0;r=l;l=l+16|0;p=r;o=r+8|0;m=(Kl(e)|0)&255;Vl(e)|0;n=(Kl(e)|0)&255;if((tb(b,m,n+1|0)|0)<0){e=-1;l=r;return e|0}k=b+136|0;q=b+172|0;j=b+168|0;i=0;while(1){f=Kl(e)|0;if(f<<24>>24){h=f&255;while(1){f=h&31;if((f|0)<(c[k>>2]|0))g=(c[(c[q>>2]|0)+(c[(c[(c[j>>2]|0)+(m<<2)>>2]|0)+4+(f<<2)>>2]<<2)>>2]|0)+4+(i<<3)|0;else g=o;if(h&128|0){d=Kl(e)|0;f=Kl(e)|0;b=f&255;if(f<<24>>24!=20){if((f&255)>15){c[p>>2]=b;c[p+4>>2]=d&255;Jo(21308,p);d=0;f=0}}else f=-93;a[g+3>>0]=f;a[g+4>>0]=d}if(h&64|0){a[g+1>>0]=Kl(e)|0;b=Kl(e)|0;a[g>>0]=b<<24>>24==-128?-127:b}if(h&32|0)a[g+2>>0]=(((Kl(e)|0)&255)>>>1)+1<<24>>24;f=Kl(e)|0;if(!(f<<24>>24))break;else h=f&255}}if((i|0)==(n|0)){f=0;break}else i=i+1|0}l=r;return f|0}function Sf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;Xl(d)|0;Kl(d)|0;g=(Kl(d)|0)&255;f=a+176|0;Zl((c[f>>2]|0)+(g*764|0)|0,1,28,d)|0;pl((c[f>>2]|0)+(g*764|0)|0)|0;_l(d,290,1)|0;b=Ml(d)|0;e=b&65535;c[(c[f>>2]|0)+(g*764|0)+36>>2]=e;if(!(b<<16>>16)){a=0;return a|0}if((ob(a,g,e)|0)<0){a=-1;return a|0}Xl(d)|0;Xl(d)|0;Xl(d)|0;Xl(d)|0;Xl(d)|0;Xl(d)|0;e=a+180|0;Zl((c[e>>2]|0)+(g*52|0)|0,1,28,d)|0;pl((c[e>>2]|0)+(g*52|0)|0)|0;Xl(d)|0;Kl(d)|0;c[(c[(c[f>>2]|0)+(g*764|0)+756>>2]|0)+40>>2]=g;i=(Kl(d)|0)&255;b=c[f>>2]|0;c[b+(g*764|0)+32>>2]=i;c[(c[b+(g*764|0)+756>>2]|0)+8>>2]=128;b=(((Ml(d)|0)&65535)+1|0)>>>9;c[c[(c[f>>2]|0)+(g*764|0)+756>>2]>>2]=b;b=(Ml(d)|0)&65535;Ml(d)|0;i=Vl(d)|0;c[(c[e>>2]|0)+(g*52|0)+32>>2]=i;i=Vl(d)|0;c[(c[e>>2]|0)+(g*52|0)+36>>2]=i;i=Vl(d)|0;h=c[e>>2]|0;c[h+(g*52|0)+40>>2]=i;c[h+(g*52|0)+44>>2]=b>>>2&1|((b&16|0)==0?b>>>2&2:6);h=Vl(d)|0;f=c[(c[f>>2]|0)+(g*764|0)+756>>2]|0;mi(h,f+12|0,f+16|0);Vl(d)|0;Vl(d)|0;e=c[e>>2]|0;if((c[e+(g*52|0)+32>>2]|0)>1?(Ub(a,d,b>>>6&2^2,e+(g*52|0)|0,0)|0)<0:0){i=-1;return i|0}i=0;return i|0}function Tf(a,b,c){a=a|0;b=b|0;c=c|0;if(((Xl(a)|0)==1380533830?(Xl(a)|0,(Xl(a)|0)==1095583302):0)?(Xl(a)|0)==1296124238:0){Xl(a)|0;xb(a,b,64);a=0}else a=-1;return a|0}function Uf(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;i=l;l=l+16|0;h=i;_l(b,d,0)|0;Xl(b)|0;Xl(b)|0;Xl(b)|0;f=$l(b)|0;c[a+140>>2]=0;c[a+144>>2]=0;e=Fb()|0;if(!e){a=-1;l=i;return a|0}g=Jb(e,21288,63)|0;g=Jb(e,21293,64)|0|g;g=g|(Jb(e,21298,65)|0);if(g|(Jb(e,21303,66)|0)|0){a=-1;l=i;return a|0}Qb(e,1);Qb(e,32);g=(Gb(e,a,b,h)|0)<0;Mb(e);if(g){a=-1;l=i;return a|0}g=a+136|0;c[a+132>>2]=O(c[g>>2]|0,c[a+128>>2]|0)|0;if((nb(a)|0)<0){a=-1;l=i;return a|0}if((pb(a)|0)<0){a=-1;l=i;return a|0}_l(b,f+d|0,0)|0;c[h>>2]=0;e=Fb()|0;if(!e){a=-1;l=i;return a|0}d=Jb(e,21298,67)|0;if(Jb(e,21303,68)|0|d|0){a=-1;l=i;return a|0}Qb(e,1);Qb(e,32);b=(Gb(e,a,b,h)|0)<0;Mb(e);if(b){a=-1;l=i;return a|0}if((c[g>>2]|0)>0){e=0;do{c[a+184+(e*12|0)>>2]=128;e=e+1|0}while((e|0)<(c[g>>2]|0))}b=a+1280|0;c[b>>2]=c[b>>2]|704643104;c[a+1284>>2]=1;a=0;l=i;return a|0}function Vf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;e=l;l=l+80|0;b=e+8|0;Zl(b,1,64,d)|0;yo(a,b,64)|0;Eb(a,21264,e);if(!((Kl(d)|0)&1))c[a+1280>>2]=4096;c[a+136>>2]=(Kl(d)|0)&255;c[a+148>>2]=(Kl(d)|0)&255;c[a+152>>2]=(Kl(d)|0)&255;Ml(d)|0;Ml(d)|0;Kl(d)|0;l=e;return 0}function Wf(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;f=Kl(e)|0;d=b+156|0;c[d>>2]=f&255;if(!(f<<24>>24))return 0;else f=0;do{a[b+952+f>>0]=Kl(e)|0;f=f+1|0}while((f|0)<(c[d>>2]|0));return 0}function Xf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;e=(Kl(d)|0)&255;d=a+128|0;if((e|0)<(c[d>>2]|0))return 0;c[d>>2]=e+1;return 0}function Yf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;Kl(d)|0;e=(Kl(d)|0)&255;b=a+140|0;if((e|0)>=(c[b>>2]|0))c[b>>2]=e+1;_l(d,28,1)|0;d=(Kl(d)|0)&255;a=a+144|0;c[a>>2]=(c[a>>2]|0)+d;return 0}function Zf(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0;r=l;l=l+16|0;p=r;o=r+8|0;m=(Kl(e)|0)&255;Vl(e)|0;n=(Kl(e)|0)&255;if((tb(b,m,n+1|0)|0)<0){e=-1;l=r;return e|0}k=b+136|0;q=b+172|0;j=b+168|0;i=0;while(1){f=Kl(e)|0;if(f<<24>>24){h=f&255;while(1){f=h&31;if((f|0)<(c[k>>2]|0))g=(c[(c[q>>2]|0)+(c[(c[(c[j>>2]|0)+(m<<2)>>2]|0)+4+(f<<2)>>2]<<2)>>2]|0)+4+(i<<3)|0;else g=o;if(h&128|0){d=Kl(e)|0;f=Kl(e)|0;b=f&255;if(f<<24>>24!=20){if((f&255)>15){c[p>>2]=b;c[p+4>>2]=d&255;Jo(21308,p);d=0;f=0}}else f=-93;a[g+3>>0]=f;a[g+4>>0]=d}if(h&64|0){a[g+1>>0]=Kl(e)|0;b=Kl(e)|0;a[g>>0]=b<<24>>24==-128?-127:b}if(h&32|0)a[g+2>>0]=(((Kl(e)|0)&255)>>>1)+1<<24>>24;f=Kl(e)|0;if(!(f<<24>>24))break;else h=f&255}}if((i|0)==(n|0)){f=9;break}else i=i+1|0}l=r;return f|0}function _f(e,f,g,h){e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;s=l;l=l+32|0;k=s;Kl(g)|0;q=(Kl(g)|0)&255;r=e+176|0;Zl((c[r>>2]|0)+(q*764|0)|0,1,28,g)|0;pl((c[r>>2]|0)+(q*764|0)|0)|0;f=(Kl(g)|0)&255;c[(c[r>>2]|0)+(q*764|0)+36>>2]=f;f=0;do{p=Kl(g)|0;a[(c[r>>2]|0)+(q*764|0)+512+(f<<1)>>0]=p;f=f+1|0}while((f|0)!=108);_l(g,11,1)|0;m=(Kl(g)|0)&255;n=(Kl(g)|0)&255;Kl(g)|0;Kl(g)|0;o=((Kl(g)|0)&255)>>>2&255;p=((Ml(g)|0)&65535)>>>4&65535;Kl(g)|0;f=(Kl(g)|0)&255;if(f&1|0){j=(c[r>>2]|0)+(q*764|0)+44|0;c[j>>2]=c[j>>2]|1}if(f&2|0){j=(c[r>>2]|0)+(q*764|0)+44|0;c[j>>2]=c[j>>2]|2}if(f&4|0){j=(c[r>>2]|0)+(q*764|0)+44|0;c[j>>2]=c[j>>2]|4}f=f>>>4;if(f&1|0){j=(c[r>>2]|0)+(q*764|0)+200|0;c[j>>2]=c[j>>2]|1}if(f&2|0){j=(c[r>>2]|0)+(q*764|0)+200|0;c[j>>2]=c[j>>2]|2}if(f&4|0){j=(c[r>>2]|0)+(q*764|0)+200|0;c[j>>2]=c[j>>2]|4}f=(Kl(g)|0)&255;j=c[r>>2]|0;c[j+(q*764|0)+48>>2]=(f&15)+1;c[j+(q*764|0)+204>>2]=(f>>>4)+1;j=(Kl(g)|0)&255;f=c[r>>2]|0;c[f+(q*764|0)+56>>2]=j&15;c[f+(q*764|0)+212>>2]=j>>>4;f=(Kl(g)|0)&255;j=f&15;i=c[r>>2]|0;c[i+(q*764|0)+64>>2]=j;f=f>>>4;c[i+(q*764|0)+220>>2]=f;Kl(g)|0;i=c[r>>2]|0;c[i+(q*764|0)+68>>2]=j;c[i+(q*764|0)+224>>2]=f;f=i+(q*764|0)+44|0;if(((c[i+(q*764|0)+48>>2]|0)+-1|0)>>>0>30)c[f>>2]=c[f>>2]&-2;f=i+(q*764|0)+200|0;if(((c[i+(q*764|0)+204>>2]|0)+-1|0)>>>0>30)c[f>>2]=c[f>>2]&-2;Zl(k,1,30,g)|0;f=c[r>>2]|0;j=f+(q*764|0)+48|0;if((c[j>>2]|0)>0){i=0;do{u=i*3|0;v=k+u|0;t=i<<1;b[f+(q*764|0)+72+(t<<1)>>1]=((bj(a[v>>0]|0,a[v+1>>0]|0)|0)&65535)>>>4;b[f+(q*764|0)+72+((t|1)<<1)>>1]=d[k+(u+2)>>0]|0;i=i+1|0}while((i|0)<(c[j>>2]|0))}Zl(k,1,30,g)|0;f=c[r>>2]|0;j=f+(q*764|0)+204|0;if((c[j>>2]|0)>0){i=0;do{u=i*3|0;t=k+u|0;v=i<<1;b[f+(q*764|0)+228+(v<<1)>>1]=((bj(a[t>>0]|0,a[t+1>>0]|0)|0)&65535)>>>4;b[f+(q*764|0)+228+((v|1)<<1)>>1]=d[k+(u+2)>>0]|0;i=i+1|0}while((i|0)<(c[j>>2]|0))}Kl(g)|0;Kl(g)|0;f=c[(c[r>>2]|0)+(q*764|0)+36>>2]|0;if(!f){v=0;l=s;return v|0}if((ob(e,q,f)|0)<0){v=-1;l=s;return v|0}if((c[(c[r>>2]|0)+(q*764|0)+36>>2]|0)<=0){v=0;l=s;return v|0}k=e+180|0;j=0;while(1){Xl(g)|0;Xl(g)|0;Zl((c[k>>2]|0)+((c[h>>2]|0)*52|0)|0,1,28,g)|0;pl((c[k>>2]|0)+((c[h>>2]|0)*52|0)|0)|0;v=Kl(g)|0;c[(c[(c[r>>2]|0)+(q*764|0)+756>>2]|0)+(j<<6)+8>>2]=v<<24>>24==0?128:(v&255)<<2;v=(Kl(g)|0)&255;c[(c[(c[r>>2]|0)+(q*764|0)+756>>2]|0)+(j<<6)>>2]=v;v=(Kl(g)|0)&255;Kl(g)|0;u=c[(c[r>>2]|0)+(q*764|0)+756>>2]|0;c[u+(j<<6)+20>>2]=m;c[u+(j<<6)+24>>2]=o;c[u+(j<<6)+28>>2]=p;c[u+(j<<6)+32>>2]=n;c[u+(j<<6)+40>>2]=c[h>>2];u=Vl(g)|0;c[(c[k>>2]|0)+((c[h>>2]|0)*52|0)+32>>2]=u;u=Vl(g)|0;c[(c[k>>2]|0)+((c[h>>2]|0)*52|0)+36>>2]=u;u=Vl(g)|0;i=c[k>>2]|0;f=c[h>>2]|0;c[i+(f*52|0)+40>>2]=u;c[i+(f*52|0)+44>>2]=v>>>2&4|(v>>>2&2|v>>>2&1);f=Vl(g)|0;i=c[(c[r>>2]|0)+(q*764|0)+756>>2]|0;mi(f,i+(j<<6)+12|0,i+(j<<6)+16|0);Vl(g)|0;Vl(g)|0;i=c[k>>2]|0;f=c[h>>2]|0;if((c[i+(f*52|0)+32>>2]|0)>1){if((Ub(e,g,0,i+(f*52|0)|0,0)|0)<=-1){f=-1;i=31;break}f=c[h>>2]|0}j=j+1|0;c[h>>2]=f+1;if((j|0)>=(c[(c[r>>2]|0)+(q*764|0)+36>>2]|0)){f=0;i=31;break}}if((i|0)==31){l=s;return f|0}return 0}function $f(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0;m=l;l=l+384|0;k=m;if(c[b>>2]|0){e=-1;l=m;return e|0}if((Zl(k,1,384,b)|0)>>>0<384){e=-1;l=m;return e|0}if((a[k+249>>0]|0)==127)j=0;else{e=-1;l=m;return e|0}while(1){f=j<<3;g=k+f|0;i=cj(a[g>>0]|0,a[g+1>>0]|0)|0;if(i<<16>>16<0){f=-1;g=14;break}if((d[k+(f|2)>>0]|0)>15){f=-1;g=14;break}if((d[k+(f|3)>>0]|0)>64){f=-1;g=14;break}h=cj(a[g+4>>0]|0,a[g+5>>0]|0)|0;if((h&65535)>(i&65535)){f=-1;g=14;break}f=cj(a[g+6>>0]|0,a[g+7>>0]|0)|0;if(((h&65535)+-1+(f&65535)|0)>(i&65535|0)){f=-1;g=14;break}j=j+1|0;if(i<<16>>16!=0&f<<16>>16==0){f=-1;g=14;break}if((j|0)>=31){g=11;break}}if((g|0)==11){j=d[k+248>>0]|0;f=cj(a[k+378>>0]|0,a[k+379>>0]|0)|0;if((j|0)!=(f&65535|0)){e=-1;l=m;return e|0}if(f<<16>>16!=(cj(a[k+380>>0]|0,a[k+381>>0]|0)|0)<<16>>16){e=-1;l=m;return e|0}xb(b,e,0);e=0;l=m;return e|0}else if((g|0)==14){l=m;return f|0}return 0}function ag(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;F=l;l=l+7296|0;A=F+32|0;y=F+24|0;x=F+16|0;w=F+8|0;v=F+2088|0;z=F+3192|0;t=F+40|0;r=F+2168|0;s=F+36|0;_l(e,f,0)|0;Eb(b,21334,F);h=b+136|0;c[h>>2]=4;c[b+144>>2]=31;C=b+140|0;c[C>>2]=31;if((nb(b)|0)<0){E=-1;l=F;return E|0}E=b+180|0;D=b+176|0;g=0;do{if((ob(b,g,1)|0)<0){f=-1;B=38;break}f=((Pl(e)|0)&65535)<<1;c[(c[E>>2]|0)+(g*52|0)+32>>2]=f;f=((Kl(e)|0)&255)<<28>>24;c[(c[(c[D>>2]|0)+(g*764|0)+756>>2]|0)+16>>2]=f;f=(Kl(e)|0)&255;c[c[(c[D>>2]|0)+(g*764|0)+756>>2]>>2]=f;f=((Pl(e)|0)&65535)<<1;c[(c[E>>2]|0)+(g*52|0)+36>>2]=f;f=Pl(e)|0;q=c[E>>2]|0;c[q+(g*52|0)+40>>2]=(c[q+(g*52|0)+36>>2]|0)+((f&65535)<<1);c[q+(g*52|0)+44>>2]=(f&65535)>1?2:0;f=c[D>>2]|0;p=c[f+(g*764|0)+756>>2]|0;c[p+8>>2]=128;c[p+40>>2]=g;c[f+(g*764|0)+40>>2]=4095;if((c[q+(g*52|0)+32>>2]|0)>0)c[f+(g*764|0)+36>>2]=1;g=g+1|0}while((g|0)<31);if((B|0)==38){l=F;return f|0}f=(Kl(e)|0)&255;q=b+128|0;c[q>>2]=f;c[b+156>>2]=f;Kl(e)|0;f=0;do{a[b+952+f>>0]=Kl(e)|0;f=f+1|0}while((f|0)!=128);c[b+132>>2]=O(c[h>>2]|0,c[q>>2]|0)|0;if((pb(b)|0)<0){E=-1;l=F;return E|0}p=Pl(e)|0;f=p&65535;Pl(e)|0;if(p<<16>>16){g=0;do{c[t+(g<<4)>>2]=(Pl(e)|0)&65535;c[t+(g<<4)+4>>2]=(Pl(e)|0)&65535;c[t+(g<<4)+8>>2]=(Pl(e)|0)&65535;c[t+(g<<4)+12>>2]=(Pl(e)|0)&65535;g=g+1|0}while((g|0)!=(f|0))}g=$l(e)|0;a:do if((c[q>>2]|0)>0){p=b+172|0;o=b+168|0;h=0;while(1){if((tb(b,h,64)|0)<0){f=-1;break}else i=0;do{_l(e,(c[t+(h<<4)+(i<<2)>>2]|0)+g|0,0)|0;Zl(r,1,1024,e)|0;j=0;k=0;while(1){f=r+j|0;m=k;n=0;while(1){G=(c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(h<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+(m<<3)|0;H=r+(d[r+(d[r+((d[f>>0]|0)+n)>>0]|0)>>0]<<1)|0;c[s>>2]=d[H>>0]|d[H+1>>0]<<8|d[H+2>>0]<<16|d[H+3>>0]<<24;Bb(G,s);G=m|1;H=(c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(h<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+(G<<3)|0;I=r+(d[r+((d[r+((d[f>>0]|0)+n)>>0]|0)+1)>>0]<<1)|0;c[s>>2]=d[I>>0]|d[I+1>>0]<<8|d[I+2>>0]<<16|d[I+3>>0]<<24;Bb(H,s);G=(c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(h<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+(G+1<<3)|0;H=r+(d[r+((d[r+((d[f>>0]|0)+n)>>0]|0)+2)>>0]<<1)|0;c[s>>2]=d[H>>0]|d[H+1>>0]<<8|d[H+2>>0]<<16|d[H+3>>0]<<24;Bb(G,s);G=(c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(h<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+((m|3)<<3)|0;H=r+(d[r+((d[r+((d[f>>0]|0)+n)>>0]|0)+3)>>0]<<1)|0;c[s>>2]=d[H>>0]|d[H+1>>0]<<8|d[H+2>>0]<<16|d[H+3>>0]<<24;Bb(G,s);n=n+1|0;if((n|0)==4)break;else m=m+4|0}j=j+1|0;if((j|0)==4)break;else k=k+16|0}i=i+1|0}while((i|0)!=4);h=h+1|0;if((h|0)>=(c[q>>2]|0))break a}l=F;return f|0}while(0);g=b+1212|0;f=c[g>>2]|0;do if((Zn(f)|0)>>>0>=5?(a[f+3>>0]|0)==46:0){a[f>>0]=115;a[(c[g>>2]|0)+1>>0]=109;a[(c[g>>2]|0)+2>>0]=112;I=c[g>>2]|0;c[x>>2]=c[b+1208>>2];c[x+4>>2]=I;ao(z,4096,21386,x);if((go(z,v)|0)<0){if(_n(c[g>>2]|0,45)|0?(u=vo(z,45)|0,u|0):0){a[u>>0]=a[21391]|0;a[u+1>>0]=a[21392]|0;a[u+2>>0]=a[21393]|0;a[u+3>>0]=a[21394]|0;a[u+4>>0]=a[21395]|0}if((go(z,v)|0)<0){c[y>>2]=z;so(0,21396,y);break}}g=bm(z,21621)|0;if(!g){c[A>>2]=z;so(0,21421,A);break}b:do if((c[C>>2]|0)>0){f=0;while(1){if((Ub(b,g,512,(c[E>>2]|0)+((c[(c[(c[D>>2]|0)+(f*764|0)+756>>2]|0)+40>>2]|0)*52|0)|0,0)|0)<0){f=-1;break}f=f+1|0;if((f|0)>=(c[C>>2]|0))break b}l=F;return f|0}while(0);dm(g);I=b+1280|0;c[I>>2]=c[I>>2]|8192;I=0;l=F;return I|0}else B=23;while(0);if((B|0)==23){c[w>>2]=f;so(0,21357,w)}if((c[C>>2]|0)>0)f=0;else{I=0;l=F;return I|0}do{c[(c[D>>2]|0)+(f*764|0)+36>>2]=0;g=(c[E>>2]|0)+(f*52|0)|0;h=g+52|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));f=f+1|0}while((f|0)<(c[C>>2]|0));f=0;l=F;return f|0}function bg(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+32|0;c=d;if((Zl(c,1,32,a)|0)>>>0>=32?(en(c,21481,32)|0)==0:0){xb(a,b,0);c=0}else c=-1;l=d;return c|0}function cg(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;u=l;l=l+48|0;q=u;_l(e,f,0)|0;_l(e,32,1)|0;c[b+148>>2]=(Kl(e)|0)&255;c[b+152>>2]=(Kl(e)|0)&255;t=b+140|0;c[t>>2]=(Kl(e)|0)&255;s=b+128|0;c[s>>2]=(Kl(e)|0)&255;r=b+156|0;c[r>>2]=(Kl(e)|0)&255;Kl(e)|0;Zl(b+952|0,1,c[r>>2]|0,e)|0;_l(e,f+294|0,0)|0;r=b+136|0;c[r>>2]=8;c[b+144>>2]=c[t>>2];c[b+132>>2]=c[s>>2]<<3;ao(b+64|0,64,21456,q);if((nb(b)|0)<0){b=-1;l=u;return b|0}f=c[t>>2]|0;a:do if((f|0)>0){j=q+22|0;o=b+176|0;k=q+23|0;m=q+24|0;g=q+25|0;p=b+180|0;h=q+29|0;i=q+33|0;n=0;while(1){if((ob(b,n,1)|0)<0)break;Zl(q,1,37,e)|0;vb(c[o>>2]|0,n,q,22);v=c[(c[o>>2]|0)+(n*764|0)+756>>2]|0;c[v+16>>2]=d[j>>0]<<28>>24;c[v>>2]=d[k>>0];c[v+12>>2]=a[m>>0];c[v+8>>2]=128;c[v+40>>2]=n;v=fj(g)|0;f=c[p>>2]|0;c[f+(n*52|0)+32>>2]=v;v=fj(h)|0;c[f+(n*52|0)+36>>2]=v;v=(fj(i)|0)+v|0;c[f+(n*52|0)+40>>2]=v;c[f+(n*52|0)+44>>2]=(v|0)>2?2:0;n=n+1|0;f=c[t>>2]|0;if((n|0)>=(f|0))break a}v=-1;l=u;return v|0}while(0);_l(e,(64-f|0)*37|0,1)|0;if((pb(b)|0)<0){v=-1;l=u;return v|0}b:do if((c[s>>2]|0)>0){n=b+172|0;m=b+168|0;k=0;while(1){if((tb(b,k,64)|0)<0){f=-1;break}f=c[r>>2]|0;if((f|0)>0){j=0;do{i=c[(c[n>>2]|0)+(c[(c[(c[m>>2]|0)+(k<<2)>>2]|0)+4+(((j|0)%(f|0)|0)<<2)>>2]<<2)>>2]|0;h=(j|0)/(f|0)|0;f=i+4+(h<<3)|0;g=f;v=g;a[v>>0]=0;a[v+1>>0]=0;a[v+2>>0]=0;a[v+3>>0]=0;g=g+4|0;a[g>>0]=0;a[g+1>>0]=0;a[g+2>>0]=0;a[g+3>>0]=0;g=Kl(e)|0;if(g<<24>>24)a[f>>0]=(g&255)+13;a[i+4+(h<<3)+1>>0]=Kl(e)|0;a[i+4+(h<<3)+3>>0]=Kl(e)|0;a[i+4+(h<<3)+4>>0]=Kl(e)|0;j=j+1|0;f=c[r>>2]|0}while((j|0)<(f<<6|0))}k=k+1|0;if((k|0)>=(c[s>>2]|0))break b}l=u;return f|0}while(0);f=c[t>>2]|0;if((f|0)<=0){v=0;l=u;return v|0}j=b+180|0;i=b+176|0;h=0;while(1){g=c[j>>2]|0;if((c[g+(h*52|0)+32>>2]|0)>1){if((Ub(b,e,0,g+(h*52|0)|0,0)|0)<0){f=-1;g=22;break}c[(c[i>>2]|0)+(h*764|0)+36>>2]=1;f=c[t>>2]|0}h=h+1|0;if((h|0)>=(f|0)){f=0;g=22;break}}if((g|0)==22){l=u;return f|0}return 0}function dg(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;_l(a,c+1080|0,0)|0;d=Xl(a)|0;if((d|0)<1294355233)switch(d|0){case 1178948436:{e=2;break}default:d=-1}else switch(d|0){case 1294355233:{e=2;break}default:d=-1}if((e|0)==2){_l(a,c,0)|0;xb(a,b,20);d=0}return d|0}function eg(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;B=l;l=l+1232|0;u=B+8|0;n=B;t=B+20|0;A=B+1108|0;x=B+1104|0;_l(g,h,0)|0;i=A;k=i+124|0;do{a[i>>0]=0;i=i+1|0}while((i|0)<(k|0));Zl(t,20,1,g)|0;j=0;i=0;do{v=t+20+(j*30|0)|0;Zl(v,22,1,g)|0;if(!(en(v,21533,4)|0)){a[A+(j<<2)>>0]=1;a[A+(j<<2)+1>>0]=a[t+20+(j*30|0)+4>>0]|0;a[A+(j<<2)+2>>0]=a[t+20+(j*30|0)+5>>0]|0;a[A+(j<<2)+3>>0]=a[t+20+(j*30|0)+6>>0]|0;i=i+1|0}b[t+20+(j*30|0)+22>>1]=Pl(g)|0;a[t+20+(j*30|0)+24>>0]=Kl(g)|0;a[t+20+(j*30|0)+25>>0]=Kl(g)|0;b[t+20+(j*30|0)+26>>1]=Pl(g)|0;b[t+20+(j*30|0)+28>>1]=Pl(g)|0;j=j+1|0}while((j|0)!=31);v=t+950|0;a[v>>0]=Kl(g)|0;k=t+951|0;a[k>>0]=Kl(g)|0;j=t+952|0;Zl(j,128,1,g)|0;m=t+1080|0;Zl(m,4,1,g)|0;c[f+136>>2]=4;s=f+140|0;c[s>>2]=31;c[f+144>>2]=(i*28|0)+31;c[f+156>>2]=d[v>>0];c[f+160>>2]=d[k>>0];i=f+952|0;k=i+128|0;do{b[i>>1]=b[j>>1]|0;i=i+2|0;j=j+2|0}while((i|0)<(k|0));v=f+128|0;i=c[v>>2]|0;k=0;do{j=d[f+952+k>>0]|0;if((j|0)>(i|0)){c[v>>2]=j;i=j}k=k+1|0}while((k|0)!=128);r=i+1|0;c[v>>2]=r;c[f+132>>2]=r<<2;if(lm(f)|0){A=-1;l=B;return A|0}yo(f,t,20)|0;c[n>>2]=21514;c[n+4>>2]=m;Eb(f,21538,n);if((nb(f)|0)<0){A=-1;l=B;return A|0}a:do if((c[s>>2]|0)>0){q=f+176|0;r=f+180|0;o=0;p=c[q>>2]|0;while(1){i=p+(o*764|0)+36|0;if(a[A+(o<<2)>>0]|0){c[i>>2]=28;m=d[A+(o<<2)+2>>0]|0;n=d[A+(o<<2)+3>>0]|0;c[u>>2]=d[A+(o<<2)+1>>0];c[u+4>>2]=m;c[u+8>>2]=n;ao(p+(o*764|0)|0,32,21549,u);if(hm((c[q>>2]|0)+(o*764|0)|0)|0){y=-1;z=40;break}}else{c[i>>2]=1;vb(p,o,t+20+(o*30|0)|0,22);p=c[r>>2]|0;c[p+(o*52|0)+32>>2]=e[t+20+(o*30|0)+22>>1]<<1;m=e[t+20+(o*30|0)+26>>1]<<1;c[p+(o*52|0)+36>>2]=m;n=b[t+20+(o*30|0)+28>>1]|0;c[p+(o*52|0)+40>>2]=((n&65535)<<1)+m;c[p+(o*52|0)+44>>2]=(n&65535)>1?2:0}if((ob(f,o,c[(c[q>>2]|0)+(o*764|0)+36>>2]|0)|0)<0){y=-1;z=40;break}p=c[q>>2]|0;j=c[p+(o*764|0)+36>>2]|0;if((j|0)>0){n=0-(d[t+20+(o*30|0)+24>>0]<<27>>24)|0;k=a[t+20+(o*30|0)+25>>0]|0;i=c[p+(o*764|0)+756>>2]|0;m=0;do{c[i+(m<<6)+16>>2]=n;c[i+(m<<6)>>2]=k;c[i+(m<<6)+8>>2]=128;c[i+(m<<6)+40>>2]=o;m=m+1|0}while((m|0)!=(j|0))}o=o+1|0;if((o|0)>=(c[s>>2]|0))break a}if((z|0)==40){l=B;return y|0}}while(0);if((pb(f)|0)<0){A=-1;l=B;return A|0}b:do if((c[v>>2]|0)>0){p=f+172|0;o=f+168|0;m=0;while(1){if((tb(f,m,64)|0)<0){y=-1;break}else n=0;do{i=c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(m<<2)>>2]|0)+4+(((n|0)%4|0)<<2)>>2]<<2)>>2]|0;j=(n|0)/4|0;Zl(x,1,4,g)|0;Bb(i+4+(j<<3)|0,x);k=i+4+(j<<3)+3|0;switch(a[k>>0]|0){case 7:{w=-78;z=27;break}case 14:case 9:case 8:{a[i+4+(j<<3)+4>>0]=0;w=0;z=27;break}default:{}}if((z|0)==27){z=0;a[k>>0]=w}n=n+1|0}while((n|0)!=256);m=m+1|0;if((m|0)>=(c[v>>2]|0))break b}l=B;return y|0}while(0);q=f+1280|0;c[q>>2]=c[q>>2]|8192;q=f+180|0;i=0;do{if((Ub(f,g,512,(c[q>>2]|0)+(i*52|0)|0,0)|0)<0){y=-1;z=40;break}i=i+1|0}while((i|0)<31);if((z|0)==40){l=B;return y|0}p=f+176|0;n=h+1084|0;o=0;i=0;c:while(1){j=c[(c[p>>2]|0)+(o*764|0)+760>>2]|0;if(a[A+(o<<2)>>0]|0){_l(g,n+(d[A+(o<<2)+1>>0]<<10)|0,0)|0;k=(i*28|0)+31|0;m=0;do{h=k+m|0;c[(c[(c[p>>2]|0)+(o*764|0)+756>>2]|0)+(m<<6)+40>>2]=h;z=c[q>>2]|0;c[z+(h*52|0)+32>>2]=32;c[z+(h*52|0)+36>>2]=0;c[z+(h*52|0)+40>>2]=32;c[z+(h*52|0)+44>>2]=2;m=m+1|0;if((Ub(f,g,0,z+(h*52|0)|0,0)|0)<=-1){y=-1;z=40;break c}}while((m|0)<28);c[j+4>>2]=d[A+(o<<2)+2>>0];c[j+8>>2]=d[A+(o<<2)+3>>0];Zl(j+12|0,1,64,g)|0;Zl(j+76|0,1,64,g)|0;i=i+1|0}o=o+1|0;if((o|0)>=31){y=0;z=40;break}}if((z|0)==40){l=B;return y|0}return 0}function fg(a,b,c){a=a|0;b=b|0;c=c|0;if((Tl(a)|0)!=5064532){b=-1;return b|0}Kl(a)|0;if((Xl(a)|0)!=-1119009965){b=-1;return b|0}_l(a,18,1)|0;_l(a,(Xl(a)|0)+c|0,0)|0;xb(a,b,32);b=0;return b|0}function gg(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+272|0;s=w;v=w+8|0;_l(d,e,0)|0;Tl(d)|0;i=(Kl(d)|0)&255;Xl(d)|0;c[s>>2]=i>>>4;c[s+4>>2]=i&15;Eb(b,21581,s);s=b+136|0;c[s>>2]=(Pl(d)|0)&65535;Pl(d)|0;i=b+156|0;c[i>>2]=(Pl(d)|0)&65535;t=b+128|0;c[t>>2]=(Pl(d)|0)&65535;p=b+132|0;c[p>>2]=(Pl(d)|0)&65535;f=(Pl(d)|0)&65535;c[b+144>>2]=f;u=b+140|0;c[u>>2]=f;Pl(d)|0;Xl(d)|0;f=Xl(d)|0;Xl(d)|0;h=Xl(d)|0;q=Xl(d)|0;j=Xl(d)|0;Xl(d)|0;Xl(d)|0;Xl(d)|0;_l(d,f+e|0,0)|0;Zl(b,1,32,d)|0;f=Xl(d)|0;c[i>>2]=(Pl(d)|0)&65535;c[b+160>>2]=(Pl(d)|0)&65535;c[b+152>>2]=(Kl(d)|0)&255;c[b+148>>2]=(Kl(d)|0)&255;Pl(d)|0;Kl(d)|0;Kl(d)|0;if((c[s>>2]|0)>0){g=0;do{Pl(d)|0;g=g+1|0}while((g|0)<(c[s>>2]|0))}_l(d,f+e|0,0)|0;if((c[i>>2]|0)>0){f=0;do{a[b+952+f>>0]=Pl(d)|0;f=f+1|0}while((f|0)<(c[i>>2]|0))}if((nb(b)|0)<0){e=-1;l=w;return e|0}_l(d,h+e|0,0)|0;a:do if((c[u>>2]|0)>0){g=b+176|0;h=b+180|0;f=0;while(1){if((ob(b,f,1)|0)<0){f=-1;break}Zl((c[g>>2]|0)+(f*764|0)|0,1,32,d)|0;c[v+(f<<2)>>2]=Xl(d)|0;n=Xl(d)|0;c[(c[h>>2]|0)+(f*52|0)+32>>2]=n;n=Xl(d)|0;c[(c[h>>2]|0)+(f*52|0)+36>>2]=n;n=(Xl(d)|0)+n|0;c[(c[h>>2]|0)+(f*52|0)+40>>2]=n;Xl(d)|0;Xl(d)|0;n=Xl(d)|0;o=c[(c[g>>2]|0)+(f*764|0)+756>>2]|0;mi(n,o+12|0,o+16|0);o=((Pl(d)|0)&65535)>>>4;c[c[(c[g>>2]|0)+(f*764|0)+756>>2]>>2]=o;Kl(d)|0;Kl(d)|0;c[(c[(c[g>>2]|0)+(f*764|0)+756>>2]|0)+8>>2]=128;o=(Kl(d)|0)&255;c[(c[h>>2]|0)+(f*52|0)+44>>2]=(o&3|0?2:0)|o<<1&4;Kl(d)|0;Kl(d)|0;Kl(d)|0;Kl(d)|0;Kl(d)|0;Pl(d)|0;Xl(d)|0;Xl(d)|0;o=c[g>>2]|0;c[o+(f*764|0)+36>>2]=(c[(c[h>>2]|0)+(f*52|0)+32>>2]|0)!=0&1;c[(c[o+(f*764|0)+756>>2]|0)+40>>2]=f;f=f+1|0;if((f|0)>=(c[u>>2]|0))break a}l=w;return f|0}while(0);if((pb(b)|0)<0){e=-1;l=w;return e|0}b:do if((c[p>>2]|0)>1){m=j+e|0;f=b+172|0;o=1;while(1){_l(d,m+(o<<2)|0,0)|0;_l(d,(Xl(d)|0)+e|0,0)|0;g=Pl(d)|0;n=g&65535;if((rb(b,o,n)|0)<0){f=-1;break}if(g<<16>>16){g=0;do{h=(Kl(d)|0)&255;k=(h&3)+g|0;j=c[(c[f>>2]|0)+(o<<2)>>2]|0;if(!(h&4))i=0;else i=Kl(d)|0;if(h&8|0)a[j+4+(k<<3)+1>>0]=Kl(d)|0;if(h&16|0)a[j+4+(k<<3)+2>>0]=Kl(d)|0;if(h&32|0)a[j+4+(k<<3)+3>>0]=Kl(d)|0;if(h&64|0)a[j+4+(k<<3)+4>>0]=Kl(d)|0;if(h&128|0)Kl(d)|0;g=i&255;do if(i<<24>>24==1){g=-127;r=31}else{if((i&255)<=11)break;g=g+1&255;r=31}while(0);if((r|0)==31){r=0;a[j+4+(k<<3)>>0]=g}h=j+4+(k<<3)+3|0;g=a[h>>0]|0;c:do if((g&255)>=16)switch(g<<24>>24){case 30:case 29:case 28:case 23:case 21:case 20:case 19:{a[h>>0]=14;i=j+4+(k<<3)+4|0;a[i>>0]=a[i>>0]&15|-32;break c}default:{a[j+4+(k<<3)+4>>0]=0;a[h>>0]=0;break c}}while(0);i=j+4+(k<<3)+2|0;g=a[i>>0]|0;h=g&255;d:do if((g+-16&255)<65)g=h+241&255;else{do switch((g&255)>>>4&15){case 6:{a[j+4+(k<<3)+5>>0]=-92;g=h+-96|0;break}case 7:{a[j+4+(k<<3)+5>>0]=-92;g=(h<<4)+-1792|0;break}case 8:{a[j+4+(k<<3)+5>>0]=14;g=h+-128|176;break}case 9:{a[j+4+(k<<3)+5>>0]=14;g=h+-144|160;break}case 10:{a[j+4+(k<<3)+5>>0]=4;g=(h<<4)+-2560|0;break}case 11:{a[j+4+(k<<3)+5>>0]=4;g=h+-176|0;break}case 12:{a[j+4+(k<<3)+5>>0]=8;g=(h<<4)+-3064|0;break}case 13:{a[j+4+(k<<3)+5>>0]=25;g=(h<<4)+-3328|0;break}case 14:{a[j+4+(k<<3)+5>>0]=25;g=h+-224|0;break}case 15:{a[j+4+(k<<3)+5>>0]=3;g=h<<4;break}default:{g=0;break d}}while(0);a[j+4+(k<<3)+6>>0]=g;g=0}while(0);a[i>>0]=g;g=k+1|0}while((g|0)<(n|0))}o=o+1|0;if((o|0)>=(c[p>>2]|0))break b}l=w;return f|0}else f=b+172|0;while(0);r=Qm(523,1)|0;c[c[f>>2]>>2]=r;c[c[c[f>>2]>>2]>>2]=64;_l(d,q+e|0,0)|0;e:do if((c[t>>2]|0)>0){h=b+168|0;f=0;while(1){if((qb(b,f)|0)<0){f=-1;break}r=(Pl(d)|0)&65535;c[c[(c[h>>2]|0)+(f<<2)>>2]>>2]=r;if((c[s>>2]|0)>0){g=0;do{r=((Pl(d)|0)&65535)+-1|0;c[(c[(c[h>>2]|0)+(f<<2)>>2]|0)+4+(g<<2)>>2]=r;g=g+1|0}while((g|0)<(c[s>>2]|0))}f=f+1|0;if((f|0)>=(c[t>>2]|0))break e}l=w;return f|0}while(0);f=c[u>>2]|0;if((f|0)<=0){e=0;l=w;return e|0}h=b+176|0;i=b+180|0;g=0;while(1){if(c[(c[h>>2]|0)+(g*764|0)+36>>2]|0){_l(d,(c[v+(g<<2)>>2]|0)+e|0,0)|0;if((Ub(b,d,0,(c[i>>2]|0)+(g*52|0)|0,0)|0)<0){f=-1;r=64;break}f=c[u>>2]|0}g=g+1|0;if((g|0)>=(f|0)){f=0;r=64;break}}if((r|0)==64){l=w;return f|0}return 0}function hg(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;e=l;l=l+16|0;d=e;_l(a,c+952|0,0)|0;if((Zl(d,1,4,a)|0)>>>0>=4?(en(d,21616,4)|0)==0:0){_l(a,c,0)|0;xb(a,b,20);d=0}else d=-1;l=e;return d|0}function ig(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;u=l;l=l+1088|0;r=u;p=u+4|0;_l(g,h,0)|0;t=Qm(1,1024)|0;if(!t){f=-1;l=u;return f|0}Zl(p,20,1,g)|0;Pl(g)|0;h=0;do{Zl(p+20+(h*30|0)|0,22,1,g)|0;b[p+20+(h*30|0)+22>>1]=Pl(g)|0;a[p+20+(h*30|0)+24>>0]=Kl(g)|0;a[p+20+(h*30|0)+25>>0]=Kl(g)|0;b[p+20+(h*30|0)+26>>1]=Pl(g)|0;b[p+20+(h*30|0)+28>>1]=Pl(g)|0;h=h+1|0}while((h|0)!=31);Zl(p+1080|0,4,1,g)|0;q=p+950|0;a[q>>0]=Kl(g)|0;m=p+951|0;a[m>>0]=Kl(g)|0;Zl(t,1024,1,g)|0;Pl(g)|0;c[f+136>>2]=4;n=f+140|0;c[n>>2]=31;s=f+144|0;c[s>>2]=31;q=a[q>>0]|0;k=q&255;o=f+156|0;c[o>>2]=k;c[f+128>>2]=k;c[f+160>>2]=d[m>>0];if(!(q<<24>>24))h=1;else{h=0;i=0;do{a[f+952+h>>0]=h;m=h<<3;q=d[t+m>>0]|0;q=(q|0)>(i|0)?q:i;k=d[t+(m|2)>>0]|0;q=(k|0)>(q|0)?k:q;k=d[t+(m|4)>>0]|0;q=(k|0)>(q|0)?k:q;m=d[t+(m|6)>>0]|0;i=(m|0)>(q|0)?m:q;h=h+1|0}while((h|0)<(c[o>>2]|0));h=i+1|0}q=f+132|0;c[q>>2]=h;yo(f,p,20)|0;Eb(f,21604,r);a:do if((nb(f)|0)>=0){b:do if((c[n>>2]|0)>0){k=f+176|0;m=f+180|0;j=0;while(1){h=c[k>>2]|0;i=c[m>>2]|0;if((ob(f,j,1)|0)<0){h=-1;break}w=c[h+(j*764|0)+756>>2]|0;v=b[p+20+(j*30|0)+22>>1]|0;c[i+(j*52|0)+32>>2]=(v&65535)<<1;y=e[p+20+(j*30|0)+26>>1]|0;c[i+(j*52|0)+36>>2]=y;x=b[p+20+(j*30|0)+28>>1]|0;c[i+(j*52|0)+40>>2]=((x&65535)<<1)+y;c[i+(j*52|0)+44>>2]=(x&65535)>1?2:0;c[w+16>>2]=d[p+20+(j*30|0)+24>>0]<<28>>24;c[w>>2]=a[p+20+(j*30|0)+25>>0];c[w+8>>2]=128;c[w+40>>2]=j;if(v<<16>>16)c[h+(j*764|0)+36>>2]=1;vb(c[k>>2]|0,j,p+20+(j*30|0)|0,22);j=j+1|0;if((j|0)>=(c[n>>2]|0))break b}l=u;return h|0}while(0);if((pb(f)|0)>=0){if((c[o>>2]|0)>0){i=f+168|0;h=0;do{if((qb(f,h)|0)<0)break a;y=c[(c[i>>2]|0)+(h<<2)>>2]|0;c[y>>2]=64;x=h<<3;c[y+4>>2]=d[t+x>>0];c[y+8>>2]=d[t+(x|2)>>0];c[y+12>>2]=d[t+(x|4)>>0];c[y+16>>2]=d[t+(x|6)>>0];h=h+1|0}while((h|0)<(c[o>>2]|0))}if((c[q>>2]|0)>0){p=f+172|0;j=r+1|0;k=r+2|0;m=r+3|0;n=0;do{if((rb(f,n,64)|0)<0)break a;else o=0;do{h=c[(c[p>>2]|0)+(n<<2)>>2]|0;Zl(r,1,4,g)|0;i=a[r>>0]|0;switch(i<<24>>24){case -88:case 0:break;default:a[h+4+(o<<3)>>0]=((i&255)>>>1)+13<<24>>24}a[h+4+(o<<3)+1>>0]=a[j>>0]|0;a[h+4+(o<<3)+3>>0]=a[k>>0]&15;a[h+4+(o<<3)+4>>0]=a[m>>0]|0;o=o+1|0}while((o|0)!=64);n=n+1|0}while((n|0)<(c[q>>2]|0))}h=f+1280|0;c[h>>2]=c[h>>2]|8192;h=c[s>>2]|0;if((h|0)>0){k=f+180|0;j=0;do{i=c[k>>2]|0;if(c[i+(j*52|0)+32>>2]|0){if((Ub(f,g,512,i+(j*52|0)|0,0)|0)<0)break a;h=c[s>>2]|0}j=j+1|0}while((j|0)<(h|0))}Pm(t);y=0;l=u;return y|0}}while(0);Pm(t);y=-1;l=u;return y|0}function jg(a,b,c){a=a|0;b=b|0;c=c|0;kj(a,b,c);return}function kg(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;d=l;l=l+1024|0;c=d;do{f=(b|0)<1024?b:1024;cp(c|0,0,f|0)|0;co(c,1,f,a);e=b;b=b-f|0}while((e|0)>0&(b|0)>0);l=d;return}function lg(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;k=l;l=l+112|0;e=k;i=k+76|0;g=jo(Oo(a)|0,21621)|0;do if((g|0)!=0?(h=jo(Oo(b)|0,21624)|0,(h|0)!=0):0){f=(Ln(Eo(g)|0,e)|0)<0;f=f?-1:c[e+36>>2]|0;if((f|0)>=2048){e=Om(f+4096|0)|0;if(!e){Io();a=-1;break}Go(e,f,1,g)|0;b=2560;a=0;while(1){a=a+1|0;if((Ja[c[(c[b>>2]|0)+4>>2]&255](e,i,f)|0)>-1)break;if((a|0)==39){j=9;break}else b=2560+(a<<2)|0}if((j|0)==9){Pm(e);a=-1;break}ro(g,0,0)|0;if((Ia[c[(c[b>>2]|0)+8>>2]&63](g,h)|0)>=0){no(h)|0;no(g)|0;Pm(e);if(!d)a=0;else{c[d>>2]=c[c[b>>2]>>2];a=0}}else a=-1}else a=-2}else a=-1;while(0);l=k;return a|0}function mg(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=l;l=l+32|0;f=g;d=2560;e=0;while(1){d=Ja[c[(c[d>>2]|0)+4>>2]&255](a,f,b)|0;if((d|0)>0)break;e=e+1|0;if(!d){d=0;break}if((e|0)==39){d=-1;break}else d=2560+(e<<2)|0}l=g;return d|0}function ng(b,c,d){b=b|0;c=c|0;d=d|0;if(!c)return;d=(d|0)<20?d:20;if(b){ap(c|0,b|0,d|0)|0;c=c+d|0}a[c>>0]=0;return}function og(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0;if((e|0)<896){h=896-e|0;return h|0}if((a[b+2>>0]|0)!=-84){h=-1;return h|0}if((a[b+3>>0]|0)!=29){h=-1;return h|0}if((a[b>>0]|0)<0){h=-1;return h|0}else e=0;while(1){if((d[b+((e<<3)+10)>>0]|0)>15){g=-1;h=11;break}e=e+1|0;if((e|0)>=31){f=0;break}}if((h|0)==11)return g|0;do{if((a[b+(f+768)>>0]|0)<0){g=-1;h=11;break}f=f+1|0}while((f|0)<128);if((h|0)==11)return g|0;ng(0,c,0);h=0;return h|0}function pg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+1536|0;v=w+512|0;t=w;cp(t|0,0,512)|0;h=Vi(b)|0;i=Vi(b)|0;Yi(b)|0;s=aj(b)|0;kg(e,20);f=0;u=0;do{kg(e,22);r=Yi(b)|0;ij(e,r);u=((r&65535)<<1)+u|0;hj(e,Vi(b)|0);hj(e,Vi(b)|0);ij(e,Yi(b)|0);ij(e,Yi(b)|0);f=f+1|0}while((f|0)!=31);g=0;f=0;do{r=aj(b)|0;c[t+(g<<2)>>2]=r;if(!r){f=g&255;break}g=g+1|0;f=f+1<<24>>24}while((g&255)<<24>>24>-1);q=f+-1<<24>>24;r=q&255;hj(e,h);hj(e,i);ro(b,768,0)|0;jg(e,b,128);jj(e,1294879534);if(!(q<<24>>24)){ro(b,s,0)|0;jg(e,b,u);l=w;return 0}else o=0;do{ro(b,c[t+(o<<2)>>2]|0,0)|0;aj(b)|0;aj(b)|0;aj(b)|0;cp(v|0,0,1024)|0;p=0;do{q=p<<2;f=0;do{k=(f<<4)+q|0;h=Vi(b)|0;g=h&255;do if(!(g&128)){m=Vi(b)|0;j=g>>>2;n=m&255;switch(h&63){case 63:{g=-1;break}case 0:{g=0;break}default:g=(g&63)+245&255}i=(g<<24>>24==0&1)+g<<24>>24;g=j&48;h=v+k|0;a[h>>0]=g;if(i<<24>>24!=-1){j=i&255;a[h>>0]=d[21653+(j<<1)>>0]|0|g;a[v+(k|1)>>0]=a[21653+(j<<1)+1>>0]|0}if((n&15|0)==7){a[v+(k|2)>>0]=n&240;break}else{n=Vi(b)|0;a[v+(k|2)>>0]=m;a[v+(k|3)>>0]=n;break}}else f=f+-1+(g&127)|0;while(0);f=f+1|0}while((f|0)<64);p=p+1|0}while((p|0)!=4);co(v,1024,1,e);o=o+1|0}while((o|0)!=(r|0));ro(b,s,0)|0;jg(e,b,u);l=w;return 0}function qg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;if((e|0)<21){c=21-e|0;return c|0}k=cj(a[b>>0]|0,a[b+1>>0]|0)|0;l=k&65535;if((k+-1&65535)>30){c=-1;return c|0}f=cj(a[b+14>>0]|0,a[b+15>>0]|0)|0;i=(f&65535)<<1;g=cj(a[b+18>>0]|0,a[b+19>>0]|0)|0;h=cj(a[b+20>>0]|0,a[b+21>>0]|0)|0;f=(g|f|h)<<16>>16<0;g=(h&65535)+(g&65535)<<1>>>0>i>>>0;h=0;k=0;while(1){if(f|g){f=-1;g=18;break}j=h<<3;if((d[b+(j+16)>>0]|0)>15){f=-1;g=18;break}if((d[b+(j+17)>>0]|0)>64){f=-1;g=18;break}k=i+k|0;h=h+1|0;if((h|0)>=(l|0)){g=9;break}}if((g|0)==9){if((k|0)<3){c=-1;return c|0}f=gj(b+2|0)|0;g=gj(b+6|0)|0;h=gj(b+10|0)|0;if((f|0)<(l<<3|2|0)|((g-f|0)>128|(h|0)>(g|0)&((g|0)>(f|0)&(h|0)>(f|0))^1)){c=-1;return c|0}g=g+-1|0;if((g|0)>(e|0)){c=g-e|0;return c|0}a:do if((f|0)<(g|0)){while(1){if((d[b+f>>0]|0)>128){f=-1;break}f=f+1|0;if((f|0)>=(g|0))break a}return f|0}while(0);if((h|0)>65535?1:(a[b+g>>0]|0)!=-1){c=-1;return c|0}ng(0,c,0);c=0;return c|0}else if((g|0)==18)return f|0;return 0}function rg(c,d){c=c|0;d=d|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;t=l;l=l+448|0;s=t+440|0;o=t+312|0;r=t;k=t+256|0;h=o;i=h+128|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));a[s>>0]=0;a[s+1>>0]=0;a[s+2>>0]=0;a[s+3>>0]=0;a[s+4>>0]=0;h=r;i=h+128|0;do{b[h>>1]=0;h=h+2|0}while((h|0)<(i|0));kg(d,20);j=Yi(c)|0;n=aj(c)|0;aj(c)|0;q=aj(c)|0;j=j&255;f=j&65535;if(j<<16>>16){h=0;g=0;do{kg(d,22);p=Yi(c)|0;ij(d,p);g=((p&65535)<<1)+g|0;hj(d,Vi(c)|0);hj(d,Vi(c)|0);ij(d,Yi(c)|0);ij(d,Yi(c)|0);h=h+1|0}while((h|0)!=(f|0));h=k;i=h+50|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));if((j&65535)<31)m=5;else p=g}else{h=k;i=h+50|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));g=0;m=5}if((m|0)==5){do{co(k,30,1,d);f=f+1|0}while((f|0)!=31);p=g}h=Ho(c)|0;ro(c,n,0)|0;g=0;while(1){n=Vi(c)|0;f=o+g|0;a[f>>0]=n;if(n<<24>>24==-1)break;else g=g+1|0}a[f>>0]=0;hj(d,g&255);hj(d,127);f=0;g=0;do{n=a[o+f>>0]|0;hj(d,n);g=(n&255)>(g&255)?n:g;f=f+1|0}while((f|0)!=128);jj(d,1294879534);ro(c,h,0)|0;n=(g&255)+1|0;f=0;do{b[r+(f<<1)>>1]=Yi(c)|0;f=f+1|0}while((f|0)!=(n|0));f=s+1|0;g=s+2|0;h=s+3|0;k=0;do{ro(c,e[r+(k<<1)>>1]|0,0)|0;m=0;do{a[s>>0]=0;a[s+1>>0]=0;a[s+2>>0]=0;a[s+3>>0]=0;a[s+4>>0]=0;i=Vi(c)|0;j=i&255;do if(j&128)if(i<<24>>24==-1){a[s>>0]=0;a[s+1>>0]=0;a[s+2>>0]=0;a[s+3>>0]=0;a[s+4>>0]=0;co(s,4,1,d);break}else{i=Vi(c)|0;o=Vi(c)|0;i=i&255;v=i>>>4|j<<4&48;u=a[21653+(v<<1)>>0]|0;a[f>>0]=a[21653+(v<<1)+1>>0]|0;j=j>>>2;a[s>>0]=u&255|j&16;a[g>>0]=i&15|j<<4;a[h>>0]=o;co(s,4,1,d);break}else{u=(Vi(c)|0)&255;v=u>>>4|j<<4&48;o=a[21653+(v<<1)>>0]|0;a[f>>0]=a[21653+(v<<1)+1>>0]|0;v=j>>>2;a[s>>0]=o&255|v&16;a[g>>0]=u&15|v<<4;a[h>>0]=0;co(s,4,1,d)}while(0);m=m+1|0}while((m|0)!=256);k=k+1|0}while((k|0)!=(n|0));ro(c,q,0)|0;jg(d,c,p);l=t;return 0}function sg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;if((e|0)<1084){c=1084-e|0;return c|0}l=a[b+950>>0]|0;m=l&255;if(l<<24>>24<1){c=-1;return c|0}else h=0;while(1){j=h*30|0;p=d[b+(j+42)>>0]<<8;k=d[b+(j+46)>>0]<<8;g=d[b+(j+48)>>0]<<8|d[b+(j+49)>>0];i=(p|d[b+(j+43)>>0])<<1;if(((k|p)&32768|0)!=0|g>>>0>32767){n=-1;k=31;break}if((d[b+(j+47)>>0]|k)+g<<1>>>0>(i+2|0)>>>0){n=-1;k=31;break}if((d[b+(j+44)>>0]|0)>15){n=-1;k=31;break}h=h+1|0;if((d[b+(j+45)>>0]|0)>64){n=-1;k=31;break}if((h|0)>=31){k=9;break}}if((k|0)==9){p=d[b+1081>>0]<<16|d[b+1080>>0]<<24|d[b+1082>>0]<<8|d[b+1083>>0];if((p|0)<1084){c=-1;return c|0}do if(l<<24>>24){h=0;j=0;while(1){l=a[b+(h+952)>>0]|0;g=l&255;if(l<<24>>24<0){n=-1;k=31;break}j=(g|0)>(j|0)?g:j;g=h+1|0;if((g|0)>=(m|0)){k=13;break}else h=g}if((k|0)==13){h=h+3|0;g=(j<<2)+4|0;if((h|0)==128){q=g;break}else{f=h;o=g;k=14;break}}else if((k|0)==31)return n|0}else{f=2;o=4;k=14}while(0);a:do if((k|0)==14){while(1){if(a[b+(f+952)>>0]|0){n=-1;break}f=f+1|0;if((f|0)==128){q=o;break a}}return n|0}while(0);f=(q<<1)+1085|0;if((f|0)>(e|0)){c=f-e|0;return c|0}b:do if((q|0)>0){f=999999;g=0;while(1){h=g<<1;h=d[b+(h+1084)>>0]<<8|d[b+(h+1085)>>0];if((h|0)>(p|0)|h>>>0<1084){n=-1;break}f=(h|0)<(f|0)?h:f;g=g+1|0;if((g|0)>=(q|0)){i=h;break b}}return n|0}else f=999999;while(0);c:do if((f|0)<(i|0)){d:while(1){g=a[b+f>>0]|0;h=g&255;switch((h&192)<<24>>24){case 0:{if((g&255)>19){n=-1;k=31;break d}f=f+3|0;break}case -128:{f=f+2|0;break}case 64:{f=f+1|0;if((h&63|0)==0?(a[b+f>>0]|0)==0:0){n=-1;k=31;break d}break}default:{}}f=f+1|0;if((f|0)>=(i|0))break c}if((k|0)==31)return n|0}while(0);ng(b,c,20);c=0;return c|0}else if((k|0)==31)return n|0;return 0}function tg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=l;l=l+3136|0;p=s+2048|0;q=s;Go(p,1080,1,b)|0;co(p,1080,1,e);f=0;r=0;do{o=p+(f*30|0)|0;r=(((cj(a[o+42>>0]|0,a[o+43>>0]|0)|0)&65535)<<1)+r|0;f=f+1|0}while((f|0)!=31);f=0;o=0;do{n=d[p+(f+952)>>0]|0;o=(n|0)>(o|0)?n:o;f=f+1|0}while((f|0)!=128);jj(e,1294879534);n=aj(b)|0;f=0;while(1){c[q+(f<<4)>>2]=(Yi(b)|0)&65535;c[q+(f<<4)+4>>2]=(Yi(b)|0)&65535;c[q+(f<<4)+8>>2]=(Yi(b)|0)&65535;c[q+(f<<4)+12>>2]=(Yi(b)|0)&65535;if((f|0)<(o|0))f=f+1|0;else break}j=0;a:while(1){cp(p|0,0,1024)|0;k=0;do{ro(b,c[q+(j<<4)+(k<<2)>>2]|0,0)|0;m=k<<2;f=0;do{g=p+((f<<4)+m)|0;h=Vi(b)|0;i=h&255;switch((h&255)>>>6&3){case 0:{a[g>>0]=h;a[g+1>>0]=Vi(b)|0;a[g+2>>0]=Vi(b)|0;a[g+3>>0]=Vi(b)|0;break}case 3:{f=(i&63)+f|0;break}case 1:{a[g+2>>0]=i&15;a[g+3>>0]=Vi(b)|0;break}case 2:{a[g>>0]=Vi(b)|0;a[g+1>>0]=Vi(b)|0;a[g+2>>0]=i<<4;break}default:{f=14;break a}}f=f+1|0}while((f|0)<64);k=k+1|0}while((k|0)<4);co(p,1024,1,e);if((j|0)<(o|0))j=j+1|0;else{f=18;break}}if((f|0)!=14)if((f|0)==18){ro(b,n,0)|0;jg(e,b,r);l=s;return 0}return 0}function ug(b,c,e){b=b|0;c=c|0;e=e|0;a:do if((e|0)>=285)if((((((a[b>>0]|0)==70?(a[b+1>>0]|0)==67:0)?(a[b+2>>0]|0)==45:0)?(a[b+3>>0]|0)==77:0)?(a[b+4>>0]|0)==1:0)?(a[b+5>>0]|0)==0:0){e=0;do{if((d[b+((e<<3)+37)>>0]|0)>64){e=-1;break a}e=e+1|0}while((e|0)<31);ng(b+10|0,c,20);e=0}else e=-1;else e=285-e|0;while(0);return e|0}function vg(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0;aj(a)|0;Yi(a)|0;aj(a)|0;jg(b,a,20);aj(a)|0;c=0;h=0;do{kg(b,22);f=Yi(a)|0;ij(b,f);h=((f&65535)<<1)+h|0;hj(b,Vi(a)|0);hj(b,Vi(a)|0);ij(b,Yi(a)|0);f=Yi(a)|0;ij(b,f<<16>>16==0?1:f);c=c+1|0}while((c|0)!=31);aj(a)|0;e=Vi(a)|0;hj(b,e);hj(b,Vi(a)|0);aj(a)|0;c=e&255;if(e<<24>>24){f=0;d=0;do{i=Vi(a)|0;hj(b,i);d=(i&255)>(d&255)?i:d;f=f+1|0}while((f|0)!=(c|0));if(e<<24>>24>-1)g=5;else c=d}else{c=0;d=0;g=5}if((g|0)==5){do{hj(b,0);c=c+1|0}while((c|0)!=128);c=d}jj(b,1294879534);aj(a)|0;c=c&255;d=0;while(1){jg(b,a,1024);if((d|0)==(c|0))break;else d=d+1|0}aj(a)|0;jg(b,a,h);return 0}function wg(a,b,c){a=a|0;b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0;if((gj(a+192|0)|0)!=1397706311){b=-1;return b|0}g=(d[a+11>>0]|0)<<16|(d[a+10>>0]|0)<<24|(d[a+12>>0]|0)<<8|(d[a+13>>0]|0);if((g+-3|0)>>>0>1048556){b=-1;return b|0}else{e=0;h=0}while(1){f=e<<1;c=(d[a+(f+14)>>0]|0)<<8|(d[a+(f+15)>>0]|0);if((d[a+(f+46)>>0]|0)>64){i=-1;e=10;break}if(c>>>0<((d[a+(f+78)>>0]|0)<<8|(d[a+(f+79)>>0]|0))>>>0){i=-1;e=10;break}h=c+h|0;e=e+1|0;if((e|0)>=16){e=6;break}}if((e|0)==6){if((h|0)<3|(h|0)>(g|0)){b=-1;return b|0}else c=0;do{if((d[a+((c<<1)+113)>>0]|0)>40){i=-1;e=10;break}c=c+1|0}while((c|0)<40);if((e|0)==10)return i|0;ng(0,b,0);b=0;return b|0}else if((e|0)==10)return i|0;return 0}function xg(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0;m=l;l=l+128|0;k=m+64|0;g=m;e=k;f=e+64|0;do{c[e>>2]=0;e=e+4|0}while((e|0)<(f|0));e=g;f=e+64|0;do{c[e>>2]=0;e=e+4|0}while((e|0)<(f|0));kg(d,1080);ro(d,0,0)|0;jg(d,b,10);aj(b)|0;e=0;do{ro(d,(e*30|0)+42|0,0)|0;f=Yi(b)|0;c[k+(e<<2)>>2]=f&65535;ij(d,(f&65535)>>>1);e=e+1|0}while((e|0)!=16);e=0;do{ro(d,(e*30|0)+45|0,0)|0;ro(b,1,1)|0;hj(d,Vi(b)|0);e=e+1|0}while((e|0)!=16);e=0;do{ro(d,(e*30|0)+46|0,0)|0;f=Yi(b)|0;c[g+(e<<2)>>2]=f&65535;hj(d,(f&65535)>>>1&255);e=e+1|0}while((e|0)!=16);e=0;do{ro(d,(e*30|0)+48|0,0)|0;n=c[g+(e<<2)>>2]|0;f=(c[k+(e<<2)>>2]|0)-n|0;if((n|0)==0|(f|0)==0)ij(d,1);else ij(d,((f|0)/2|0)&65535);e=e+1|0}while((e|0)!=16);e=16;do{ro(d,(e*30|0)+48|0,0)|0;ij(d,1);e=e+1|0}while((e|0)!=31);ro(d,950,0)|0;ro(b,1,1)|0;hj(d,Vi(b)|0);hj(d,127);e=0;do{ro(b,1,1)|0;hj(d,Vi(b)|0);e=e+1|0}while((e|0)!=40);ro(d,0,2)|0;jj(d,1294879534);ro(b,4,1)|0;e=aj(b)|0;f=Om(e)|0;Go(f,e,1,b)|0;if((e|0)>0){g=0;do{do if((a[f+(g|2)>>0]&15)==12?(i=f+(g|3)|0,h=a[i>>0]|0,j=h&255,(h&255)>=10):0){if((h+-16&255)<10){a[i>>0]=j+250;break}if((h+-32&255)<10){a[i>>0]=j+244;break}if((h+-48&255)<10){a[i>>0]=j+238;break}if((h+-64&255)<10){a[i>>0]=j+232;break}if((h+-80&255)<10){a[i>>0]=j+226;break}if((h+-96&255)<5)a[i>>0]=j+220}while(0);g=g+4|0}while((g|0)<(e|0))}co(f,e,1,d);Pm(f);ro(b,4,1)|0;f=0;do{e=c[k+(f<<2)>>2]|0;if(e|0)jg(d,b,e);f=f+1|0}while((f|0)!=16);l=m;return 0}function yg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0;if((gj(b)|0)==1295068720)e=0;else{i=-1;return i|0}while(1){if((d[b+((e*68|0)+72)>>0]|0)>15){h=-1;i=10;break}e=e+1|0;if((e|0)>=31){f=0;break}}if((i|0)==10)return h|0;while(1){if((d[b+((f*68|0)+73)>>0]|0)>64){h=-1;i=10;break}f=f+1|0;if((f|0)>=31){g=0;break}}if((i|0)==10)return h|0;do{f=b+(g*68|0)+66|0;g=g+1|0;if(((cj(a[f>>0]|0,a[f+1>>0]|0)|0)&65535)>32768){h=-1;i=10;break}}while((g|0)<31);if((i|0)==10)return h|0;if(!(a[b+2114>>0]|0)){i=-1;return i|0}ng(0,c,0);i=0;return i|0}function zg(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;u=l;l=l+4736|0;r=u+3712|0;p=u+3584|0;o=u+1536|0;s=u+1024|0;t=u;cp(o|0,0,2048)|0;cp(s|0,0,512)|0;e=p;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));aj(b)|0;Yi(b)|0;kg(c,20);e=0;q=0;do{jg(c,b,22);ro(b,38,1)|0;m=Yi(b)|0;ij(c,m);q=((m&65535)<<1)+q|0;m=Yi(b)|0;n=Yi(b)|0;hj(c,Vi(b)|0);hj(c,Vi(b)|0);ij(c,m);ij(c,n<<16>>16?n:1);e=e+1|0}while((e|0)!=31);n=Vi(b)|0;k=n&255;hj(c,n);f=Vi(b)|0;hj(c,127);ro(b,2118,0)|0;if(!(n<<24>>24)){n=f&255;m=0}else{e=0;do{Go(o+(e<<4)|0,1,4,b)|0;e=e+1|0}while((e|0)!=(k|0));e=0;do{Go(o+(e<<4)+4|0,1,4,b)|0;e=e+1|0}while((e|0)!=(k|0));e=0;do{Go(o+(e<<4)+8|0,1,4,b)|0;e=e+1|0}while((e|0)!=(k|0));e=0;do{Go(o+(e<<4)+12|0,1,4,b)|0;e=e+1|0}while((e|0)!=(k|0));n=f&255;j=0;m=0;do{do if(j){if((j|0)>0){f=a[o+(j<<4)>>0]|0;g=o+(j<<4)+4|0;h=o+(j<<4)+8|0;i=o+(j<<4)+12|0;e=0;while(1){if((((a[o+(e<<4)>>0]|0)==f<<24>>24?(a[o+(e<<4)+4>>0]|0)==(a[g>>0]|0):0)?(a[o+(e<<4)+8>>0]|0)==(a[h>>0]|0):0)?(a[o+(e<<4)+12>>0]|0)==(a[i>>0]|0):0){i=30;break}e=e+1|0;if((e|0)>=(j|0)){i=12;break}}if((i|0)==12){i=0;a[p+j>>0]=m;m=m+1|0;break}else if((i|0)==30){i=0;a[p+j>>0]=a[p+e>>0]|0;break}}}else{a[p>>0]=m;m=m+1|0}while(0);j=j+1|0}while((j|0)!=(k|0));f=0;h=0;e=1;do{a:do if(!h)i=20;else{if((h|0)<=0)if(!(e<<24>>24)){e=0;break}else{e=1;i=20;break}e=a[p+h>>0]|0;g=0;while(1){if(e<<24>>24==(a[p+g>>0]|0)){e=0;break a}g=g+1|0;if((g|0)>=(h|0)){e=1;i=20;break}}}while(0);if((i|0)==20){i=0;j=f&255;a[s+(j<<2)>>0]=a[o+(h<<4)>>0]|0;a[s+(j<<2)+1>>0]=a[o+(h<<4)+4>>0]|0;a[s+(j<<2)+2>>0]=a[o+(h<<4)+8>>0]|0;a[s+(j<<2)+3>>0]=a[o+(h<<4)+12>>0]|0;f=f+1<<24>>24}h=h+1|0}while((h|0)!=(k|0))}co(p,128,1,c);jj(c,1294879534);k=k<<4;e=k+2118|0;if((m|0)<=0){t=n<<8;s=k+2122|0;t=s+t|0;ro(b,t,0)|0;jg(c,b,q);l=u;return 0}f=t+256|0;g=t+512|0;h=t+768|0;i=0;do{cp(r|0,0,1024)|0;cp(t|0,0,1024)|0;ro(b,(d[s+(i<<2)>>0]<<8)+e|0,0)|0;Go(t,256,1,b)|0;ro(b,(d[s+(i<<2)+1>>0]<<8)+e|0,0)|0;Go(f,256,1,b)|0;ro(b,(d[s+(i<<2)+2>>0]<<8)+e|0,0)|0;Go(g,256,1,b)|0;ro(b,(d[s+(i<<2)+3>>0]<<8)+e|0,0)|0;Go(h,256,1,b)|0;j=0;do{p=j<<4;v=r+p|0;o=j<<2;w=t+o|0;w=d[w>>0]|d[w+1>>0]<<8|d[w+2>>0]<<16|d[w+3>>0]<<24;a[v>>0]=w;a[v+1>>0]=w>>8;a[v+2>>0]=w>>16;a[v+3>>0]=w>>24;v=r+(p|4)|0;w=t+256+o|0;w=d[w>>0]|d[w+1>>0]<<8|d[w+2>>0]<<16|d[w+3>>0]<<24;a[v>>0]=w;a[v+1>>0]=w>>8;a[v+2>>0]=w>>16;a[v+3>>0]=w>>24;v=r+(p|8)|0;w=t+512+o|0;w=d[w>>0]|d[w+1>>0]<<8|d[w+2>>0]<<16|d[w+3>>0]<<24;a[v>>0]=w;a[v+1>>0]=w>>8;a[v+2>>0]=w>>16;a[v+3>>0]=w>>24;v=r+(p|12)|0;w=t+768+o|0;w=d[w>>0]|d[w+1>>0]<<8|d[w+2>>0]<<16|d[w+3>>0]<<24;a[v>>0]=w;a[v+1>>0]=w>>8;a[v+2>>0]=w>>16;a[v+3>>0]=w>>24;a[r+(p|15)>>0]=a[(o|3)+(t+768)>>0]|0;j=j+1|0}while((j|0)!=64);co(r,1024,1,c);i=i+1|0}while((i|0)!=(m|0));w=n<<8;v=k+2122|0;w=v+w|0;ro(b,w,0)|0;jg(c,b,q);l=u;return 0}function Ag(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;if((e|0)<1024){c=1024-e|0;return c|0}else{f=0;g=0}do{k=f<<4;i=(d[b+(k|4)>>0]|0)<<8|(d[b+(k|5)>>0]|0);h=i<<1;if((i>>>0>32767?1:(d[b+(k|7)>>0]|0)>64)|((d[b+(k|12)>>0]|0)<<8|(d[b+(k|13)>>0]|0))>>>0>h>>>0){l=-1;j=25;break}g=h+g|0;f=f+1|0}while((f|0)<15);if((j|0)==25)return l|0;if((g|0)<5){c=-1;return c|0}i=a[b+243>>0]|0;if((i+-1&255)>99){c=-1;return c|0}f=b+244|0;k=0;h=0;do{g=f+(h<<1)|0;g=(cj(a[g>>0]|0,a[g+1>>0]|0)|0)&65535;if(g&1023|0){l=-1;j=25;break}m=g>>>10;k=(m|0)>(k|0)?m:k;h=h+1|0}while((h|0)<100);if((j|0)==25)return l|0;if((k|0)==0|(k|0)>99){m=-1;return m|0}f=(g<<10|444)+(h<<2)|3;if((f|0)>(e|0)){m=f-e|0;return m|0}g=(i&255)+1|0;i=0;a:while(1){f=i<<10|444;j=0;do{m=(j<<2)+f|0;h=b+m|0;if((m|0)>65532){l=-1;j=25;break a}switch(a[h+2>>0]&15){case 3:{if((d[h+3>>0]|0)>64){l=-1;j=25;break a}break}case 4:{if((d[h+3>>0]|0)>99){l=-1;j=25;break a}break}case 5:{if((d[h+3>>0]|0)>>>0>g>>>0){l=-1;j=25;break a}break}case 6:{if((d[h+3>>0]|0)>1){l=-1;j=25;break a}break}case 7:{if((d[h+3>>0]|0)>1){l=-1;j=25;break a}break}default:{}}j=j+1|0}while((j|0)<256);if((i|0)<(k|0))i=i+1|0;else{j=24;break}}if((j|0)==24){ng(0,c,0);m=0;return m|0}else if((j|0)==25)return l|0;return 0}function Bg(b,c){b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0;n=l;l=l+1152|0;k=n+128|0;f=n;d=f;e=d+128|0;do{a[d>>0]=0;d=d+1|0}while((d|0)<(e|0));kg(c,20);d=0;j=0;do{kg(c,22);aj(b)|0;h=Yi(b)|0;ij(c,h);h=h&65535;j=(h<<1)+j|0;Vi(b)|0;hj(c,0);hj(c,Vi(b)|0);aj(b)|0;i=Yi(b)|0;ij(c,(i&65535)>2?h-(i&65535)&65535:0);ij(c,(i&65535)<3?1:i);Yi(b)|0;d=d+1|0}while((d|0)!=15);d=k;e=d+29|0;do{a[d>>0]=0;d=d+1|0}while((d|0)<(e|0));a[k+29>>0]=1;co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);co(k,30,1,c);ro(b,243,0)|0;hj(c,Vi(b)|0);hj(c,127);d=0;do{a[f+d>>0]=((Yi(b)|0)&65535)>>>10;d=d+1|0}while((d|0)!=100);co(f,128,1,c);d=0;e=0;do{i=a[f+d>>0]|0;e=(i&255)>(e&255)?i:e;d=d+1|0}while((d|0)!=128);jj(c,1294879534);ro(b,444,0)|0;f=e&255;g=0;while(1){cp(k|0,0,1024)|0;Go(k,1024,1,b)|0;h=0;do{e=k+(h<<2|2)|0;i=a[e>>0]|0;switch(i&15){case 4:case 3:{d=9;m=14;break}case 5:{d=6;m=14;break}case 6:{d=8;m=14;break}case 7:{d=7;m=14;break}case 8:{d=7;m=14;break}default:{}}if((m|0)==14){m=0;a[e>>0]=(i&255)+d}h=h+1|0}while((h|0)!=256);co(k,1024,1,c);if((g|0)==(f|0))break;else g=g+1|0}jg(c,b,j);l=n;return 0}function Cg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;if((e|0)<378){c=378-e|0;return c|0}if((a[b+248>>0]|0)<1){c=-1;return c|0}if((a[b+249>>0]|0)==127){i=0;j=0}else{c=-1;return c|0}while(1){f=i<<3;if((d[b+(f|2)>>0]|0)>15){t=-1;l=27;break}if((d[b+(f|3)>>0]|0)>64){t=-1;l=27;break}g=b+f|0;l=cj(a[g>>0]|0,a[g+1>>0]|0)|0;h=(l&65535)<<1;f=g+4|0;f=cj(a[f>>0]|0,a[f+1>>0]|0)|0;g=g+6|0;g=cj(a[g>>0]|0,a[g+1>>0]|0)|0;if((f|l|g)<<16>>16<0){t=-1;l=27;break}if((g&65535)>1){if((g&65535)+(f&65535)<<1>>>0>h>>>0){t=-1;l=27;break}}else if(f<<16>>16){t=-1;l=27;break}j=h+j|0;i=i+1|0;if((i|0)>=31){l=12;break}}if((l|0)==12){if((j|0)<5){c=-1;return c|0}else{g=0;k=0}do{j=a[b+(g+250)>>0]|0;f=j&255;if(j<<24>>24<0){t=-1;l=27;break}k=(f|0)>(k|0)?f:k;g=g+1|0}while((g|0)<128);if((l|0)==27)return t|0;f=k<<10|379;if((f|0)>(e|0)){c=f-e|0;return c|0}else{f=0;j=0}a:while(1){i=0;b:while(1){g=d[b+(f+378)>>0]|0;switch((g&192)<<24>>24){case -64:{l=23;break b}case 0:{if((g&12)>>>0>3){t=-1;l=27;break a}h=f+4|0;g=i;break}case -128:{if(a[b+(f+379)>>0]|0){t=-1;l=27;break a}h=f+4|0;g=(d[b+(f+381)>>0]|0)+i|0;break}default:{h=f;g=i}}i=g+1|0;if((i|0)>=64){p=h;m=0;break}else f=h}if((l|0)==23){l=0;if(a[b+(f+379)>>0]|0){t=-1;l=27;break}p=f+4|0;m=0}c:while(1){f=d[b+(p+378)>>0]|0;switch((f&192)<<24>>24){case -64:{l=29;break c}case 0:{if((f&12)>>>0>3){t=-1;l=27;break a}g=p+4|0;f=m;break}case -128:{if(a[b+(p+379)>>0]|0){t=-1;l=27;break a}g=p+4|0;f=(d[b+(p+381)>>0]|0)+m|0;break}default:{g=p;f=m}}m=f+1|0;if((m|0)>=64){q=g;n=0;break}else p=g}if((l|0)==29){l=0;if(a[b+(p+379)>>0]|0){t=-1;l=27;break}q=p+4|0;n=0}d:while(1){f=d[b+(q+378)>>0]|0;switch((f&192)<<24>>24){case -64:{l=37;break d}case 0:{if((f&12)>>>0>3){t=-1;l=27;break a}g=q+4|0;f=n;break}case -128:{if(a[b+(q+379)>>0]|0){t=-1;l=27;break a}g=q+4|0;f=(d[b+(q+381)>>0]|0)+n|0;break}default:{g=q;f=n}}n=f+1|0;if((n|0)>=64){r=g;o=0;break}else q=g}if((l|0)==37){l=0;if(a[b+(q+379)>>0]|0){t=-1;l=27;break}r=q+4|0;o=0}e:while(1){f=d[b+(r+378)>>0]|0;switch((f&192)<<24>>24){case -64:{l=45;break e}case 0:{if((f&12)>>>0>3){t=-1;l=27;break a}g=r+4|0;f=o;break}case -128:{if(a[b+(r+379)>>0]|0){t=-1;l=27;break a}g=r+4|0;f=(d[b+(r+381)>>0]|0)+o|0;break}default:{g=r;f=o}}o=f+1|0;if((o|0)>=64){s=g;break}else r=g}if((l|0)==45){l=0;if(a[b+(r+379)>>0]|0){t=-1;l=27;break}s=r+4|0}if((j|0)<(k|0)){f=s;j=j+1|0}else{l=26;break}}if((l|0)==26){ng(0,c,0);c=0;return c|0}else if((l|0)==27)return t|0}else if((l|0)==27)return t|0;return 0}function Dg(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=l;l=l+3072|0;p=s+2048|0;r=s;cp(r|0,0,2048)|0;kg(d,20);e=0;q=0;do{kg(d,22);o=Yi(b)|0;ij(d,o);q=((o&65535)<<1)+q|0;hj(d,Vi(b)|0);hj(d,Vi(b)|0);ij(d,Yi(b)|0);o=Yi(b)|0;ij(d,o<<16>>16?o:1);e=e+1|0}while((e|0)!=31);hj(d,Vi(b)|0);hj(d,Vi(b)|0);e=0;f=0;do{o=Vi(b)|0;hj(d,o);f=(o&255)>(f&255)?o:f;e=e+1|0}while((e|0)!=128);o=f+1<<24>>24;jj(d,1294879534);j=o&255;if(!(o<<24>>24)){jg(d,b,q);l=s;return 0}k=0;do{cp(p|0,0,1024)|0;n=k<<2;m=0;do{c[r+(m+n<<2)>>2]=Ho(b)|0;o=m<<2;e=0;do{f=(e<<4)+o|0;g=Vi(b)|0;switch(g<<24>>24){case -128:{Vi(b)|0;Vi(b)|0;e=((Vi(b)|0)&255)+e|0;break}case -64:{Vi(b)|0;h=Vi(b)|0;f=Vi(b)|0;i=Ho(b)|0;ro(b,c[r+(((h&255)<<8|f&255)>>>2<<2)>>2]|0,0)|0;f=0;do{g=(f<<4)+o|0;h=Vi(b)|0;if(h<<24>>24==-128){Vi(b)|0;Vi(b)|0;f=((Vi(b)|0)&255)+f|0}else{a[p+g>>0]=h;a[p+(g|1)>>0]=Vi(b)|0;a[p+(g|2)>>0]=Vi(b)|0;a[p+(g|3)>>0]=Vi(b)|0}f=f+1|0}while((f|0)<64);ro(b,i,0)|0;e=e+100|0;break}default:{a[p+f>>0]=g;a[p+(f|1)>>0]=Vi(b)|0;a[p+(f|2)>>0]=Vi(b)|0;a[p+(f|3)>>0]=Vi(b)|0}}e=e+1|0}while((e|0)<64);m=m+1|0}while((m|0)!=4);co(p,1024,1,d);k=k+1|0}while((k|0)!=(j|0));jg(d,b,q);l=s;return 0}function Eg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;if((e|0)<1536){i=1536-e|0;return i|0}if((a[b>>0]|0)!=77){i=-1;return i|0}if((a[b+1>>0]|0)!=46){i=-1;return i|0}if((a[b+15>>0]|0)!=97){i=-1;return i|0}if((d[b+54>>0]|0)>64){i=-1;return i|0}if((d[b+86>>0]|0)>64){i=-1;return i|0}if((d[b+118>>0]|0)>64){i=-1;return i|0}if((d[b+150>>0]|0)>64){i=-1;return i|0}if((d[b+182>>0]|0)>64){i=-1;return i|0}if((d[b+214>>0]|0)>64){i=-1;return i|0}if((d[b+246>>0]|0)>64){i=-1;return i|0}if((d[b+278>>0]|0)>64){i=-1;return i|0}if((d[b+310>>0]|0)>64){i=-1;return i|0}if((d[b+342>>0]|0)>64){i=-1;return i|0}if((d[b+374>>0]|0)>64){i=-1;return i|0}if((d[b+406>>0]|0)>64){i=-1;return i|0}if((d[b+438>>0]|0)>64){i=-1;return i|0}if((d[b+470>>0]|0)>64){i=-1;return i|0}if((d[b+502>>0]|0)>64){i=-1;return i|0}else{h=0;f=0}while(1){j=a[b+(f+512)>>0]|0;g=j&255;if(j<<24>>24==-1){g=h;break}g=(g|0)>(h|0)?g:h;f=f+1|0;if((f|0)<1024)h=g;else break}if((g|0)==0|(f|0)==1024){j=-1;return j|0}f=(g*192|0)+1725|0;if((f|0)>(e|0)){j=f-e|0;return j|0}else h=0;a:while(1){f=(h*192|0)+1536|0;e=0;do{if((d[b+(f+(e*3|0))>>0]|0)>36){f=-1;i=18;break a}e=e+1|0}while((e|0)<64);if((h|0)<(g|0))h=h+1|0;else break}if((i|0)==18)return f|0;ng(b+2|0,c,13);j=0;return j|0} -function hd(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0;La=l;l=l+3024|0;N=La+64|0;v=La+56|0;t=La+48|0;s=La+40|0;I=La+32|0;J=La+16|0;u=La+8|0;H=La;Aa=La+3016|0;Ca=La+2504|0;p=La+2032|0;na=La+1472|0;oa=La+1168|0;ta=La+1088|0;ma=La+2224|0;Ea=La+2440|0;pa=La+608|0;qa=La+124|0;M=La+2400|0;Ba=La+2336|0;K=La+80|0;L=La+76|0;_l(g,h,0)|0;Xl(g)|0;q=p+4|0;Zl(q,26,1,g)|0;y=p+30|0;a[y>>0]=Kl(g)|0;x=p+31|0;a[x>>0]=Kl(g)|0;C=p+32|0;b[C>>1]=Ml(g)|0;z=p+34|0;b[z>>1]=Ml(g)|0;j=p+36|0;b[j>>1]=Ml(g)|0;D=p+38|0;b[D>>1]=Ml(g)|0;r=p+40|0;b[r>>1]=Ml(g)|0;la=p+42|0;b[la>>1]=Ml(g)|0;Ka=p+44|0;b[Ka>>1]=Ml(g)|0;Ga=p+46|0;b[Ga>>1]=Ml(g)|0;w=p+48|0;a[w>>0]=Kl(g)|0;B=p+49|0;a[B>>0]=Kl(g)|0;A=p+50|0;a[A>>0]=Kl(g)|0;m=p+51|0;a[m>>0]=Kl(g)|0;G=p+52|0;a[G>>0]=Kl(g)|0;E=p+53|0;a[E>>0]=Kl(g)|0;Ja=p+54|0;b[Ja>>1]=Ml(g)|0;Ia=p+56|0;c[Ia>>2]=Vl(g)|0;F=p+60|0;c[F>>2]=Vl(g)|0;Zl(p+64|0,64,1,g)|0;Zl(p+128|0,64,1,g)|0;yo(f,q,64)|0;q=f+156|0;c[q>>2]=e[C>>1];Ha=b[z>>1]|0;i=Ha&65535;sa=f+140|0;c[sa>>2]=i;j=e[j>>1]|0;ua=f+144|0;c[ua>>2]=j;k=e[D>>1]|0;Fa=f+128|0;c[Fa>>2]=k;if(Ha<<16>>16){i=Qm(4,i)|0;if(!i){f=-1;l=La;return f|0}else{za=i;ka=i}}else{za=0;ka=0}ya=Qm(4,j)|0;if(ya|0){xa=Qm(4,k)|0;if(xa|0){c[f+148>>2]=d[A>>0];c[f+152>>2]=d[m>>0];j=b[Ka>>1]|0;i=j&65535;if(i&8|0){Ha=f+1280|0;c[Ha>>2]=c[Ha>>2]|4096}Ha=(i&4|0)==0;ja=Ha^1;if((e[la>>1]|0)>511&ja){wa=f+1280|0;c[wa>>2]=c[wa>>2]|16384}o=(j&1)==0;n=0;do{i=f+184+(n*12|0)|0;k=p+64+n|0;j=a[k>>0]|0;if(j<<24>>24==100){a[k>>0]=32;j=32}k=j&255;m=f+184+(n*12|0)+8|0;if(k&128|0){a[p+128+n>>0]=0;c[m>>2]=c[m>>2]|2}if(!o){c[i>>2]=k<<2;if((j&255)>63){j=255;ra=17}}else{j=128;ra=17}if((ra|0)==17){ra=0;c[i>>2]=j}c[f+184+(n*12|0)+4>>2]=d[p+128+n>>0];n=n+1|0}while((n|0)!=64);i=c[q>>2]|0;j=f+952|0;if((i|0)<257){Zl(j,1,i,g)|0;i=c[q>>2]|0;k=(e[Ka>>1]|0)>>>4&1^1;j=k&65535;if((i|0)>1)ra=22;else{va=j;wa=k}}else{Zl(j,1,256,g)|0;_l(g,(c[q>>2]|0)+-256|0,1)|0;c[q>>2]=256;k=(e[Ka>>1]|0)>>>4&1^1;j=k&65535;i=256;ra=22}if((ra|0)==22){o=0;do{m=f+952+o|0;n=o;o=o+1|0;if((a[m>>0]|0)==-2){bp(m|0,f+952+o|0,i+~n|0)|0;i=(c[q>>2]|0)+-1|0;c[q>>2]=i}}while((o|0)<(i+-1|0));va=j;wa=k}if((c[sa>>2]|0)>0){i=0;do{c[ka+(i<<2)>>2]=Vl(g)|0;i=i+1|0}while((i|0)<(c[sa>>2]|0))}if((c[ua>>2]|0)>0){i=0;do{c[ya+(i<<2)>>2]=Vl(g)|0;i=i+1|0}while((i|0)<(c[ua>>2]|0))}if((c[Fa>>2]|0)>0){i=0;do{c[xa+(i<<2)>>2]=Vl(g)|0;i=i+1|0}while((i|0)<(c[Fa>>2]|0))}c[f+1264>>2]=8363;j=b[r>>1]|0;k=j&65535;a:do switch(((j&65535)>>>8&255)<<24>>24){case 0:{a[M>>0]=a[18636]|0;a[M+1>>0]=a[18637]|0;a[M+2>>0]=a[18638]|0;a[M+3>>0]=a[18639]|0;a[M+4>>0]=a[18640]|0;a[M+5>>0]=a[18641]|0;break}case 2:case 1:{i=(b[la>>1]|0)==512;b:do if((b[z>>1]|0)==0&(j<<16>>16==532&i&(b[Ka>>1]|0)==9&(b[Ga>>1]|0)==0&(a[y>>0]|a[x>>0])<<24>>24==0))if(((a[w>>0]|0)==-128?((e[D>>1]|0)+1|0)==(e[C>>1]|0):0)&(a[B>>0]|0)==100&(a[A>>0]|0)==1&(a[G>>0]|0)==-128&(a[E>>0]|0)==0&(b[Ja>>1]|0)==0&(c[F>>2]|c[Ia>>2]|0)==0){k=M;i=18642;m=k+19|0;do{a[k>>0]=a[i>>0]|0;k=k+1|0;i=i+1|0}while((k|0)<(m|0));break a}else ra=42;else{if(i&j<<16>>16==535){k=M;i=18661;m=k+21|0;do{a[k>>0]=a[i>>0]|0;k=k+1|0;i=i+1|0}while((k|0)<(m|0));b[la>>1]=Ha?256:532;break a}switch(j<<16>>16){case 532:{ra=42;break b}case 534:{k=M;i=18682;m=k+23|0;do{a[k>>0]=a[i>>0]|0;k=k+1|0;i=i+1|0}while((k|0)<(m|0));break a}case 535:{k=M;i=18705;m=k+23|0;do{a[k>>0]=a[i>>0]|0;k=k+1|0;i=i+1|0}while((k|0)<(m|0));break a}default:break b}}while(0);if((ra|0)==42?(en(F,18728,4)|0)==0:0){k=M;i=18733;m=k+14|0;do{a[k>>0]=a[i>>0]|0;k=k+1|0;i=i+1|0}while((k|0)<(m|0));break a}c[H>>2]=k>>>8&15;c[H+4>>2]=k&255;ao(M,40,18747,H);break}case 127:case 8:{c:do if(j<<16>>16<32767){switch(j<<16>>16){case 2184:break;default:break c}k=M;i=18771;m=k+14|0;do{a[k>>0]=a[i>>0]|0;k=k+1|0;i=i+1|0}while((k|0)<(m|0));break a}else{switch(j<<16>>16){case 32767:break;default:break c}k=M;i=18785;m=k+9|0;do{a[k>>0]=a[i>>0]|0;k=k+1|0;i=i+1|0}while((k|0)<(m|0));break a}while(0);c[u>>2]=k;ao(M,40,18794,u);break}default:switch((j&65535)>>>12&15){case 1:{i=k&4095;if(i>>>0>80){c[L>>2]=(i*86400|0)+1247443200;if(Da(L|0,K|0)|0){ha=(c[K+16>>2]|0)+1|0;ia=c[K+12>>2]|0;c[J>>2]=(c[K+20>>2]|0)+1900;c[J+4>>2]=ha;c[J+8>>2]=ia;ao(M,40,18809,J)}}else{c[I>>2]=i;ao(M,40,18839,I)}break a}case 5:{c[s>>2]=k>>>8&15;c[s+4>>2]=k&255;ao(M,40,18859,s);if(!(en(F,18875,4)|0))break a;k=M+(Zn(M)|0)|0;i=18880;m=k+11|0;do{a[k>>0]=a[i>>0]|0;k=k+1|0;i=i+1|0}while((k|0)<(m|0));break a}case 6:{c[t>>2]=k>>>8&15;c[t+4>>2]=k&255;ao(M,40,18891,t);break a}default:{c[v>>2]=k;ao(M,40,18794,v);break a}}}while(0);ia=e[la>>1]|0;c[N>>2]=M;c[N+4>>2]=ia>>>8;c[N+8>>2]=ia&255;Eb(f,18911,N);if(Ha)c[sa>>2]=c[ua>>2];d:do if((nb(f)|0)>=0){if((c[sa>>2]|0)>0){ga=f+176|0;s=oa+4|0;ha=oa+16|0;Q=oa+17|0;C=oa+18|0;B=oa+19|0;F=oa+20|0;W=oa+22|0;V=oa+23|0;I=oa+24|0;D=oa+25|0;$=oa+26|0;X=oa+27|0;ca=oa+28|0;S=oa+30|0;Y=oa+31|0;t=oa+32|0;K=oa+58|0;L=oa+59|0;N=oa+60|0;P=oa+61|0;M=oa+62|0;u=oa+64|0;U=ma+1|0;v=na+4|0;ia=na+16|0;H=na+17|0;fa=na+18|0;ea=na+19|0;ba=na+20|0;aa=na+21|0;Z=na+22|0;G=na+24|0;R=na+26|0;E=na+27|0;da=na+28|0;T=na+30|0;_=na+31|0;w=na+32|0;x=na+58|0;y=na+64|0;z=na+304|0;A=na+504|0;J=0;do{p=c[ga>>2]|0;i=p+(J*764|0)|0;do if(!((e[la>>1]|0)>511&ja)){if(!Ha){_l(g,(c[ka+(J<<2)>>2]|0)+h|0,0)|0;c[na>>2]=Xl(g)|0;Zl(v,12,1,g)|0;a[ia>>0]=Kl(g)|0;a[H>>0]=Kl(g)|0;a[fa>>0]=Kl(g)|0;a[ea>>0]=Kl(g)|0;a[ba>>0]=Kl(g)|0;a[aa>>0]=Kl(g)|0;b[Z>>1]=Ml(g)|0;b[G>>1]=Ml(g)|0;a[R>>0]=Kl(g)|0;a[E>>0]=Kl(g)|0;b[da>>1]=Ml(g)|0;a[T>>0]=Kl(g)|0;a[_>>0]=Kl(g)|0;Zl(w,26,1,g)|0;id(w);Zl(x,6,1,g)|0;Zl(y,240,1,g)|0;Zl(z,200,1,g)|0;Zl(A,50,1,g)|0;wb(i,w,25)|0;c[p+(J*764|0)+40>>2]=e[G>>1]<<7;r=a[H>>0]|0;i=(r<<1&4|r&1)&255;i=(r&4)==0?i:i|18;c[p+(J*764|0)+44>>2]=(r&8)==0?i:i|34;c[p+(J*764|0)+64>>2]=d[fa>>0];c[p+(J*764|0)+68>>2]=d[ea>>0];c[p+(J*764|0)+56>>2]=d[ba>>0];c[p+(J*764|0)+60>>2]=d[aa>>0];i=0;while(1)if((a[(i<<1)+(na+504)>>0]|0)==-1)break;else i=i+1|0;c[p+(J*764|0)+48>>2]=i;if(i|0)do{i=i+-1|0;r=i<<1;b[p+(J*764|0)+72+(r<<1)>>1]=d[na+504+r>>0]|0;r=r|1;b[p+(J*764|0)+72+(r<<1)>>1]=d[na+504+r>>0]|0}while((i|0)!=0);cp(pa|0,-1,480)|0;o=0;j=0;while(1){do if((o|0)==120)ra=107;else{n=o<<1;r=a[(n|1)+(na+64)>>0]|0;m=(r&255)+-1|0;if(!(r<<24>>24)){ra=107;break}k=pa+(m<<2)|0;i=c[k>>2]|0;if((i|0)==-1){c[k>>2]=j;c[qa+(j<<2)>>2]=m;i=j;j=j+1|0}a[p+(J*764|0)+512+(o<<1)>>0]=i;i=(d[na+64+n>>0]|0)-o&255;n=j}while(0);if((ra|0)==107){ra=0;a[p+(J*764|0)+512+(o<<1)>>0]=0;i=0;n=j}a[p+(J*764|0)+512+(o<<1)+1>>0]=i;o=o+1|0;if((o|0)==121)break;else j=n}c[p+(J*764|0)+36>>2]=n;c[p+(J*764|0)+32>>2]=(d[I>>0]|0)>>>1;if(!n)break;m=Qm(64,n)|0;c[p+(J*764|0)+756>>2]=m;if(!m)break d;if((n|0)<=0)break;j=d[R>>0]|0;i=(a[E>>0]|0)!=0&1;k=0;do{c[m+(k<<6)+40>>2]=c[qa+(k<<2)>>2];c[m+(k<<6)+44>>2]=j;c[m+(k<<6)+48>>2]=i;c[m+(k<<6)+8>>2]=128;k=k+1|0}while((k|0)!=(n|0))}}else{if(_l(g,(c[ka+(J<<2)>>2]|0)+h|0,0)|0)break d;c[oa>>2]=Xl(g)|0;Zl(s,12,1,g)|0;a[ha>>0]=Kl(g)|0;a[Q>>0]=Kl(g)|0;a[C>>0]=Kl(g)|0;a[B>>0]=Kl(g)|0;b[F>>1]=Ml(g)|0;a[W>>0]=Kl(g)|0;a[V>>0]=Kl(g)|0;a[I>>0]=Kl(g)|0;a[D>>0]=Kl(g)|0;a[$>>0]=Kl(g)|0;a[X>>0]=Kl(g)|0;b[ca>>1]=Ml(g)|0;a[S>>0]=Kl(g)|0;a[Y>>0]=Kl(g)|0;Zl(t,26,1,g)|0;id(t);a[K>>0]=Kl(g)|0;a[L>>0]=Kl(g)|0;a[N>>0]=Kl(g)|0;a[P>>0]=Kl(g)|0;b[M>>1]=Ml(g)|0;Zl(u,240,1,g)|0;wb(i,t,25)|0;c[p+(J*764|0)+40>>2]=e[F>>1]<<6;i=p+(J*764|0)+44|0;jd(i,ma,g);m=p+(J*764|0)+200|0;jd(m,ma,g);n=p+(J*764|0)+356|0;jd(n,ma,g);do if(c[m>>2]&1|0){k=p+(J*764|0)+204|0;if((c[k>>2]|0)>0)j=0;else break;do{r=p+(J*764|0)+228+((j<<1|1)<<1)|0;b[r>>1]=(e[r>>1]|0)+32;j=j+1|0}while((j|0)<(c[k>>2]|0))}while(0);do if(c[i>>2]&1|0){i=p+(J*764|0)+48|0;if(c[i>>2]|0)break;c[i>>2]=1}while(0);do if(c[m>>2]&1|0){i=p+(J*764|0)+204|0;if(c[i>>2]|0)break;c[i>>2]=1}while(0);i=c[n>>2]|0;do if(i&1|0){j=p+(J*764|0)+360|0;if(c[j>>2]|0)break;c[j>>2]=1}while(0);do if((a[ma>>0]|0)<0){c[n>>2]=i|8;i=a[U>>0]|0;if(!(i<<24>>24))break;i=i&255;j=0;do{r=p+(J*764|0)+384+((j<<1|1)<<1)|0;b[r>>1]=((e[r>>1]<<16)+2097152|0)>>>14;j=j+1|0}while((j|0)!=(i|0))}else{i=a[U>>0]|0;if(!(i<<24>>24))break;i=i&255;j=0;do{r=p+(J*764|0)+384+((j<<1|1)<<1)|0;b[r>>1]=(b[r>>1]|0)*50;j=j+1|0}while((j|0)!=(i|0))}while(0);cp(pa|0,-1,480)|0;o=0;j=0;do{n=o<<1;r=a[(n|1)+(oa+64)>>0]|0;m=(r&255)+-1|0;if(!(r<<24>>24)){a[p+(J*764|0)+512+(o<<1)>>0]=-1;i=0}else{k=pa+(m<<2)|0;i=c[k>>2]|0;if((i|0)==-1){c[k>>2]=j;c[qa+(j<<2)>>2]=m;i=j;j=j+1|0}a[p+(J*764|0)+512+(o<<1)>>0]=i;i=(d[oa+64+n>>0]|0)-o&255}a[p+(J*764|0)+512+(o<<1)+1>>0]=i;o=o+1|0}while((o|0)!=120);c[p+(J*764|0)+36>>2]=j;c[p+(J*764|0)+32>>2]=(d[I>>0]|0)>>>1;if(!j)break;r=Qm(64,j)|0;c[p+(J*764|0)+756>>2]=r;if(!r)break d;if((j|0)<=0)break;k=d[Q>>0]|0;m=d[C>>0]|0;i=c[1844+((a[B>>0]&3)<<2)>>2]|0;q=d[D>>0]|0;q=(q&128|0)==0?q<<2:-1;n=d[K>>0]|0;o=d[L>>0]|0;p=0;do{c[r+(p<<6)+40>>2]=c[qa+(p<<2)>>2];c[r+(p<<6)+44>>2]=k;c[r+(p<<6)+48>>2]=m;c[r+(p<<6)+52>>2]=i;c[r+(p<<6)+8>>2]=q;c[r+(p<<6)+56>>2]=n;c[r+(p<<6)+60>>2]=o;p=p+1|0}while((p|0)!=(j|0))}while(0);J=J+1|0}while((J|0)<(c[sa>>2]|0))}e:do if((c[ua>>2]|0)>0){L=f+180|0;K=f+176|0;r=ta+4|0;M=ta+16|0;x=ta+17|0;w=ta+18|0;J=ta+19|0;s=ta+20|0;u=ta+46|0;v=ta+47|0;z=ta+48|0;A=ta+52|0;B=ta+56|0;t=ta+60|0;D=ta+64|0;E=ta+68|0;C=ta+72|0;H=ta+76|0;F=ta+77|0;G=ta+78|0;I=ta+79|0;y=0;f:while(1){i=c[L>>2]|0;if(Ha?(ra=Qm(64,1)|0,c[(c[K>>2]|0)+(y*764|0)+756>>2]=ra,(ra|0)==0):0)break d;_l(g,(c[ya+(y<<2)>>2]|0)+h|0,0)|0;c[ta>>2]=Xl(g)|0;Zl(r,12,1,g)|0;a[M>>0]=Kl(g)|0;a[x>>0]=Kl(g)|0;a[w>>0]=Kl(g)|0;a[J>>0]=Kl(g)|0;Zl(s,26,1,g)|0;id(s);a[u>>0]=Kl(g)|0;a[v>>0]=Kl(g)|0;c[z>>2]=Vl(g)|0;c[A>>2]=Vl(g)|0;c[B>>2]=Vl(g)|0;c[t>>2]=Vl(g)|0;c[D>>2]=Vl(g)|0;c[E>>2]=Vl(g)|0;c[C>>2]=Vl(g)|0;a[H>>0]=Kl(g)|0;a[F>>0]=Kl(g)|0;a[G>>0]=Kl(g)|0;a[I>>0]=Kl(g)|0;do if((c[ta>>2]|0)==1229803603){j=a[w>>0]|0;o=i+(y*52|0)+44|0;if(!(j&2))m=c[o>>2]|0;else{c[o>>2]=1;m=1}k=c[z>>2]|0;q=i+(y*52|0)+32|0;c[q>>2]=k;p=i+(y*52|0)+36|0;c[p>>2]=c[A>>2];n=i+(y*52|0)+40|0;c[n>>2]=c[B>>2];c[o>>2]=(j&64)>>>4|((j&16)>>>3|m);if(Ha){ra=c[K>>2]|0;qa=c[ra+(y*764|0)+756>>2]|0;c[qa>>2]=d[J>>0];c[qa+8>>2]=128;c[qa+40>>2]=y;c[ra+(y*764|0)+36>>2]=(k|0)!=0&1;vb(ra,y,s,25)}else wb(i+(y*52|0)|0,s,25)|0;i=c[sa>>2]|0;if((i|0)>0){j=c[K>>2]|0;m=0;do{if((c[j+(m*764|0)+36>>2]|0)>0){k=0;do{i=c[j+(m*764|0)+756>>2]|0;if((c[i+(k<<6)+40>>2]|0)==(y|0)){c[i+(k<<6)>>2]=d[J>>0];c[i+(k<<6)+4>>2]=d[x>>0];c[i+(k<<6)+28>>2]=d[H>>0];c[i+(k<<6)+24>>2]=(d[F>>0]|0)>>>1;c[i+(k<<6)+20>>2]=d[I>>0];c[i+(k<<6)+32>>2]=((a[G>>0]^-2)&255)>>>1;mi(c[t>>2]|0,i+(k<<6)+12|0,i+(k<<6)+16|0);j=c[K>>2]|0}k=k+1|0}while((k|0)<(c[j+(m*764|0)+36>>2]|0));i=c[sa>>2]|0}m=m+1|0}while((m|0)<(i|0))}if(!(a[w>>0]&1))break;if((c[q>>2]|0)<=1)break;if(_l(g,(c[C>>2]|0)+h|0,0)|0)break d;ra=c[n>>2]|0;i=c[q>>2]|0;if(!((ra|0)<=(i|0)?(c[p>>2]|0)<(ra|0):0))c[o>>2]=c[o>>2]&-3;k=a[u>>0]|0;n=(k<<1&2^2)&255;o=a[w>>0]|0;if(!(o&8))if((Ub(f,g,n,(c[L>>2]|0)+(y*52|0)|0,0)|0)<0){i=-1;ra=219;break f}else break;m=Qm(1,i<<1)|0;if(!m)break d;j=c[q>>2]|0;i=k&4;if(!(o&2))Rb(g,m,j,i);else Tb(g,m,j,i)|0;ra=(Ub(f,0,n|16,(c[L>>2]|0)+(y*52|0)|0,m)|0)<0;Pm(m);if(ra){i=-1;ra=219;break f}}while(0);y=y+1|0;if((y|0)>=(c[ua>>2]|0))break e}if((ra|0)==219){l=La;return i|0}}while(0);i=c[Fa>>2]|0;if((i|0)>0){n=0;j=0;do{k=c[xa+(n<<2)>>2]|0;if(k){_l(g,k+h|0,0)|0;i=(Ml(g)|0)&65535;Ml(g)|0;k=Ea;m=k+64|0;do{a[k>>0]=0;k=k+1|0}while((k|0)<(m|0));Ml(g)|0;Ml(g)|0;g:while(1){while(1){m=i+-1|0;if((i|0)<=0)break g;k=Kl(g)|0;if(!(k<<24>>24))i=m;else break}ua=k&255;k=ua+63&63;j=(k|0)>(j|0)?k:j;if(!(ua&128)){k=a[Ea+k>>0]|0;i=m}else{ua=Kl(g)|0;a[Ea+k>>0]=ua;k=ua;i=i+-2|0}k=k&255;if(k&1){Kl(g)|0;i=i+-1|0}if(k&2){Kl(g)|0;i=i+-1|0}if(k&4){Kl(g)|0;i=i+-1|0}if(!(k&8))continue;Kl(g)|0;Kl(g)|0;i=i+-2|0}i=c[Fa>>2]|0}n=n+1|0}while((n|0)<(i|0))}else j=0;k=j+1|0;s=f+136|0;c[s>>2]=k;c[f+132>>2]=O(i,k)|0;k=Ba;m=k+64|0;do{a[k>>0]=0;k=k+1|0}while((k|0)<(m|0));if((pb(f)|0)>=0){if((c[Fa>>2]|0)>0){q=f+168|0;r=f+172|0;p=0;do{if((qb(f,p)|0)<0)break d;i=c[xa+(p<<2)>>2]|0;h:do if(!i){c[c[(c[q>>2]|0)+(p<<2)>>2]>>2]=64;i=c[s>>2]|0;if((i|0)>0)j=0;else break;do{i=(O(i,p)|0)+j|0;if((rb(f,i,64)|0)<0)break d;c[(c[(c[q>>2]|0)+(p<<2)>>2]|0)+4+(j<<2)>>2]=i;j=j+1|0;i=c[s>>2]|0}while((j|0)<(i|0))}else{_l(g,i+h|0,0)|0;i=Ml(g)|0;ua=(Ml(g)|0)&65535;c[c[(c[q>>2]|0)+(p<<2)>>2]>>2]=ua;if((sb(f,p)|0)<0)break d;k=Ea;m=k+64|0;do{a[k>>0]=0;k=k+1|0}while((k|0)<(m|0));Ml(g)|0;Ml(g)|0;if(!(i<<16>>16))break;i=i&65535;o=0;while(1){k=i;while(1){i=k+-1|0;j=Kl(g)|0;if(!(j<<24>>24))break;ua=j&255;n=ua+63&63;if(ua&128){a[Ea+n>>0]=Kl(g)|0;i=k+-2|0}do if((n|0)<(c[s>>2]|0)){j=c[(c[q>>2]|0)+(p<<2)>>2]|0;if((o|0)>=(c[j>>2]|0)){m=Aa;break}m=(c[(c[r>>2]|0)+(c[j+4+(n<<2)>>2]<<2)>>2]|0)+4+(o<<3)|0}else m=Aa;while(0);k=a[Ea+n>>0]|0;if(k&1){j=Kl(g)|0;switch(j<<24>>24){case -1:{j=-127;break}case -2:{j=-126;break}default:j=(j&255)>119?-125:j+1<<24>>24}a[m>>0]=j;a[Ca+(n<<3)>>0]=j;i=i+-1|0}j=k&255;if(j&2){ua=Kl(g)|0;a[m+1>>0]=ua;a[Ca+(n<<3)+1>>0]=ua;i=i+-1|0}if(j&4){ua=Kl(g)|0;a[m+2>>0]=ua;a[Ca+(n<<3)+2>>0]=ua;kd(m);i=i+-1|0}if(j&8){ta=m+3|0;a[ta>>0]=Kl(g)|0;ua=m+4|0;a[ua>>0]=Kl(g)|0;ld(n,m,Ba,va);a[Ca+(n<<3)+3>>0]=a[ta>>0]|0;a[Ca+(n<<3)+4>>0]=a[ua>>0]|0;i=i+-2|0}if(j&16|0)a[m>>0]=a[Ca+(n<<3)>>0]|0;if(j&32|0)a[m+1>>0]=a[Ca+(n<<3)+1>>0]|0;if(j&64|0){a[m+2>>0]=a[Ca+(n<<3)+2>>0]|0;kd(m)}if(j&128|0){a[m+3>>0]=a[Ca+(n<<3)+3>>0]|0;a[m+4>>0]=a[Ca+(n<<3)+4>>0]|0}if((i|0)>0)k=i;else break h}if((k|0)>1)o=o+1|0;else break}}while(0);p=p+1|0}while((p|0)<(c[Fa>>2]|0))}Pm(xa);Pm(ya);Pm(za);do if(b[Ga>>1]&1){Ga=Om((e[Ja>>1]|0)+1|0)|0;k=f+1220|0;c[k>>2]=Ga;if(!Ga)break;_l(g,(c[Ia>>2]|0)+h|0,0)|0;if(!(b[Ja>>1]|0))i=0;else{i=0;do{j=Kl(g)|0;if(j<<24>>24==13)j=10;else j=(j&255)<32^j<<24>>24>-1|(j+-9&255)<2?j:46;a[(c[k>>2]|0)+i>>0]=j;i=i+1|0}while((i|0)<(e[Ja>>1]|0))}a[(c[k>>2]|0)+i>>0]=0}while(0);Ja=f+1280|0;Ka=(b[Ka>>1]&32?4194304:1024)|(c[Ja>>2]|26708003);Ka=wa<<16>>16?Ka|2621440:Ka&-1048577;c[Ja>>2]=Ha?Ka&-32769:Ka;c[f+1272>>2]=128;c[f+1284>>2]=3;f=0;l=La;return f|0}}while(0);Pm(xa)}Pm(ya)}Pm(za);f=-1;l=La;return f|0}function id(b){b=b|0;var c=0,d=0;d=0;do{c=b+d|0;if(!(a[c>>0]|0))a[c>>0]=32;d=d+1|0}while((d|0)!=25);c=b+24|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+23|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+22|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+21|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+20|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+19|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+18|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+17|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+16|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+15|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+14|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+13|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+12|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+11|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+10|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+9|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+8|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+7|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+6|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+5|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+4|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+3|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+2|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+1|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;if((a[b>>0]|0)!=32)return;a[b>>0]=0;return}function jd(e,f,g){e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0;a[f>>0]=Kl(g)|0;j=f+1|0;a[j>>0]=Kl(g)|0;k=f+2|0;a[k>>0]=Kl(g)|0;l=f+3|0;a[l>>0]=Kl(g)|0;m=f+4|0;a[m>>0]=Kl(g)|0;n=f+5|0;a[n>>0]=Kl(g)|0;h=Kl(g)|0;i=0;do{a[f+6+(i<<2)>>0]=h;b[f+6+(i<<2)+2>>1]=Ml(g)|0;i=i+1|0;h=Kl(g)|0}while((i|0)!=25);a[f+106>>0]=h;i=d[f>>0]|0;i=i<<1&4|i&1|i<<2&32|(i&4|0?18:0);c[e>>2]=i;h=a[j>>0]|0;j=h&255;g=e+4|0;c[g>>2]=j;c[e+12>>2]=d[m>>0];c[e+16>>2]=d[n>>0];c[e+20>>2]=d[k>>0];c[e+24>>2]=d[l>>0];if((j+-1|0)>>>0>=31){c[e>>2]=i&54;return}if(!(h<<24>>24))return;else h=0;do{n=h<<1;b[e+28+(n<<1)>>1]=b[f+6+(h<<2)+2>>1]|0;b[e+28+((n|1)<<1)>>1]=a[f+6+(h<<2)>>0]|0;h=h+1|0}while((h|0)<(c[g>>2]|0));return}function kd(b){b=b|0;var c=0,d=0,e=0;e=b+2|0;c=a[e>>0]|0;d=c&255;a[e>>0]=0;if((c&255)<65){a[e>>0]=d+1;return}if((c&255)<75){a[b+5>>0]=14;a[b+6>>0]=d+63|160;return}if((c&255)<85){a[b+5>>0]=14;a[b+6>>0]=d+53|176;return}if((c&255)<95){a[b+5>>0]=-92;a[b+6>>0]=(d<<4)+176;return}if((c&255)<105){a[b+5>>0]=-92;a[b+6>>0]=d+161;return}if((c&255)<115){a[b+5>>0]=2;a[b+6>>0]=(d<<2)+92;return}if((c&255)<125){a[b+5>>0]=1;a[b+6>>0]=(d<<2)+52;return}if(c<<24>>24<0&(c&255)<193){a[b+5>>0]=8;a[b+6>>0]=c<<24>>24==-64?-4:d<<2&255;return}if((c+63&255)<10){a[b+5>>0]=3;a[b+6>>0]=(d<<2)+252;return}if((c+53&255)>=10)return;a[b+5>>0]=4;a[b+6>>0]=d+53;return}function ld(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0;l=c+4|0;k=a[l>>0]|0;h=(k&255)>>>4;m=c+3|0;g=a[18925+(d[m>>0]|0)>>0]|0;a[m>>0]=g;a:do switch(g<<24>>24){case -2:{a[m>>0]=14;g=e+b|0;if(!((h|k)<<24>>24)){h=a[g>>0]|0;a[l>>0]=h;b=h&15;h=(h&255)>>>4}else{a[g>>0]=k;b=k&15}g=b&255;do switch(h&15){case 1:{a[l>>0]=b|48;j=30;break a}case 2:{a[l>>0]=b|80;j=30;break a}case 3:{a[l>>0]=b|64;j=30;break a}case 4:{a[l>>0]=b|112;j=30;break a}case 5:{if(b>>>0<4){a[m>>0]=-117;a[l>>0]=g;j=30;break a}a[l>>0]=0;a[m>>0]=0;return}case 6:{a[l>>0]=b|224;j=30;break a}case 7:{a[m>>0]=-125;a[l>>0]=a[l>>0]&15;j=30;break a}case 8:{a[m>>0]=8;a[l>>0]=b<<4;j=30;break a}case 9:{a[l>>0]=0;a[m>>0]=0;return}case 11:{a[l>>0]=b|96;j=30;break a}case 13:case 12:{a[l>>0]=((b|0)==0&1)+g<<24>>24|h<<4&255;j=30;break a}case 14:{a[m>>0]=-120;a[l>>0]=g;j=30;break a}default:{a[l>>0]=0;a[m>>0]=0;return}}while(0)}case -124:{g=k&255;if(k<<24>>24<0&(k&255)<144){a[m>>0]=-123;a[l>>0]=g<<4;j=30;break a}else{a[l>>0]=g<<1;j=30;break a}}case 29:{if((f|0)==0?(i=k&255,k<<24>>24!=0):0){a[l>>0]=i+16&240|(i&15)+1;j=30}else j=30;break}case 16:{if((k&255)>128){a[l>>0]=0;a[m>>0]=0;return}else j=30;break}case -1:{a[l>>0]=0;a[m>>0]=0;return}default:{}}while(0);if((j|0)==30)g=a[m>>0]|0;if(g<<24>>24!=9)return;g=c+5|0;if((a[g>>0]|0)!=3)return;a[c+6>>0]=0;a[g>>0]=0;return}function md(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;e=l;l=l+16|0;d=e;_l(a,c+20|0,0)|0;do if((Zl(d,1,8,a)|0)>>>0>=8){if(en(d,19008,8)|0?en(d,18962,8)|0:0){d=-1;break}_l(a,c+60|0,0)|0;if((Zl(d,1,4,a)|0)>>>0>=4?(en(d,19017,4)|0)==0:0){_l(a,c,0)|0;xb(a,b,20);d=0}else d=-1}else d=-1;while(0);l=e;return d|0}function nd(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0;L=l;l=l+176|0;i=L+8|0;I=L+160|0;E=L+96|0;D=L+16|0;_l(g,h,0)|0;Zl(E,20,1,g)|0;F=E+20|0;Zl(F,8,1,g)|0;H=E+28|0;b[H>>1]=Ml(g)|0;b[E+30>>1]=Ml(g)|0;j=E+32|0;b[j>>1]=Ml(g)|0;k=E+34|0;b[k>>1]=Ml(g)|0;m=E+36|0;b[m>>1]=Ml(g)|0;b[E+38>>1]=Ml(g)|0;b[E+40>>1]=Ml(g)|0;a[E+42>>0]=Kl(g)|0;B=E+43|0;a[B>>0]=Kl(g)|0;b[E+44>>1]=Ml(g)|0;b[E+46>>1]=Ml(g)|0;n=E+48|0;b[n>>1]=Ml(g)|0;C=E+50|0;b[C>>1]=Ml(g)|0;A=E+52|0;b[A>>1]=Ml(g)|0;b[E+54>>1]=Ml(g)|0;b[E+56>>1]=Ml(g)|0;b[E+58>>1]=Ml(g)|0;Zl(E+60|0,4,1,g)|0;F=(fn(F,18962,8)|0)==0;C=e[C>>1]|0;K=f+140|0;c[K>>2]=C;n=e[n>>1]|0;J=f+128|0;c[J>>2]=n;G=f+136|0;c[f+132>>2]=O(c[G>>2]|0,n)|0;n=f+156|0;c[n>>2]=e[A>>1];c[f+148>>2]=(d[B>>0]|0)>>>4;c[f+144>>2]=C;c[f+1264>>2]=8363;_l(g,(e[j>>1]<<4)+h|0,0)|0;_l(g,(((Ml(g)|0)&65535)<<4)+h|0,0)|0;C=Ml(g)|0;H=C<<16>>16==(b[H>>1]|0);yo(f,E,20)|0;if(F)Eb(f,18971,L);else{c[i>>2]=(H^1)&1;ao(f+64|0,64,18984,i)}E=Qm(2,c[J>>2]|0)|0;if(!E){f=-1;l=L;return f|0}F=Qm(2,c[K>>2]|0)|0;if(F|0){_l(g,(e[j>>1]<<4)+h|0,0)|0;if((c[J>>2]|0)>0){i=0;do{b[E+(i<<1)>>1]=Ml(g)|0;i=i+1|0}while((i|0)<(c[J>>2]|0))}_l(g,(e[k>>1]<<4)+h|0,0)|0;if((c[K>>2]|0)>0){i=0;do{b[F+(i<<1)>>1]=Ml(g)|0;i=i+1|0}while((i|0)<(c[K>>2]|0))}_l(g,h+32+(e[m>>1]<<4)|0,0)|0;if((c[n>>2]|0)>0){i=0;do{a[f+952+i>>0]=Kl(g)|0;_l(g,4,1)|0;i=i+1|0}while((i|0)<(c[n>>2]|0))}a:do if((nb(f)|0)>=0){if((c[K>>2]|0)>0){i=D+1|0;w=D+14|0;t=D+16|0;u=D+20|0;v=D+24|0;A=D+28|0;y=D+29|0;x=D+30|0;o=D+31|0;n=D+32|0;z=D+34|0;j=D+36|0;r=D+40|0;q=D+42|0;s=D+44|0;k=D+48|0;m=D+76|0;C=f+180|0;B=f+176|0;p=0;do{if((ob(f,p,1)|0)<0)break a;_l(g,(e[F+(p<<1)>>1]<<4)+h|0,0)|0;a[D>>0]=Kl(g)|0;Zl(i,13,1,g)|0;b[w>>1]=Ml(g)|0;c[t>>2]=Vl(g)|0;c[u>>2]=Vl(g)|0;c[v>>2]=Vl(g)|0;a[A>>0]=Kl(g)|0;a[y>>0]=Kl(g)|0;a[x>>0]=Kl(g)|0;a[o>>0]=Kl(g)|0;b[n>>1]=Ml(g)|0;b[z>>1]=Ml(g)|0;Zl(j,4,1,g)|0;b[r>>1]=Ml(g)|0;b[q>>1]=Ml(g)|0;c[s>>2]=Vl(g)|0;Zl(k,28,1,g)|0;Zl(m,4,1,g)|0;N=c[C>>2]|0;c[N+(p*52|0)+32>>2]=c[t>>2];c[N+(p*52|0)+36>>2]=c[u>>2];P=c[v>>2]|0;M=(P|0)==65535;c[N+(p*52|0)+40>>2]=M?0:P;c[N+(p*52|0)+44>>2]=(P|0)>0&(M^1)?2:0;N=c[B>>2]|0;M=c[N+(p*764|0)+756>>2]|0;c[M>>2]=d[A>>0];c[M+8>>2]=128;c[M+40>>2]=p;c[N+(p*764|0)+36>>2]=1;vb(N,p,k,12);N=(((e[n>>1]|0)*8363|0)>>>0)/8448|0;b[n>>1]=N;M=c[(c[B>>2]|0)+(p*764|0)+756>>2]|0;mi(N&65535,M+12|0,M+16|0);p=p+1|0}while((p|0)<(c[K>>2]|0))}if((pb(f)|0)>=0){if((c[J>>2]|0)>0){q=f+172|0;p=f+168|0;o=0;do{if((tb(f,o,64)|0)<0)break a;i=b[E+(o<<1)>>1]|0;if(i<<16>>16){_l(g,((i&65535)<<4)+h|0,0)|0;if(H){_l(g,2,1)|0;n=0}else n=0;do{i=Kl(g)|0;if(i<<24>>24){j=i&255;while(1){i=j&31;if((i|0)<(c[G>>2]|0))m=(c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+(n<<3)|0;else m=I;if(j&32|0){P=Kl(g)|0;i=P&255;switch(P<<24>>24){case -1:{i=0;break}case -2:{i=-127;break}default:i=(i&15)+37+((i>>>4)*12|0)&255}a[m>>0]=i;a[m+1>>0]=Kl(g)|0}if(j&64|0)a[m+2>>0]=((Kl(g)|0)&255)+1;b:do if(j&128|0){k=m+3|0;a[k>>0]=a[18997+((Kl(g)|0)&255)>>0]|0;i=Kl(g)|0;j=m+4|0;a[j>>0]=i;switch(a[k>>0]|0){case 15:{i=(i&255)>>>4;break}case -1:{a[k>>0]=0;i=0;break}default:break b}a[j>>0]=i}while(0);i=Kl(g)|0;if(!(i<<24>>24))break;else j=i&255}}n=n+1|0}while((n|0)!=64)}o=o+1|0}while((o|0)<(c[J>>2]|0))}Pm(F);Pm(E);c:do if((c[K>>2]|0)>0){j=f+180|0;i=0;while(1){if((Ub(f,g,0,(c[j>>2]|0)+(i*52|0)|0,0)|0)<0){i=-1;break}i=i+1|0;if((i|0)>=(c[K>>2]|0))break c}l=L;return i|0}while(0);P=f+1280|0;c[P>>2]=c[P>>2]|293601889;c[f+1284>>2]=2;P=0;l=L;return P|0}}while(0);Pm(F)}Pm(E);P=-1;l=L;return P|0}function od(a,b,c){a=a|0;b=b|0;c=c|0;do if(((Xl(a)|0)==1179603533?(Xl(a)|0,(Xl(a)|0)==1297040460):0)?(Xl(a)|0)==1447383635:0){Xl(a)|0;_l(a,10,1)|0;if((Xl(a)|0)==1229866575){Xl(a)|0;xb(a,b,32);a=0;break}else{xb(a,b,0);a=0;break}}else a=-1;while(0);return a|0}function pd(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;e=l;l=l+32|0;f=e;g=e+4|0;_l(b,d,0)|0;Xl(b)|0;Xl(b)|0;Xl(b)|0;Xl(b)|0;Xl(b)|0;Zl(g,1,10,b)|0;c[f>>2]=g+4;Eb(a,19035,f);d=Fb()|0;if(!d){g=-1;l=e;return g|0}g=Jb(d,21008,20)|0;g=Jb(d,19050,21)|0|g;if(g|(Jb(d,19055,22)|0)|0){g=-1;l=e;return g|0}Qb(d,2);g=Gb(d,a,b,0)|0;Mb(d);g=g>>31;l=e;return g|0}function qd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;Zl(a,1,32,d)|0;c[a+140>>2]=(Pl(d)|0)&65535;c[a+156>>2]=(Pl(d)|0)&65535;c[a+128>>2]=(Pl(d)|0)&65535;c[a+164>>2]=(Pl(d)|0)&65535;c[a+152>>2]=(Pl(d)|0)&65535;Pl(d)|0;Pl(d)|0;Pl(d)|0;Pl(d)|0;Pl(d)|0;Pl(d)|0;Pl(d)|0;Pl(d)|0;Pl(d)|0;Pl(d)|0;return 0}function rd(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return 0}function sd(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;td(a,c);return 0}function td(f,g){f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;r=l;l=l+1088|0;o=r;p=r+1084|0;Zl(o,20,1,g)|0;h=0;do{Zl(o+20+(h*30|0)|0,22,1,g)|0;b[o+20+(h*30|0)+22>>1]=Pl(g)|0;a[o+20+(h*30|0)+24>>0]=Kl(g)|0;a[o+20+(h*30|0)+25>>0]=Kl(g)|0;b[o+20+(h*30|0)+26>>1]=Pl(g)|0;b[o+20+(h*30|0)+28>>1]=Pl(g)|0;h=h+1|0}while((h|0)!=31);j=o+950|0;a[j>>0]=Kl(g)|0;h=o+951|0;a[h>>0]=Kl(g)|0;i=o+952|0;Zl(i,128,1,g)|0;Zl(o+1080|0,4,1,g)|0;m=f+140|0;c[m>>2]=31;q=f+144|0;c[q>>2]=31;c[f+136>>2]=4;c[f+156>>2]=d[j>>0];c[f+160>>2]=d[h>>0];h=f+952|0;j=h+128|0;do{b[h>>1]=b[i>>1]|0;h=h+2|0;i=i+2|0}while((h|0)<(j|0));n=f+128|0;h=c[n>>2]|0;j=0;do{i=d[f+952+j>>0]|0;if((i|0)>(h|0)){c[n>>2]=i;h=i}j=j+1|0}while((j|0)!=128);k=h+1|0;c[n>>2]=k;c[f+132>>2]=k<<2;if((nb(f)|0)<0){l=r;return}a:do if((c[m>>2]|0)>0){k=f+180|0;h=f+176|0;j=0;while(1){if((ob(f,j,1)|0)<0)break;s=b[o+20+(j*30|0)+22>>1]|0;i=c[k>>2]|0;c[i+(j*52|0)+32>>2]=(s&65535)<<1;u=e[o+20+(j*30|0)+26>>1]<<1;c[i+(j*52|0)+36>>2]=u;t=b[o+20+(j*30|0)+28>>1]|0;c[i+(j*52|0)+40>>2]=((t&65535)<<1)+u;c[i+(j*52|0)+44>>2]=(t&65535)>1?2:0;i=c[h>>2]|0;if(s<<16>>16)c[i+(j*764|0)+36>>2]=1;u=c[i+(j*764|0)+756>>2]|0;c[u+16>>2]=d[o+20+(j*30|0)+24>>0]<<28>>24;c[u>>2]=a[o+20+(j*30|0)+25>>0];c[u+8>>2]=128;c[u+40>>2]=j;c[i+(j*764|0)+40>>2]=4095;vb(i,j,o+20+(j*30|0)|0,22);j=j+1|0;if((j|0)>=(c[m>>2]|0))break a}l=r;return}while(0);if((pb(f)|0)<0){l=r;return}b:do if((c[n>>2]|0)>0){k=f+172|0;j=f+168|0;h=0;while(1){if((tb(f,h,64)|0)<0)break;else i=0;do{u=(c[(c[k>>2]|0)+(c[(c[(c[j>>2]|0)+(h<<2)>>2]|0)+4+(((i|0)%4|0)<<2)>>2]<<2)>>2]|0)+4+(((i|0)/4|0)<<3)|0;Zl(p,1,4,g)|0;Bb(u,p);i=i+1|0}while((i|0)!=256);h=h+1|0;if((h|0)>=(c[n>>2]|0))break b}l=r;return}while(0);h=f+1280|0;c[h>>2]=c[h>>2]|8192;h=c[q>>2]|0;if((h|0)<=0){l=r;return}k=f+180|0;j=0;while(1){i=c[k>>2]|0;if(c[i+(j*52|0)+32>>2]|0){if((Ub(f,g,0,i+(j*52|0)|0,0)|0)<0){h=26;break}h=c[q>>2]|0}j=j+1|0;if((j|0)>=(h|0)){h=26;break}}if((h|0)==26){l=r;return}}function ud(a,b,c){a=a|0;b=b|0;c=c|0;_l(a,60,1)|0;c=Xl(a)|0;_l(a,60,1)|0;if((c|0)!=1397706311&(Xl(a)|0)!=1397706311){b=-1;return b|0}xb(a,b,0);b=0;return b|0}function vd(a,b,c){a=a|0;b=b|0;c=c|0;if((wd(a,b,15,c)|0)>=0){c=0;return c|0}c=wd(a,b,31,c)|0;return c|0}function wd(f,g,h,i){f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;y=l;l=l+1232|0;p=y+8|0;o=y;m=y+136|0;n=y+1092|0;x=y+1088|0;r=y+12|0;q=y+156|0;_l(g,i,0)|0;k=(h|0)>0;i=Xl(g)|0;if(k){j=0;do{c[r+(j<<2)>>2]=i;j=j+1|0;i=Xl(g)|0}while((j|0)!=(h|0))}c[m>>2]=i;w=Pl(g)|0;i=m+4|0;b[i>>1]=w;if((w&65535)<178){f=-1;l=y;return f|0}Zl(m+6|0,14,1,g)|0;if((c[m>>2]|0)!=1397706311){f=-1;l=y;return f|0}w=f+140|0;c[w>>2]=h;c[f+144>>2]=h;c[f+152>>2]=1776930/((e[i>>1]|0)>>>0)|0;if(k){i=0;do{Zl(q+(i*30|0)|0,22,1,g)|0;b[q+(i*30|0)+22>>1]=Pl(g)|0;a[q+(i*30|0)+24>>0]=Kl(g)|0;a[q+(i*30|0)+25>>0]=Kl(g)|0;b[q+(i*30|0)+26>>1]=Pl(g)|0;b[q+(i*30|0)+28>>1]=Pl(g)|0;i=i+1|0}while((i|0)<(c[w>>2]|0))}a[n>>0]=Kl(g)|0;a[n+1>>0]=Kl(g)|0;i=n+2|0;Zl(i,128,1,g)|0;j=a[n>>0]|0;m=j&255;c[f+156>>2]=m;if(j<<24>>24<0){f=-1;l=y;return f|0}ap(f+952|0,i|0,m|0)|0;v=f+128|0;c[v>>2]=0;if(!(j<<24>>24))i=0;else{i=0;k=0;do{j=d[f+952+k>>0]|0;if((j|0)>(i|0)){c[v>>2]=j;i=j}k=k+1|0}while((k|0)!=(m|0))}t=i+1|0;c[v>>2]=t;u=f+136|0;c[f+132>>2]=O(c[u>>2]|0,t)|0;if((c[w>>2]|0)==15)Eb(f,19077,o);else Eb(f,19089,p);if((nb(f)|0)<0){f=-1;l=y;return f|0}a:do if((c[w>>2]|0)>0){k=f+180|0;j=f+176|0;i=0;while(1){if((ob(f,i,1)|0)<0){i=-1;break}t=c[k>>2]|0;c[t+(i*52|0)+32>>2]=c[r+(i<<2)>>2];p=e[q+(i*30|0)+26>>1]|0;c[t+(i*52|0)+36>>2]=p;s=b[q+(i*30|0)+28>>1]|0;c[t+(i*52|0)+40>>2]=((s&65535)<<1)+p;c[t+(i*52|0)+44>>2]=(s&65535)>1?2:0;t=c[j>>2]|0;c[t+(i*764|0)+36>>2]=1;s=c[t+(i*764|0)+756>>2]|0;c[s>>2]=d[q+(i*30|0)+25>>0];c[s+16>>2]=(d[q+(i*30|0)+24>>0]|0)<<28>>24;c[s+8>>2]=128;c[s+40>>2]=i;vb(t,i,q+(i*30|0)|0,22);i=i+1|0;if((i|0)>=(c[w>>2]|0))break a}l=y;return i|0}while(0);if((pb(f)|0)<0){f=-1;l=y;return f|0}b:do if((c[v>>2]|0)>0){t=f+172|0;s=f+168|0;o=x+1|0;p=x+2|0;q=x+3|0;r=0;while(1){if((tb(f,r,64)|0)<0){i=-1;break}i=c[u>>2]|0;c:do if((i|0)>0){n=0;while(1){h=c[(c[t>>2]|0)+(c[(c[(c[s>>2]|0)+(r<<2)>>2]|0)+4+(((n|0)%(i|0)|0)<<2)>>2]<<2)>>2]|0;k=(n|0)/(i|0)|0;Zl(x,1,4,g)|0;i=a[x>>0]|0;a[h+4+(k<<3)>>0]=ki((i&15)<<8|(d[o>>0]|0))|0;j=a[p>>0]|0;a[h+4+(k<<3)+1>>0]=(j&255)>>>4|i&-16&255;i=a[q>>0]|0;m=h+4+(k<<3)+4|0;a[m>>0]=i;d:do switch(j&15){case 1:{a[h+4+(k<<3)+3>>0]=0;break}case 2:{j=i&255;if(j&240|0){a[h+4+(k<<3)+3>>0]=2;a[m>>0]=(i&255)>>>4;break d}if(j&15|0){a[h+4+(k<<3)+3>>0]=1;a[m>>0]=i&15}break}case 5:{a[h+4+(k<<3)+3>>0]=-95;break}case 6:{a[h+4+(k<<3)+3>>0]=12;a[m>>0]=64-(i&255);break}default:{a[m>>0]=0;a[h+4+(k<<3)+3>>0]=0}}while(0);n=n+1|0;i=c[u>>2]|0;if((n|0)>=(i<<6|0))break c}}while(0);r=r+1|0;if((r|0)>=(c[v>>2]|0))break b}l=y;return i|0}while(0);i=f+1280|0;c[i>>2]=c[i>>2]|8192;i=c[w>>2]|0;if((i|0)<=0){f=0;l=y;return f|0}m=f+180|0;k=0;while(1){j=c[m>>2]|0;if((c[j+(k*52|0)+32>>2]|0)>=3){if((Ub(f,g,0,j+(k*52|0)|0,0)|0)<0){i=-1;j=42;break}i=c[w>>2]|0}k=k+1|0;if((k|0)>=(i|0)){i=0;j=42;break}}if((j|0)==42){l=y;return i|0}return 0}function xd(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;f=l;l=l+16|0;e=f;_l(b,d+1080|0,0)|0;a:do if((Zl(e,1,4,b)|0)>>>0<4)e=-1;else{if(en(e,19355,3)|0?en(e,19359,3)|0:0){e=-1;break}switch(a[e+3>>0]|0){case 77:case 56:case 52:break;default:{e=-1;break a}}_l(b,d,0)|0;xb(b,c,20);e=0}while(0);l=f;return e|0}function yd(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;z=l;l=l+2176|0;s=z+32|0;o=z+24|0;m=z+16|0;j=z+8|0;i=z;w=z+40|0;y=z+2168|0;n=z+1144|0;p=z+1128|0;_l(g,h,0)|0;k=f+1208|0;h=f+1212|0;v=c[h>>2]|0;c[i>>2]=c[k>>2];c[i+4>>2]=v;ao(n,1024,19113,i);i=ho(n,21621)|0;if(!i){i=c[h>>2]|0;c[j>>2]=c[k>>2];c[j+4>>2]=i;ao(n,1024,19121,j);i=ho(n,21621)|0;if(!i){i=c[h>>2]|0;c[m>>2]=c[k>>2];c[m+4>>2]=i;ao(n,1024,19129,m);i=ho(n,21621)|0;if(!i){h=c[h>>2]|0;c[o>>2]=c[k>>2];c[o+4>>2]=h;ao(n,1024,19137,o);h=ho(n,21621)|0;if(!h){t=0;h=0;v=0;o=19101}else{i=1;x=6}}else x=4}else x=4}else x=4;if((x|0)==4){h=i;i=(i|0)!=0;x=6}if((x|0)==6){Go(p,1,16,h)|0;if(en(p,19145,16)|0)if(!(en(p,19162,16)|0)){t=1;v=i;o=19231}else{o=(en(p,19179,16)|0)==0;t=o&1;v=i;o=o?19196:19101}else{t=1;v=i;o=19215}}Zl(w,20,1,g)|0;i=0;do{Zl(w+20+(i*30|0)|0,22,1,g)|0;b[w+20+(i*30|0)+22>>1]=Pl(g)|0;a[w+20+(i*30|0)+24>>0]=Kl(g)|0;a[w+20+(i*30|0)+25>>0]=Kl(g)|0;b[w+20+(i*30|0)+26>>1]=Pl(g)|0;b[w+20+(i*30|0)+28>>1]=Pl(g)|0;i=i+1|0}while((i|0)!=31);k=w+950|0;a[k>>0]=Kl(g)|0;i=w+951|0;a[i>>0]=Kl(g)|0;j=w+952|0;Zl(j,128,1,g)|0;n=w+1080|0;Zl(n,4,1,g)|0;r=f+136|0;m=(a[w+1083>>0]|0)==52?4:8;c[r>>2]=m;p=f+140|0;c[p>>2]=31;u=f+144|0;c[u>>2]=31;c[f+156>>2]=d[k>>0];c[f+160>>2]=d[i>>0];i=f+952|0;k=i+128|0;do{b[i>>1]=b[j>>1]|0;i=i+2|0;j=j+2|0}while((i|0)<(k|0));q=f+128|0;k=0;do{j=f+952+k|0;i=a[j>>0]|0;if((m|0)>4){i=(i&255)>>>1;a[j>>0]=i}j=i&255;i=c[q>>2]|0;if((j|0)>(i|0)){c[q>>2]=j;i=j}k=k+1|0;m=c[r>>2]|0}while((k|0)!=128);k=i+1|0;c[q>>2]=k;c[f+132>>2]=O(k,m)|0;yo(f,w,20)|0;c[s>>2]=o;c[s+4>>2]=n;Eb(f,19247,s);if((nb(f)|0)<0){f=-1;l=z;return f|0}a:do if((c[p>>2]|0)>0){m=f+176|0;n=f+180|0;k=0;while(1){i=c[m>>2]|0;j=c[n>>2]|0;if((ob(f,k,1)|0)<0)break a;o=c[i+(k*764|0)+756>>2]|0;s=b[w+20+(k*30|0)+22>>1]|0;c[j+(k*52|0)+32>>2]=(s&65535)<<1;B=e[w+20+(k*30|0)+26>>1]<<1;c[j+(k*52|0)+36>>2]=B;A=b[w+20+(k*30|0)+28>>1]|0;c[j+(k*52|0)+40>>2]=((A&65535)<<1)+B;c[j+(k*52|0)+44>>2]=(A&65535)>1?2:0;c[o+16>>2]=d[w+20+(k*30|0)+24>>0]<<28>>24;c[o>>2]=a[w+20+(k*30|0)+25>>0];c[o+8>>2]=128;c[o+40>>2]=k;c[i+(k*764|0)+40>>2]=4095;if(s<<16>>16)c[i+(k*764|0)+36>>2]=1;vb(c[m>>2]|0,k,w+20+(k*30|0)|0,22);k=k+1|0;if((k|0)>=(c[p>>2]|0)){x=24;break}}}else x=24;while(0);b:do if((x|0)==24?(pb(f)|0)>=0:0){if((c[q>>2]|0)>0){p=f+172|0;o=f+168|0;n=0;do{if((tb(f,n,64)|0)<0)break b;else i=0;do{B=(c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(n<<2)>>2]|0)+4+(((i|0)%4|0)<<2)>>2]<<2)>>2]|0)+4+(((i|0)/4|0)<<3)|0;Zl(y,1,4,g)|0;zb(B,y);i=i+1|0}while((i|0)!=256);if((c[r>>2]|0)>4){m=0;do{i=c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(n<<2)>>2]|0)+4+(((m|0)%4|0)+4<<2)>>2]<<2)>>2]|0;j=(m|0)/4|0;Zl(y,1,4,g)|0;zb(i+4+(j<<3)|0,y);k=i+4+(j<<3)+3|0;if((a[k>>0]|0)==14){a[i+4+(j<<3)+4>>0]=0;a[k>>0]=0}m=m+1|0}while((m|0)!=256)}n=n+1|0}while((n|0)<(c[q>>2]|0))}if((c[u>>2]|0)>0){m=f+180|0;k=(t|0)==0;j=0;do{i=c[m>>2]|0;if(!(c[i+(j*52|0)+32>>2]|0)){if((!k?zd(h,j)|0:0)?(Ad(f,h,j)|0)<0:0)break b}else if((Ub(f,g,512,i+(j*52|0)|0,0)|0)<0)break b;j=j+1|0}while((j|0)<(c[u>>2]|0))}if(!v){B=0;l=z;return B|0}no(h)|0;B=0;l=z;return B|0}while(0);if(!v){B=-1;l=z;return B|0}no(h)|0;B=-1;l=z;return B|0}function zd(a,b){a=a|0;b=b|0;var c=0,d=0;d=l;l=l+16|0;c=d;ro(a,(b*120|0)+144|0,0)|0;if((Go(c,1,2,a)|0)>>>0>=2?(en(c,19352,2)|0)==0:0){ro(a,24,1)|0;c=((Yi(a)|0)&65535)<4&1}else c=0;l=d;return c|0}function Ad(d,e,f){d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;A=l;l=l+1024|0;g=A;j=c[d+176>>2]|0;k=c[d+180>>2]|0;m=k+(f*52|0)|0;ro(e,(f*120|0)+150|0,0)|0;v=Yi(e)|0;w=Yi(e)|0;x=Yi(e)|0;n=Yi(e)|0;o=Yi(e)|0;p=Yi(e)|0;q=Yi(e)|0;r=Yi(e)|0;Yi(e)|0;s=Yi(e)|0;h=Yi(e)|0;z=0-((Yi(e)|0)&65535)|0;y=z&65535;t=Yi(e)|0;u=Yi(e)|0;i=Yi(e)|0;if(h<<16>>16<3){c[k+(f*52|0)+32>>2]=32;c[k+(f*52|0)+36>>2]=0;c[k+(f*52|0)+40>>2]=32;g=19256+(h<<16>>16<<5)|0}else{c[k+(f*52|0)+32>>2]=1024;c[k+(f*52|0)+36>>2]=0;c[k+(f*52|0)+40>>2]=1024;e=0;do{a[g+e>>0]=Ao()|0;e=e+1|0}while((e|0)!=1024)}c[k+(f*52|0)+44>>2]=2;k=c[j+(f*764|0)+756>>2]|0;c[k>>2]=64;c[j+(f*764|0)+36>>2]=1;c[k+12>>2]=O(i<<16>>16,-12)|0;c[k+20>>2]=0;c[k+24>>2]=t<<16>>16;c[k+28>>2]=u<<16>>16;c[j+(f*764|0)+48>>2]=6;c[j+(f*764|0)+44>>2]=1;b[j+(f*764|0)+72>>1]=0;t=v<<16>>16;b[j+(f*764|0)+74>>1]=(t|0)/4|0;u=w<<16>>16;k=w<<16>>16>v<<16>>16;v=k?256-t|0:t;x=((k?u-t|0:t-u|0)<<8|0)/(O((v|0)==0?1:v,x<<16>>16==0?1:x<<16>>16)|0)|0;b[j+(f*764|0)+76>>1]=x;b[j+(f*764|0)+78>>1]=(u|0)/4|0;v=n<<16>>16;w=n<<16>>16>w<<16>>16;t=w?256-u|0:u;t=x+(((w?v-u|0:u-v|0)<<8|0)/(O((t|0)==0?1:t,o<<16>>16==0?1:o<<16>>16)|0)|0)|0;b[j+(f*764|0)+80>>1]=t;b[j+(f*764|0)+82>>1]=(v|0)/4|0;w=p<<16>>16;u=p<<16>>16>n<<16>>16;x=u?256-v|0:v;x=(t&65535)+(((u?w-v|0:v-w|0)<<8|0)/(O((x|0)==0?1:x,q<<16>>16==0?1:q<<16>>16)|0)|0)|0;b[j+(f*764|0)+84>>1]=x;w=((w|0)/4|0)&65535;b[j+(f*764|0)+86>>1]=w;x=x+(r&65535)|0;b[j+(f*764|0)+88>>1]=x;b[j+(f*764|0)+90>>1]=w;b[j+(f*764|0)+92>>1]=(256/((s<<16>>16==0?1:s<<16>>16)|0)|0)+x;b[j+(f*764|0)+94>>1]=0;if(!(y<<16>>16)){z=Ub(d,0,16,m,g)|0;z=(z|0)!=0;z=z<<31>>31;l=A;return z|0}c[j+(f*764|0)+360>>2]=2;c[j+(f*764|0)+356>>2]=1;b[j+(f*764|0)+384>>1]=0;b[j+(f*764|0)+386>>1]=0;z=z<<16;y=z>>16;b[j+(f*764|0)+388>>1]=1024/(((z|0)>-65536?y:0-y|0)|0)|0;b[j+(f*764|0)+390>>1]=(z>>31&-512|256)*10;z=Ub(d,0,16,m,g)|0;z=(z|0)!=0;z=z<<31>>31;l=A;return z|0}function Bd(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;u=l;l=l+688|0;p=u+80|0;s=u+680|0;q=u;fm(f,q)|0;q=q+36|0;if((c[q>>2]|0)<600){g=-1;l=u;return g|0}_l(f,h,0)|0;Zl(p,1,20,f)|0;if((yb(p,20)|0)<0){g=-1;l=u;return g|0}else i=0;do{Zl(p+20+(i*30|0)|0,1,22,f)|0;b[p+20+(i*30|0)+22>>1]=Pl(f)|0;a[p+20+(i*30|0)+24>>0]=Kl(f)|0;a[p+20+(i*30|0)+25>>0]=Kl(f)|0;b[p+20+(i*30|0)+26>>1]=Pl(f)|0;b[p+20+(i*30|0)+28>>1]=Pl(f)|0;i=i+1|0}while((i|0)!=15);k=p+470|0;a[k>>0]=Kl(f)|0;a[p+471>>0]=Kl(f)|0;Zl(p+472|0,1,128,f)|0;j=0;r=0;do{o=a[p+472+j>>0]|0;i=o&255;if(o<<24>>24<0){t=-1;m=26;break}r=(i|0)>(r|0)?i:r;j=j+1|0}while((j|0)<128);if((m|0)==26){l=u;return t|0}if((r|0)>126|(a[k>>0]|0)<1){g=-1;l=u;return g|0}else{m=0;o=0}while(1){if((yb(p+20+(m*30|0)|0,22)|0)<0){t=-1;m=26;break}if((a[p+20+(m*30|0)+25>>0]|0)>64){t=-1;m=26;break}if((a[p+20+(m*30|0)+24>>0]|0)>15){t=-1;m=26;break}i=b[p+20+(m*30|0)+22>>1]|0;k=i&65535;if((i&65535)>32768){t=-1;m=26;break}j=b[p+20+(m*30|0)+26>>1]|0;n=(j&65535)>>>1;if(n>>>0>k>>>0?1:(e[p+20+(m*30|0)+28>>1]|0)>32768){t=-1;m=26;break}i=i<<16>>16!=0;if(!(i&(n|0)==(k|0)^(i|j<<16>>16==0))){t=-1;m=26;break}o=(k<<1)+o|0;m=m+1|0;if((m|0)>=15){m=15;break}}if((m|0)==15){if((o|0)<8){g=-1;l=u;return g|0}if((c[q>>2]|0)<(o+((r<<10)+1024|600)|0)){g=-1;l=u;return g|0}k=s+1|0;m=0;a:while(1){n=0;do{Zl(s,1,4,f)|0;i=d[s>>0]|0;if(i&240|0){t=-1;m=26;break a}i=d[k>>0]|i<<8&3840;b:do switch(i&4095){case 162:case 0:break;default:{j=0;while(1){if((i|0)==(c[1916+(j<<2)>>2]|0))break b;j=j+1|0;if((j|0)==36){t=-1;m=26;break a}}}}while(0);n=n+1|0}while((n|0)<256);if((m|0)<(r|0))m=m+1|0;else{m=25;break}}if((m|0)==25){_l(f,h,0)|0;xb(f,g,20);g=0;l=u;return g|0}else if((m|0)==26){l=u;return t|0}}else if((m|0)==26){l=u;return t|0}return 0}function Cd(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;A=l;l=l+624|0;t=A;s=A+616|0;y=A+8|0;v=A+608|0;_l(g,h,0)|0;p=f+140|0;c[p>>2]=15;z=f+144|0;c[z>>2]=15;Zl(y,1,20,g)|0;i=0;do{Zl(y+20+(i*30|0)|0,1,22,g)|0;b[y+20+(i*30|0)+22>>1]=Pl(g)|0;a[y+20+(i*30|0)+24>>0]=Kl(g)|0;a[y+20+(i*30|0)+25>>0]=Kl(g)|0;b[y+20+(i*30|0)+26>>1]=Pl(g)|0;b[y+20+(i*30|0)+28>>1]=Pl(g)|0;i=i+1|0}while((i|0)!=15);x=y+470|0;a[x>>0]=Kl(g)|0;m=y+471|0;a[m>>0]=Kl(g)|0;j=y+472|0;Zl(j,1,128,g)|0;w=f+156|0;c[w>>2]=d[x>>0];m=a[m>>0]|0;x=f+160|0;c[x>>2]=m&255;i=f+952|0;k=i+128|0;do{b[i>>1]=b[j>>1]|0;i=i+2|0;j=j+2|0}while((i|0)<(k|0));u=f+128|0;i=c[u>>2]|0;k=0;while(1){j=d[f+952+k>>0]|0;if((j|0)>(i|0))c[u>>2]=j;else j=i;k=k+1|0;if((k|0)==128)break;else i=j}i=(m&255)>63&1;c[u>>2]=j+1;j=c[p>>2]|0;if((j|0)>0){k=0;do{i=(a[y+20+(k*30|0)+24>>0]|0)==0?i:0;if(!(((e[y+20+(k*30|0)+22>>1]|0)<=4999?(e[y+20+(k*30|0)+26>>1]|0)<=9999:0)?(e[y+20+(k*30|0)+28>>1]|0)<=4999:0))i=0;k=k+1|0}while((k|0)!=(j|0))}if((nb(f)|0)<0){z=-1;l=A;return z|0}a:do if((c[p>>2]|0)>0){n=f+176|0;o=f+180|0;m=0;while(1){j=c[n>>2]|0;k=c[o>>2]|0;if((ob(f,m,1)|0)<0){i=-1;break}q=c[j+(m*764|0)+756>>2]|0;r=k+(m*52|0)+32|0;c[r>>2]=(e[y+20+(m*30|0)+22>>1]<<1)-(e[y+20+(m*30|0)+26>>1]|0);c[k+(m*52|0)+36>>2]=0;B=b[y+20+(m*30|0)+28>>1]|0;c[k+(m*52|0)+40>>2]=(B&65535)<<1;c[k+(m*52|0)+44>>2]=(B&65535)>1?2:0;c[q+16>>2]=d[y+20+(m*30|0)+24>>0]<<28>>24;c[q>>2]=a[y+20+(m*30|0)+25>>0];c[q+8>>2]=128;c[q+40>>2]=m;q=j+(m*764|0)|0;yo(q,y+20+(m*30|0)|0,22)|0;pl(q)|0;if((c[r>>2]|0)>0)c[j+(m*764|0)+36>>2]=1;m=m+1|0;if((m|0)>=(c[p>>2]|0))break a}l=A;return i|0}while(0);r=f+136|0;c[f+132>>2]=O(c[u>>2]|0,c[r>>2]|0)|0;yo(f,y,20)|0;q=$l(g)|0;j=c[u>>2]|0;if((j|0)>0){p=s+3|0;o=s+4|0;k=c[r>>2]|0;m=j;j=0;n=0;do{if((k|0)>0){m=0;do{Zl(v,1,4,g)|0;Bb(s,v);B=a[p>>0]|0;k=a[o>>0]|0;j=(B<<24>>24==0?k<<24>>24!=0&1:1<<(B&255))|j;i=(B&255)<3?i:0;switch(B<<24>>24){case 1:{i=k<<24>>24==0?0:i;break}case 2:{B=k&255;i=(B&15|0)==0|(B&240|0)==0?i:0;break}default:{}}m=m+1|0;k=c[r>>2]|0}while((m|0)<(k<<6|0));m=c[u>>2]|0}n=n+1|0}while((n|0)<(m|0))}else j=0;o=(i|0)!=0&(j&-7|0)==0;if(o)i=19431;else i=(j&-53256|0)==0?19415:(j&-63496|0)==0?19376:19399;c[t>>2]=i;ao(f+64|0,64,21202,t);_l(g,q+h|0,0)|0;if((pb(f)|0)<0){B=-1;l=A;return B|0}i=c[u>>2]|0;b:do if((i|0)>0){n=f+172|0;m=f+168|0;k=0;while(1){if((tb(f,k,64)|0)<0){i=-1;break}i=c[r>>2]|0;if((i|0)>0){j=0;do{B=(c[(c[n>>2]|0)+(c[(c[(c[m>>2]|0)+(k<<2)>>2]|0)+4+(((j|0)%(i|0)|0)<<2)>>2]<<2)>>2]|0)+4+(((j|0)/(i|0)|0)<<3)|0;Zl(v,1,4,g)|0;Bb(B,v);j=j+1|0;i=c[r>>2]|0}while((j|0)<(i<<6|0))}k=k+1|0;i=c[u>>2]|0;if((k|0)>=(i|0)){u=i;break b}}l=A;return i|0}else u=i;while(0);i=f+1280|0;c[i>>2]=c[i>>2]|8192;i=c[x>>2]|0;if(o){c[f+152>>2]=i;c[x>>2]=0;if((u|0)>0){k=c[r>>2]|0;o=(k|0)>0;t=f+172|0;h=f+168|0;s=k<<6;q=0;do{c:do if(o){m=c[t>>2]|0;n=c[(c[h>>2]|0)+(q<<2)>>2]|0;r=0;while(1){i=c[m+(c[n+4+(((r|0)%(k|0)|0)<<2)>>2]<<2)>>2]|0;j=(r|0)/(k|0)|0;p=i+4+(j<<3)+3|0;d:do switch(a[p>>0]|0){case 1:{a[p>>0]=0;break}case 2:{j=i+4+(j<<3)+4|0;i=a[j>>0]|0;if((i&255)<16){a[p>>0]=1;break d}if(!(i&15))a[j>>0]=(i&255)>>>4;break}default:{}}while(0);r=r+1|0;if((r|0)>=(s|0))break c}}while(0);q=q+1|0}while((q|0)!=(u|0))}}else if((i|0)>=(c[w>>2]|0))c[x>>2]=0;i=c[z>>2]|0;if((i|0)<=0){B=0;l=A;return B|0}k=f+180|0;j=0;while(1){if(c[(c[k>>2]|0)+(j*52|0)+32>>2]|0){_l(g,e[y+20+(j*30|0)+26>>1]|0,1)|0;if((Ub(f,g,0,(c[k>>2]|0)+(j*52|0)|0,0)|0)<0){i=-1;j=59;break}i=c[z>>2]|0}j=j+1|0;if((j|0)>=(i|0)){i=0;j=59;break}}if((j|0)==59){l=A;return i|0}return 0}function Dd(a,b,c){a=a|0;b=b|0;c=c|0;do if((Xl(a)|0)==1179603533?(Xl(a)|0,(Xl(a)|0)==1162694468):0)if((Xl(a)|0)==1162692931){Xl(a)|0;Pl(a)|0;xb(a,b,20);a=0;break}else{xb(a,b,0);a=0;break}else a=-1;while(0);return a|0}function Ed(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;_l(b,c,0)|0;Xl(b)|0;Xl(b)|0;Xl(b)|0;c=Fb()|0;if(!c){a=-1;return a|0}d=Jb(c,19469,23)|0;d=Jb(c,21298,24)|0|d;if(d|(Jb(c,19474,25)|0)|0){d=-1;return d|0}d=Gb(c,a,b,0)|0;Mb(c);d=d>>31;return d|0}function Fd(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0;m=l;l=l+272|0;j=m;k=m+8|0;i=(Pl(e)|0)&65535;Zl(b,1,20,e)|0;_l(e,20,1)|0;c[b+152>>2]=(Kl(e)|0)&255;g=(Kl(e)|0)&255;h=b+140|0;c[h>>2]=g;c[b+144>>2]=g;g=b+1280|0;c[g>>2]=c[g>>2]|8192;c[j>>2]=i;ao(b+64|0,64,19479,j);if((nb(b)|0)<0){b=-1;l=m;return b|0}a:do if((c[h>>2]|0)>0){i=b+176|0;j=b+180|0;g=0;while(1){f=c[i>>2]|0;d=c[j>>2]|0;if((ob(b,g,1)|0)<0){f=-1;break}n=c[f+(g*764|0)+756>>2]|0;Kl(e)|0;c[n>>2]=(Kl(e)|0)&255;c[d+(g*52|0)+32>>2]=((Pl(e)|0)&65535)<<1;Zl(f+(g*764|0)|0,1,20,e)|0;c[d+(g*52|0)+44>>2]=(Kl(e)|0)<<1&2;c[n+16>>2]=(Kl(e)|0)&255;o=((Pl(e)|0)&65535)<<1;c[d+(g*52|0)+36>>2]=o;c[d+(g*52|0)+40>>2]=(((Pl(e)|0)&65535)<<1)+o;Xl(e)|0;c[f+(g*764|0)+36>>2]=1;c[n+8>>2]=128;c[n+40>>2]=g;g=g+1|0;if((g|0)>=(c[h>>2]|0))break a}l=m;return f|0}while(0);Kl(e)|0;o=(Kl(e)|0)&255;d=b+128|0;c[d>>2]=o;c[b+132>>2]=O(c[b+136>>2]|0,o)|0;if((pb(b)|0)<0){o=-1;l=m;return o|0}cp(k|0,0,256)|0;b:do if((c[d>>2]|0)>0){f=0;while(1){a[k+((Kl(e)|0)&255)>>0]=f;if((tb(b,f,((Kl(e)|0)&255)+1|0)|0)<0){f=-1;break}_l(e,20,1)|0;Xl(e)|0;f=f+1|0;if((f|0)>=(c[d>>2]|0))break b}l=m;return f|0}while(0);o=Kl(e)|0;d=b+156|0;c[d>>2]=o&255;if(!(o<<24>>24)){o=0;l=m;return o|0}else f=0;do{a[b+952+f>>0]=a[k+((Kl(e)|0)&255)>>0]|0;f=f+1|0}while((f|0)<(c[d>>2]|0));f=0;l=m;return f|0}function Gd(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;l=b+128|0;f=c[l>>2]|0;if((f|0)<=0)return 0;m=b+168|0;k=b+136|0;j=b+172|0;d=c[m>>2]|0;i=0;do{if((c[c[d+(i<<2)>>2]>>2]|0)>0){f=c[k>>2]|0;h=0;do{if((f|0)>0){b=0;while(1){f=c[(c[j>>2]|0)+(c[(c[d+(i<<2)>>2]|0)+4+(b<<2)>>2]<<2)>>2]|0;a[f+4+(h<<3)+1>>0]=Kl(e)|0;g=(Kl(e)|0)&255;d=g+1|0;a[f+4+(h<<3)>>0]=(d&255|0)==0?d:g+49|0;g=f+4+(h<<3)+3|0;a[g>>0]=(Kl(e)|0)&15;d=Kl(e)|0;f=f+4+(h<<3)+4|0;a[f>>0]=d;switch(a[g>>0]|0){case 4:{d=d&255;d=d<<1&14|d&240;n=9;break}case 9:{f=g;d=18;n=9;break}case 11:{f=g;d=17;n=9;break}default:{}}if((n|0)==9){n=0;a[f>>0]=d}b=b+1|0;f=c[k>>2]|0;if((b|0)>=(f|0))break;d=c[m>>2]|0}d=c[m>>2]|0}h=h+1|0}while((h|0)<(c[c[d+(i<<2)>>2]>>2]|0));f=c[l>>2]|0}i=i+1|0}while((i|0)<(f|0));return 0}function Hd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=a+180|0;b=a+144|0;if((c[b>>2]|0)>0)e=0;else{a=0;return a|0}while(1){if((Ub(a,d,0,(c[f>>2]|0)+(e*52|0)|0,0)|0)<0){e=-1;b=4;break}e=e+1|0;if((e|0)>=(c[b>>2]|0)){e=0;b=4;break}}if((b|0)==4)return e|0;return 0}function Id(a,b,c){a=a|0;b=b|0;c=c|0;_l(a,c+60|0,0)|0;if((Xl(a)|0)!=1229795632){b=-1;return b|0}_l(a,c,0)|0;xb(a,b,32);b=0;return b|0}function Jd(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0;ja=l;l=l+1296|0;p=ja;v=ja+1288|0;r=ja+456|0;ha=ja+72|0;ia=ja+8|0;_l(g,h,0)|0;Zl(r,32,1,g)|0;i=r+32|0;b[i>>1]=Ml(g)|0;n=r+34|0;b[n>>1]=Ml(g)|0;j=r+36|0;b[j>>1]=Ml(g)|0;m=r+38|0;b[m>>1]=Ml(g)|0;Zl(r+40|0,8,1,g)|0;o=r+48|0;a[o>>0]=Kl(g)|0;k=r+49|0;a[k>>0]=Kl(g)|0;a[r+50>>0]=Kl(g)|0;a[r+51>>0]=Kl(g)|0;Zl(r+52|0,8,1,g)|0;c[r+60>>2]=Xl(g)|0;h=0;do{Zl(r+64+(h<<4)|0,12,1,g)|0;a[r+64+(h<<4)+12>>0]=Kl(g)|0;a[r+64+(h<<4)+13>>0]=Kl(g)|0;a[r+64+(h<<4)+14>>0]=Kl(g)|0;a[r+64+(h<<4)+15>>0]=Kl(g)|0;h=h+1|0}while((h|0)!=32);q=r+576|0;Zl(q,256,1,g)|0;wb(f,r,32)|0;s=f+156|0;c[s>>2]=e[i>>1];fa=f+140|0;c[fa>>2]=e[j>>1];ga=f+144|0;c[ga>>2]=1024;u=f+128|0;c[u>>2]=e[n>>1];if(b[m>>1]&1){ea=f+1280|0;c[ea>>2]=c[ea>>2]|4096}c[f+148>>2]=d[o>>0];c[f+152>>2]=d[k>>0];Eb(f,19523,p);t=f+136|0;c[t>>2]=0;h=0;do{i=h;h=h+1|0;if(a[r+64+(i<<4)+12>>0]|0){c[t>>2]=h;c[f+184+(i*12|0)>>2]=d[r+64+(i<<4)+13>>0]}}while((h|0)!=32);c[f+132>>2]=O(c[t>>2]|0,c[u>>2]|0)|0;h=c[s>>2]|0;ap(f+952|0,q|0,h|0)|0;if((h|0)>0){j=0;do{i=f+952+j|0;if((a[i>>0]|0)==-1){a[i>>0]=-2;h=c[s>>2]|0}j=j+1|0}while((j|0)<(h|0))}c[f+1264>>2]=8363;if((pb(f)|0)<0){f=-1;l=ja;return f|0}a:do if((c[u>>2]|0)>0){q=f+172|0;p=f+168|0;o=0;while(1){h=Ml(g)|0;if((tb(f,o,(Ml(g)|0)&65535)|0)<0){h=-1;break}i=h&65535;b:do if((h&65535)>4){j=i+-5|0;h=i+-4|0;n=0;while(1){k=j;while(1){ea=Kl(g)|0;m=ea&255;if(!(ea<<24>>24))break;i=m&31;if((i|0)<(c[t>>2]|0))j=(c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+(n<<3)|0;else j=v;if(!(m&32))h=k;else{ea=Kl(g)|0;i=ea&255;switch(ea<<24>>24){case -96:case -1:{i=-127;break}default:i=(i&15)+13+((i>>>4)*12|0)&255}a[j>>0]=i;a[j+1>>0]=Kl(g)|0;h=h+-3|0}if(m&128){da=j+3|0;a[da>>0]=Kl(g)|0;ea=j+4|0;a[ea>>0]=Kl(g)|0;Kd(da,ea);h=h+-2|0}if(m&64){da=j+5|0;a[da>>0]=Kl(g)|0;ea=j+6|0;a[ea>>0]=Kl(g)|0;Kd(da,ea);h=h+-2|0}if((h|0)>0)k=h+-1|0;else break b}if((k|0)>0){j=k+-1|0;h=k;n=n+1|0}else break}}while(0);o=o+1|0;if((o|0)>=(c[u>>2]|0))break a}l=ja;return h|0}while(0);if((nb(f)|0)<0){f=-1;l=ja;return f|0}c:do if((c[fa>>2]|0)>0){u=ha+32|0;v=ha+152|0;E=ha+376|0;Z=ha+378|0;U=ha+380|0;ea=f+176|0;Y=ha+352|0;ca=ha+353|0;S=ha+354|0;N=ha+355|0;H=ha+356|0;w=ia+13|0;K=ia+16|0;T=ia+20|0;P=ia+24|0;$=ia+28|0;da=ia+32|0;_=ia+33|0;x=ia+34|0;I=ia+48|0;y=ia+49|0;D=ia+54|0;C=ia+56|0;V=ia+60|0;h=f+180|0;z=ha+357|0;W=ha+360|0;aa=ha+361|0;Q=ha+362|0;L=ha+363|0;F=ha+364|0;A=ha+365|0;X=ha+368|0;ba=ha+369|0;R=ha+370|0;M=ha+371|0;G=ha+372|0;B=ha+373|0;J=0;i=0;d:while(1){Zl(ha,32,1,g)|0;Zl(u,120,1,g)|0;Zl(v,8,1,g)|0;j=0;do{b[ha+160+(j<<1)>>1]=Ml(g)|0;j=j+1|0}while((j|0)!=32);j=0;do{b[ha+224+(j<<1)>>1]=Ml(g)|0;j=j+1|0}while((j|0)!=32);j=0;do{b[ha+288+(j<<1)>>1]=Ml(g)|0;j=j+1|0}while((j|0)!=32);a[Y>>0]=Kl(g)|0;a[ca>>0]=Kl(g)|0;a[S>>0]=Kl(g)|0;a[N>>0]=Kl(g)|0;a[H>>0]=Kl(g)|0;Zl(z,3,1,g)|0;a[W>>0]=Kl(g)|0;a[aa>>0]=Kl(g)|0;a[Q>>0]=Kl(g)|0;a[L>>0]=Kl(g)|0;a[F>>0]=Kl(g)|0;Zl(A,3,1,g)|0;a[X>>0]=Kl(g)|0;a[ba>>0]=Kl(g)|0;a[R>>0]=Kl(g)|0;a[M>>0]=Kl(g)|0;a[G>>0]=Kl(g)|0;Zl(B,3,1,g)|0;b[E>>1]=Ml(g)|0;b[Z>>1]=Ml(g)|0;t=Xl(g)|0;c[U>>2]=t;if((t|0)!=1229533488){h=-2;j=57;break}t=b[Z>>1]|0;j=t&65535;c[(c[ea>>2]|0)+(J*764|0)+36>>2]=j;if(t<<16>>16?(ob(f,J,j)|0)<0:0){h=-1;j=57;break}pl(ha)|0;yo((c[ea>>2]|0)+(J*764|0)|0,ha,24)|0;m=c[ea>>2]|0;j=0;do{a[m+(J*764|0)+512+(j+12<<1)>>0]=a[ha+32+j>>0]|0;j=j+1|0}while((j|0)!=108);t=a[Y>>0]|0;k=m+(J*764|0)+48|0;c[k>>2]=t&255;c[m+(J*764|0)+56>>2]=d[ca>>0];c[m+(J*764|0)+64>>2]=d[S>>0];c[m+(J*764|0)+68>>2]=d[N>>0];c[m+(J*764|0)+44>>2]=a[H>>0]&7;if(t<<24>>24){j=0;do{t=j<<1;b[m+(J*764|0)+72+(t<<1)>>1]=b[ha+160+(t<<1)>>1]|0;t=t|1;b[m+(J*764|0)+72+(t<<1)>>1]=b[ha+160+(t<<1)>>1]|0;j=j+1|0}while((j|0)<(c[k>>2]|0))}if(b[Z>>1]|0){t=0;do{Zl(ia,13,1,g)|0;Zl(w,3,1,g)|0;c[K>>2]=Vl(g)|0;c[T>>2]=Vl(g)|0;c[P>>2]=Vl(g)|0;c[$>>2]=Vl(g)|0;a[da>>0]=Kl(g)|0;a[_>>0]=Kl(g)|0;Zl(x,14,1,g)|0;a[I>>0]=Kl(g)|0;Zl(y,5,1,g)|0;b[D>>1]=Ml(g)|0;c[C>>2]=Vl(g)|0;c[V>>2]=Xl(g)|0;j=c[(c[ea>>2]|0)+(J*764|0)+756>>2]|0;c[j+(t<<6)+40>>2]=i;c[j+(t<<6)>>2]=d[da>>0];c[j+(t<<6)+8>>2]=d[_>>0];k=c[K>>2]|0;p=c[h>>2]|0;q=p+(i*52|0)+32|0;c[q>>2]=k;m=c[T>>2]|0;s=p+(i*52|0)+36|0;c[s>>2]=m;n=c[P>>2]|0;r=p+(i*52|0)+40|0;c[r>>2]=n;ka=a[I>>0]|0;o=ka<<1&2;p=p+(i*52|0)+44|0;c[p>>2]=o;if(ka&4){c[p>>2]=o|1;c[q>>2]=k>>1;c[s>>2]=m>>1;c[r>>2]=n>>1}mi(c[$>>2]|0,j+(t<<6)+12|0,j+(t<<6)+16|0);j=c[h>>2]|0;if(c[j+(i*52|0)+32>>2]|0?(Ub(f,g,0,j+((c[(c[(c[ea>>2]|0)+(J*764|0)+756>>2]|0)+(t<<6)+40>>2]|0)*52|0)|0,0)|0)<0:0){h=-1;j=57;break d}t=t+1|0;i=i+1|0}while((t|0)<(e[Z>>1]|0))}J=J+1|0;if((J|0)>=(c[fa>>2]|0))break c}if((j|0)==57){l=ja;return h|0}}else{i=0;h=f+180|0}while(0);c[ga>>2]=i;c[h>>2]=Rm(c[h>>2]|0,i*52|0)|0;ka=f+1280|0;c[ka>>2]=c[ka>>2]|293667361;c[f+1284>>2]=2;ka=0;l=ja;return ka|0}function Kd(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0;e=a[c>>0]|0;f=e&15;g=f&255;h=a[19545+(d[b>>0]|0)>>0]|0;a[b>>0]=h;switch(h<<24>>24){case -2:{a[b>>0]=1;h=a[c>>0]|0;e=h&255;if((h&255)<48){a[c>>0]=e>>>2&15|224;return}else{a[c>>0]=e>>>4|240;return}}case -3:{a[b>>0]=2;h=a[c>>0]|0;e=h&255;if((h&255)<48){a[c>>0]=e>>>2&15|224;return}else{a[c>>0]=e>>>4|240;return}}case 14:switch((e&255)>>>4&15){case 15:case 14:case 9:case 7:case 6:case 4:case 2:case 1:{a[b>>0]=0;a[c>>0]=0;return}case 3:{a[c>>0]=g|48;return}case 5:{a[c>>0]=g|64;return}case 8:{a[c>>0]=g|112;return}case 10:{a[c>>0]=g|96;return}case 11:{a[c>>0]=g|224;return}case 12:{if(f<<24>>24)return;a[c>>0]=0;a[b>>0]=0;return}default:return}case -1:{a[c>>0]=0;a[b>>0]=0;return}default:return}}function Ld(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+32|0;c=d;if((Zl(c,1,20,a)|0)>>>0>=20?(en(c,19614,19)|0)==0:0){_l(a,156,1)|0;_l(a,384,1)|0;_l(a,64,1)|0;xb(a,b,32);c=0}else c=-1;l=d;return c|0}function Md(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=l;l=l+1648|0;m=v;n=v+4|0;u=v+1640|0;t=v+1576|0;_l(e,f,0)|0;Zl(n,20,1,e)|0;j=n+20|0;Zl(j,4,1,e)|0;a[n+24>>0]=Kl(e)|0;i=n+25|0;a[i>>0]=Kl(e)|0;s=n+26|0;a[s>>0]=Kl(e)|0;Zl(n+27|0,19,1,e)|0;g=n+46|0;a[g>>0]=Kl(e)|0;k=n+47|0;a[k>>0]=Kl(e)|0;Zl(n+48|0,128,1,e)|0;f=0;do{c[n+176+(f<<2)>>2]=Xl(e)|0;f=f+1|0}while((f|0)!=31);f=0;do{c[n+300+(f<<2)>>2]=Xl(e)|0;f=f+1|0}while((f|0)!=31);f=0;do{c[n+424+(f<<2)>>2]=Xl(e)|0;f=f+1|0}while((f|0)!=31);f=0;do{a[n+548+f>>0]=Kl(e)|0;f=f+1|0}while((f|0)!=31);f=0;do{a[n+579+f>>0]=Il(e)|0;f=f+1|0}while((f|0)!=31);h=n+610|0;Zl(h,32,1,e)|0;f=0;do{Zl(n+642+(f*30|0)|0,30,1,e)|0;f=f+1|0}while((f|0)!=31);r=b+140|0;c[r>>2]=31;c[b+144>>2]=31;g=(d[g>>0]|0)+1|0;q=b+128|0;c[q>>2]=g;o=d[i>>0]|0;p=b+136|0;c[p>>2]=o;c[b+132>>2]=O(o,g)|0;g=b+156|0;c[g>>2]=(d[k>>0]|0)+1;o=b+1280|0;c[o>>2]=c[o>>2]|8192;wb(b,h,32)|0;c[m>>2]=j;Eb(b,19594,m);if((c[g>>2]|0)>0){f=0;do{a[b+952+f>>0]=a[n+48+f>>0]|0;f=f+1|0}while((f|0)<(c[g>>2]|0))}if((nb(b)|0)<0){b=-1;l=v;return b|0}a:do if((c[r>>2]|0)>0){i=b+180|0;h=b+176|0;g=0;while(1){if((ob(b,g,1)|0)<0){f=-1;break}o=c[n+176+(g<<2)>>2]|0;f=c[i>>2]|0;c[f+(g*52|0)+32>>2]=o;m=n+300+(g<<2)|0;c[f+(g*52|0)+36>>2]=c[m>>2];m=(c[n+424+(g<<2)>>2]|0)+(c[m>>2]|0)|0;c[f+(g*52|0)+40>>2]=m;c[f+(g*52|0)+44>>2]=(m|0)>0?2:0;f=c[h>>2]|0;m=c[f+(g*764|0)+756>>2]|0;c[m>>2]=d[n+548+g>>0];c[m+16>>2]=a[n+579+g>>0];c[m+8>>2]=128;c[m+40>>2]=g;if((o|0)>0)c[f+(g*764|0)+36>>2]=1;vb(f,g,n+642+(g*30|0)|0,30);g=g+1|0;if((g|0)>=(c[r>>2]|0))break a}l=v;return f|0}while(0);if((pb(b)|0)<0){b=-1;l=v;return b|0}b:do if((c[q>>2]|0)>0){o=b+172|0;n=b+168|0;m=0;while(1){if((tb(b,m,64)|0)<0){f=-1;break}if(!(a[s>>0]|0)){f=c[p>>2]|0;g=t;h=g+64|0;do{a[g>>0]=255;g=g+1|0}while((g|0)<(h|0));k=0}else{Pl(e)|0;Zl(t,1,64,e)|0;f=c[p>>2]|0;k=0}do{if((f|0)>0){j=t+k|0;h=0;i=128;while(1){if(d[j>>0]&i){Zl(u,4,1,e)|0;f=c[(c[o>>2]|0)+(c[(c[(c[n>>2]|0)+(m<<2)>>2]|0)+4+(h<<2)>>2]<<2)>>2]|0;Bb(f+4+(k<<3)|0,u);g=f+4+(k<<3)+3|0;c:do switch(a[g>>0]|0){case 8:{a[f+4+(k<<3)+4>>0]=0;a[g>>0]=0;break}case 14:{f=f+4+(k<<3)+4|0;switch((d[f>>0]|0)>>>4&15){case 9:case 8:case 3:case 0:{a[f>>0]=0;f=g;break}case 4:{a[g>>0]=12;break}default:break c}a[f>>0]=0;break}default:{}}while(0);f=c[p>>2]|0}h=h+1|0;if((h|0)>=(f|0))break;else i=i>>1}}k=k+1|0}while((k|0)!=64);m=m+1|0;if((m|0)>=(c[q>>2]|0))break b}l=v;return f|0}while(0);g=b+180|0;if((c[r>>2]|0)>0)f=0;else{b=0;l=v;return b|0}while(1){if((Ub(b,e,0,(c[g>>2]|0)+(f*52|0)|0,0)|0)<0){f=-1;g=42;break}f=f+1|0;if((f|0)>=(c[r>>2]|0)){f=0;g=42;break}}if((g|0)==42){l=v;return f|0}return 0}function Nd(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;g=l;l=l+80|0;d=g;if(((((Xl(a)|0)==1182101099?(Kl(a)|0,h=Kl(a)|0,f=Kl(a)|0,Kl(a)|0,(h&255)>=20):0)?!(f<<24>>24<0|(f&14)>9):0)?(e=Vl(a)|0,(e|0)>=1024):0)?(fm(a,d)|0,(e|0)==(c[d+36>>2]|0)):0){xb(a,b,0);d=0}else d=-1;l=g;return d|0}function Od(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;x=l;l=l+2736|0;n=x+16|0;m=x+8|0;k=x;v=x+20|0;u=x+2728|0;_l(e,f,0)|0;Zl(v,4,1,e)|0;Zl(v+4|0,4,1,e)|0;c[v+8>>2]=Vl(e)|0;j=v+12|0;Zl(j,4,1,e)|0;a[v+16>>0]=Kl(e)|0;i=v+17|0;Zl(i,256,1,e)|0;Zl(v+273|0,128,1,e)|0;f=0;do{Zl(v+404+(f*36|0)|0,19,1,e)|0;c[v+404+(f*36|0)+20>>2]=Vl(e)|0;c[v+404+(f*36|0)+24>>2]=Vl(e)|0;a[v+404+(f*36|0)+28>>0]=Kl(e)|0;a[v+404+(f*36|0)+29>>0]=Kl(e)|0;a[v+404+(f*36|0)+30>>0]=Kl(e)|0;a[v+404+(f*36|0)+31>>0]=Kl(e)|0;a[v+404+(f*36|0)+32>>0]=Kl(e)|0;f=f+1|0}while((f|0)!=64);w=b+140|0;c[w>>2]=64;c[b+144>>2]=64;t=b+128|0;g=c[t>>2]|0;f=0;do{s=a[v+17+f>>0]|0;h=s&255;if(s<<24>>24==-1)break;if((h|0)>(g|0)){c[t>>2]=h;g=h}f=f+1|0}while((f|0)<256);c[t>>2]=g+1;c[b+156>>2]=f;ap(b+952|0,i|0,f|0)|0;c[b+148>>2]=4;g=b+152|0;c[g>>2]=125;s=b+136|0;c[s>>2]=0;a:do if((a[j>>0]|0)==70)switch(a[v+13>>0]|0){case 50:{q=a[v+7>>0]|0;r=(q&255)>>>1&63;c[g>>2]=(q<<24>>24<0?0-r|0:r)+125;Eb(b,19646,k);break a}case 107:case 118:{Eb(b,19634,m);break a}default:{o=12;break a}}else o=12;while(0);if((o|0)==12){c[s>>2]=8;Eb(b,19662,n)}f=c[s>>2]|0;if(!f){f=a[v+14>>0]|0;if((f+-48&255)>9)f=8;else{r=a[v+15>>0]|0;f=(r+-48&255)>9?8:((f&255)*10|0)+-528+(r&255)|0}c[s>>2]=f}c[g>>2]=(c[g>>2]<<2|0)/5|0;c[b+132>>2]=O(c[t>>2]|0,f)|0;r=b+1280|0;c[r>>2]=c[r>>2]|4096;if((nb(b)|0)<0){b=-1;l=x;return b|0}b:do if((c[w>>2]|0)>0){i=b+180|0;h=b+176|0;g=0;while(1){if((ob(b,g,1)|0)<0){f=-1;break}q=c[v+404+(g*36|0)+24>>2]|0;f=c[i>>2]|0;c[f+(g*52|0)+32>>2]=q;p=c[v+404+(g*36|0)+20>>2]|0;c[f+(g*52|0)+36>>2]=(p|0)==-1?0:p;c[f+(g*52|0)+40>>2]=q;c[f+(g*52|0)+44>>2]=(p|0)!=-1?2:0;f=c[h>>2]|0;p=c[f+(g*764|0)+756>>2]|0;c[p>>2]=d[v+404+(g*36|0)+28>>0];c[p+8>>2]=d[v+404+(g*36|0)+29>>0];c[p+40>>2]=g;if((q|0)>0)c[f+(g*764|0)+36>>2]=1;vb(f,g,v+404+(g*36|0)|0,19);g=g+1|0;if((g|0)>=(c[w>>2]|0))break b}l=x;return f|0}while(0);if((pb(b)|0)<0){b=-1;l=x;return b|0}c:do if((c[t>>2]|0)>0){q=b+172|0;p=b+168|0;m=u+1|0;n=u+2|0;o=0;while(1){if((tb(b,o,64)|0)<0){f=-1;break}h=c[q>>2]|0;g=c[(c[p>>2]|0)+(o<<2)>>2]|0;a[(c[h+(c[g+8>>2]<<2)>>2]|0)+4+(d[v+273+o>>0]<<3)+5>>0]=13;f=c[s>>2]|0;d:do if((f|0)>0){i=0;while(1){k=c[h+(c[g+4+(((i|0)%(f|0)|0)<<2)>>2]<<2)>>2]|0;j=(i|0)/(f|0)|0;Zl(u,1,3,e)|0;f=a[u>>0]|0;g=(f&255)>>>2;h=a[m>>0]|0;if((g+-61|0)>>>0>=3){a[k+4+(j<<3)>>0]=g+37;g=(h&255)>>>4;f=f<<4&48;a[k+4+(j<<3)+1>>0]=g+1+f;a[k+4+(j<<3)+2>>0]=a[v+404+((f|g)*36|0)+28>>0]|0}e:do switch(h&15){case 0:{a[k+4+(j<<3)+3>>0]=121;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 1:{a[k+4+(j<<3)+3>>0]=120;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 2:{a[k+4+(j<<3)+3>>0]=122;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 3:{a[k+4+(j<<3)+3>>0]=123;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 6:{a[k+4+(j<<3)+3>>0]=124;a[k+4+(j<<3)+4>>0]=d[n>>0]<<1;break}case 7:{a[k+4+(j<<3)+3>>0]=125;a[k+4+(j<<3)+4>>0]=d[n>>0]<<1;break}case 11:{a[k+4+(j<<3)+3>>0]=0;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 13:{a[k+4+(j<<3)+3>>0]=12;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 14:{f=a[n>>0]|0;g=f&255;if((f+-10&255)<3){a[k+4+(j<<3)+3>>0]=127;break e}switch((f&255)>>>4&15){case 1:{a[k+4+(j<<3)+3>>0]=14;f=g&15|192;break}case 2:{a[k+4+(j<<3)+3>>0]=14;f=g&15|208;break}case 13:{a[k+4+(j<<3)+3>>0]=14;f=g&15|144;break}case 14:{a[k+4+(j<<3)+3>>0]=8;f=g<<4&240|8;break}case 15:{a[k+4+(j<<3)+3>>0]=15;f=g&15;break}default:break e}a[k+4+(j<<3)+4>>0]=f;break}default:{}}while(0);i=i+1|0;f=c[s>>2]|0;if((i|0)>=(f<<6|0))break d;g=c[(c[p>>2]|0)+(o<<2)>>2]|0;h=c[q>>2]|0}}while(0);o=o+1|0;if((o|0)>=(c[t>>2]|0))break c}l=x;return f|0}while(0);f=c[w>>2]|0;f:do if((f|0)>0){i=b+180|0;h=0;while(1){g=c[i>>2]|0;if((c[g+(h*52|0)+32>>2]|0)>=3){if((Ub(b,e,0,g+(h*52|0)|0,0)|0)<0){f=-1;break}f=c[w>>2]|0}h=h+1|0;if((h|0)>=(f|0))break f}l=x;return f|0}while(0);if((c[s>>2]|0)>0){f=0;do{c[b+184+(f*12|0)>>2]=128;f=f+1|0}while((f|0)<(c[s>>2]|0))}c[b+1268>>2]=255;c[r>>2]=64;b=0;l=x;return b|0}function Pd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;_l(a,c+1464|0,0)|0;d=Xl(a)|0;if((d|0)<1297370624)switch(d|0){case 1230254384:{e=2;break}default:d=-1}else switch(d|0){case 1297370624:{e=2;break}default:d=-1}if((e|0)==2){_l(a,c,0)|0;xb(a,b,28);d=0}return d|0}function Qd(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;s=l;l=l+1488|0;k=s+8|0;j=s;p=s+12|0;q=s+1480|0;_l(g,h,0)|0;Zl(p,20,1,g)|0;h=0;do{Zl(p+20+(h*30|0)|0,22,1,g)|0;b[p+20+(h*30|0)+22>>1]=Pl(g)|0;a[p+20+(h*30|0)+24>>0]=Kl(g)|0;a[p+20+(h*30|0)+25>>0]=Kl(g)|0;b[p+20+(h*30|0)+26>>1]=Pl(g)|0;b[p+20+(h*30|0)+28>>1]=Pl(g)|0;h=h+1|0}while((h|0)!=31);i=p+950|0;a[i>>0]=Kl(g)|0;m=p+951|0;a[m>>0]=Kl(g)|0;Zl(p+952|0,512,1,g)|0;h=Xl(g)|0;c[p+1464>>2]=h;a:do if((h|0)<1297370624)switch(h|0){case 1230254384:{Eb(f,19709,j);break a}default:{f=-1;l=s;return f|0}}else switch(h|0){case 1297370624:{Eb(f,19726,k);break a}default:{f=-1;l=s;return f|0}}while(0);r=f+140|0;c[r>>2]=31;c[f+144>>2]=31;o=d[i>>0]|0;n=f+128|0;c[n>>2]=o;c[f+156>>2]=o;o=f+132|0;c[o>>2]=d[m>>0];yo(f,p,20)|0;if((nb(f)|0)<0){f=-1;l=s;return f|0}b:do if((c[r>>2]|0)>0){k=f+180|0;j=f+176|0;i=0;while(1){if((ob(f,i,1)|0)<0){h=-1;break}m=b[p+20+(i*30|0)+22>>1]|0;h=c[k>>2]|0;c[h+(i*52|0)+32>>2]=(m&65535)<<1;u=(e[p+20+(i*30|0)+26>>1]|0)<<1;c[h+(i*52|0)+36>>2]=u;t=b[p+20+(i*30|0)+28>>1]|0;c[h+(i*52|0)+40>>2]=((t&65535)<<1)+u;c[h+(i*52|0)+44>>2]=(t&65535)>1?2:0;h=c[j>>2]|0;t=c[h+(i*764|0)+756>>2]|0;c[t>>2]=d[p+20+(i*30|0)+25>>0];c[t+16>>2]=((d[p+20+(i*30|0)+24>>0]|0)/72|0)<<4&255;c[t+8>>2]=128;c[t+40>>2]=i;if(m<<16>>16)c[h+(i*764|0)+36>>2]=1;i=i+1|0;if((i|0)>=(c[r>>2]|0))break b}l=s;return h|0}while(0);if((pb(f)|0)<0){u=-1;l=s;return u|0}c:do if((c[n>>2]|0)>0){m=f+168|0;i=f+136|0;j=0;while(1){if((qb(f,j)|0)<0){h=-1;break}h=c[(c[m>>2]|0)+(j<<2)>>2]|0;c[h>>2]=64;if((c[i>>2]|0)>0){k=0;do{c[h+4+(k<<2)>>2]=d[p+952+(j<<2)+k>>0];k=k+1|0}while((k|0)<(c[i>>2]|0))}a[f+952+j>>0]=j;j=j+1|0;if((j|0)>=(c[n>>2]|0))break c}l=s;return h|0}while(0);d:do if((c[o>>2]|0)>0){k=f+172|0;j=0;while(1){if((rb(f,j,64)|0)<0){h=-1;break}h=c[(c[k>>2]|0)+(j<<2)>>2]|0;if((c[h>>2]|0)>0){i=0;do{Zl(q,1,4,g)|0;Bb(h+4+(i<<3)|0,q);i=i+1|0;h=c[(c[k>>2]|0)+(j<<2)>>2]|0}while((i|0)<(c[h>>2]|0))}j=j+1|0;if((j|0)>=(c[o>>2]|0))break d}l=s;return h|0}while(0);h=f+1280|0;c[h>>2]=c[h>>2]|8192;h=c[r>>2]|0;if((h|0)<=0){u=0;l=s;return u|0}k=f+180|0;j=0;while(1){i=c[k>>2]|0;if((c[i+(j*52|0)+32>>2]|0)>=5){if((Ub(f,g,0,i+(j*52|0)|0,0)|0)<0){h=-1;i=32;break}h=c[r>>2]|0}j=j+1|0;if((j|0)>=(h|0)){h=0;i=32;break}}if((i|0)==32){l=s;return h|0}return 0}function Rd(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;i=l;l=l+1200|0;h=i;_l(b,1536,1)|0;if((Zl(h,1,51,b)|0)==51){d=0;f=0}else{c=-1;l=i;return c|0}while(1){g=a[h+d>>0]|0;e=g&255;if(g<<24>>24==-1){e=f;break}e=(e|0)>(f|0)?e:f;d=d+1|0;if((d|0)<51)f=e;else break}if((e|0)>50|((d|0)>50|((d|0)==0|(e|0)==0))){c=-1;l=i;return c|0}a:do if((e|0)>0){d=0;b:while(1){Zl(h,1,1152,b)|0;g=0;do{f=g*18|0;j=a[h+(f|1)>>0]|0;if((j+-112&255)<48|((j+-7&255)<9?(a[h+f>>0]|0)!=-128:0)){d=-1;e=11;break b}j=f+2|0;k=a[h+(j|1)>>0]|0;if((k+-112&255)<48|((k+-7&255)<9?(a[h+j>>0]|0)!=-128:0)){d=-1;e=11;break b}k=f+4|0;j=a[h+(k|1)>>0]|0;if((j+-112&255)<48|((j+-7&255)<9?(a[h+k>>0]|0)!=-128:0)){d=-1;e=11;break b}k=f+6|0;j=a[h+(k|1)>>0]|0;if((j+-112&255)<48|((j+-7&255)<9?(a[h+k>>0]|0)!=-128:0)){d=-1;e=11;break b}k=f+8|0;j=a[h+(k|1)>>0]|0;if((j+-112&255)<48|((j+-7&255)<9?(a[h+k>>0]|0)!=-128:0)){d=-1;e=11;break b}k=f+10|0;j=a[h+(k|1)>>0]|0;if((j+-112&255)<48|((j+-7&255)<9?(a[h+k>>0]|0)!=-128:0)){d=-1;e=11;break b}k=f+12|0;j=a[h+(k|1)>>0]|0;if((j+-112&255)<48|((j+-7&255)<9?(a[h+k>>0]|0)!=-128:0)){d=-1;e=11;break b}k=f+14|0;j=a[h+(k|1)>>0]|0;if((j+-112&255)<48|((j+-7&255)<9?(a[h+k>>0]|0)!=-128:0)){d=-1;e=11;break b}k=f+16|0;j=a[h+(k|1)>>0]|0;if((j+-112&255)<48|((j+-7&255)<9?(a[h+k>>0]|0)!=-128:0)){d=-1;e=11;break b}g=g+1|0}while((g|0)<64);d=d+1|0;if((d|0)>=(e|0))break a}if((e|0)==11){l=i;return d|0}}while(0);xb(b,c,0);k=0;l=i;return k|0}function Sd(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=l;l=l+1584|0;u=v;t=v+1576|0;k=v+40|0;_l(e,f,0)|0;Zl(k,1,1536,e)|0;g=0;h=k;while(1){if((d[h+9>>0]|0)>3)break;if((d[h+10>>0]|0)>3)break;if((d[h+8>>0]|0)>15)break;g=g+1|0;if((g|0)<128)h=h+12|0;else break}j=b+140|0;c[j>>2]=g;_l(e,f,0)|0;s=b+136|0;c[s>>2]=9;c[b+152>>2]=135;c[b+148>>2]=6;c[b+144>>2]=c[j>>2];r=b+1280|0;c[r>>2]=c[r>>2]|4096;Eb(b,19747,u);if((nb(b)|0)<0){b=-1;l=v;return b|0}Zl(k,1,1536,e)|0;a:do if((c[j>>2]|0)>0){f=b+176|0;i=b+180|0;h=0;g=k;while(1){if((ob(b,h,1)|0)<0){g=-1;f=34;break}r=c[f>>2]|0;c[r+(h*764|0)+36>>2]=1;q=c[r+(h*764|0)+756>>2]|0;c[q>>2]=64;c[q+16>>2]=((a[g+11>>0]|0)/4|0)<<24>>24;c[q+8>>2]=128;c[q+12>>2]=0;c[q+40>>2]=h;c[r+(h*764|0)+40>>2]=(a[g+7>>0]&15)<<5;if((Ub(b,e,12288,(c[i>>2]|0)+(h*52|0)|0,g)|0)<0){g=-1;f=34;break}h=h+1|0;if((h|0)>=(c[j>>2]|0)){g=0;h=0;break a}else g=g+12|0}if((f|0)==34){l=v;return g|0}}else{g=0;h=0}while(0);do{f=b+952+g|0;Zl(f,1,1,e)|0;f=d[f>>0]|0;if(f&128|0)break;h=(f|0)>(h|0)?f:h;g=g+1|0}while((g|0)<51);_l(e,50-g|0,1)|0;c[b+156>>2]=g;r=h+1|0;p=b+128|0;c[p>>2]=r;c[b+132>>2]=O(c[s>>2]|0,r)|0;if((pb(b)|0)<0){b=-1;l=v;return b|0}b:do if((c[p>>2]|0)>0){q=b+168|0;r=b+172|0;n=t+1|0;o=0;while(1){g=u;h=2136;f=g+36|0;do{c[g>>2]=c[h>>2];g=g+4|0;h=h+4|0}while((g|0)<(f|0));if((tb(b,o,64)|0)<0)break;if((c[c[(c[q>>2]|0)+(o<<2)>>2]>>2]|0)>0){m=0;do{k=0;do{Zl(t,1,2,e)|0;j=c[(c[q>>2]|0)+(o<<2)>>2]|0;i=c[(c[r>>2]|0)+(c[j+4+(k<<2)>>2]<<2)>>2]|0;h=i+4+(m<<3)|0;g=a[t>>0]|0;f=g&255;c:do if(!(f&128))switch(g<<24>>24){case 0:break c;case 127:{a[h>>0]=-127;break c}default:{a[h>>0]=f+25;a[i+4+(m<<3)+1>>0]=c[u+(k<<2)>>2];break c}}else c[u+(k<<2)>>2]=(d[n>>0]|0)+1;while(0);h=i+4+(m<<3)+3|0;a[h>>0]=0;g=i+4+(m<<3)+4|0;a[g>>0]=0;if((a[n>>0]|0)==1){a[h>>0]=13;a[g>>0]=0}k=k+1|0}while((k|0)!=9);m=m+1|0}while((m|0)<(c[j>>2]|0))}o=o+1|0;if((o|0)>=(c[p>>2]|0))break b}b=-1;l=v;return b|0}while(0);if((c[s>>2]|0)>0){g=0;do{c[b+184+(g*12|0)>>2]=128;c[b+184+(g*12|0)+8>>2]=1;g=g+1|0}while((g|0)<(c[s>>2]|0))}c[b+6556>>2]=7212;b=0;l=v;return b|0}function Td(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+16|0;c=d;if((Zl(c,1,14,a)|0)>>>0>=14?(en(c,20103,14)|0)==0:0){xb(a,b,30);c=0}else c=-1;l=d;return c|0}function Ud(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0;_=l;l=l+352|0;Z=_;t=_+208|0;X=_+56|0;A=_+16|0;r=_+320|0;_l(g,h,0)|0;Zl(t,14,1,g)|0;p=t+14|0;Zl(p,30,1,g)|0;Zl(t+44|0,20,1,g)|0;Kl(g)|0;q=t+65|0;Zl(q,20,1,g)|0;s=t+86|0;b[s>>1]=Ml(g)|0;k=t+88|0;b[k>>1]=Ml(g)|0;i=t+90|0;b[i>>1]=Ml(g)|0;b[t+92>>1]=Ml(g)|0;b[t+94>>1]=Ml(g)|0;j=t+96|0;b[j>>1]=Ml(g)|0;c[t+100>>2]=Vl(g)|0;m=t+104|0;b[m>>1]=Ml(g)|0;n=t+106|0;b[n>>1]=Ml(g)|0;o=t+108|0;b[o>>1]=Ml(g)|0;t=t+110|0;b[t>>1]=Ml(g)|0;if((e[s>>1]|0)<256){b[t>>1]=b[o>>1]|0;b[o>>1]=0;_l(g,-2,1)|0}c[f+148>>2]=e[k>>1];c[f+152>>2]=e[i>>1];S=e[j>>1]|0;x=f+136|0;c[x>>2]=S;i=e[m>>1]|0;w=f+128|0;c[w>>2]=i;k=e[n>>1]|0;c[f+144>>2]=k;T=f+140|0;c[T>>2]=k;k=f+156|0;c[k>>2]=e[o>>1];c[f+132>>2]=O(i,S)|0;S=f+1280|0;c[S>>2]=c[S>>2]|16384;yo(f,p,30)|0;yo(r,q,20)|0;a[r+20>>0]=0;i=r+19|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;U=78;break}case 0:{U=78;break}default:{}}a:do if((U|0)==78){i=r+18|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+17|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+16|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+15|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+14|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+13|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+12|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+11|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+10|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+9|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+8|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+7|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+6|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+5|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+4|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+3|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+2|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+1|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}if((a[r>>0]|0)==32)a[r>>0]=0}while(0);R=e[s>>1]|0;c[Z>>2]=r;c[Z+4>>2]=R>>>8;c[Z+8>>2]=R&255;ao(f+64|0,64,19759,Z);if(!(b[s>>1]|0)){_l(g,h+240|0,0)|0;Zl(f+952|0,1,256,g)|0;_l(g,(e[t>>1]|0)+h|0,0)|0;i=0;do{if((a[f+952+i>>0]|0)==-1)break;i=i+1|0}while((i|0)<256);c[k>>2]=i}else{if((c[x>>2]|0)>0){j=0;do{c[f+184+(j*12|0)>>2]=((Kl(g)|0)&255)<<2;j=j+1|0;i=c[x>>2]|0}while((j|0)<(i|0));if((i|0)>0){i=0;do{c[f+184+(i*12|0)+4>>2]=(Kl(g)|0)&255;i=i+1|0}while((i|0)<(c[x>>2]|0))}}Zl(f+952|0,1,c[k>>2]|0,g)|0;_l(g,(e[t>>1]|0)+-109+(O(c[x>>2]|0,-2)|0)-(c[k>>2]|0)|0,1)|0}if((pb(f)|0)<0){Z=-1;l=_;return Z|0}b:do if((c[w>>2]|0)>0){s=A+30|0;t=A+32|0;r=A+36|0;u=f+168|0;v=f+172|0;h=0;i=0;c:while(1){if((qb(f,h)|0)<0){Y=-1;U=76;break}j=Xl(g)|0;if((j|0)>=1280311296){switch(j|0){case 1280311296:break;default:{Y=-1;U=76;break c}}Zl(A,30,1,g)|0;b[s>>1]=Ml(g)|0;c[t>>2]=Vl(g)|0;c[r>>2]=Vl(g)|0;c[c[(c[u>>2]|0)+(h<<2)>>2]>>2]=e[s>>1];sb(f,h)|0;q=$l(g)|0;j=c[(c[u>>2]|0)+(h<<2)>>2]|0;p=0;m=0;k=0;d:while(1){j=(c[(c[v>>2]|0)+(c[j+4+(p<<2)>>2]<<2)>>2]|0)+4+(m<<3)|0;e:do if(!(k<<24>>24)){i=Kl(g)|0;f:while(1){n=c[(c[v>>2]|0)+(c[(c[(c[u>>2]|0)+(h<<2)>>2]|0)+4+(p<<2)>>2]<<2)>>2]|0;o=n+4+(m<<3)|0;j=i&255;switch(i<<24>>24){case -64:break d;case -128:{o=p;i=-128;n=0;break e}case -31:{U=26;break f}case -96:{z=p;B=-96;break f}case -32:{U=28;break f}default:{}}if((i+63&255)<31){U=30;break}if((i+95&255)<31){U=32;break}if((i+127&255)<31){U=34;break}if(i<<24>>24!=-1)a[o>>0]=j+37;y=Kl(g)|0;if((y&255)<=100){U=41;break}m=m+1|0;i=y}if((U|0)==26){U=0;B=Kl(g)|0;z=(B&255)+p|0}else if((U|0)==28){U=0;i=Kl(g)|0;o=p;m=(i&255)+m|0;n=0;break}else if((U|0)==30){U=0;Vd(i,o,g);Wd(o);o=p;n=0;break}else if((U|0)==32){U=0;n=Kl(g)|0;Vd(i,o,g);Wd(o);o=p;break}else if((U|0)==34){U=0;j=Kl(g)|0;Vd(i,o,g);Wd(o);if(!(j<<24>>24)){o=p;n=0;break}n=j+-1<<24>>24;k=m;do{k=k+1|0;Q=o;N=Q;N=d[N>>0]|d[N+1>>0]<<8|d[N+2>>0]<<16|d[N+3>>0]<<24;Q=Q+4|0;Q=d[Q>>0]|d[Q+1>>0]<<8|d[Q+2>>0]<<16|d[Q+3>>0]<<24;R=(c[(c[v>>2]|0)+(c[(c[(c[u>>2]|0)+(h<<2)>>2]|0)+4+(p<<2)>>2]<<2)>>2]|0)+4+(k<<3)|0;P=R;a[P>>0]=N;a[P+1>>0]=N>>8;a[P+2>>0]=N>>16;a[P+3>>0]=N>>24;R=R+4|0;a[R>>0]=Q;a[R+1>>0]=Q>>8;a[R+2>>0]=Q>>16;a[R+3>>0]=Q>>24;j=j+-1<<24>>24}while(j<<24>>24!=0);o=p;m=m+1+(n&255)|0;n=0;break}else if((U|0)==41){U=0;k=n+4+(m<<3)+1|0;a[k>>0]=(y&255)+1;i=Kl(g)|0;if(i<<24>>24!=-1)a[n+4+(m<<3)+2>>0]=i;i=Kl(g)|0;j=n+4+(m<<3)+3|0;if(i<<24>>24!=-1)a[j>>0]=(i&255)+191;i=Kl(g)|0;a[n+4+(m<<3)+4>>0]=i;if((d[j>>0]|0)>=27){U=46;break c}Wd(o);R=a[o>>0]|0;if(!((R&255)<120|R<<24>>24==-127)){U=48;break c}if((d[k>>0]|0)>=101){U=50;break c}if((d[n+4+(m<<3)+2>>0]|0)<66){o=p;n=0;break}else{U=52;break c}}o=z+1|0;o=(o|0)<(c[x>>2]|0)?o:z;m=-1;i=B;n=0}else{Vd(i,j,g);Wd(j);o=p;n=k+-1<<24>>24}while(0);m=m+1|0;j=c[(c[u>>2]|0)+(h<<2)>>2]|0;k=o+1|0;if((m|0)<(c[j>>2]|0)){p=o;k=n;continue}p=(k|0)>=(c[x>>2]|0)?0:k;m=0;k=0}R=($l(g)|0)-q|0;if((R|0)==(c[t>>2]|0))i=-64;else{U=25;break}}else switch(j|0){case 555819297:break;default:{Y=-1;U=76;break c}}h=h+1|0;if((h|0)>=(c[w>>2]|0))break b}if((U|0)==25)da(19774,19806,363,19832);else if((U|0)==46)da(19841,19806,443,19832);else if((U|0)==48)da(19858,19806,450,19832);else if((U|0)==50)da(19907,19806,451,19832);else if((U|0)==52)da(19925,19806,452,19832);else if((U|0)==76){l=_;return Y|0}}while(0);if((nb(f)|0)<0){Z=-1;l=_;return Z|0}g:do if((c[T>>2]|0)>0){Q=f+176|0;R=f+180|0;w=Z+1|0;x=Z+2|0;y=Z+3|0;p=X+2|0;q=X+32|0;h=X+52|0;G=X+72|0;I=X+76|0;K=X+80|0;J=X+84|0;z=X+88|0;P=X+92|0;D=X+93|0;N=X+94|0;M=X+95|0;E=X+96|0;A=X+97|0;F=X+98|0;B=X+100|0;C=X+104|0;L=X+108|0;r=X+109|0;s=X+120|0;H=0;while(1){n=c[Q>>2]|0;t=c[R>>2]|0;v=t+(H*52|0)|0;if((ob(f,H,1)|0)<0){U=61;break}u=c[n+(H*764|0)+756>>2]|0;Zl(Z,1,4,g)|0;k=a[Z>>0]|0;m=a[w>>0]|0;if(k<<24>>24==63){i=a[x>>0]|0;j=a[y>>0]|0;if(m<<24>>24==63&i<<24>>24==63&j<<24>>24==63)U=72;else{V=i;W=j;U=65}}else{V=a[x>>0]|0;W=a[y>>0]|0;U=65}if((U|0)==65){U=0;if(!(k<<24>>24==76&m<<24>>24==68&V<<24>>24==83&W<<24>>24==83)){U=66;break}b[X>>1]=Ml(g)|0;Zl(p,30,1,g)|0;Zl(q,20,1,g)|0;Zl(h,20,1,g)|0;a[G>>0]=Kl(g)|0;c[I>>2]=Vl(g)|0;c[K>>2]=Vl(g)|0;c[J>>2]=Vl(g)|0;c[z>>2]=Vl(g)|0;a[P>>0]=Kl(g)|0;a[D>>0]=Kl(g)|0;a[N>>0]=Kl(g)|0;a[M>>0]=Kl(g)|0;a[E>>0]=Kl(g)|0;a[A>>0]=Kl(g)|0;b[F>>1]=Ml(g)|0;b[B>>1]=Ml(g)|0;c[C>>2]=Vl(g)|0;a[L>>0]=Kl(g)|0;Zl(r,11,1,g)|0;Zl(s,25,1,g)|0;o=c[I>>2]|0;c[n+(H*764|0)+36>>2]=(o|0)!=0&1;c[n+(H*764|0)+32>>2]=64;k=t+(H*52|0)+32|0;c[k>>2]=o;i=c[K>>2]|0;n=t+(H*52|0)+36|0;c[n>>2]=i;j=c[J>>2]|0;m=t+(H*52|0)+40|0;c[m>>2]=j;if(a[D>>0]&1){c[t+(H*52|0)+44>>2]=1;c[k>>2]=o>>1;c[n>>2]=i>>1;c[m>>2]=j>>1}if(j|0)c[t+(H*52|0)+44>>2]=2;a[E>>0]=64;c[u>>2]=d[P>>0];c[u+4>>2]=64;c[u+8>>2]=d[N>>0];c[u+40>>2]=H;vb(c[Q>>2]|0,H,p,31);mi(c[z>>2]|0,u+12|0,u+16|0);_l(g,(e[F>>1]|0)+-144|0,1)|0;if(c[k>>2]|0){if((Ub(f,g,0,v,0)|0)<0){Y=-1;U=76;break}}else U=72}H=H+1|0;if((H|0)>=(c[T>>2]|0))break g}if((U|0)==61){Z=-1;l=_;return Z|0}else if((U|0)==66)da(19942,19806,495,19832);else if((U|0)==76){l=_;return Y|0}}while(0);c[S>>2]=c[S>>2]|293601825;c[f+1284>>2]=2;Z=0;l=_;return Z|0}function Vd(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0;f=c;g=f;a[g>>0]=0;a[g+1>>0]=0;a[g+2>>0]=0;a[g+3>>0]=0;f=f+4|0;a[f>>0]=0;a[f+1>>0]=0;a[f+2>>0]=0;a[f+3>>0]=0;b=b&255;if(b&1|0){g=Kl(e)|0;a[c>>0]=g<<24>>24==-2?-127:(g&255)+37&255}if(b&2|0)a[c+1>>0]=((Kl(e)|0)&255)+1;if(b&4|0)a[c+2>>0]=Kl(e)|0;if(b&8|0)a[c+3>>0]=((Kl(e)|0)&255)+191;if(b&16|0)a[c+4>>0]=Kl(e)|0;g=a[c>>0]|0;if(!((g&255)<108|g<<24>>24==-127))da(20024,19806,209,20073);if((d[c+1>>0]|0)>=101)da(19907,19806,210,20073);if((d[c+2>>0]|0)>=65)da(20086,19806,211,20073);if((d[c+3>>0]|0)<27)return;else da(19841,19806,212,20073)}function Wd(b){b=b|0;var c=0,e=0,f=0,g=0,h=0;g=b+4|0;c=a[g>>0]|0;e=c&15;f=e&255;b=b+3|0;h=a[19999+(d[b>>0]|0)>>0]|0;a[b>>0]=h;switch(h<<24>>24){case 14:switch((c&255)>>>4&15){case 3:{a[g>>0]=f|48;return}case 4:{a[g>>0]=(e<<24>>24==3&1)+f|64;return}case 5:{a[g>>0]=f|80;return}case 6:{a[g>>0]=f|96;return}case 7:{a[g>>0]=(e<<24>>24==3&1)+f|112;return}case 12:{a[g>>0]=f|192;return}case 13:{a[g>>0]=f|208;return}case 14:{a[g>>0]=f|224;return}default:{a[g>>0]=0;a[b>>0]=0;return}}case -1:{a[g>>0]=0;a[b>>0]=0;return}default:return}}function Xd(c,f,g){c=c|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0;r=l;l=l+1088|0;q=r;Zl(q,20,1,c)|0;k=0;p=0;while(1){h=q+20+(k*30|0)|0;if((Zl(h,1,20,c)|0)>>>0<20){h=-1;i=15;break}b[q+20+(k*30|0)+20>>1]=Pl(c)|0;i=q+20+(k*30|0)+22|0;b[i>>1]=Pl(c)|0;a[q+20+(k*30|0)+24>>0]=Kl(c)|0;o=q+20+(k*30|0)+25|0;a[o>>0]=Kl(c)|0;m=q+20+(k*30|0)+26|0;b[m>>1]=Pl(c)|0;j=Pl(c)|0;b[q+20+(k*30|0)+28>>1]=j;i=b[i>>1]|0;n=(i&65535)<<1;p=n+p|0;if((yb(h,20)|0)<0){h=-1;i=15;break}if((d[o>>0]|0)>64|(i&65535)>32768){h=-1;i=15;break}if((e[m>>1]|0)>(i&65535)){h=-1;i=15;break}if(i<<16>>16!=0&(j&65535)>>>0>n>>>0){h=-1;i=15;break}k=k+1|0;if((k|0)>=31){i=8;break}}if((i|0)==8){if((p|0)<8){f=-1;l=r;return f|0}h=q+950|0;a[h>>0]=Kl(c)|0;p=q+951|0;a[p>>0]=Kl(c)|0;Zl(q+952|0,128,1,c)|0;Zl(q+1080|0,4,1,c)|0;if((d[p>>0]|0)>1){f=-1;l=r;return f|0}h=a[h>>0]|0;if(h<<24>>24<1|(a[q+1083>>0]|0)!=60){f=-1;l=r;return f|0}h=h&255;i=0;j=0;do{p=d[q+952+i>>0]|0;j=(p|0)>(j|0)?p:j;i=i+1|0}while((i|0)<(h|0));if((j|0)>126){f=-1;l=r;return f|0}_l(c,g,0)|0;xb(c,f,20);f=0;l=r;return f|0}else if((i|0)==15){l=r;return h|0}return 0}function Yd(e,f,g){e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=l;l=l+1104|0;k=v;n=v+4|0;t=v+1088|0;_l(f,g,0)|0;m=e+140|0;c[m>>2]=31;u=e+144|0;c[u>>2]=31;Zl(n,20,1,f)|0;g=0;do{Zl(n+20+(g*30|0)|0,20,1,f)|0;b[n+20+(g*30|0)+20>>1]=Pl(f)|0;b[n+20+(g*30|0)+22>>1]=Pl(f)|0;a[n+20+(g*30|0)+24>>0]=Kl(f)|0;a[n+20+(g*30|0)+25>>0]=Kl(f)|0;b[n+20+(g*30|0)+26>>1]=Pl(f)|0;b[n+20+(g*30|0)+28>>1]=Pl(f)|0;g=g+1|0}while((g|0)!=31);r=n+950|0;a[r>>0]=Kl(f)|0;a[n+951>>0]=Kl(f)|0;s=n+952|0;Zl(s,128,1,f)|0;Zl(n+1080|0,4,1,f)|0;r=a[r>>0]|0;j=r&255;c[e+156>>2]=j;ap(e+952|0,s|0,j|0)|0;s=e+128|0;g=c[s>>2]|0;if(r<<24>>24){i=0;do{h=d[e+952+i>>0]|0;if((h|0)>(g|0)){c[s>>2]=h;g=h}i=i+1|0}while((i|0)!=(j|0))}r=g+1|0;c[s>>2]=r;c[e+132>>2]=O(c[e+136>>2]|0,r)|0;yo(e,n,20)|0;Eb(e,20118,k);if((nb(e)|0)<0){e=-1;l=v;return e|0}a:do if((c[m>>2]|0)>0){j=e+180|0;i=e+176|0;h=0;while(1){if((ob(e,h,1)|0)<0){g=-1;break}r=b[n+20+(h*30|0)+22>>1]|0;g=c[j>>2]|0;c[g+(h*52|0)+32>>2]=(r&65535)<<1;q=b[n+20+(h*30|0)+28>>1]|0;c[g+(h*52|0)+40>>2]=((q&65535)<<1)+(c[g+(h*52|0)+36>>2]|0);c[g+(h*52|0)+44>>2]=(q&65535)>1?2:0;g=c[i>>2]|0;q=c[g+(h*764|0)+756>>2]|0;c[q+16>>2]=0;c[q>>2]=d[n+20+(h*30|0)+25>>0];c[q+8>>2]=128;c[q+40>>2]=h;c[g+(h*764|0)+40>>2]=4095;if(r<<16>>16)c[g+(h*764|0)+36>>2]=1;vb(g,h,n+20+(h*30|0)|0,20);h=h+1|0;if((h|0)>=(c[m>>2]|0))break a}l=v;return g|0}while(0);if((pb(e)|0)<0){e=-1;l=v;return e|0}b:do if((c[s>>2]|0)>0){r=e+172|0;q=e+168|0;m=t+1|0;n=t+2|0;o=0;while(1){if((tb(e,o,64)|0)<0){g=-1;break}else p=0;do{h=c[(c[r>>2]|0)+(c[(c[(c[q>>2]|0)+(o<<2)>>2]|0)+4+((p&3)<<2)>>2]<<2)>>2]|0;i=p>>2;k=h+4+(i<<3)|0;Zl(t,1,3,f)|0;j=a[t>>0]|0;g=j&63;a[k>>0]=g;switch(j&63){case 63:case 0:{g=0;break}default:g=g+33<<24>>24}a[k>>0]=g;g=d[m>>0]|0;a[h+4+(i<<3)+1>>0]=(j&64)>>>2|g>>>4;j=h+4+(i<<3)+3|0;a[j>>0]=g&15;g=h+4+(i<<3)+4|0;a[g>>0]=a[n>>0]|0;Ab(k);if((a[j>>0]|0)==13){k=a[g>>0]|0;a[g>>0]=(((k&255)/10|0)&255)<<4|((k&255)%10|0)&255}p=p+1|0}while((p|0)!=256);o=o+1|0;if((o|0)>=(c[s>>2]|0))break b}l=v;return g|0}while(0);g=e+1280|0;c[g>>2]=c[g>>2]|8192;g=c[u>>2]|0;if((g|0)<=0){e=0;l=v;return e|0}j=e+180|0;i=0;while(1){h=c[j>>2]|0;if(c[h+(i*52|0)+32>>2]|0){if((Ub(e,f,0,h+(i*52|0)|0,0)|0)<0){g=-1;h=30;break}g=c[u>>2]|0}i=i+1|0;if((i|0)>=(g|0)){g=0;h=30;break}}if((h|0)==30){l=v;return g|0}return 0}function Zd(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)!=1347636512){b=-1;return b|0}Kl(a)|0;Kl(a)|0;Kl(a)|0;if((Kl(a)|0)<<24>>24){b=-1;return b|0}if((Xl(a)|0)!=1179208773){b=-1;return b|0}Xl(a)|0;_l(a,Vl(a)|0,1)|0;if((Xl(a)|0)==1414091852){xb(a,b,Vl(a)|0);b=0;return b|0}else{xb(a,b,0);b=0;return b|0}return 0}function _d(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0;p=l;l=l+32|0;n=p+4|0;_l(d,e,0)|0;Xl(d)|0;c[n>>2]=0;a[b>>0]=0;_l(d,8,1)|0;c[b+140>>2]=0;c[b+144>>2]=0;c[n+4>>2]=0;c[n+8>>2]=0;g=$l(d)|0;f=Fb()|0;if(!f){b=-1;l=p;return b|0}m=Jb(f,20158,26)|0;m=Jb(f,20163,27)|0|m;m=m|(Jb(f,21013,28)|0);m=m|(Jb(f,20168,29)|0);if(m|(Jb(f,20173,30)|0)|0){b=-1;l=p;return b|0}Qb(f,1);m=(Gb(f,b,d,n)|0)<0;Mb(f);if(m){b=-1;l=p;return b|0}j=b+128|0;f=c[j>>2]|0;c[b+132>>2]=O(c[b+136>>2]|0,f)|0;f=Om(f<<3)|0;k=n+12|0;c[k>>2]=f;if(!f){b=-1;l=p;return b|0}i=Om(2040)|0;m=n+16|0;c[m>>2]=i;if(i){Eb(b,c[n>>2]|0?20178:20190,p);if(((((nb(b)|0)>=0?(pb(b)|0)>=0:0)?(_l(d,g+e|0,0)|0,o=b+156|0,c[o>>2]=0,h=Fb()|0,h|0):0)?(i=Jb(h,21013,31)|0,i=Jb(h,20168,32)|0|i,(i|(Jb(h,20173,33)|0)|0)==0):0)?(Qb(h,1),i=(Gb(h,b,d,n)|0)<0,Mb(h),!i):0){a:do if((c[o>>2]|0)>0){g=c[j>>2]|0;i=0;do{b:do if((g|0)>0){d=(c[m>>2]|0)+(i<<3)|0;h=c[k>>2]|0;e=c[n>>2]|0?8:4;f=0;while(1){if(!(en(d,h+(f<<3)|0,e)|0))break;f=f+1|0;if((f|0)>=(g|0))break b}a[b+952+i>>0]=f;g=c[j>>2]|0}else f=0;while(0);i=i+1|0;if((f|0)==(g|0))break a}while((i|0)<(c[o>>2]|0))}while(0);Pm(c[m>>2]|0);Pm(c[k>>2]|0);b=0;l=p;return b|0}Pm(c[m>>2]|0);f=c[k>>2]|0}Pm(f);b=-1;l=p;return b|0}function $d(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;d=l;l=l+48|0;e=d;Zl(e,1,40,c)|0;yo(a,e,(b|0)<32?b:32)|0;l=d;return 0}function ae(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return 0}function be(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;_l(d,10,1)|0;c[a+136>>2]=(Kl(d)|0)&255;return 0}function ce(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;e=a+140|0;b=(c[e>>2]|0)+1|0;c[e>>2]=b;c[a+144>>2]=b;return 0}function de(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0;g=l;l=l+32|0;d=g;b=b+128|0;c[b>>2]=(c[b>>2]|0)+1;Zl(d,1,20,e)|0;if(!(a[d+9>>0]|0)){l=g;return 0}if(a[d+13>>0]|0){l=g;return 0}c[f>>2]=1;l=g;return 0}function ee(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;j=l;l=l+32|0;i=j;Zl(j+12|0,1,9,d)|0;Ml(d)|0;h=(Xl(d)|0)==1330662472;b=Vl(d)|0;if(!h)do{_l(d,b,1)|0;h=(Xl(d)|0)==1330662472;b=Vl(d)|0}while(!h);_l(d,9,1)|0;b=Kl(d)|0;a:do if(b<<24>>24!=1){h=a+148|0;g=a+152|0;b=b<<24>>24;f=0;while(1){b:while(1){switch(b|0){case 13:break b;case 7:{c[h>>2]=(Kl(d)|0)&255;Kl(d)|0;c[g>>2]=(Kl(d)|0)&255;break}case 14:{Kl(d)|0;Kl(d)|0;break}default:{k=(Kl(d)|0)&255;c[i>>2]=f;c[i+4>>2]=b;c[i+8>>2]=k;Jo(20214,i)}}b=Kl(d)|0;if(b<<24>>24==1)break a;else b=b<<24>>24}Kl(d)|0;c[a+184+(f*12|0)>>2]=(Kl(d)|0)&255;Kl(d)|0;b=Kl(d)|0;if(b<<24>>24==1)break;else{b=b<<24>>24;f=f+1|0}}}while(0);f=e+16|0;b=a+156|0;do{Zl((c[f>>2]|0)+(c[b>>2]<<3)|0,1,c[e>>2]|0?8:4,d)|0;c[b>>2]=(c[b>>2]|0)+1}while((Kl(d)|0)<<24>>24==1);l=j;return 0}function fe(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;Kl(d)|0;_l(d,8,1)|0;_l(d,c[e>>2]|0?8:4,1)|0;m=e+8|0;j=c[m>>2]|0;if((ob(a,j,1)|0)<0){a=-1;return a|0}g=c[a+176>>2]|0;k=c[g+(j*764|0)+756>>2]|0;b=c[a+180>>2]|0;l=b+(j*52|0)|0;h=g+(j*764|0)|0;Zl(h,1,31,d)|0;pl(h)|0;_l(d,8,1)|0;Kl(d)|0;Kl(d)|0;h=b+(j*52|0)+32|0;c[h>>2]=Vl(d)|0;c[b+(j*52|0)+36>>2]=Vl(d)|0;f=Vl(d)|0;i=b+(j*52|0)+40|0;c[i>>2]=f;c[b+(j*52|0)+44>>2]=(f|0)>2?2:0;Ml(d)|0;b=c[i>>2]|0;if((b|0)<0){c[i>>2]=0;b=0}f=c[h>>2]|0;if((f|0)>0)c[g+(j*764|0)+36>>2]=1;if(!(c[e>>2]|0))b=0;else{if((f|0)>2)c[h>>2]=f+-2;if((b|0)>2)c[i>>2]=b+-2;b=((Il(d)|0)&255)<<28>>24}c[k>>2]=(((Kl(d)|0)&255)>>>1)+1&255;Vl(d)|0;c[k+8>>2]=128;c[k+40>>2]=j;e=k+16|0;mi(((Vl(d)|0)*8363|0)/8448|0,k+12|0,e);c[e>>2]=(c[e>>2]|0)+b;_l(d,16,1)|0;if((Ub(a,d,4,l,0)|0)<0){a=-1;return a|0}c[m>>2]=(c[m>>2]|0)+1;a=0;return a|0}function ge(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+16|0;r=t;q=f+4|0;n=c[q>>2]|0;Vl(e)|0;Zl((c[f+12>>2]|0)+(n<<3)|0,1,c[f>>2]|0?8:4,e)|0;p=(Ml(e)|0)&65535;if((tb(b,n,p)|0)<0){f=-1;l=t;return f|0}o=b+136|0;s=b+172|0;m=b+168|0;k=0;do{d=Ml(e)|0;a:do if((d&65535)>2){d=(d&65535)+-2|0;do{g=Kl(e)|0;if((d|0)==1)break a;b=(Kl(e)|0)&255;if((b|0)<(c[o>>2]|0))j=(c[(c[s>>2]|0)+(c[(c[(c[m>>2]|0)+(n<<2)>>2]|0)+4+(b<<2)>>2]<<2)>>2]|0)+4+(k<<3)|0;else j=r;g=g&255;if(!(g&128))d=d+-2|0;else{b=Kl(e)|0;b=b&255;if(!(c[f>>2]|0))b=(b&15)+14+((b>>>4)*12|0)|0;else b=b+37|0;a[j>>0]=b;d=d+-3|0}if(g&64){a[j+1>>0]=((Kl(e)|0)&255)+1;d=d+-1|0}if(g&32){a[j+2>>0]=((Kl(e)|0)&255)>>>1;d=d+-1|0}if(g&16){b=Kl(e)|0;g=Kl(e)|0;i=d+-2|0;h=b&255;b:do if((b&255)>63){d=g&255;if(!(d&240)){a[j>>0]=(h&15)+2+((h>>>4)*12|0);g=(d<<1)+2&255;b=3;d=i}else d=i}else do switch(b<<24>>24){case 51:{b=11;d=i;break b}case 1:{g=(g&255)>>>1&15|-96;b=14;d=i;break b}case 2:{g=((g&255)>>>1&255)<<4&255;b=10;d=i;break b}case 3:{g=(g&255)>>>1&15|-80;b=14;d=i;break b}case 4:{g=(g&255)>>>1;b=10;d=i;break b}case 12:{g=(((g&255)+-1|0)/2|0)&255;b=1;d=i;break b}case 14:{g=(((g&255)+-1|0)/2|0)&255;b=2;d=i;break b}case 15:{g=(g&255)>>>2;b=3;d=i;break b}case 21:{b=c[f>>2]|0?4:-84;d=i;break b}case 42:{g=g&15|-112;b=14;d=i;break b}case 41:{Ml(e)|0;b=41;d=d+-4|0;break b}case 52:{b=13;d=i;break b}case 61:{b=15;d=i;break b}case 62:{b=15;d=i;break b}default:{g=0;b=0;d=i;break b}}while(0);while(0);a[j+3>>0]=b;a[j+4>>0]=g}}while((d|0)>0)}while(0);k=k+1|0}while((k|0)<(p|0));c[q>>2]=(c[q>>2]|0)+1;f=0;l=t;return f|0}function he(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;e=l;l=l+16|0;d=e;f=(Zl(d,1,3,b)|0)>>>0>2;if(((f&(a[d>>0]|0)==65?(a[d+1>>0]|0)==77:0)?(a[d+2>>0]|0)==70:0)?((Kl(b)|0)+-10&255)<=4:0){xb(b,c,32);d=0}else d=-1;l=e;return d|0}function ie(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+1040|0;s=t;n=t+8|0;_l(e,f,0)|0;Zl(n,1,3,e)|0;j=Kl(e)|0;f=j&255;Zl(n,1,32,e)|0;yo(b,n,32)|0;c[s>>2]=((j&255)/10|0)&255;c[s+4>>2]=((j&255)%10|0)&255;Eb(b,20265,s);s=b+140|0;c[s>>2]=(Kl(e)|0)&255;h=b+156|0;c[h>>2]=(Kl(e)|0)&255;r=b+132|0;c[r>>2]=(Ml(e)|0)&65535;p=b+136|0;c[p>>2]=(Kl(e)|0)&255;c[b+144>>2]=c[s>>2];q=b+128|0;c[q>>2]=c[h>>2];do if(j<<24>>24!=10){if((j&255)>12){Zl(n,1,32,e)|0;c[b+184>>2]=(a[n+31>>0]<<1)+128;c[b+152>>2]=(Kl(e)|0)&255;c[b+148>>2]=(Kl(e)|0)&255;break}if((j&255)>10)Zl(n,1,16,e)|0}else Zl(n,1,16,e)|0;while(0);if((c[h>>2]|0)>0){g=0;do{a[b+952+g>>0]=g;g=g+1|0}while((g|0)<(c[h>>2]|0))}g=c[q>>2]|0;m=Qm(4,g+1|0)|0;o=b+168|0;c[o>>2]=m;if(!m){b=-1;l=t;return b|0}a:do if((g|0)>0){h=(j&255)>13;i=0;while(1){if((qb(b,i)|0)<0){f=-1;break}if(h)g=(Ml(e)|0)&65535;else g=64;c[c[(c[o>>2]|0)+(i<<2)>>2]>>2]=g;if((c[p>>2]|0)>0){g=0;do{m=(Ml(e)|0)&65535;c[(c[(c[o>>2]|0)+(i<<2)>>2]|0)+4+(g<<2)>>2]=m;g=g+1|0}while((g|0)<(c[p>>2]|0))}i=i+1|0;if((i|0)>=(c[q>>2]|0))break a}l=t;return f|0}while(0);if((nb(b)|0)<0){b=-1;l=t;return b|0}if((j&255)<11){i=$l(e)|0;b:do if((c[s>>2]|0)>0){h=0;do{if(((Kl(e)|0)&255)>=2){f=9;break b}_l(e,45,1)|0;if((Vl(e)|0)>>>0>1048576){f=9;break b}g=Vl(e)|0;if(g>>>0>1048576){f=9;break b}if(!((Ml(e)|0)<<16>>16)){f=9;break b}if(((Kl(e)|0)&255)>64){f=9;break b}if((Vl(e)|0)>>>0>g>>>0){f=9;break b}h=h+1|0;if((Vl(e)|0)>>>0>g>>>0){f=9;break b}}while((h|0)<(c[s>>2]|0))}while(0);_l(e,i,0)|0}c:do if((c[s>>2]|0)>0){k=b+176|0;m=b+180|0;i=(f|0)<10;j=0;while(1){if((ob(b,j,1)|0)<0){f=-1;break}Kl(e)|0;Zl(n,1,32,e)|0;vb(c[k>>2]|0,j,n,32);Zl(n,1,13,e)|0;Vl(e)|0;g=c[k>>2]|0;c[g+(j*764|0)+36>>2]=1;g=c[g+(j*764|0)+756>>2]|0;c[g+40>>2]=j;c[g+8>>2]=128;g=Vl(e)|0;c[(c[m>>2]|0)+(j*52|0)+32>>2]=g;g=(Ml(e)|0)&65535;h=c[(c[k>>2]|0)+(j*764|0)+756>>2]|0;mi(g,h+12|0,h+16|0);h=(Kl(e)|0)&255;c[c[(c[k>>2]|0)+(j*764|0)+756>>2]>>2]=h;if(i){g=(Ml(e)|0)&65535;h=c[m>>2]|0;c[h+(j*52|0)+36>>2]=g;c[h+(j*52|0)+40>>2]=c[h+(j*52|0)+32>>2];f=0}else{g=Vl(e)|0;c[(c[m>>2]|0)+(j*52|0)+36>>2]=g;g=Vl(e)|0;h=c[m>>2]|0;c[h+(j*52|0)+40>>2]=g;f=c[h+(j*52|0)+36>>2]|0}c[h+(j*52|0)+44>>2]=(g|0)>(f|0)?2:0;j=j+1|0;if((j|0)>=(c[s>>2]|0))break c}l=t;return f|0}while(0);f=c[r>>2]|0;m=Qm(4,f)|0;if(!m){b=-1;l=t;return b|0}if((f|0)>0){g=0;f=0;do{n=(Ml(e)|0)&65535;c[m+(g<<2)>>2]=n;f=(n|0)>(f|0)?n:f;g=g+1|0}while((g|0)<(c[r>>2]|0))}else f=0;g=c[q>>2]|0;if((g|0)>0){h=c[p>>2]|0;k=0;do{if((h|0)>0){i=c[(c[o>>2]|0)+(k<<2)>>2]|0;j=0;do{h=i+4+(j<<2)|0;g=c[h>>2]|0;if((g|0)>=1?(g|0)<=(c[r>>2]|0):0)g=g+-1|0;else g=0;c[h>>2]=c[m+(g<<2)>>2];j=j+1|0;h=c[p>>2]|0}while((j|0)<(h|0));g=c[q>>2]|0}k=k+1|0}while((k|0)<(g|0))}c[r>>2]=f;Pm(m);q=(c[r>>2]|0)+1|0;c[r>>2]=q;q=Qm(4,q)|0;p=b+172|0;c[p>>2]=q;if(!q){b=-1;l=t;return b|0}if((rb(b,0,64)|0)<0){b=-1;l=t;return b|0}d:do if((c[r>>2]|0)>1){n=1;while(1){if((rb(b,n,64)|0)<0){f=-1;break}k=Rl(e)|0;e:do if((k|0)>0){o=0;do{q=Kl(e)|0;g=Kl(e)|0;i=Kl(e)|0;m=q&255;h=g&255;if((g&q)<<24>>24==-1&i<<24>>24==-1)break e;j=c[(c[p>>2]|0)+(n<<2)>>2]|0;f=j+4+(m<<3)|0;f:do if((g&255)<127){if(g<<24>>24)a[f>>0]=h+1;a[j+4+(m<<3)+2>>0]=i}else{g:do switch(g<<24>>24){case 127:{m=j+4+(m+-1<<3)|0;i=m;i=d[i>>0]|d[i+1>>0]<<8|d[i+2>>0]<<16|d[i+3>>0]<<24;m=m+4|0;m=d[m>>0]|d[m+1>>0]<<8|d[m+2>>0]<<16|d[m+3>>0]<<24;q=f;j=q;a[j>>0]=i;a[j+1>>0]=i>>8;a[j+2>>0]=i>>16;a[j+3>>0]=i>>24;q=q+4|0;a[q>>0]=m;a[q+1>>0]=m>>8;a[q+2>>0]=m>>16;a[q+3>>0]=m>>24;break f}case -128:{a[j+4+(m<<3)+1>>0]=(i&255)+1;break f}case -127:{g=i;f=15;break}case -126:{f=i&255;if(i<<24>>24>0){g=f<<4&255;f=10;break g}else{g=0-f&15;f=10;break g}}case -125:{a[j+4+(m<<3)+2>>0]=i;g=0;f=0;break}case -124:{if(i<<24>>24>-1){g=i;f=2;break g}if(i<<24>>24==-128){g=0;f=1;break g}g=0-(i&255)&255;f=1;break}case -105:{g=(i<<24>>24<<1)+128&255;f=8;break}case -122:{g=i;f=3;break}case -121:{g=i;f=7;break}case -120:{g=i;f=0;break}case -119:{g=i;f=4;break}case -118:{f=i&255;if(i<<24>>24>0){g=f<<4&255;f=5;break g}else{g=0-f&15;f=5;break g}}case -117:{f=i&255;if(i<<24>>24>0){g=f<<4&255;f=6;break g}else{g=0-f&15;f=6;break g}}case -116:{g=i;f=13;break}case -115:{g=i;f=11;break}case -106:{g=-32;f=i<<24>>24>0?2:1;break}case -113:{g=i&15|-112;f=14;break}case -112:{g=i;f=9;break}case -111:{f=i&15;if(i<<24>>24>0){g=(f|160)&255;f=14;break g}else{g=(f|176)&255;f=14;break g}}case -110:{g=-16;f=i<<24>>24>0?2:1;break}case -109:{g=i&15|-48;f=14;break}case -108:{g=i&15|-64;f=14;break}case -107:{g=(i&255)>33?i:33;f=15;break}default:{g=0;f=0}}while(0);a[j+4+(m<<3)+3>>0]=f;a[j+4+(m<<3)+4>>0]=g}while(0);o=o+1|0}while((o|0)<(k|0))}while(0);n=n+1|0;if((n|0)>=(c[r>>2]|0))break d}l=t;return f|0}while(0);h:do if((c[s>>2]|0)>0){g=b+180|0;f=0;while(1){if((Ub(b,e,2,(c[g>>2]|0)+(f*52|0)|0,0)|0)<0){f=-1;break}f=f+1|0;if((f|0)>=(c[s>>2]|0))break h}l=t;return f|0}while(0);b=b+1280|0;c[b>>2]=c[b>>2]|32;b=0;l=t;return b|0}function je(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)==1347636734){xb(a,b,60);a=0}else a=-1;return a|0}function ke(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+1296|0;g=t;k=t+264|0;s=t+8|0;_l(d,e,0)|0;Xl(d)|0;Zl(k,1,60,d)|0;yo(b,k,64)|0;r=Kl(d)|0;f=(Kl(d)|0)&255;Kl(d)|0;if(r&1){e=-1;l=t;return e|0}c[g>>2]=f>>>4;c[g+4>>2]=f&15;Eb(b,20298,g);c[b+148>>2]=(Kl(d)|0)&255;c[b+152>>2]=(Kl(d)|0)&255;Kl(d)|0;Ml(d)|0;n=b+156|0;c[n>>2]=(Ml(d)|0)&65535;q=b+128|0;c[q>>2]=(Ml(d)|0)&65535;r=b+140|0;c[r>>2]=(Ml(d)|0)&65535;Ml(d)|0;m=(Ml(d)|0)&65535;p=b+136|0;c[p>>2]=m;c[b+144>>2]=c[r>>2];c[b+132>>2]=O(c[q>>2]|0,m)|0;m=Vl(d)|0;o=Vl(d)|0;j=Vl(d)|0;f=Vl(d)|0;_l(d,m+e|0,0)|0;Zl(b+952|0,1,c[n>>2]|0,d)|0;_l(d,o+e|0,0)|0;Zl(k,1,16,d)|0;if((nb(b)|0)<0){e=-1;l=t;return e|0}_l(d,f+e|0,0)|0;a:do if((c[r>>2]|0)>0){h=b+176|0;i=b+180|0;g=0;while(1){if((ob(b,g,1)|0)<0){f=-1;break}Zl(k,1,13,d)|0;Zl(k,1,24,d)|0;yo((c[h>>2]|0)+(g*764|0)|0,k,24)|0;pl((c[h>>2]|0)+(g*764|0)|0)|0;c[s+(g<<2)>>2]=Vl(d)|0;Vl(d)|0;Ml(d)|0;m=Kl(d)|0;n=Vl(d)|0;c[(c[i>>2]|0)+(g*52|0)+32>>2]=n;n=Vl(d)|0;c[(c[i>>2]|0)+(g*52|0)+36>>2]=n;n=Vl(d)|0;c[(c[i>>2]|0)+(g*52|0)+40>>2]=n;n=((Kl(d)|0)&255)<<28>>24;o=(Kl(d)|0)&255;c[c[(c[h>>2]|0)+(g*764|0)+756>>2]>>2]=o;o=((((Ml(d)|0)&65535)*8363|0)>>>0)/8448|0;f=c[(c[h>>2]|0)+(g*764|0)+756>>2]|0;c[f+8>>2]=128;c[f+40>>2]=g;m=m&255;c[(c[i>>2]|0)+(g*52|0)+44>>2]=m>>>6&2|m>>>3&4;mi(o&65535,f+12|0,f+16|0);f=c[h>>2]|0;o=(c[f+(g*764|0)+756>>2]|0)+16|0;c[o>>2]=(c[o>>2]|0)+n;if((c[(c[i>>2]|0)+(g*52|0)+32>>2]|0)>0)c[f+(g*764|0)+36>>2]=1;g=g+1|0;if((g|0)>=(c[r>>2]|0))break a}l=t;return f|0}while(0);if((pb(b)|0)<0){e=-1;l=t;return e|0}_l(d,j+e|0,0)|0;b:do if((c[q>>2]|0)>0){o=b+172|0;n=b+168|0;m=0;c:while(1){f=Ml(d)|0;g=Kl(d)|0;Kl(d)|0;k=g&255;if((tb(b,m,k)|0)<0){f=-1;g=32;break}f=(f&65535)+-4|0;if(g<<24>>24){j=0;do{d:do if((f|0)>0){h=f;while(1){g=Kl(d)|0;f=h+-1|0;i=g&255;if(!(g<<24>>24))break d;g=i&15;if((g|0)>=(c[p>>2]|0)){f=-1;g=32;break c}g=c[(c[o>>2]|0)+(c[(c[(c[n>>2]|0)+(m<<2)>>2]|0)+4+(g<<2)>>2]<<2)>>2]|0;if(i&128){a[g+4+(j<<3)>>0]=((Kl(d)|0)&255)+37;a[g+4+(j<<3)+1>>0]=Kl(d)|0;f=h+-3|0}if(i&64){a[g+4+(j<<3)+2>>0]=((Kl(d)|0)&255)+1;f=f+-1|0}if(i&32){a[g+4+(j<<3)+3>>0]=Kl(d)|0;a[g+4+(j<<3)+4>>0]=Kl(d)|0;f=f+-2|0}if((f|0)>0)h=f;else break}}while(0);j=j+1|0}while((j|0)<(k|0))}if((f|0)>0)_l(d,f,1)|0;m=m+1|0;if((m|0)>=(c[q>>2]|0))break b}if((g|0)==32){l=t;return f|0}}while(0);if((c[r>>2]|0)<=0){e=0;l=t;return e|0}h=b+180|0;g=b+176|0;f=0;while(1){_l(d,(c[s+(f<<2)>>2]|0)+e|0,0)|0;if((Ub(b,d,1,(c[h>>2]|0)+((c[(c[(c[g>>2]|0)+(f*764|0)+756>>2]|0)+40>>2]|0)*52|0)|0,0)|0)<0){f=-1;g=32;break}f=f+1|0;if((f|0)>=(c[r>>2]|0)){f=0;g=32;break}}if((g|0)==32){l=t;return f|0}return 0}function le(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)==1398032717?((Pl(a)|0)&65535)<=16:0){xb(a,b,0);a=0}else a=-1;return a|0}function me(d,f,g){d=d|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;v=l;l=l+416|0;m=v;s=v+8|0;_l(f,g,0)|0;c[s>>2]=Xl(f)|0;t=s+4|0;c[t>>2]=Xl(f)|0;Xl(f)|0;Xl(f)|0;k=s+16|0;b[k>>1]=Pl(f)|0;i=s+18|0;b[i>>1]=Pl(f)|0;j=s+20|0;b[j>>1]=Pl(f)|0;Zl(s+22|0,128,1,f)|0;h=0;do{c[s+152+(h<<2)>>2]=(Xl(f)|0)+12;h=h+1|0}while((h|0)!=64);q=b[i>>1]|0;i=d+156|0;c[i>>2]=q&65535;p=e[j>>1]|0;r=d+128|0;c[r>>2]=p;o=e[k>>1]|0;c[d+140>>2]=o;u=d+144|0;c[u>>2]=o;c[d+132>>2]=O(c[d+136>>2]|0,p)|0;if(q<<16>>16){h=0;do{a[d+952+h>>0]=a[s+22+h>>0]|0;h=h+1|0}while((h|0)<(c[i>>2]|0))}Eb(d,20328,m);if((pb(d)|0)<0){d=-1;l=v;return d|0}a:do if((c[r>>2]|0)>0){m=g+8|0;q=d+172|0;p=d+168|0;n=0;while(1){if((tb(d,n,64)|0)<0){h=-1;break}_l(f,m+(c[s+152+(n<<2)>>2]|0)|0,0)|0;o=0;do{h=0;do{i=c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(n<<2)>>2]|0)+4+(o<<2)>>2]<<2)>>2]|0;j=i+4+(h<<3)|0;k=(Kl(f)|0)&255;if(!(k&128)){x=Kl(f)|0;w=Kl(f)|0;x=x&255;y=x&63;a[j>>0]=(y|0)==0?0:y+47&255;a[i+4+(h<<3)+1>>0]=k&31;a[i+4+(h<<3)+3>>0]=x>>>4&12|k>>>5;a[i+4+(h<<3)+4>>0]=w;Ab(j)}else h=(k&127)+h|0;h=h+1|0}while((h|0)<64);o=o+1|0}while((o|0)!=4);n=n+1|0;if((n|0)>=(c[r>>2]|0))break a}l=v;return h|0}while(0);if((nb(d)|0)<0){y=-1;l=v;return y|0}_l(f,(c[t>>2]|0)+g+(c[u>>2]<<2)|0,0)|0;b:do if((c[u>>2]|0)>0){q=d+180|0;p=d+176|0;o=0;while(1){k=Pl(f)|0;m=Kl(f)|0;n=Kl(f)|0;h=Pl(f)|0;i=Pl(f)|0;if((ob(d,o,1)|0)<0){h=-1;i=25;break}j=c[q>>2]|0;c[j+(o*52|0)+32>>2]=(k&65535)<<1;h=(h&65535)<<1;c[j+(o*52|0)+36>>2]=h;c[j+(o*52|0)+40>>2]=((i&65535)<<1)+h;c[j+(o*52|0)+44>>2]=(i&65535)>1?2:0;h=c[p>>2]|0;y=c[h+(o*764|0)+756>>2]|0;c[y+16>>2]=(m&255)<<28>>24;c[y>>2]=n&255;c[y+8>>2]=128;c[y+40>>2]=o;c[h+(o*764|0)+40>>2]=4095;if(k<<16>>16?(c[h+(o*764|0)+36>>2]=1,(Ub(d,f,0,j+(o*52|0)|0,0)|0)<0):0){h=-1;i=25;break}o=o+1|0;if((o|0)>=(c[u>>2]|0))break b}if((i|0)==25){l=v;return h|0}}while(0);y=d+1280|0;c[y>>2]=c[y>>2]|8192;y=0;l=v;return y|0}function ne(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0;h=b+3|0;do switch(a[h>>0]|0){case 4:{a[h>>0]=-110;return}case 8:{a[b+4>>0]=0;a[h>>0]=0;return}case 9:{a[h>>0]=15;return}case 13:{a[h>>0]=10;return}case 14:{a[b+4>>0]=0;a[h>>0]=0;return}case 15:{g=b+4|0;f=a[g>>0]|0;e=f&255;if(!(f<<24>>24)){a[h>>0]=13;return}if((f&255)<241){a[h>>0]=-85;if(c)e=oe(e)|0;a[g>>0]=e;return}switch(f<<24>>24){case -15:{a[h>>0]=14;a[g>>0]=-109;return}case -14:{a[h>>0]=14;a[g>>0]=-45;return}case -13:{a[h>>0]=14;a[g>>0]=-110;return}case -2:case -3:case -5:case -6:case -7:case -8:{a[g>>0]=0;a[h>>0]=0;return}case -1:{a[g>>0]=0;a[h>>0]=0;a[b>>0]=-126;return}default:{a[g>>0]=0;a[h>>0]=0;return}}}case 17:{a[h>>0]=-81;return}case 18:{a[h>>0]=-80;return}case 20:{a[h>>0]=4;return}case 21:{a[h>>0]=-90;h=b+4|0;a[h>>0]=(d[h>>0]<<4)+128;return}case 22:{a[h>>0]=14;f=b+4|0;e=a[f>>0]|0;if((e&255)>15){a[f>>0]=15;e=15}a[f>>0]=e|96;return}case 24:{a[h>>0]=14;f=b+4|0;e=a[f>>0]|0;if((e&255)>15){a[f>>0]=15;e=15}a[f>>0]=e|-64;return}case 25:{a[h>>0]=9;return}case 26:{a[h>>0]=-83;return}case 27:{a[h>>0]=-82;return}case 29:{a[h>>0]=13;return}case 30:{a[h>>0]=-77;return}case 31:{f=b+4|0;e=d[f>>0]|0;if(e&240|0){a[h>>0]=14;a[f>>0]=e>>>4|208;return}e=e&15;if(!e)return;a[h>>0]=14;a[f>>0]=e|144;return}case 46:{f=b+4|0;g=a[f>>0]|0;e=g<<24>>24<<3;b=e+128|0;if((g+-17&255)<=222)return;a[h>>0]=8;a[f>>0]=(b|0)==256?e+127|0:b;return}case 12:case 11:case 10:case 7:case 6:case 5:case 3:case 2:case 1:case 0:return;default:{a[b+4>>0]=0;a[h>>0]=0;return}}while(0)}function oe(a){a=a|0;if((a|0)<=0)return a|0;a=c[2244+(((a|0)<10?a:10)+-1<<2)>>2]|0;return a|0}function pe(a,b,d){a=a|0;b=b|0;d=d|0;var f=0,g=0,h=0,i=0;g=c[a+6552>>2]|0;f=e[d+14>>1]|0;a=Qm(1,f)|0;h=g+4|0;c[(c[h>>2]|0)+(b<<2)>>2]=a;a=c[(c[h>>2]|0)+(b<<2)>>2]|0;if(!a){d=-1;return d|0}ap(a|0,d+22|0,f|0)|0;f=e[d+16>>1]|0;i=Qm(1,f)|0;a=g+8|0;c[(c[a>>2]|0)+(b<<2)>>2]=i;a=c[(c[a>>2]|0)+(b<<2)>>2]|0;if(!a){Pm(c[(c[h>>2]|0)+(b<<2)>>2]|0);i=-1;return i|0}else{ap(a|0,d+150|0,f|0)|0;i=0;return i|0}return 0}function qe(f,g,h,i,j,k,l){f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0;m=c[g+176>>2]|0;p=$l(f)|0;a[j+6>>0]=Kl(f)|0;_l(f,3,1)|0;b[j+10>>1]=Pl(f)|0;b[j+12>>1]=Pl(f)|0;b[j+14>>1]=Pl(f)|0;b[j+16>>1]=Pl(f)|0;n=j+18|0;a[n>>0]=Kl(f)|0;o=j+19|0;a[o>>0]=Kl(f)|0;b[j+20>>1]=Pl(f)|0;Zl(j+22|0,1,128,f)|0;Zl(j+150|0,1,128,f)|0;_l(f,p+-6+(Xl(f)|0)|0,0)|0;j=Xl(f)|0;Pl(f)|0;if(Jj(m+(h*764|0)|0)|0){p=-1;return p|0}c[m+(h*764|0)+36>>2]=1;if((ob(g,h,1)|0)<0){p=-1;return p|0}p=c[m+(h*764|0)+760>>2]|0;c[p+4>>2]=d[n>>0];c[p+8>>2]=d[o>>0];p=c[m+(h*764|0)+756>>2]|0;c[p+8>>2]=128;c[p>>2]=d[l+6>>0];c[p+12>>2]=(a[l+7>>0]|0)+36;c[p+40>>2]=i;c[p+16>>2]=a[k+3>>0];p=c[g+180>>2]|0;c[p+(i*52|0)+32>>2]=j;n=e[l>>1]<<1;c[p+(i*52|0)+36>>2]=n;o=b[l+2>>1]|0;c[p+(i*52|0)+40>>2]=((o&65535)<<1)+n;c[p+(i*52|0)+44>>2]=(o&65535)>1?2:0;p=(Ub(g,f,0,p+(i*52|0)|0,0)|0)>>31;return p|0}function re(f,g,h,i,j,k,l){f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0;q=g+176|0;n=c[q>>2]|0;r=$l(f)|0;a[j+6>>0]=Kl(f)|0;_l(f,3,1)|0;b[j+10>>1]=Pl(f)|0;b[j+12>>1]=Pl(f)|0;b[j+14>>1]=Pl(f)|0;b[j+16>>1]=Pl(f)|0;o=j+18|0;a[o>>0]=Kl(f)|0;p=j+19|0;a[p>>0]=Kl(f)|0;s=j+20|0;b[s>>1]=Pl(f)|0;Zl(j+22|0,1,128,f)|0;Zl(j+150|0,1,128,f)|0;m=0;do{c[j+280+(m<<2)>>2]=Xl(f)|0;m=m+1|0}while((m|0)!=64);m=b[s>>1]|0;if(m<<16>>16==-1){s=1;return s|0}if((m&65535)>64){s=-1;return s|0}if(Jj((c[q>>2]|0)+(h*764|0)|0)|0){s=-1;return s|0}m=e[s>>1]|0;c[(c[q>>2]|0)+(h*764|0)+36>>2]=m;if((ob(g,h,m)|0)<0){s=-1;return s|0}q=c[n+(h*764|0)+760>>2]|0;c[q+4>>2]=d[o>>0];c[q+8>>2]=d[p>>0];p=n+(h*764|0)+756|0;if(!(b[s>>1]|0)){s=0;return s|0}q=g+180|0;o=l+7|0;h=k+3|0;n=r+-6|0;m=0;while(1){k=c[p>>2]|0;r=c[q>>2]|0;c[k+(m<<6)+8>>2]=128;c[k+(m<<6)>>2]=64;c[k+(m<<6)+12>>2]=(a[o>>0]|0)+12;c[k+(m<<6)+40>>2]=i;c[k+(m<<6)+16>>2]=a[h>>0];_l(f,n+(c[j+280+(m<<2)>>2]|0)|0,0)|0;c[r+(i*52|0)+32>>2]=((Pl(f)|0)&65535)<<1;c[r+(i*52|0)+36>>2]=0;c[r+(i*52|0)+40>>2]=c[(c[q>>2]|0)+(i*52|0)+32>>2];c[r+(i*52|0)+44>>2]=2;if((Ub(g,f,0,r+(i*52|0)|0,0)|0)<0){i=-1;m=11;break}m=m+1|0;if((m|0)>=(e[s>>1]|0)){i=0;m=11;break}else i=i+1|0}if((m|0)==11)return i|0;return 0}function se(f,g,h,i,j,k,l,m,n){f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;var o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=c[g+176>>2]|0;if(Jj(v+(h*764|0)|0)|0){n=-1;return n|0}c[(c[v+(h*764|0)+760>>2]|0)+12>>2]=d[l>>0];c[v+(h*764|0)+40>>2]=d[l+1>>0]<<4^4095;c[v+(h*764|0)+36>>2]=1;if((ob(g,h,1)|0)<0){n=-1;return n|0}o=c[v+(h*764|0)+756>>2]|0;c[o>>2]=d[m+6>>0];c[o+8>>2]=128;q=a[m+7>>0]|0;r=o+12|0;c[r>>2]=q+36;if(((n|0)>1?(e[k+10>>1]|0)>4:0)?(p=a[l+4>>0]|0,p<<24>>24):0)c[r>>2]=q+11+(p&255);c[o+40>>2]=i;c[o+16>>2]=a[l+3>>0]<<4;k=c[g+180>>2]|0;r=c[j>>2]|0;t=k+(i*52|0)+32|0;c[t>>2]=r;s=e[m>>1]|0;p=s<<1;u=k+(i*52|0)+36|0;c[u>>2]=p;o=b[m+2>>1]|0;p=((o&65535)<<1)+p|0;l=k+(i*52|0)+40|0;c[l>>2]=p;q=k+(i*52|0)+44|0;o=(o&65535)>1?2:0;c[q>>2]=o;if(b[j+4>>1]&16){c[q>>2]=o|1;c[t>>2]=r>>1;c[u>>2]=s;c[l>>2]=p>>>1}if((n|0)<3){a[v+(h*764|0)+513>>0]=12;a[v+(h*764|0)+515>>0]=12;a[v+(h*764|0)+517>>0]=12;a[v+(h*764|0)+519>>0]=12;a[v+(h*764|0)+521>>0]=12;a[v+(h*764|0)+523>>0]=12;a[v+(h*764|0)+525>>0]=12;a[v+(h*764|0)+527>>0]=12;a[v+(h*764|0)+529>>0]=12;a[v+(h*764|0)+531>>0]=12;a[v+(h*764|0)+533>>0]=12;a[v+(h*764|0)+535>>0]=12;a[v+(h*764|0)+537>>0]=0;a[v+(h*764|0)+539>>0]=0;a[v+(h*764|0)+541>>0]=0;a[v+(h*764|0)+543>>0]=0;a[v+(h*764|0)+545>>0]=0;a[v+(h*764|0)+547>>0]=0;a[v+(h*764|0)+549>>0]=0;a[v+(h*764|0)+551>>0]=0;a[v+(h*764|0)+553>>0]=0;a[v+(h*764|0)+555>>0]=0;a[v+(h*764|0)+557>>0]=0;a[v+(h*764|0)+559>>0]=0;a[v+(h*764|0)+561>>0]=0;a[v+(h*764|0)+563>>0]=0;a[v+(h*764|0)+565>>0]=0;a[v+(h*764|0)+567>>0]=0;a[v+(h*764|0)+569>>0]=0;a[v+(h*764|0)+571>>0]=0;a[v+(h*764|0)+573>>0]=0;a[v+(h*764|0)+575>>0]=0;a[v+(h*764|0)+577>>0]=0;a[v+(h*764|0)+579>>0]=0;a[v+(h*764|0)+581>>0]=0;a[v+(h*764|0)+583>>0]=0;a[v+(h*764|0)+585>>0]=0;a[v+(h*764|0)+587>>0]=0;a[v+(h*764|0)+589>>0]=0;a[v+(h*764|0)+591>>0]=0;a[v+(h*764|0)+593>>0]=0;a[v+(h*764|0)+595>>0]=0;a[v+(h*764|0)+597>>0]=0;a[v+(h*764|0)+599>>0]=0;a[v+(h*764|0)+601>>0]=0;a[v+(h*764|0)+603>>0]=0;a[v+(h*764|0)+605>>0]=0;a[v+(h*764|0)+607>>0]=0;a[v+(h*764|0)+609>>0]=-12;a[v+(h*764|0)+611>>0]=-12;a[v+(h*764|0)+613>>0]=-12;a[v+(h*764|0)+615>>0]=-12;a[v+(h*764|0)+617>>0]=-12;a[v+(h*764|0)+619>>0]=-12;a[v+(h*764|0)+621>>0]=-12;a[v+(h*764|0)+623>>0]=-12;a[v+(h*764|0)+625>>0]=-12;a[v+(h*764|0)+627>>0]=-12;a[v+(h*764|0)+629>>0]=-12;a[v+(h*764|0)+631>>0]=-12;a[v+(h*764|0)+633>>0]=-24;a[v+(h*764|0)+635>>0]=-24;a[v+(h*764|0)+637>>0]=-24;a[v+(h*764|0)+639>>0]=-24;a[v+(h*764|0)+641>>0]=-24;a[v+(h*764|0)+643>>0]=-24;a[v+(h*764|0)+645>>0]=-24;a[v+(h*764|0)+647>>0]=-24;a[v+(h*764|0)+649>>0]=-24;a[v+(h*764|0)+651>>0]=-24;a[v+(h*764|0)+653>>0]=-24;a[v+(h*764|0)+655>>0]=-24;a[v+(h*764|0)+657>>0]=-36;a[v+(h*764|0)+659>>0]=-36;a[v+(h*764|0)+661>>0]=-36;a[v+(h*764|0)+663>>0]=-36;a[v+(h*764|0)+665>>0]=-36;a[v+(h*764|0)+667>>0]=-36;a[v+(h*764|0)+669>>0]=-36;a[v+(h*764|0)+671>>0]=-36;a[v+(h*764|0)+673>>0]=-36;a[v+(h*764|0)+675>>0]=-36;a[v+(h*764|0)+677>>0]=-36;a[v+(h*764|0)+679>>0]=-36;a[v+(h*764|0)+681>>0]=-48;a[v+(h*764|0)+683>>0]=-48;a[v+(h*764|0)+685>>0]=-48;a[v+(h*764|0)+687>>0]=-48;a[v+(h*764|0)+689>>0]=-48;a[v+(h*764|0)+691>>0]=-48;a[v+(h*764|0)+693>>0]=-48;a[v+(h*764|0)+695>>0]=-48;a[v+(h*764|0)+697>>0]=-48;a[v+(h*764|0)+699>>0]=-48;a[v+(h*764|0)+701>>0]=-48;a[v+(h*764|0)+703>>0]=-48;a[v+(h*764|0)+705>>0]=-60;a[v+(h*764|0)+707>>0]=-60;a[v+(h*764|0)+709>>0]=-60;a[v+(h*764|0)+711>>0]=-60;a[v+(h*764|0)+713>>0]=-60;a[v+(h*764|0)+715>>0]=-60;a[v+(h*764|0)+717>>0]=-60;a[v+(h*764|0)+719>>0]=-60;a[v+(h*764|0)+721>>0]=-60;a[v+(h*764|0)+723>>0]=-60;a[v+(h*764|0)+725>>0]=-60;a[v+(h*764|0)+727>>0]=-60}n=(Ub(g,f,64,k+(i*52|0)|0,0)|0)>>31;return n|0}function te(f,g,h,i,j,k,l,m){f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;w=c[g+176>>2]|0;x=k+-2|0;if(x>>>0>5){y=-1;return y|0}if(Jj(w+(h*764|0)|0)|0){y=-1;return y|0}c[(c[w+(h*764|0)+760>>2]|0)+12>>2]=d[l>>0];c[w+(h*764|0)+40>>2]=d[l+1>>0]<<4^4095;c[w+(h*764|0)+36>>2]=k;if((ob(g,h,k)|0)<0){y=-1;return y|0}s=m+2|0;n=b[s>>1]|0;u=w+(h*764|0)+756|0;v=m+6|0;t=m+7|0;q=l+3|0;r=g+180|0;p=n;l=0;m=e[m>>1]|0;n=n&65535;o=((c[j>>2]|0)>>>0)/(((1<>>0)|0;while(1){j=n<<1;m=m<<1;n=c[u>>2]|0;c[n+(l<<6)>>2]=d[v>>0];c[n+(l<<6)+8>>2]=128;c[n+(l<<6)+12>>2]=(a[t>>0]|0)+24;c[n+(l<<6)+40>>2]=i;c[n+(l<<6)+16>>2]=a[q>>0]<<4;n=c[r>>2]|0;c[n+(i*52|0)+32>>2]=o;c[n+(i*52|0)+36>>2]=m;c[n+(i*52|0)+40>>2]=j+m;c[n+(i*52|0)+44>>2]=(p&65535)>1?2:0;if((Ub(g,f,64,n+(i*52|0)|0,0)|0)<0){l=-1;y=9;break}l=l+1|0;if((l|0)>=(k|0)){l=0;break}p=b[s>>1]|0;n=j;o=o<<1;i=i+1|0}if((y|0)==9)return l|0;do{u=a[20337+(x*9|0)+l>>0]|0;y=l*12|0;v=a[20391+(x*9|0)+l>>0]|0;a[w+(h*764|0)+512+(y<<1)>>0]=u;a[w+(h*764|0)+512+(y<<1)+1>>0]=v;t=y|1;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y|2;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y|3;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+4|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+5|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+6|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+7|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+8|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+9|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+10|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;y=y+11|0;a[w+(h*764|0)+512+(y<<1)>>0]=u;a[w+(h*764|0)+512+(y<<1)+1>>0]=v;l=l+1|0}while((l|0)!=9);l=0;return l|0}function ue(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;if(b|0){c[a+152>>2]=oe(d)|0;return}c[a+152>>2]=d;if(!e)return;h[a+1256>>3]=40.0/+(f|0);return}function ve(b,d){b=b|0;d=d|0;var e=0,f=0;Xl(b)|0;Pl(b)|0;if((Pl(b)|0)<<16>>16!=1)return;e=Xl(b)|0;if(!e)return;f=Om(e+1|0)|0;d=d+1220|0;c[d>>2]=f;if(!f)return;Zl(f,1,e,b)|0;a[(c[d>>2]|0)+e>>0]=0;return}function we(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0;e=l;l=l+16|0;d=e;if((Zl(d,1,4,a)|0)>>>0<4){b=-1;l=e;return b|0}if(en(d,20512,4)|0?en(d,20517,4)|0:0){b=-1;l=e;return b|0}_l(a,28,1)|0;d=Xl(a)|0;if(!d){xb(a,b,0);b=0;l=e;return b|0}else{_l(a,c+44+d|0,0)|0;f=Xl(a)|0;d=Xl(a)|0;_l(a,f+c|0,0)|0;xb(a,b,d);b=0;l=e;return b|0}return 0}function xe(f,g,i){f=f|0;g=g|0;i=i|0;var j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0;V=l;l=l+1504|0;y=V;K=V+656|0;U=V+708|0;R=V+648|0;S=V+112|0;P=V+88|0;Q=V+4|0;_l(g,i,0)|0;Zl(K,4,1,g)|0;z=a[K+3>>0]|0;N=(z<<24>>24)+-48|0;c[K+4>>2]=Xl(g)|0;L=Xl(g)|0;Pl(g)|0;Pl(g)|0;x=Xl(g)|0;Xl(g)|0;I=Xl(g)|0;Xl(g)|0;o=Xl(g)|0;Xl(g)|0;b[K+40>>1]=Pl(g)|0;b[K+42>>1]=Pl(g)|0;b[K+44>>1]=Pl(g)|0;b[K+46>>1]=Pl(g)|0;b[K+48>>1]=Pl(g)|0;a[K+50>>0]=Kl(g)|0;a[K+51>>0]=Kl(g)|0;if(_l(g,L+i|0,0)|0){U=-1;l=V;return U|0}k=Pl(g)|0;j=0;do{b[U+(j<<3)>>1]=k;b[U+(j<<3)+2>>1]=Pl(g)|0;a[U+(j<<3)+4>>0]=Kl(g)|0;a[U+(j<<3)+5>>0]=Kl(g)|0;a[U+(j<<3)+6>>0]=Kl(g)|0;a[U+(j<<3)+7>>0]=Il(g)|0;j=j+1|0;k=Pl(g)|0}while((j|0)!=63);m=U+504|0;b[m>>1]=k;L=Pl(g)|0;k=U+506|0;b[k>>1]=L;if((L&65535)>256){U=-1;l=V;return U|0}else j=0;do{a[U+508+j>>0]=Kl(g)|0;j=j+1|0}while((j|0)!=256);n=U+764|0;b[n>>1]=Pl(g)|0;H=U+766|0;a[H>>0]=Kl(g)|0;F=U+767|0;a[F>>0]=Kl(g)|0;L=U+768|0;a[L>>0]=Kl(g)|0;G=U+769|0;a[G>>0]=Kl(g)|0;a[U+770>>0]=Kl(g)|0;a[U+771>>0]=Kl(g)|0;a[U+772>>0]=Kl(g)|0;a[U+773>>0]=Kl(g)|0;a[U+774>>0]=Kl(g)|0;a[U+775>>0]=Kl(g)|0;a[U+776>>0]=Kl(g)|0;a[U+777>>0]=Kl(g)|0;a[U+778>>0]=Kl(g)|0;a[U+779>>0]=Kl(g)|0;a[U+780>>0]=Kl(g)|0;a[U+781>>0]=Kl(g)|0;a[U+782>>0]=Kl(g)|0;a[U+783>>0]=Kl(g)|0;a[U+784>>0]=Kl(g)|0;a[U+785>>0]=Kl(g)|0;a[U+786>>0]=Kl(g)|0;J=U+787|0;a[J>>0]=Kl(g)|0;c[f+1264>>2]=8363;F=a[F>>0]|0;K=f+1280|0;c[K>>2]=(F&32?0:192)|c[K>>2];F=F&64;L=d[L>>0]|0;h[f+1256>>3]=2.64;ue(f,F,e[n>>1]|0,L&32,(L&31)+1|0);c[f+148>>2]=d[G>>0];G=f+128|0;c[G>>2]=e[m>>1];J=a[J>>0]|0;L=f+140|0;c[L>>2]=J&255;n=e[k>>1]|0;c[f+156>>2]=n;c[f+160>>2]=0;K=f+136|0;c[K>>2]=0;ap(f+952|0,U+508|0,n|0)|0;a[f>>0]=0;n=f+144|0;c[n>>2]=0;a:do if(J<<24>>24){k=I+i|0;m=0;while(1){if(_l(g,k+(m<<2)|0,0)|0){j=-1;T=95;break}j=Xl(g)|0;if(j|0){if(_l(g,j+i|0,0)|0){j=-1;T=95;break}Xl(g)|0;j=Pl(g)|0;if(j<<16>>16!=-1)if((j+-1&65535)<6)j=c[2308+((j<<16>>16)+-1<<2)>>2]|0;else j=1;else{_l(g,14,1)|0;j=(Pl(g)|0)&65535}c[n>>2]=(c[n>>2]|0)+j}m=m+1|0;if((m|0)>=(c[L>>2]|0))break a}if((T|0)==95){l=V;return j|0}}while(0);j=Q+8|0;b[j>>1]=0;k=Q+10|0;b[k>>1]=0;p=Q+24|0;b[p>>1]=0;q=Q+26|0;b[q>>1]=0;J=(o|0)!=0;if(J){if(_l(g,o+i|0,0)|0){U=-1;l=V;return U|0}Xl(g)|0;u=Xl(g)|0;r=Pl(g)|0;b[j>>1]=r;s=Pl(g)|0;b[k>>1]=s;m=Xl(g)|0;n=Xl(g)|0;c[Q+16>>2]=n;t=Xl(g)|0;o=Pl(g)|0;b[p>>1]=o;p=Pl(g)|0;b[q>>1]=p;Xl(g)|0;Xl(g)|0;Xl(g)|0;Xl(g)|0;E=Xl(g)|0;j=Xl(g)|0;c[Q+48>>2]=j;_l(g,E+i|0,0)|0;if(j|0){k=0;do{a[f+k>>0]=Kl(g)|0;E=k;k=k+1|0}while(!((E|0)>62|k>>>0>=j>>>0))}if(!((m|0)==0|(n|0)==0)?(E=Om(n+1|0)|0,v=f+1220|0,c[v>>2]=E,(E|0)!=0):0){_l(g,m+i|0,0)|0;Zl(c[v>>2]|0,1,n,g)|0;a[(c[v>>2]|0)+n>>0]=0;E=o;D=u;C=t}else{E=o;D=u;C=t}}else{E=0;p=0;r=0;s=0;D=0;C=0}j=c[G>>2]|0;b:do if((j|0)>0){k=x+i|0;m=z<<24>>24>48;n=0;while(1){if(_l(g,k+(n<<2)|0,0)|0){j=-1;T=95;break}j=Xl(g)|0;if(j|0){if(_l(g,j+i|0,0)|0){j=-1;T=95;break}if(m){j=Pl(g)|0;Pl(g)|0}else{j=(Kl(g)|0)&255;Kl(g)|0}j=j&65535;if((j|0)>(c[K>>2]|0))c[K>>2]=j}n=n+1|0;j=c[G>>2]|0;if((n|0)>=(j|0)){w=j;break b}}if((T|0)==95){l=V;return j|0}}else w=j;while(0);B=c[K>>2]|0;c[f+132>>2]=O(B,w)|0;Eb(f,(N|0)==0?((B|0)>4?20462:20480):20494,y);if((pb(f)|0)<0){U=-1;l=V;return U|0}c:do if((c[G>>2]|0)>0){B=x+i|0;x=z<<24>>24>48;z=f+168|0;A=f+172|0;y=0;d:while(1){if(_l(g,B+(y<<2)|0,0)|0){j=-1;T=95;break}j=Xl(g)|0;e:do if(j|0){if(_l(g,j+i|0,0)|0){j=-1;T=95;break d}if(x){k=Pl(g)|0;j=Pl(g)|0;Xl(g)|0}else{k=(Kl(g)|0)&255;j=(Kl(g)|0)&255}if((tb(f,y,(j&65535)+1|0)|0)<0){j=-1;T=95;break d}m=c[z>>2]|0;j=(c[c[m+(y<<2)>>2]>>2]|0)>0;if(!x){if(!j)break;u=k&65535;t=k<<16>>16==0;j=m;q=0;while(1){if(!t){o=0;do{v=Kl(g)|0;n=Kl(g)|0;m=Kl(g)|0;j=c[(c[A>>2]|0)+(c[(c[(c[z>>2]|0)+(y<<2)>>2]|0)+4+(o<<2)>>2]<<2)>>2]|0;k=j+4+(q<<3)|0;v=v&255;w=v&63;w=(w|0)==0?0:w+12&255;w=(w&255)>120?0:w;a[k>>0]=w;n=n&255;v=n>>>4|v>>>3&16|v>>>1&32;a[j+4+(q<<3)+1>>0]=v;if((v|0)!=0&w<<24>>24==0)a[j+4+(q<<3)+5>>0]=-79;a[j+4+(q<<3)+3>>0]=n&15;a[j+4+(q<<3)+4>>0]=m;ne(k,F);o=o+1|0}while((o|0)!=(u|0));j=c[z>>2]|0}q=q+1|0;if((q|0)>=(c[c[j+(y<<2)>>2]>>2]|0))break e}}if(j){w=k&65535;v=k<<16>>16==0;j=m;u=0;do{if(!v){t=0;do{j=Kl(g)|0;n=Kl(g)|0;o=Kl(g)|0;q=Kl(g)|0;k=c[(c[A>>2]|0)+(c[(c[(c[z>>2]|0)+(y<<2)>>2]|0)+4+(t<<2)>>2]<<2)>>2]|0;m=k+4+(u<<3)|0;j=j&127;a[m>>0]=j;if(!(j<<24>>24))j=0;else{j=(j+12&255)+(d[H>>0]|0)&255;j=(j&255)>120?0:j;a[m>>0]=j}n=n&63;a[k+4+(u<<3)+1>>0]=n;if(n<<24>>24!=0&j<<24>>24==0)a[k+4+(u<<3)+5>>0]=-79;a[k+4+(u<<3)+3>>0]=o;a[k+4+(u<<3)+4>>0]=q;ne(m,F);t=t+1|0}while((t|0)!=(w|0));j=c[z>>2]|0}u=u+1|0}while((u|0)<(c[c[j+(y<<2)>>2]>>2]|0))}}while(0);y=y+1|0;if((y|0)>=(c[G>>2]|0))break c}if((T|0)==95){l=V;return j|0}}while(0);if(Nj(f)|0){U=-1;l=V;return U|0}if((nb(f)|0)<0){U=-1;l=V;return U|0}f:do if((c[L>>2]|0)>0){q=I+i|0;x=R+4|0;z=f+176|0;u=P+3|0;t=P+1|0;w=P+2|0;y=S+20|0;v=0;j=0;g:while(1){if(_l(g,q+(v<<2)|0,0)|0){j=-1;T=95;break}k=Xl(g)|0;h:do if(k){m=k+i|0;if(_l(g,m,0)|0){j=-1;T=95;break g}c[R>>2]=Xl(g)|0;n=Pl(g)|0;b[x>>1]=n;o=$l(g)|0;if(J){if((v|0)<(E&65535|0)){k=c[z>>2]|0;if(_l(g,(O(p&65535,v)|0)+C|0,0)|0){j=-1;T=95;break g}Zl(k+(v*764|0)|0,40,1,g)|0}a[u>>0]=0;if((v|0)<(r&65535|0)){if(_l(g,(O(s&65535,v)|0)+D|0,0)|0){j=-1;T=95;break g}a[P>>0]=Kl(g)|0;a[t>>0]=Kl(g)|0;a[w>>0]=Kl(g)|0;M=Kl(g)|0;T=80}}else{M=0;T=80}if((T|0)==80){T=0;a[u>>0]=M}_l(g,o,0)|0;switch(n<<16>>16){case -2:{if((qe(g,f,v,j,S,P,U+(v<<3)|0)|0)<0){j=-1;T=95;break g}if(!(pe(f,v,S)|0)){j=j+1|0;break h}else{j=-1;T=95;break g}}case -1:{k=re(g,f,v,j,S,P,U+(v<<3)|0)|0;if((k|0)>0)break h;if((k|0)<0){j=-1;T=95;break g}j=(e[y>>1]|0)+j|0;if(!(pe(f,v,S)|0))break h;else{j=-1;T=95;break g}}default:{if((n+-1&65535)<6){k=c[2308+((n<<16>>16)+-1<<2)>>2]|0;_l(g,m+6|0,0)|0;m=te(g,f,v,j,R,k,P,U+(v<<3)|0)|0;k=(m|0)<0?0:k}else{if(n<<16>>16)break h;_l(g,m+6|0,0)|0;m=se(g,f,v,j,R,Q,P,U+(v<<3)|0,N)|0;k=m>>>31^1}if(!(m>>31&-80)){j=k+j|0;break h}else{j=-1;T=95;break g}}}}while(0);v=v+1|0;if((v|0)>=(c[L>>2]|0))break f}if((T|0)==95){l=V;return j|0}}while(0);if((c[K>>2]|0)>0){j=0;do{c[f+184+(j*12|0)+4>>2]=d[U+770+j>>0];T=j;j=j+1|0;c[f+184+(T*12|0)>>2]=(((j|0)/2|0|0)%2|0)*255}while((j|0)<(c[K>>2]|0))}c[f+1284>>2]=4;U=0;l=V;return U|0}function ye(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0;e=l;l=l+16|0;d=e;if((Zl(d,1,4,a)|0)>>>0<4){b=-1;l=e;return b|0}if(en(d,20572,4)|0?en(d,20577,4)|0:0){b=-1;l=e;return b|0}_l(a,28,1)|0;d=Xl(a)|0;if(!d){xb(a,b,0);b=0;l=e;return b|0}else{_l(a,c+44+d|0,0)|0;f=Xl(a)|0;d=Xl(a)|0;_l(a,f+c|0,0)|0;xb(a,b,d);b=0;l=e;return b|0}return 0} -function si(b){b=b|0;var e=0,f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0.0;if((c[b+8140>>2]|0)<2){b=-8;return b|0}if((c[b+1708>>2]|0)<1){b=-1;return b|0}m=b+2504|0;e=c[b>>2]|0;if((a[m+e>>0]|0)==-1){b=-1;return b|0}f=b+4|0;g=c[f>>2]|0;if((e|0)==(g|0)){e=b+12|0;l=(c[e>>2]|0)+1|0;c[e>>2]=l;if((l|0)>=(O((c[b+332>>2]|0)+1|0,c[b+16>>2]|0)|0))ui(b)}else{i=c[b+52>>2]|0;j=c[b+7972+(i<<3)>>2]|0;switch(g|0){case -1:{c[f>>2]=j;e=j;k=9;break}case -2:{b=-1;return b|0}default:if((g|0)==(j|0)){e=g;k=9}else{f=b+368|0;e=g}}if((k|0)==9){f=b+368|0;c[b+356>>2]=c[f+(i<<4)+12>>2]}if((e|0)>(c[f+(i<<4)+4>>2]|0))c[b+356>>2]=0;c[b+340>>2]=0;c[b+328>>2]=-1;c[b>>2]=((e|0)>(j|0)?e:j)+-1;ti(b);g=b+2848|0;e=c[b>>2]|0;f=c[g+(e*20|0)>>2]|0;if(f|0)c[b+16>>2]=f;c[b+20>>2]=c[g+(e*20|0)+4>>2];c[b+320>>2]=c[g+(e*20|0)+8>>2];h[b+32>>3]=+(c[g+(e*20|0)+12>>2]|0);Sh(b);ri(b);e=b+12|0}if(!(c[e>>2]|0)){j=c[b>>2]|0;i=b+368|0;g=c[b+52>>2]|0;k=c[b+8>>2]|0;if((j|0)==(c[i+(g<<4)+4>>2]|0)?(k|0)==(c[i+(g<<4)+8>>2]|0):0){l=b+356|0;f=c[l>>2]|0;if(!f){f=b+48|0;c[f>>2]=(c[f>>2]|0)+1;f=c[i+(g<<4)+12>>2]|0;c[l>>2]=f}c[l>>2]=f+-1}vi(b,d[m+j>>0]|0,k)}wi(b);g=b+952|0;if((c[g>>2]|0)>0){f=0;do{xi(b,f,c[e>>2]|0);f=f+1|0}while((f|0)<(c[g>>2]|0))}n=+h[b+2808>>3]*+h[b+2800>>3]/+(c[b+20>>2]|0);h[b+40>>3]=n;m=b+32|0;h[m>>3]=+h[m>>3]+n;qk(b);b=0;return b|0}function ti(b){b=b|0;var e=0,f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;o=b+1712|0;p=b+52|0;m=b+320|0;n=b+1680|0;i=c[b+1708>>2]|0;e=c[b>>2]|0;while(1){f=e+1|0;c[b>>2]=f;if((f|0)<(i|0)?(j=a[b+2504+f>>0]|0,j<<24>>24!=-1):0){g=f;e=j}else{e=c[o>>2]|0;if(((e|0)<=(i|0)?(d[b+2504+e>>0]|0|0)<(c[n>>2]|0):0)?(k=c[p>>2]|0,l=b+7972+(k<<3)|0,(f|0)>=(c[l>>2]|0)):0){e=(zj(b,e)|0)==(k|0);e=e?o:l}else e=b+7972+(c[p>>2]<<3)|0;e=c[e>>2]|0;c[b>>2]=e;c[m>>2]=c[b+2848+(e*20|0)+8>>2];g=e;e=a[b+2504+e>>0]|0}if((e&255|0)<(c[n>>2]|0))break;else e=g}h[b+32>>3]=+(c[b+2848+(g*20|0)+12>>2]|0);p=c[c[(c[b+1720>>2]|0)+((d[b+2504+g>>0]|0)<<2)>>2]>>2]|0;c[b+352>>2]=p;f=b+340|0;e=c[f>>2]|0;if((e|0)>=(p|0)){c[f>>2]=0;e=0}c[b+8>>2]=e;c[f>>2]=0;c[b+4>>2]=g;c[b+12>>2]=0;if(!(c[b+2832>>2]&256))return;g=c[b+1688>>2]|0;if((g|0)<=0)return;e=c[b+624>>2]|0;f=0;do{c[e+(f*440|0)+4>>2]=0;f=f+1|0}while((f|0)!=(g|0));return}function ui(a){a=a|0;var b=0,d=0,e=0;d=a+332|0;b=a+324|0;e=(c[b>>2]|0)!=0;if(!((c[d>>2]|0)==0|e^1))c[a+336>>2]=1;c[a+12>>2]=0;c[d>>2]=0;if(e){c[b>>2]=0;d=a+328|0;b=c[d>>2]|0;if((b|0)!=-1){c[a>>2]=b+-1;c[d>>2]=-1}ti(a);return}d=a+344|0;b=c[d>>2]|0;if(b|0){c[a+8>>2]=(c[(c[a+348>>2]|0)+(b+-1<<3)>>2]|0)+-1;c[d>>2]=0}d=a+360|0;b=c[d>>2]|0;if(!b){e=a+8|0;b=(c[e>>2]|0)+1|0;c[e>>2]=b;c[a+364>>2]=0}else{c[d>>2]=b+-1;b=c[a+8>>2]|0}if((b|0)<(c[a+352>>2]|0))return;ti(a);return}function vi(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;e=a+336|0;if(c[e>>2]|0){c[e>>2]=0;return}f=a+1688|0;if((c[f>>2]|0)<=0)return;k=a+1724|0;j=a+1720|0;i=a+364|0;h=a+360|0;e=0;do{g=c[(c[k>>2]|0)+(c[(c[(c[j>>2]|0)+(b<<2)>>2]|0)+4+(e<<2)>>2]<<2)>>2]|0;g=(c[g>>2]|0)>(d|0)?g+4+(d<<3)|0:27493;do if(!(Gi(a,g,e)|0)){if(c[i>>2]|0?(c[h>>2]|0)<=0:0)break;Ji(a,g,e);Qj(a,b,e,d)}while(0);e=e+1|0}while((e|0)<(c[f>>2]|0));return}function wi(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0;h=b+1688|0;e=c[h>>2]|0;i=b+8120|0;d=c[i>>2]|0;if((d+e|0)>0)g=0;else return;do{f=b+972+(g<<3)+7|0;if(a[f>>0]|0){Ji(b,b+972+(g<<3)|0,g);a[f>>0]=0;e=c[h>>2]|0;d=c[i>>2]|0}g=g+1|0}while((g|0)<(d+e|0));return}function xi(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;m=a+1552|0;k=c[a+624>>2]|0;l=k+(b*440|0)|0;c[k+(b*440|0)+428>>2]=0;do if(c[l>>2]&2097152|0?c[a+12>>2]|0:0){f=a+20|0;e=(c[f>>2]|0)+(c[k+(b*440|0)+372>>2]|0)|0;c[f>>2]=e;if((e|0)<32){c[f>>2]=32;break}if((e|0)>255)c[f>>2]=255}while(0);f=k+(b*440|0)+64|0;e=c[f>>2]|0;if((e|0)>0?(g=e+-1|0,c[f>>2]=g,(g|0)==0):0)Ji(a,k+(b*440|0)+404|0,b);g=hi(a,b)|0;if((g|0)==-1){yi(a,b,d);return}e=c[k+(b*440|0)+44>>2]|0;f=c[a+1692>>2]|0;do if((d|0)==0&(g|0)!=256){if(e>>>0>>0?(c[(c[a+1728>>2]|0)+(e*764|0)+36>>2]|0)>0:0){if(g|0)break}else i=15;if(((i|0)==15?(h=c[a+8124>>2]|0,(h|0)>0):0)?!((g|0)==0|e>>>0>=(f+h|0)>>>0):0)break;Vh(a,b);return}while(0);if(!(e>>>0>>0?(c[(c[a+1728>>2]|0)+(e*764|0)+36>>2]|0)>0:0))i=21;if((i|0)==21?(i=c[a+8124>>2]|0,!((i|0)>0&e>>>0<(i+f|0)>>>0)):0)return;sm(a,l,b,d);if(c[l>>2]&262144|0?(f=(c[a+2832>>2]&16777216|0)!=0,j=k+(b*440|0)+216|0,h=c[j>>2]|0,i=h+-1|0,c[j>>2]=i,f?(h|0)<2:(i|0)==0):0){f=k+(b*440|0)+220|0;e=c[f>>2]|0;if((e|0)<16){fi(a,b,0);e=c[f>>2]|0}i=k+(b*440|0)+80|0;h=O(c[4132+(e*12|0)+4>>2]|0,(c[i>>2]|0)+(c[4132+(e*12|0)>>2]|0)|0)|0;c[i>>2]=(h|0)/(c[4132+(e*12|0)+8>>2]|0)|0;c[j>>2]=c[k+(b*440|0)+212>>2]&15}zi(a,b,g);Ai(a,b,d,g);Bi(a,b,g);yi(a,b,d);Ci(a,b,d);Di(a,b,d);f=k+(b*440|0)+68|0;e=c[f>>2]|0;if(e|0?(d=e+-1|0,c[f>>2]=d,n=k+(b*440|0)+8|0,(d|0)==0):0)c[n>>2]=c[n>>2]|2;if(c[a+2832>>2]&4|0)Ei(m,l);c[k+(b*440|0)+424>>2]=Zh(a,b)|0;return}function yi(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;k=c[a+624>>2]|0;e=k+(b*440|0)|0;j=((d|0)%(c[a+16>>2]|0)|0|0)==0;if(j?(c[a+2832>>2]&64|0)==0:0){f=c[e>>2]|0;e=k+(b*440|0)+80|0;l=20}else{f=c[e>>2]|0;d=a+320|0;if(f&1048576|0)c[d>>2]=(c[d>>2]|0)+(c[k+(b*440|0)+260>>2]|0);h=k+(b*440|0)+4|0;g=c[h>>2]|0;if((f|g)&1|0){e=k+(b*440|0)+80|0;c[e>>2]=(c[e>>2]|0)+(c[k+(b*440|0)+236>>2]|0)}do if(g&1|0){d=c[k+(b*440|0)+236>>2]|0;if((d|0)>0){e=k+(b*440|0)+80|0;d=c[a+2820>>2]|0;if((c[e>>2]|0)<=(d|0))break;c[e>>2]=d;c[h>>2]=g&-2;break}if((d|0)<0?(i=k+(b*440|0)+80|0,(c[i>>2]|0)<0):0){c[i>>2]=0;c[h>>2]=g&-2}}while(0);e=k+(b*440|0)+80|0;if(f&8192|0)c[e>>2]=(c[e>>2]|0)+(c[k+(b*440|0)+244>>2]|0);d=k+(b*440|0)+60|0;if(f&512|0)c[d>>2]=(c[d>>2]|0)+(c[k+(b*440|0)+272>>2]|0);if(j)l=20;else f=e}if((l|0)==20){if(f&64|0)c[e>>2]=(c[e>>2]|0)+(c[k+(b*440|0)+240>>2]|0);d=k+(b*440|0)+60|0;if(f&1024|0)c[d>>2]=(c[d>>2]|0)+(c[k+(b*440|0)+276>>2]|0);d=a+320|0;if(!(f&1048576))f=e;else{c[d>>2]=(c[d>>2]|0)+(c[k+(b*440|0)+264>>2]|0);f=e}}e=c[f>>2]|0;if((e|0)>=0){d=c[a+2820>>2]|0;if((e|0)>(d|0))l=28}else{d=0;l=28}if((l|0)==28)c[f>>2]=d;f=a+320|0;e=c[f>>2]|0;if((e|0)>=0){d=c[a+2824>>2]|0;if((e|0)>(d|0))l=31}else{d=0;l=31}if((l|0)==31)c[f>>2]=d;f=k+(b*440|0)+60|0;e=c[f>>2]|0;if((e|0)>=0){d=c[a+2820>>2]|0;if((e|0)<=(d|0))return}else d=0;c[f>>2]=d;return}function zi(a,d,f){a=a|0;d=d|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+16|0;m=t;s=c[a+624>>2]|0;o=s+(d*440|0)|0;q=xm(a,c[s+(d*440|0)+44>>2]|0)|0;p=a+2832|0;j=c[p>>2]|0;n=s+(d*440|0)+8|0;i=c[n>>2]|0;if(!((j&262144|0)!=0|(i&2|0)==0)?(c[q+44>>2]&1|0)==0:0)c[s+(d*440|0)+72>>2]=0;k=(f|0)==2;do if((f|1|0)==3|(i&3|0)!=0){h=s+(d*440|0)+72|0;f=c[h>>2]|0;g=c[q+40>>2]|0;if((f|0)>(g|0)){c[h>>2]=f-g;f=i;break}else{c[h>>2]=0;f=i|4;c[n>>2]=f;break}}else f=i;while(0);h=q+44|0;i=s+(d*440|0)+96|0;g=e[i>>1]|0;switch(yj(h,g)|0){case -1:{c[n>>2]=f|4;break}case 0:break;default:if(j&2|0)c[n>>2]=f|1}j=wj(h,g,64,m)|0;f=c[n>>2]|0;b[i>>1]=xj(h,e[i>>1]|0,f>>>1&1|k&1,c[p>>2]&134217728)|0;if(c[m>>2]|0){if(!(j&65535)){f=f|4;c[n>>2]=f}f=f|16;c[n>>2]=f}if(f&4|0?(c[a+948>>2]|0)<=(d|0):0){Vh(a,d);l=t;return}f=tm(a,o)|0;g=s+(d*440|0)+124|0;if(c[o>>2]&32){f=(qj(g,64)|0)+f|0;rj(g)}if((f|0)<0)f=0;else{o=c[a+2820>>2]|0;f=(f|0)>(o|0)?o:f}g=(O(c[s+(d*440|0)+72>>2]|0,f)|0)>>6;i=c[p>>2]|0;if(!(i&16))f=c[a+320>>2]|0;else f=64;f=O(f,j&65535)|0;f=O(f,c[s+(d*440|0)+60>>2]|0)|0;h=c[a+2820>>2]|0;f=(O((g<<6|0)/(h|0)|0,(f|0)/(c[a+2824>>2]|0)|0)|0)>>>18;f=(O(f,Fi(a,d)|0)|0)/100|0;g=c[a+2828>>2]|0;if(g){p=(h|0)==255?2:4;f=c[g+(f>>p<<2)>>2]<>2]|0,f)|0;f=(O(f,c[s+(d*440|0)+84>>2]|0)|0)>>12}h=c[s+(d*440|0)+224>>2]|0;if(h){i=s+(d*440|0)+228|0;g=c[i>>2]|0;switch(g|0){case 0:{g=h>>>4&15|128;r=33;break}case 128:{g=h&15;r=33;break}default:{}}if((r|0)==33)c[i>>2]=g;c[i>>2]=g+-1;f=(0-g&128|0)==0?f:0}r=(O(c[((c[a+1688>>2]|0)>(d|0)?a+316|0:a+312|0)>>2]|0,f)|0)/100|0;c[s+(d*440|0)+428>>2]=r;Wh(a,d,r);l=t;return}function Ai(d,f,g,i){d=d|0;f=f|0;g=g|0;i=i|0;var j=0,k=0.0,m=0.0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;w=l;l=l+16|0;t=w+8|0;u=w+4|0;v=w;s=c[d+624>>2]|0;o=s+(f*440|0)|0;q=(xm(d,c[s+(f*440|0)+44>>2]|0)|0)+356|0;n=s+(f*440|0)+100|0;p=wj(q,e[n>>1]|0,0,w+12|0)|0;r=d+2832|0;j=c[r>>2]|0;b[n>>1]=xj(q,e[n>>1]|0,(c[s+(f*440|0)+8>>2]|0)>>>1&1|(i|0)==2,j&134217728)|0;if(c[o>>2]&16384|0){n=s+(f*440|0)+396|0;i=c[n>>2]|0;if(!i){x=s+(f*440|0)+12|0;i=(c[x>>2]|0)+(c[s+(f*440|0)+384>>2]|0)|0;c[x>>2]=i;h[s+(f*440|0)+24>>3]=+ii(i,c[s+(f*440|0)+40>>2]|0,j&4096,+h[s+(f*440|0)+32>>3]);i=c[s+(f*440|0)+392>>2]|0;c[n>>2]=i}c[n>>2]=i+-1}n=s+(f*440|0)+192|0;x=s+(f*440|0)+208|0;i=qj(n,(c[x>>2]<<10)+1024|0)|0;rj(n);n=c[x>>2]|0;c[x>>2]=(n|0)>1?n+-2|0:0;if(!((c[o>>2]&16|0)==0?(c[s+(f*440|0)+4>>2]&16|0)==0:0)){j=s+(f*440|0)+104|0;n=qj(j,512<<((c[r>>2]|0)>>>19&1))|0;x=c[r>>2]|0;i=((x&2097152|0)==0?n:0-n|0)+i|0;if((g|0)%(c[d+16>>2]|0)|0|x&1048576)rj(j)}m=+h[s+(f*440|0)+24>>3];m=+(i|0)+(m+ +(um(o)|0));i=s+(f*440|0)+12|0;n=li(m,c[i>>2]|0,c[s+(f*440|0)+76>>2]|0,c[r>>2]&4096,+h[s+(f*440|0)+32>>3])|0;n=((c[q>>2]&8|0)==0?p<<7:0)+n|0;j=a[(c[s+(f*440|0)+184>>2]|0)+(s+(f*440|0)+164)>>0]|0;j=n+(vm(d,o)|0)+(j<<24>>24==0?0:(j<<24>>24)*12800|0)|0;c[s+(f*440|0)+420>>2]=j>>7;i=ji(c[i>>2]|0,j)|0;n=s+(f*440|0)+416|0;c[n>>2]=i;do if(!(c[r>>2]&8192)){if((i|0)<4096)c[n>>2]=4096}else{m=+(i|0);i=c[s+(f*440|0)+40>>2]|0;k=+ii(83,i,0,0.0)*4096.0;if(m>2]=~~k;break}k=+ii(48,i,0,0.0)*4096.0;if(m>k)c[n>>2]=~~k}while(0);ei(d,f,j);if(!(c[r>>2]&65536)){l=w;return}j=c[s+(f*440|0)+376>>2]|0;i=(O(j,p)|0)>>8;i=(c[q>>2]&8|0)==0?j:i;j=c[s+(f*440|0)+380>>2]|0;if((i|0)>254)i=255;else{Rj(c[d+1496>>2]|0,i,j,t,u,v);Yh(d,f,176,c[t>>2]|0);Yh(d,f,177,c[u>>2]|0);Yh(d,f,178,c[v>>2]|0);Yh(d,f,3,j)}Yh(d,f,2,i);l=w;return}function Bi(a,d,f){a=a|0;d=d|0;f=f|0;var g=0,h=0,i=0,j=0,k=0;k=l;l=l+16|0;i=c[a+624>>2]|0;g=(xm(a,c[i+(d*440|0)+44>>2]|0)|0)+200|0;h=i+(d*440|0)+98|0;j=wj(g,e[h>>1]|0,32,k)|0;b[h>>1]=xj(g,e[h>>1]|0,(c[i+(d*440|0)+8>>2]|0)>>>1&1|(f|0)==2,c[a+2832>>2]&134217728)|0;f=i+(d*440|0)+144|0;if(!(c[i+(d*440|0)>>2]&524288))g=-128;else{g=qj(f,512)|0;rj(f);g=g+-128|0}f=c[i+(d*440|0)+344>>2]|0;h=f+-128|0;if(c[a+1500>>2]&4|0){j=0;h=(j|0)<-128;g=(j|0)<127;j=g?j:127;j=h?-128:j;h=j+128|0;i=i+(d*440|0)+432|0;c[i>>2]=h;Xh(a,d,j);l=k;return}j=g+f+((O(128-((h|0)>-1?h:128-f|0)|0,j+-32|0)|0)/32|0)|0;j=(O(c[a+1508>>2]|0,j)|0)/100|0;h=(j|0)<-128;g=(j|0)<127;j=g?j:127;j=h?-128:j;h=j+128|0;i=i+(d*440|0)+432|0;c[i>>2]=h;Xh(a,d,j);l=k;return}function Ci(a,b,d){a=a|0;b=b|0;d=d|0;var e=0.0,f=0.0,g=0,i=0.0,j=0,k=0,l=0,m=0,n=0,o=0;o=c[a+624>>2]|0;l=o+(b*440|0)|0;m=((d|0)%(c[a+16>>2]|0)|0|0)==0;if(m?(c[a+2832>>2]&128|0)==0:0){d=c[l>>2]|0;n=14}else{d=c[l>>2]|0;if(!((d&8|0)==0?!(c[o+(b*440|0)+4>>2]&8|0):0)){k=o+(b*440|0)+24|0;h[k>>3]=+h[k>>3]+ +(c[o+(b*440|0)+288>>2]|0)}if(!((d&4|0)==0?(c[o+(b*440|0)+4>>2]&4|0)==0:0))n=9;do if((n|0)==9){g=o+(b*440|0)+312|0;j=o+(b*440|0)+320|0;i=+(c[o+(b*440|0)+324>>2]|0);k=o+(b*440|0)+24|0;f=+h[k>>3];if((c[j>>2]|0)>0){i=f+i;h[k>>3]=i;f=+h[g>>3];if(!(i>=f))break}else{i=f-i;h[k>>3]=i;f=+h[g>>3];if(!(i<=f))break}h[k>>3]=f;c[j>>2]=0;d=d&-5;c[l>>2]=d;l=o+(b*440|0)+4|0;c[l>>2]=c[l>>2]&-5}while(0);if(m)n=14}if((n|0)==14){g=o+(b*440|0)+24|0;if(d&128|0)h[g>>3]=+h[o+(b*440|0)+296>>3]+ +h[g>>3];if(d&32768|0){l=o+(b*440|0)+12|0;m=(c[l>>2]|0)+(c[o+(b*440|0)+388>>2]|0)|0;c[l>>2]=m;h[g>>3]=+ii(m,c[o+(b*440|0)+40>>2]|0,c[a+2832>>2]&4096,+h[o+(b*440|0)+32>>3])}}d=c[a+2832>>2]|0;do if(!(d&4096)){g=o+(b*440|0)+24|0;f=+h[g>>3];if(d&8192){d=c[o+(b*440|0)+40>>2]|0;e=+ii(83,d,0,0.0);if(f>3]=e;n=28;break}e=+ii(48,d,0,0.0);if(f>e){h[g>>3]=e;n=28}else{e=f;n=28}}else{e=f;n=28}}else{d=o+(b*440|0)+24|0;f=+h[d>>3];if(f<0.0){h[d>>3]=0.0;break}if(f>7680.0){h[d>>3]=7680.0;n=o+(b*440|0)+184|0;a=c[n>>2]|0;a=a+1|0;b=o+(b*440|0)+180|0;b=c[b>>2]|0;b=(a|0)%(b|0)|0;c[n>>2]=b;return}else{e=f;n=28}}while(0);if((n|0)==28?!(e<1.0):0){n=o+(b*440|0)+184|0;a=c[n>>2]|0;a=a+1|0;b=o+(b*440|0)+180|0;b=c[b>>2]|0;b=(a|0)%(b|0)|0;c[n>>2]=b;return}c[o+(b*440|0)+80>>2]=0;n=o+(b*440|0)+184|0;a=c[n>>2]|0;a=a+1|0;b=o+(b*440|0)+180|0;b=c[b>>2]|0;b=(a|0)%(b|0)|0;c[n>>2]=b;return}function Di(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;e=c[a+624>>2]|0;if(!(c[e+(b*440|0)>>2]&2))return;f=e+(b*440|0)+344|0;e=(c[f>>2]|0)+(c[(((d|0)%(c[a+16>>2]|0)|0|0)==0?e+(b*440|0)+352|0:e+(b*440|0)+348|0)>>2]|0)|0;c[f>>2]=e;if((e|0)<0){c[f>>2]=0;return}if((e|0)<=255)return;c[f>>2]=255;return}function Ei(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;g=c[b+180>>2]|0;h=c[d+56>>2]|0;e=d+364|0;f=(c[e>>2]|0)+(c[4336+(c[d+360>>2]<<2)>>2]|0)|0;c[e>>2]=f;i=c[g+(h*52|0)+44>>2]|0;if(!((f|0)>127&(i&2|0)!=0))return;c[e>>2]=0;f=c[g+(h*52|0)+36>>2]|0;if(c[b+1280>>2]&8|0)return;d=d+368|0;e=c[d>>2]|0;e=(e|0)<((c[g+(h*52|0)+40>>2]|0)-f|0)?e+1|0:0;c[d>>2]=e;if(i&1|0)return;i=(c[g+(h*52|0)+48>>2]|0)+(e+f)|0;a[i>>0]=~a[i>>0];return}function Fi(a,b){a=a|0;b=b|0;if((c[a+948>>2]|0)>(b|0)){a=c[a+628+(b<<2)>>2]|0;return a|0}if((c[a+952>>2]|0)<=(b|0)){a=0;return a|0}b=Oh(a,b)|0;if((b|0)<0){a=0;return a|0}a=c[a+628+(b<<2)>>2]|0;return a|0}function Gi(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;n=c[b+624>>2]|0;j=a[e+3>>0]|0;switch(j<<24>>24){case 15:{h=a[e+4>>0]|0;if((h&255)<32){i=h;m=4}break}case -93:{i=a[e+4>>0]|0;m=4;break}default:{}}if((m|0)==4?i<<24>>24:0)c[b+16>>2]=i&255;h=a[e+5>>0]|0;switch(h<<24>>24){case 15:{i=a[e+6>>0]|0;if((i&255)<32){k=i;m=9}break}case -93:{k=a[e+6>>0]|0;m=9;break}default:{}}if((m|0)==9?k<<24>>24:0)c[b+16>>2]=k&255;if(!((j<<24>>24==14?(l=d[e+4>>0]|0,(l&240|0)==208):0)?(g=l&15,(g|0)!=0):0)){if(h<<24>>24!=14){e=0;return e|0}g=d[e+6>>0]|0;if((g&240|0)!=208){e=0;return e|0}g=g&15;if(!g){e=0;return e|0}}c[n+(f*440|0)+64>>2]=g+1;h=n+(f*440|0)+404|0;i=e;l=i;l=d[l>>0]|d[l+1>>0]<<8|d[l+2>>0]<<16|d[l+3>>0]<<24;i=i+4|0;i=d[i>>0]|d[i+1>>0]<<8|d[i+2>>0]<<16|d[i+3>>0]<<24;g=h;m=g;a[m>>0]=l;a[m+1>>0]=l>>8;a[m+2>>0]=l>>16;a[m+3>>0]=l>>24;g=g+4|0;a[g>>0]=i;a[g+1>>0]=i>>8;a[g+2>>0]=i>>16;a[g+3>>0]=i>>24;g=a[e+1>>0]|0;i=g<<24>>24==0;if(!i)c[n+(f*440|0)+412>>2]=g&255;g=c[b+2832>>2]|0;if(!(g&33554432)){e=1;return e|0}if(!(a[e>>0]|0))a[h>>0]=(c[n+(f*440|0)+16>>2]|0)+1;if(!((g&67108864|0)==0&i)){e=1;return e|0}a[n+(f*440|0)+405>>0]=c[n+(f*440|0)+48>>2];e=1;return e|0}function Hi(e){e=e|0;var f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;if((c[e+8140>>2]|0)<1)return;p=c[e+1688>>2]|0;f=c[e+4>>2]|0;if(!((f|0)>-1?(f|0)<(c[e+1708>>2]|0):0))f=0;c[6316]=f;o=d[e+2504+f>>0]|0;c[6317]=o;n=(o|0)<(c[e+1680>>2]|0);if(n)m=c[c[(c[e+1720>>2]|0)+(o<<2)>>2]>>2]|0;else m=0;c[6319]=m;l=c[e+8>>2]|0;c[6318]=l;c[6320]=c[e+12>>2];c[6321]=c[e+16>>2];c[6322]=c[e+20>>2];f=c[e+52>>2]|0;c[6324]=c[e+368+(f<<4)>>2];c[6325]=~~(+h[e+40>>3]*1.0e3);c[6323]=~~+h[e+32>>3];c[6326]=c[e+1520>>2];c[6328]=24585;g=c[e+1532>>2]|0;c[6327]=g;i=~c[e+1500>>2];if(i&5|0)c[6327]=g<<(i>>>2&1)<<(i&1);c[6329]=c[e+320>>2];c[6330]=c[e+48>>2];c[6331]=c[e+952>>2];c[6332]=c[e+956>>2];c[6333]=f;j=c[e+624>>2]|0;if(!((j|0)!=0&(p|0)>0))return;k=e+1720|0;i=e+1724|0;g=0;do{a[25336+(g*24|0)+10>>0]=c[j+(g*440|0)+16>>2];b[25336+(g*24|0)+8>>1]=c[j+(g*440|0)+420>>2];c[25336+(g*24|0)>>2]=c[j+(g*440|0)+416>>2];c[25336+(g*24|0)+4>>2]=c[j+(g*440|0)+424>>2];a[25336+(g*24|0)+11>>0]=c[j+(g*440|0)+44>>2];a[25336+(g*24|0)+12>>0]=c[j+(g*440|0)+56>>2];a[25336+(g*24|0)+13>>0]=(c[j+(g*440|0)+428>>2]|0)>>>4;a[25336+(g*24|0)+14>>0]=c[j+(g*440|0)+432>>2];a[25336+(g*24|0)+15>>0]=0;f=25336+(g*24|0)+16|0;e=f;c[e>>2]=0;c[e+4>>2]=0;if(!((l|0)>=(m|0)|n^1)?(q=c[(c[i>>2]|0)+(c[(c[(c[k>>2]|0)+(o<<2)>>2]|0)+4+(g<<2)>>2]<<2)>>2]|0,(l|0)<(c[q>>2]|0)):0){r=q+4+(l<<3)|0;s=r;r=r+4|0;r=d[r>>0]|d[r+1>>0]<<8|d[r+2>>0]<<16|d[r+3>>0]<<24;e=f;c[e>>2]=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;c[e+4>>2]=r}g=g+1|0}while((g|0)!=(p|0));return}function Ii(a){a=a|0;var b=0;if((c[a+8140>>2]|0)<1)return;b=a+2776|0;c[6718]=c[b>>2];c[6719]=c[b+4>>2];c[6720]=c[b+8>>2];c[6721]=c[b+12>>2];c[6723]=a+1552;c[6724]=c[a+2772>>2];c[6725]=c[a+7968>>2];c[6726]=a+7972;c[6722]=c[a+2820>>2];return}function Ji(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;f=a[d+1>>0]|0;if(f<<24>>24)c[(c[b+624>>2]|0)+(e*440|0)+48>>2]=f&255;if((c[b+1688>>2]|0)<=(e|0)){Ki(b,d,e);return}switch(c[b+2836>>2]|0){case 0:{Li(b,d,e);return}case 1:{Mi(b,d,e);return}case 2:{Ni(b,d,e);return}case 3:{Oi(b,d,e)|0;return}case 4:{Pi(b,d,e);return}default:{Li(b,d,e);return}}}function Ki(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;o=c[b+624>>2]|0;p=o+(f*440|0)|0;c[p>>2]=0;q=e+1|0;g=a[q>>0]|0;if(!(g<<24>>24))return;g=g&255;m=g+-1|0;c[p>>2]=2048;c[o+(f*440|0)+72>>2]=65536;c[o+(f*440|0)+4>>2]=0;n=o+(f*440|0)+92|0;c[n>>2]=0;k=o+(f*440|0)+8|0;i=c[k>>2]|0;c[k>>2]=i&-3;c[o+(f*440|0)+44>>2]=m;j=c[b+1692>>2]|0;if((g|0)>(j|0))h=(g|0)<=((c[b+8124>>2]|0)+j|0)&1;else h=0;c[p>>2]=67584;g=a[e>>0]|0;if(g<<24>>24==-127){c[k>>2]=i|2;return}l=(g&255)+-1|0;c[o+(f*440|0)+16>>2]=l;c[k>>2]=i&-7;if(!h){i=a[(c[b+1728>>2]|0)+(m*764|0)+512+(l<<1)+1>>0]|0;g=Qi(b,m,l)|0;i=i+l+(c[g+12>>2]|0)|0;h=c[g+40>>2]|0;h=(c[(c[b+1732>>2]|0)+(h*52|0)+32>>2]|0)==0?-1:h;if((h|0)>-1?(h|0)<(c[b+1696>>2]|0):0){ai(b,f,m,h,i,0,0,0)|0;c[o+(f*440|0)+56>>2]=h}}else{g=c[(c[b+8132>>2]|0)+((m-j|0)*764|0)+756>>2]|0;if(!g)return;i=(c[g+12>>2]|0)+l|0;h=c[g+40>>2]|0;h=(c[(c[b+8136>>2]|0)+(h*52|0)+32>>2]|0)==0?-1:h;if((h|0)>-1?(h|0)<(c[b+8128>>2]|0):0){l=(c[b+1696>>2]|0)+h|0;ai(b,f,m,l,i,0,0,0)|0;c[o+(f*440|0)+56>>2]=l}}Ri(i,g,p);Ti(b,i,g,p,0);if((g|0)!=0&(a[q>>0]|0)!=0)Si(b,p,0);c[o+(f*440|0)+80>>2]=(d[e+2>>0]|0)+-1;c[p>>2]=c[p>>2]|4096;c[o+(f*440|0)+12>>2]=i;fi(b,f,c[n>>2]|0);return}function Li(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;o=c[b+624>>2]|0;p=o+(f*440|0)|0;c[p>>2]=0;m=e+3|0;switch(a[m>>0]|0){case 122:case 5:case 3:{g=3;break}default:switch(a[e+5>>0]|0){case 122:case 5:case 3:{g=3;break}default:n=0}}if((g|0)==3)n=1;l=e+1|0;g=a[l>>0]|0;do if(!(g<<24>>24)){h=0;k=0}else{g=(g&255)+-1|0;c[p>>2]=2048;c[o+(f*440|0)+72>>2]=65536;c[o+(f*440|0)+4>>2]=0;c[o+(f*440|0)+92>>2]=0;k=o+(f*440|0)+8|0;c[k>>2]=c[k>>2]&-4;if(g>>>0<(c[b+1692>>2]|0)>>>0?(c[(c[b+1728>>2]|0)+(g*764|0)+36>>2]|0)>0:0){if(!n){c[o+(f*440|0)+44>>2]=g;h=0;k=1;break}g=Qi(b,g,d[e>>0]|0)|0;if(!g){h=0;k=1;break}c[o+(f*440|0)+80>>2]=c[g>>2];h=0;k=0;break}Vh(b,f);h=1;k=1}while(0);g=a[e>>0]|0;do if(g<<24>>24){c[p>>2]=c[p>>2]|65536;if(g<<24>>24==-127){h=o+(f*440|0)+8|0;c[h>>2]=c[h>>2]|2;h=-1;k=0;break}if(!n){g=(g&255)+-1|0;c[o+(f*440|0)+16>>2]=g;j=o+(f*440|0)+8|0;c[j>>2]=c[j>>2]&-5;j=c[o+(f*440|0)+44>>2]|0;i=Qi(b,j,g)|0;if(!((h|0)==0&(i|0)!=0)){c[p>>2]=0;h=-1;k=0;break}h=(c[i+12>>2]|0)+g+(a[(c[b+1728>>2]|0)+(j*764|0)+512+(g<<1)+1>>0]|0)|0;g=c[i+40>>2]|0;g=(c[(c[b+1732>>2]|0)+(g*52|0)+32>>2]|0)==0?-1:g;if((g|0)>-1?(g|0)<(c[b+1696>>2]|0):0){ai(b,f,j,g,h,0,0,0)|0;c[o+(f*440|0)+56>>2]=g}}else h=-1}else h=-1;while(0);j=Qi(b,c[o+(f*440|0)+44>>2]|0,c[o+(f*440|0)+16>>2]|0)|0;Ri(h,j,p);if((j|0)!=0&(a[l>>0]|0)!=0)Si(b,p,0);g=a[e+2>>0]|0;if(g<<24>>24){c[o+(f*440|0)+80>>2]=(g&255)+-1;c[p>>2]=c[p>>2]|4096}nk(b,p,f,a[e>>0]|0,a[e+5>>0]|0,a[e+6>>0]|0,1);nk(b,p,f,a[e>>0]|0,a[m>>0]|0,a[e+4>>0]|0,0);Ti(b,h,j,p,n);g=c[p>>2]|0;i=g&4096;if(!j)return;if((h|0)>-1){c[o+(f*440|0)+12>>2]=h;h=o+(f*440|0)+92|0;fi(b,f,c[h>>2]|0);g=c[p>>2]|0;if(g&256|0?c[b+28>>2]&2|0:0)c[h>>2]=c[h>>2]<<1;g=g&-257;c[p>>2]=g}if((k|0)==0|(i|0)!=0)return;c[o+(f*440|0)+80>>2]=c[j>>2];c[p>>2]=g|4096;return}function Mi(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;t=c[b+624>>2]|0;u=t+(e*440|0)|0;c[u>>2]=0;j=a[d>>0]|0;k=j&255;f=a[d+1>>0]|0;h=f&255;r=d+3|0;switch(a[r>>0]|0){case 122:case 5:case 3:{m=3;break}default:switch(a[d+5>>0]|0){case 122:case 5:case 3:{m=3;break}default:s=0}}if((m|0)==3)s=1;l=f<<24>>24==0;do if(!l){o=h+-1|0;g=c[b+1692>>2]|0;if(!(o>>>0>>0?(c[(c[b+1728>>2]|0)+(o*764|0)+36>>2]|0)>0:0))h=0;c[u>>2]=2048;c[t+(e*440|0)+72>>2]=65536;c[t+(e*440|0)+4>>2]=0;f=t+(e*440|0)+8|0;c[f>>2]=c[f>>2]&-4;f=h+-1|0;if(f>>>0>>0?(c[(c[b+1728>>2]|0)+(f*764|0)+36>>2]|0)>0:0){if(s|0){f=67584;i=0;g=1;m=13;break}c[t+(e*440|0)+44>>2]=f;f=67584;i=0;g=1;m=13;break}c[u>>2]=0;if(!s){f=65536;i=1;g=1;m=13}else{k=0;n=1;j=1}}else{f=65536;i=0;g=0;m=13}while(0);do if((m|0)==13)if(!(j<<24>>24)){k=0;n=i;j=g}else{c[u>>2]=f;if(j<<24>>24==-127){f=t+(e*440|0)+8|0;c[f>>2]=c[f>>2]|2;f=129;g=0}else f=(s|0)==0?k:0;if(l){o=(c[t+(e*440|0)+48>>2]|0)+-1|0;if(o>>>0<(c[b+1692>>2]|0)>>>0?((i|0)==0?(c[(c[b+1728>>2]|0)+(o*764|0)+36>>2]|0)>0:0):0){k=f;n=0;j=g;break}}else if(!i){k=f;n=0;j=g;break}Vh(b,e);k=f;n=1;j=g}while(0);o=(h|0)!=0;do if(o){if((k|0)==0|(k|0)>128){f=Qi(b,c[t+(e*440|0)+52>>2]|0,c[t+(e*440|0)+16>>2]|0)|0;if(!f)break;c[t+(e*440|0)+80>>2]=c[f>>2];c[t+(e*440|0)+344>>2]=c[f+8>>2]}else{g=c[t+(e*440|0)+44>>2]|0;f=Qi(b,g,k+-1|0)|0;if(!f)f=0;else{m=c[f>>2]|0;c[t+(e*440|0)+344>>2]=c[f+8>>2];f=m}c[t+(e*440|0)+80>>2]=f;c[t+(e*440|0)+52>>2]=g}c[u>>2]=c[u>>2]|4096}while(0);do if(k>>>0<122&(k|0)>0){k=k+-1|0;m=t+(e*440|0)+16|0;c[m>>2]=k;c[t+(e*440|0)+72>>2]=65536;h=t+(e*440|0)+8|0;f=c[h>>2]|0;c[h>>2]=f&-5;i=c[b+1728>>2]|0;g=t+(e*440|0)+44|0;l=c[g>>2]|0;if(!(c[i+(l*764|0)+44>>2]&1))c[h>>2]=f&-8;f=Qi(b,l,k)|0;if(!((n|0)==0&(f|0)!=0)){c[u>>2]=0;f=m;i=-1;j=0;break}h=(c[f+12>>2]|0)+k+(a[i+(l*764|0)+512+(k<<1)+1>>0]|0)|0;f=c[f+40>>2]|0;f=(c[(c[b+1732>>2]|0)+(f*52|0)+32>>2]|0)==0?-1:f;if((f|0)>-1?(f|0)<(c[b+1696>>2]|0):0){ai(b,e,l,f,h,0,0,0)|0;c[t+(e*440|0)+56>>2]=f;f=m;i=h}else{f=m;i=h}}else{g=t+(e*440|0)+44|0;f=t+(e*440|0)+16|0;i=-1}while(0);h=Qi(b,c[g>>2]|0,c[f>>2]|0)|0;Ri(i,h,u);if(o&(h|0)!=0)Si(b,u,0);f=a[d+2>>0]|0;if(f<<24>>24?(c[t+(e*440|0)+80>>2]=(f&255)+-1,c[u>>2]=c[u>>2]|4096,q=t+(e*440|0)+8|0,p=c[q>>2]|0,p&4|0):0){c[t+(e*440|0)+72>>2]=65536;c[q>>2]=p&-4}f=t+(e*440|0)+92|0;c[f>>2]=0;nk(b,u,e,a[d>>0]|0,a[d+5>>0]|0,a[d+6>>0]|0,1);nk(b,u,e,a[d>>0]|0,a[r>>0]|0,a[d+4>>0]|0,0);Ti(b,i,h,u,s);g=c[u>>2]&4096;if(!h)return;do if((i|0)>-1){c[t+(e*440|0)+12>>2]=i;f=c[f>>2]|0;if((f|0)<(c[(c[b+1732>>2]|0)+((c[h+40>>2]|0)*52|0)+32>>2]|0)){fi(b,e,f);break}else{Vh(b,e);break}}while(0);if((j|0)==0|(g|0)!=0)return;c[t+(e*440|0)+80>>2]=c[h>>2];c[u>>2]=c[u>>2]|4096;return}function Ni(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;o=c[b+624>>2]|0;p=o+(f*440|0)|0;c[p>>2]=0;n=e+3|0;switch(a[n>>0]|0){case 122:case 5:case 3:{g=3;break}default:switch(a[e+5>>0]|0){case 122:case 5:case 3:{g=3;break}default:h=0}}if((g|0)==3)h=1;l=(Th(b,f)|0)<0;m=e+1|0;g=a[m>>0]|0;if(l)h=(c[o+(f*440|0)+44>>2]|0)==((g&255)+-1|0)?h:0;do if(!(g<<24>>24)){g=65536;j=0;k=0}else{i=(g&255)+-1|0;c[p>>2]=2048;c[o+(f*440|0)+72>>2]=65536;c[o+(f*440|0)+4>>2]=0;c[o+(f*440|0)+92>>2]=0;l=o+(f*440|0)+8|0;c[l>>2]=c[l>>2]&-4;if(i>>>0<(c[b+1692>>2]|0)>>>0?(c[(c[b+1728>>2]|0)+(i*764|0)+36>>2]|0)>0:0){g=o+(f*440|0)+44|0;if((c[g>>2]|0)==(i|0)){g=67584;j=0;k=1;break}if(!h){c[g>>2]=i;g=67584;j=1;k=1;break}g=Qi(b,i,d[e>>0]|0)|0;if(!g){g=67584;j=1;k=1;break}c[o+(f*440|0)+80>>2]=c[g>>2];g=67584;j=1;k=0;break}c[p>>2]=0;g=65536;j=0;k=0}while(0);i=a[e>>0]|0;do if(i<<24>>24){c[p>>2]=g;g=i&255;if(i<<24>>24==-127){i=o+(f*440|0)+8|0;c[i>>2]=c[i>>2]|2;i=-1;k=0;break}if(h|0){if(!j){i=-1;break}c[o+(f*440|0)+92>>2]=0;i=-1;break}g=g+-1|0;c[o+(f*440|0)+16>>2]=g;l=o+(f*440|0)+8|0;c[l>>2]=c[l>>2]&-5;l=c[o+(f*440|0)+44>>2]|0;j=Qi(b,l,g)|0;if(!j){c[p>>2]=0;i=-1;k=0;break}i=(c[j+12>>2]|0)+g+(a[(c[b+1728>>2]|0)+(l*764|0)+512+(g<<1)+1>>0]|0)|0;g=c[j+40>>2]|0;g=(c[(c[b+1732>>2]|0)+(g*52|0)+32>>2]|0)==0?-1:g;if((g|0)>-1?(g|0)<(c[b+1696>>2]|0):0){ai(b,f,l,g,i,0,0,0)|0;c[o+(f*440|0)+56>>2]=g}}else i=-1;while(0);j=Qi(b,c[o+(f*440|0)+44>>2]|0,c[o+(f*440|0)+16>>2]|0)|0;Ri(i,j,p);if((j|0)!=0&(a[m>>0]|0)!=0)Si(b,p,0);g=a[e+2>>0]|0;if(g<<24>>24){c[o+(f*440|0)+80>>2]=(g&255)+-1;c[p>>2]=c[p>>2]|4096}nk(b,p,f,a[e>>0]|0,a[e+5>>0]|0,a[e+6>>0]|0,1);nk(b,p,f,a[e>>0]|0,a[n>>0]|0,a[e+4>>0]|0,0);Ti(b,i,j,p,h);g=c[p>>2]&4096;if(!j)return;if((i|0)>-1){c[o+(f*440|0)+12>>2]=i;fi(b,f,c[o+(f*440|0)+92>>2]|0)}if(!((k|0)==0|(g|0)!=0)){c[o+(f*440|0)+80>>2]=c[j>>2];c[p>>2]=c[p>>2]|4096}if(!(c[b+2832>>2]&16))return;if(!(c[p>>2]&4096))return;f=o+(f*440|0)+80|0;p=O(c[b+320>>2]|0,c[f>>2]|0)|0;c[f>>2]=(p|0)/(c[b+2820>>2]|0)|0;return}function Oi(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;v=b+624|0;E=c[v>>2]|0;F=E+(e*440|0)|0;s=a[d>>0]|0;i=a[d+1>>0]|0;k=a[d+2>>0]|0;l=a[d+3>>0]|0;m=a[d+4>>0]|0;n=a[d+5>>0]|0;o=a[d+6>>0]|0;if(!(i<<24>>24))if(s<<24>>24!=0?(g=E+(e*440|0)+412|0,f=c[g>>2]|0,(f|0)!=0):0){c[g>>2]=0;i=f&255}else i=0;else c[E+(e*440|0)+412>>2]=0;c[F>>2]=0;r=s&255;C=E+(e*440|0)+44|0;q=c[C>>2]|0;f=i&255;if(i<<24>>24){d=(f|0)>(c[b+1692>>2]|0);if((s&255)<122&((s<<24>>24==0|d)^1)?(j=f+-1|0,!d):0){D=a[(c[b+1728>>2]|0)+(j*764|0)+512+(r+-1<<1)>>0]|0;if(D<<24>>24!=-1?(D&255|0)<(c[b+1696>>2]|0):0)w=11;else{D=0;i=0;A=0;B=0;z=0;n=0;o=0;f=0}}else w=11}else{i=0;w=11}a:do if((w|0)==11){switch(l<<24>>24){case 122:case 5:case 3:break;default:switch(n<<24>>24){case 122:case 5:case 3:break;default:{j=q;D=s;A=k;B=l;z=m;f=0;break a}}}j=q;D=s;A=k;B=l;z=m;f=1}while(0);y=E+(e*440|0)+8|0;d=c[y>>2]|0;t=b+2832|0;g=c[t>>2]|0;if(!(g&32768)){x=(Th(b,e)|0)<0;x=x?0:f}else x=f;u=i<<24>>24!=0;b:do if(u){m=(i&255)+-1|0;f=(x|0)!=0;if((d&3|0)!=0&f&(q|0)==(m|0)){l=0;p=0}else{c[F>>2]=2048;l=2048;p=1}c[E+(e*440|0)+4>>2]=0;if(m>>>0<(c[b+1692>>2]|0)>>>0?(c[(c[b+1728>>2]|0)+(m*764|0)+36>>2]|0)>0:0){do if(!(s<<24>>24))if((q|0)==(m|0)){c[F>>2]=2048;l=2048;k=r;f=0;m=p;p=1;w=31;break b}else{k=(c[E+(e*440|0)+16>>2]|0)+1|0;break}else k=r;while(0);if((q|0)==(m|0)){f=0;m=p;w=31;break}if(!f){j=m;f=1;m=p;w=31;break}if(g&4194304|0){f=0;m=p;w=31;break}f=Qi(b,m,k)|0;if(!f){j=m;f=1;m=p;w=31;break}c[E+(e*440|0)+80>>2]=c[f>>2];j=m;f=1;m=p;p=0;w=31;break}c[F>>2]=0;k=-1;f=p;d=0;w=51}else{l=0;k=r;f=0;m=0;p=0;w=31}while(0);c:do if((w|0)==31)if(!k){k=-1;f=m;d=p;w=51}else{c[F>>2]=l|65536;switch(k|0){case 131:{c[y>>2]=d|1;k=-1;f=0;d=0;w=51;break c}case 130:{c[y>>2]=d|12;h[E+(e*440|0)+24>>3]=0.0;Vh(b,e);k=-1;f=m;d=p;w=51;break c}case 129:{c[y>>2]=d|2;if(!(g&4194304)){k=-1;f=0;d=0;w=51;break c}c[y>>2]=d|6;k=-1;f=0;d=0;w=51;break c}default:{if(x){if(!(d&4|f)){k=-1;f=m;d=p;w=53;break c}d=d&-4;c[F>>2]=67584;c[y>>2]=d}if((k|0)<1|k>>>0>121){k=-1;f=m;d=p;w=51;break c}f=k+-1|0;c[E+(e*440|0)+16>>2]=f;c[y>>2]=d&-5;g=Qi(b,j,f)|0;if(!g){c[F>>2]=0;k=-1;f=m;d=0;w=51;break c}k=(c[g+12>>2]|0)+f+(a[(c[b+1728>>2]|0)+(j*764|0)+512+(f<<1)+1>>0]|0)|0;d=c[g+40>>2]|0;if(!((d|0)<(c[b+1696>>2]|0)?(c[(c[b+1732>>2]|0)+(d*52|0)+32>>2]|0)!=0:0))d=-1;f=ai(b,e,j,d,k,c[g+44>>2]|0,c[g+48>>2]|0,c[g+52>>2]|0)|0;if((f|0)<0){b=-1;return b|0}if((f|0)!=(e|0)){Ui(b,f,e);c[(c[v>>2]|0)+(f*440|0)>>2]=0}if((d|0)<=-1){f=m;d=p;w=51;break c}c[E+(e*440|0)+56>>2]=d;f=m;d=p;w=51;break c}}}while(0);if((w|0)==51)if(!x){m=f;l=d}else{g=c[t>>2]|0;w=53}if((w|0)==53)if(i<<24>>24==0|(g&4194304|0)==0){m=f;l=d}else{Si(b,F,0);m=f;l=d}if(i<<24>>24?c[y>>2]&16|0:0)Si(b,F,1);if(j>>>0<(c[b+1692>>2]|0)>>>0?(c[(c[b+1728>>2]|0)+(j*764|0)+36>>2]|0)>0:0){if((c[C>>2]|0)!=(j|0))Si(b,F,1);c[C>>2]=j}g=Qi(b,c[C>>2]|0,c[E+(e*440|0)+16>>2]|0)|0;Ri(k,g,F);i=(g|0)==0;do if(!i)if((k|0)>-1){d=c[g+8>>2]|0;if((d|0)>-1)c[E+(e*440|0)+344>>2]=d;Si(b,F,(c[y>>2]|0)>>>3&1);c[y>>2]=c[y>>2]&-9;break}else{if(!u)break;d=c[g+8>>2]|0;if((d|0)<=-1)break;c[E+(e*440|0)+344>>2]=d;break}while(0);if(A<<24>>24){c[E+(e*440|0)+80>>2]=(A&255)+-1;c[F>>2]=c[F>>2]|4096}f=E+(e*440|0)+92|0;c[f>>2]=0;nk(b,F,e,D,B,z,0);nk(b,F,e,D,n,o,1);Ti(b,k,g,F,x);d=c[F>>2]&4096;if(i){b=0;return b|0}if((k|0)>-1){c[E+(e*440|0)+12>>2]=k;fi(b,e,c[f>>2]|0)}if(m|0){c[y>>2]=c[y>>2]&-4;c[E+(e*440|0)+72>>2]=65536}if((l|0)==0|(d|0)!=0){b=0;return b|0}c[E+(e*440|0)+80>>2]=c[g>>2];c[F>>2]=c[F>>2]|4096;b=0;return b|0}function Pi(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;r=c[b+624>>2]|0;s=r+(e*440|0)|0;c[s>>2]=0;p=d+3|0;switch(a[p>>0]|0){case 5:case 3:{q=1;break}default:q=0}o=d+1|0;m=a[o>>0]|0;f=m&255;if(m<<24>>24){m=a[d>>0]|0;g=m&255;if(!(m<<24>>24)){g=-1;k=1}else{f=f+-1|0;c[s>>2]=2048;c[r+(e*440|0)+72>>2]=65536;c[r+(e*440|0)+92>>2]=0;m=r+(e*440|0)+8|0;c[m>>2]=c[m>>2]&-4;do if(f>>>0<(c[b+1692>>2]|0)>>>0?(c[(c[b+1728>>2]|0)+(f*764|0)+36>>2]|0)>0:0){if(!q){c[r+(e*440|0)+44>>2]=f;f=0;g=1;break}f=Qi(b,f,g)|0;if(!f){f=0;g=1}else{c[r+(e*440|0)+80>>2]=c[f>>2];f=0;g=0}}else i=11;while(0);if((i|0)==11){Vh(b,e);f=1;g=1}k=c[r+(e*440|0)+400>>2]|0;c[k+48>>2]=0;c[k+52>>2]=0;k=g;i=13}}else{f=0;k=0;i=13}a:do if((i|0)==13){g=a[d>>0]|0;if(!(g<<24>>24))g=-1;else{c[s>>2]=c[s>>2]|65536;switch(g<<24>>24){case -127:{g=r+(e*440|0)+8|0;c[g>>2]=c[g>>2]|2;g=-1;k=0;break a}case -126:{g=r+(e*440|0)+8|0;c[g>>2]=c[g>>2]|4;h[r+(e*440|0)+24>>3]=0.0;Vh(b,e);g=-1;break a}default:{if(q|0){g=-1;break a}m=c[r+(e*440|0)+44>>2]|0;if(m>>>0>=(c[b+1692>>2]|0)>>>0){g=-1;break a}l=c[b+1728>>2]|0;i=c[l+(m*764|0)+36>>2]|0;if((i|0)<=0){g=-1;break a}j=(g&255)+-1|0;c[r+(e*440|0)+16>>2]=j;g=r+(e*440|0)+8|0;c[g>>2]=c[g>>2]&-5;g=r+(e*440|0)+32|0;h[g>>3]=0.0;if(((((i|0)!=1?(n=c[l+(m*764|0)+760>>2]|0,n|0):0)?(c[n>>2]|0)==133303461:0)?(c[n+4>>2]|0)==0:0)?(c[n+8>>2]|0)==0:0)h[g>>3]=2.0;i=Qi(b,m,j)|0;if(!((f|0)==0&(i|0)!=0)){c[s>>2]=0;g=-1;k=0;break a}g=(c[i+12>>2]|0)+j+(a[l+(m*764|0)+512+(j<<1)+1>>0]|0)|0;f=c[i+40>>2]|0;f=(c[(c[b+1732>>2]|0)+(f*52|0)+32>>2]|0)==0?-1:f;if((f|0)<=-1)break a;if((f|0)>=(c[b+1696>>2]|0))break a;ai(b,e,m,f,g,0,0,0)|0;c[r+(e*440|0)+56>>2]=f;break a}}}}while(0);j=Qi(b,c[r+(e*440|0)+44>>2]|0,c[r+(e*440|0)+16>>2]|0)|0;i=r+(e*440|0)+40|0;f=c[i>>2]|0;Ri(g,j,s);if(a[o>>0]|0){if(j|0)Si(b,s,0)}else c[i>>2]=f;f=a[d+2>>0]|0;if(f<<24>>24){c[r+(e*440|0)+80>>2]=(f&255)+-1;c[s>>2]=c[s>>2]|4096}nk(b,s,e,a[d>>0]|0,a[d+5>>0]|0,a[d+6>>0]|0,1);nk(b,s,e,a[d>>0]|0,a[p>>0]|0,a[d+4>>0]|0,0);Ti(b,g,j,s,q);f=c[s>>2]&4096;if(!j)return;if((g|0)>-1){c[r+(e*440|0)+12>>2]=g;fi(b,e,c[r+(e*440|0)+92>>2]|0)}if((k|0)==0|(f|0)!=0)return;c[r+(e*440|0)+80>>2]=c[j>>2];c[s>>2]=c[s>>2]|4096;return}function Qi(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0;if(((((d|0)>-1?(c[b+1692>>2]|0)>(d|0):0)?(f=c[b+1728>>2]|0,e>>>0<121):0)?(e=a[f+(d*764|0)+512+(e<<1)>>0]|0,g=e&255,e<<24>>24!=-1):0)?(g|0)<(c[f+(d*764|0)+36>>2]|0):0)f=(c[f+(d*764|0)+756>>2]|0)+(g<<6)|0;else f=0;return f|0}function Ri(b,d,e){b=b|0;d=d|0;e=e|0;if(!((b|0)>-1&(d|0)!=0)){d=e+64|0;c[d>>2]=0;d=e+224|0;c[d>>2]=0;d=e+164|0;a[d>>0]=0;d=e+184|0;c[d>>2]=0;e=e+180|0;c[e>>2]=1;return}c[e+40>>2]=c[d+16>>2];c[e+84>>2]=c[d+4>>2];b=c[d+56>>2]|0;if(b&128|0)c[e+376>>2]=(b<<1)+-256;b=c[d+60>>2]|0;if(b&128|0)c[e+380>>2]=(b<<1)+-256;b=e+192|0;tj(b,c[d+24>>2]|0);uj(b,c[d+28>>2]>>2);vj(b,c[d+20>>2]|0);c[e+208>>2]=c[d+32>>2];sj(e+104|0);sj(e+124|0);d=e+64|0;c[d>>2]=0;d=e+224|0;c[d>>2]=0;d=e+164|0;a[d>>0]=0;d=e+184|0;c[d>>2]=0;e=e+180|0;c[e>>2]=1;return}function Si(a,d,e){a=a|0;d=d|0;e=e|0;a=xm(a,c[d+44>>2]|0)|0;if(!e){if(!(c[a+44>>2]&32))b[d+96>>1]=0;if(!(c[a+200>>2]&32))b[d+98>>1]=0;if(c[a+356>>2]&32|0){d=d+8|0;e=c[d>>2]|0;e=e&-17;c[d>>2]=e;return}}else{b[d+96>>1]=0;b[d+98>>1]=0}b[d+100>>1]=0;d=d+8|0;e=c[d>>2]|0;e=e&-17;c[d>>2]=e;return}function Ti(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0.0;if(!((b|0)>-1&(d|0)!=0))return;g=+ii(b,c[e+40>>2]|0,c[a+2832>>2]&4096,+h[e+32>>3]);h[e+312>>3]=g;a=e+24|0;if((f|0)!=0&!(+h[a>>3]<1.0))return;h[a>>3]=g;return}function Ui(a,b,d){a=a|0;b=b|0;d=d|0;if((b|0)<1|(b|0)==(d|0))return;a=c[a+624>>2]|0;ap(a+(b*440|0)|0,a+(d*440|0)|0,440)|0;return}function Vi(a){a=a|0;return (Bo(a)|0)&255|0}function Wi(a){a=a|0;return (Bo(a)|0)&255|0}function Xi(a){a=a|0;var b=0;b=(Vi(a)|0)&255;return (((Vi(a)|0)&255)<<8|b)&65535|0}function Yi(a){a=a|0;var b=0;b=(Vi(a)|0)&255;return (b<<8|(Vi(a)|0)&255)&65535|0}function Zi(a){a=a|0;var b=0,c=0;b=(Vi(a)|0)&255;c=(Vi(a)|0)&255;return c<<8|b|((Vi(a)|0)&255)<<16|0}function _i(a){a=a|0;var b=0,c=0;b=(Vi(a)|0)&255;c=(Vi(a)|0)&255;return c<<8|b<<16|(Vi(a)|0)&255|0}function $i(a){a=a|0;var b=0,c=0,d=0;c=(Vi(a)|0)&255;d=(Vi(a)|0)&255;b=(Vi(a)|0)&255;return d<<8|c|b<<16|((Vi(a)|0)&255)<<24|0}function aj(a){a=a|0;var b=0,c=0,d=0;c=(Vi(a)|0)&255;d=(Vi(a)|0)&255;b=(Vi(a)|0)&255;return d<<16|c<<24|b<<8|(Vi(a)|0)&255|0}function bj(a,b){a=a|0;b=b|0;return ((b&255)<<8|a&255)&65535|0}function cj(a,b){a=a|0;b=b|0;return ((a&255)<<8|b&255)&65535|0}function dj(a,b,c){a=a|0;b=b|0;c=c|0;return (b&255)<<8|a&255|(c&255)<<16|0}function ej(a,b,c){a=a|0;b=b|0;c=c|0;return (b&255)<<8|(a&255)<<16|c&255|0}function fj(a){a=a|0;return (d[a+1>>0]|0)<<8|(d[a>>0]|0)|(d[a+2>>0]|0)<<16|(d[a+3>>0]|0)<<24|0}function gj(a){a=a|0;return (d[a+1>>0]|0)<<16|(d[a>>0]|0)<<24|(d[a+2>>0]|0)<<8|(d[a+3>>0]|0)|0}function hj(a,b){a=a|0;b=b|0;Fo(b&255,a);return}function ij(a,b){a=a|0;b=b|0;hj(a,(b&65535)>>>8&255);hj(a,b&255);return}function jj(a,b){a=a|0;b=b|0;hj(a,b>>>24&255);hj(a,b>>>16&255);hj(a,b>>>8&255);hj(a,b&255);return}function kj(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0;e=l;l=l+1024|0;d=e;do{f=Go(d,1,(c|0)<1024?c:1024,b)|0;co(d,1,f,a);c=c-f|0}while((f|0)>0&(c|0)>0);l=e;return}function lj(a){a=a|0;var b=0;b=a+16|0;c[b>>2]=0;c[b+4>>2]=0;c[a>>2]=1732584193;c[a+4>>2]=-271733879;c[a+8>>2]=-1732584194;c[a+12>>2]=271733878;return}function mj(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0;h=a+16|0;i=h;j=c[i>>2]|0;i=c[i+4>>2]|0;e=Zo(j|0,i|0,3)|0;e=e&63;f=64-e|0;g=_o(d|0,0,3)|0;g=Qo(j|0,i|0,g|0,z|0)|0;c[h>>2]=g;c[h+4>>2]=z;if(f>>>0<=d>>>0){if(e){ap(a+24+e|0,b|0,f|0)|0;nj(a,a+24|0);b=b+f|0;d=d-f|0}if(d>>>0>63){g=d+-64|0;h=g&-64;f=h+64|0;e=b;while(1){nj(a,e);d=d+-64|0;if(d>>>0<=63)break;else e=e+64|0}e=0;b=b+f|0;d=g-h|0}else e=0}if(!d)return;ap(a+24+e|0,b|0,d|0)|0;return}function nj(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;A=d[b>>0]|d[b+1>>0]<<8|d[b+2>>0]<<16|d[b+3>>0]<<24;t=b+4|0;t=d[t>>0]|d[t+1>>0]<<8|d[t+2>>0]<<16|d[t+3>>0]<<24;m=b+8|0;m=d[m>>0]|d[m+1>>0]<<8|d[m+2>>0]<<16|d[m+3>>0]<<24;v=b+12|0;v=d[v>>0]|d[v+1>>0]<<8|d[v+2>>0]<<16|d[v+3>>0]<<24;o=b+16|0;o=d[o>>0]|d[o+1>>0]<<8|d[o+2>>0]<<16|d[o+3>>0]<<24;x=b+20|0;x=d[x>>0]|d[x+1>>0]<<8|d[x+2>>0]<<16|d[x+3>>0]<<24;q=b+24|0;q=d[q>>0]|d[q+1>>0]<<8|d[q+2>>0]<<16|d[q+3>>0]<<24;z=b+28|0;z=d[z>>0]|d[z+1>>0]<<8|d[z+2>>0]<<16|d[z+3>>0]<<24;s=b+32|0;s=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;l=b+36|0;l=d[l>>0]|d[l+1>>0]<<8|d[l+2>>0]<<16|d[l+3>>0]<<24;u=b+40|0;u=d[u>>0]|d[u+1>>0]<<8|d[u+2>>0]<<16|d[u+3>>0]<<24;n=b+44|0;n=d[n>>0]|d[n+1>>0]<<8|d[n+2>>0]<<16|d[n+3>>0]<<24;w=b+48|0;w=d[w>>0]|d[w+1>>0]<<8|d[w+2>>0]<<16|d[w+3>>0]<<24;p=b+52|0;p=d[p>>0]|d[p+1>>0]<<8|d[p+2>>0]<<16|d[p+3>>0]<<24;y=b+56|0;y=d[y>>0]|d[y+1>>0]<<8|d[y+2>>0]<<16|d[y+3>>0]<<24;r=b+60|0;r=d[r>>0]|d[r+1>>0]<<8|d[r+2>>0]<<16|d[r+3>>0]<<24;j=c[a>>2]|0;h=a+4|0;i=c[h>>2]|0;f=a+8|0;g=c[f>>2]|0;b=a+12|0;e=c[b>>2]|0;B=A+-680876936+j+((e^g)&i^e)|0;B=(B<<7|B>>>25)+i|0;e=t+-389564586+e+(B&(g^i)^g)|0;e=(e<<12|e>>>20)+B|0;g=m+606105819+g+(e&(B^i)^i)|0;g=(g<<17|g>>>15)+e|0;i=v+-1044525330+i+(g&(e^B)^B)|0;i=(i<<22|i>>>10)+g|0;B=o+-176418897+B+(i&(g^e)^e)|0;B=(B<<7|B>>>25)+i|0;e=x+1200080426+e+(B&(i^g)^g)|0;e=(e<<12|e>>>20)+B|0;g=q+-1473231341+g+(e&(B^i)^i)|0;g=(g<<17|g>>>15)+e|0;i=z+-45705983+i+(g&(e^B)^B)|0;i=(i<<22|i>>>10)+g|0;B=s+1770035416+B+(i&(g^e)^e)|0;B=(B<<7|B>>>25)+i|0;e=l+-1958414417+e+(B&(i^g)^g)|0;e=(e<<12|e>>>20)+B|0;g=u+-42063+g+(e&(B^i)^i)|0;g=(g<<17|g>>>15)+e|0;i=n+-1990404162+i+(g&(e^B)^B)|0;i=(i<<22|i>>>10)+g|0;B=w+1804603682+B+(i&(g^e)^e)|0;B=(B<<7|B>>>25)+i|0;e=p+-40341101+e+(B&(i^g)^g)|0;e=(e<<12|e>>>20)+B|0;g=y+-1502002290+g+(e&(B^i)^i)|0;g=(g<<17|g>>>15)+e|0;i=r+1236535329+i+(g&(e^B)^B)|0;i=(i<<22|i>>>10)+g|0;B=t+-165796510+B+((i^g)&e^g)|0;B=(B<<5|B>>>27)+i|0;e=q+-1069501632+e+((B^i)&g^i)|0;e=(e<<9|e>>>23)+B|0;g=n+643717713+g+((e^B)&i^B)|0;g=(g<<14|g>>>18)+e|0;i=A+-373897302+i+((g^e)&B^e)|0;i=(i<<20|i>>>12)+g|0;B=x+-701558691+B+((i^g)&e^g)|0;B=(B<<5|B>>>27)+i|0;e=u+38016083+e+((B^i)&g^i)|0;e=(e<<9|e>>>23)+B|0;g=r+-660478335+g+((e^B)&i^B)|0;g=(g<<14|g>>>18)+e|0;i=o+-405537848+i+((g^e)&B^e)|0;i=(i<<20|i>>>12)+g|0;B=l+568446438+B+((i^g)&e^g)|0;B=(B<<5|B>>>27)+i|0;e=y+-1019803690+e+((B^i)&g^i)|0;e=(e<<9|e>>>23)+B|0;g=v+-187363961+g+((e^B)&i^B)|0;g=(g<<14|g>>>18)+e|0;i=s+1163531501+i+((g^e)&B^e)|0;i=(i<<20|i>>>12)+g|0;B=p+-1444681467+B+((i^g)&e^g)|0;B=(B<<5|B>>>27)+i|0;e=m+-51403784+e+((B^i)&g^i)|0;e=(e<<9|e>>>23)+B|0;g=z+1735328473+g+((e^B)&i^B)|0;g=(g<<14|g>>>18)+e|0;k=g^e;i=w+-1926607734+i+(k&B^e)|0;i=(i<<20|i>>>12)+g|0;k=x+-378558+B+(k^i)|0;k=(k<<4|k>>>28)+i|0;e=s+-2022574463+e+(i^g^k)|0;e=(e<<11|e>>>21)+k|0;g=n+1839030562+g+(k^i^e)|0;g=(g<<16|g>>>16)+e|0;i=y+-35309556+i+(e^k^g)|0;i=(i<<23|i>>>9)+g|0;k=t+-1530992060+k+(g^e^i)|0;k=(k<<4|k>>>28)+i|0;e=o+1272893353+e+(i^g^k)|0;e=(e<<11|e>>>21)+k|0;g=z+-155497632+g+(k^i^e)|0;g=(g<<16|g>>>16)+e|0;i=u+-1094730640+i+(e^k^g)|0;i=(i<<23|i>>>9)+g|0;k=p+681279174+k+(g^e^i)|0;k=(k<<4|k>>>28)+i|0;e=A+-358537222+e+(i^g^k)|0;e=(e<<11|e>>>21)+k|0;g=v+-722521979+g+(k^i^e)|0;g=(g<<16|g>>>16)+e|0;i=q+76029189+i+(e^k^g)|0;i=(i<<23|i>>>9)+g|0;k=l+-640364487+k+(g^e^i)|0;k=(k<<4|k>>>28)+i|0;e=w+-421815835+e+(i^g^k)|0;e=(e<<11|e>>>21)+k|0;g=r+530742520+g+(k^i^e)|0;g=(g<<16|g>>>16)+e|0;i=m+-995338651+i+(e^k^g)|0;i=(i<<23|i>>>9)+g|0;k=A+-198630844+k+((i|~e)^g)|0;k=(k<<6|k>>>26)+i|0;e=z+1126891415+e+((k|~g)^i)|0;e=(e<<10|e>>>22)+k|0;g=y+-1416354905+g+((e|~i)^k)|0;g=(g<<15|g>>>17)+e|0;i=x+-57434055+i+((g|~k)^e)|0;i=(i<<21|i>>>11)+g|0;k=w+1700485571+k+((i|~e)^g)|0;k=(k<<6|k>>>26)+i|0;e=v+-1894986606+e+((k|~g)^i)|0;e=(e<<10|e>>>22)+k|0;g=u+-1051523+g+((e|~i)^k)|0;g=(g<<15|g>>>17)+e|0;i=t+-2054922799+i+((g|~k)^e)|0;i=(i<<21|i>>>11)+g|0;k=s+1873313359+k+((i|~e)^g)|0;k=(k<<6|k>>>26)+i|0;e=r+-30611744+e+((k|~g)^i)|0;e=(e<<10|e>>>22)+k|0;g=q+-1560198380+g+((e|~i)^k)|0;g=(g<<15|g>>>17)+e|0;i=p+1309151649+i+((g|~k)^e)|0;i=(i<<21|i>>>11)+g|0;k=o+-145523070+k+((i|~e)^g)|0;k=(k<<6|k>>>26)+i|0;e=n+-1120210379+e+((k|~g)^i)|0;e=(e<<10|e>>>22)+k|0;g=m+718787259+g+((e|~i)^k)|0;g=(g<<15|g>>>17)+e|0;i=l+-343485551+i+((g|~k)^e)|0;c[a>>2]=k+j;c[h>>2]=g+(c[h>>2]|0)+(i<<21|i>>>11);c[f>>2]=g+(c[f>>2]|0);c[b>>2]=e+(c[b>>2]|0);return}function oj(b,d){b=b|0;d=d|0;var e=0;pj(d);if(!b)return;a[b+3>>0]=(c[d>>2]|0)>>>24;a[b+2>>0]=(c[d>>2]|0)>>>16;a[b+1>>0]=(c[d>>2]|0)>>>8;a[b>>0]=c[d>>2];e=d+4|0;a[b+7>>0]=(c[e>>2]|0)>>>24;a[b+6>>0]=(c[e>>2]|0)>>>16;a[b+5>>0]=(c[e>>2]|0)>>>8;a[b+4>>0]=c[e>>2];e=d+8|0;a[b+11>>0]=(c[e>>2]|0)>>>24;a[b+10>>0]=(c[e>>2]|0)>>>16;a[b+9>>0]=(c[e>>2]|0)>>>8;a[b+8>>0]=c[e>>2];e=d+12|0;a[b+15>>0]=(c[e>>2]|0)>>>24;a[b+14>>0]=(c[e>>2]|0)>>>16;a[b+13>>0]=(c[e>>2]|0)>>>8;a[b+12>>0]=c[e>>2];b=d+88|0;do{c[d>>2]=0;d=d+4|0}while((d|0)<(b|0));return}function pj(b){b=b|0;var d=0,e=0,f=0,g=0,h=0;d=l;l=l+16|0;e=d;f=b+16|0;g=c[f>>2]|0;f=c[f+4>>2]|0;h=Zo(g|0,f|0,56)|0;a[e+7>>0]=h;h=Zo(g|0,f|0,48)|0;a[e+6>>0]=h;h=Zo(g|0,f|0,40)|0;a[e+5>>0]=h;a[e+4>>0]=f;h=Zo(g|0,f|0,24)|0;a[e+3>>0]=h;h=Zo(g|0,f|0,16)|0;a[e+2>>0]=h;h=Zo(g|0,f|0,8)|0;a[e+1>>0]=h;a[e>>0]=g;f=Zo(g|0,f|0,3)|0;f=Ro(64,0,f&63|0,0)|0;mj(b,22395,(f>>>0<9?f+64|0:f)+-8|0);mj(b,e,8);l=d;return}function qj(a,b){a=a|0;b=b|0;var d=0;if((b|0)==0|(c[a+4>>2]|0)==0){d=0;return d|0}switch(c[a>>2]|0){case 0:{d=c[4400+(c[a+12>>2]<<2)>>2]|0;break}case 1:{d=255-(c[a+12>>2]<<3)|0;break}case 2:{d=(c[a+12>>2]|0)<32?255:-255;break}case 3:{d=((Ao()|0)&511)+-256|0;break}case 18:{d=(c[a+12>>2]|0)<32?255:0;break}default:{d=0;return d|0}}d=(O(c[a+8>>2]|0,d)|0)/(b|0)|0;return d|0}function rj(a){a=a|0;var b=0;b=a+12|0;c[b>>2]=((c[b>>2]|0)+(c[a+4>>2]|0)|0)%64|0;return}function sj(a){a=a|0;c[a+12>>2]=0;return}function tj(a,b){a=a|0;b=b|0;c[a+8>>2]=b;return}function uj(a,b){a=a|0;b=b|0;c[a+4>>2]=b;return}function vj(a,b){a=a|0;b=b|0;c[a>>2]=b;return}function wj(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0;c[f>>2]=0;i=c[a>>2]|0;if(!(i&1)){d=e;return d|0}g=c[a+4>>2]|0;if((g|0)<1){d=e;return d|0}e=g<<1;g=e+-2|0;if((g|0)==0?1:(b[a+28+(g<<1)>>1]|0)<=(d|0)){c[f>>2]=1;d=b[a+28+(e+-1<<1)>>1]|0;return d|0}else e=g;while(1){g=e+-2|0;f=b[a+28+(g<<1)>>1]|0;if((e|0)>2&(f|0)>(d|0))e=g;else break}h=b[a+28+(e+-1<<1)>>1]|0;e=b[a+28+(e<<1)>>1]|0;if((i&4|0)!=0?(g|0)==(c[a+24>>2]<<1|0):0)g=(c[a+20>>2]<<1)+-2|0;d=((O((b[a+28+(g+3<<1)>>1]|0)-h|0,d-f|0)|0)/(e-f|0)|0)+h|0;return d|0}function xj(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;g=c[a>>2]|0;if(!(g&1)){n=d;return n|0}if((c[a+4>>2]|0)<1){n=d;return n|0}o=g&2;l=c[a+20>>2]<<1;m=c[a+24>>2]<<1;h=c[a+12>>2]<<1;i=c[a+16>>2]<<1;n=(g&4|0)!=0;k=(h|0)==(m|0);j=(e|0)!=0;f=(((g&6|0)==6&k?(j|(f|0)==0?o:0):o)|0)!=0;e=f&(j^1);do if(!(g&16)){if(e)d=(((b[a+28+(h<<1)>>1]|0)==(d|0))<<31>>31)+d|0;if(n?!(k&(j&f)|(d|0)!=(b[a+28+(m<<1)>>1]|0)):0)d=(b[a+28+(l<<1)>>1]|0)+-1|0}else{if(e){if((b[a+28+(i<<1)>>1]|0)!=(d|0))break;d=(b[a+28+(h<<1)>>1]|0)+-1|0;break}if(n?(b[a+28+(m<<1)>>1]|0)==(d|0):0)d=(b[a+28+(l<<1)>>1]|0)+-1|0}while(0);o=((d|0)<65535&1)+d|0;return o|0}function yj(a,d){a=a|0;d=d|0;var e=0;if(!(c[a>>2]&1)){d=0;return d|0}e=c[a+4>>2]<<1;if((b[a+28+(e+-2<<1)>>1]|0)>=(d|0)){d=0;return d|0}d=(b[a+28+(e+-1<<1)>>1]|0)==0?-1:1;return d|0}function zj(a,b){a=a|0;b=b|0;return d[a+56+b>>0]|0|0}function Aj(b){b=b|0;var e=0,f=0,g=0,h=0,i=0,j=0;j=l;l=l+256|0;i=j;cp(b+56|0,-1,256)|0;a[i>>0]=0;c[b+368>>2]=Bj(b,0,0)|0;g=b+1708|0;h=1;while(1){f=c[g>>2]|0;a:do if((f|0)>0){e=0;do{if((a[b+56+e>>0]|0)==-1)break a;e=e+1|0}while((e|0)<(f|0))}else e=0;while(0);if(!((h|0)<16&(e|0)!=(f|0)))break;a[i+h>>0]=e;f=Bj(b,e,h)|0;c[b+368+(h<<4)>>2]=f;h=((f|0)>0&1)+h|0}f=b+7968|0;c[f>>2]=h;if((h|0)>0)e=0;else{l=j;return}do{c[b+7972+(e<<3)>>2]=d[i+e>>0];c[b+7972+(e<<3)+4>>2]=c[b+368+(e<<4)>>2];e=e+1|0}while((e|0)<(c[f>>2]|0));l=j;return}function Bj(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,i=0,j=0,k=0,m=0,n=0.0,o=0.0,p=0,q=0,r=0,s=0,t=0,u=0.0,v=0.0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0.0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0.0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0;la=l;l=l+512|0;ha=la+256|0;ga=la;fa=b+1708|0;g=c[fa>>2]|0;if(!g){ka=0;l=la;return ka|0}if((g|0)>0){k=b+8116|0;j=b+1680|0;m=b+1720|0;i=0;do{g=d[b+2504+i>>0]|0;if((g|0)<(c[j>>2]|0)){g=c[c[(c[m>>2]|0)+(g<<2)>>2]>>2]|0;g=(g|0)==0?1:g}else g=1;cp(c[(c[k>>2]|0)+(i<<2)>>2]|0,0,g|0)|0;i=i+1|0}while((i|0)<(c[fa>>2]|0))}else{j=b+1680|0;k=b+8116|0;m=b+1720|0}X=b+1688|0;ia=c[X>>2]<<2;cp(ha|0,0,ia|0)|0;cp(ga|0,0,ia|0)|0;ia=~~+h[b+2800>>3];Y=(e|0)==0;_=f&255;da=b+1712|0;$=b+7972+(f<<3)|0;ja=b+2808|0;ea=b+1724|0;ba=b+2824|0;ca=b+2832|0;aa=b+28|0;Z=+(ia|0);q=0;p=c[b+1704>>2]|0;i=0;o=0.0;n=0.0;A=c[b+1716>>2]|0;z=0;D=0;r=e+-1|0;x=-1;C=0;w=0;g=c[b+1700>>2]|0;a:while(1){while(1){r=r+1|0;s=c[fa>>2]|0;if(r>>>0>=s>>>0){r=c[da>>2]|0;if((r|0)<=(s|0)?(d[b+2504+r>>0]|0)<(c[j>>2]|0):0)if((zj(b,r)|0)==(f|0)){r=da;ka=15}else r=e;else{r=$;ka=15}if((ka|0)==15){ka=0;r=c[r>>2]|0}s=a[b+2504+r>>0]|0;if(s<<24>>24==-1){m=0;j=r;break a}}else s=a[b+2504+r>>0]|0;W=s&255;t=b+56+r|0;if(!Y?(a[t>>0]|0)!=-1:0){m=0;j=r;break a}a[t>>0]=_;if((W|0)<(c[j>>2]|0))break;if(s<<24>>24!=-1)continue;r=c[fa>>2]|0}V=b+2504+r|0;if((i|0)<(c[c[(c[m>>2]|0)+(W<<2)>>2]>>2]|0)?a[(c[(c[k>>2]|0)+(r<<2)>>2]|0)+i>>0]|0:0){m=0;j=r;break}c[b+2848+(r*20|0)+8>>2]=A;c[b+2848+(r*20|0)+4>>2]=p;c[b+2848+(r*20|0)>>2]=g;u=+(q|0);v=+(p|0);c[b+2848+(r*20|0)+12>>2]=~~(o+u*+h[ja>>3]/v);s=b+2848+(r*20|0)+16|0;if((r|0)!=0&(c[s>>2]|0)==0){if((r|0)==(e|0))n=o+u*+h[ja>>3]/v;c[s>>2]=i}s=c[c[(c[m>>2]|0)+(W<<2)>>2]>>2]|0;if((i|0)<(s|0)){B=0;C=0;y=s;while(1){p=(p|0)>20?p:20;if((C|0)>512){m=C;j=r;break a}s=(c[(c[k>>2]|0)+(r<<2)>>2]|0)+i|0;t=a[s>>0]|0;if(!((D|0)!=0|t<<24>>24==0)){ka=31;break a}a[s>>0]=t+1<<24>>24;R=c[X>>2]|0;if((R|0)>0){S=c[ea>>2]|0;T=c[m>>2]|0;U=c[T+(W<<2)>>2]|0;Q=(w|0)==0;P=i+1|0;N=0;H=C;K=y;M=0;L=0;while(1){b:do if((i|0)<(c[c[S+(c[U+4+(N<<2)>>2]<<2)>>2]>>2]|0)){s=c[S+(c[(c[T+(d[V>>0]<<2)>>2]|0)+4+(N<<2)>>2]<<2)>>2]|0;if(Q){C=d[s+4+(i<<3)+3>>0]|0;F=d[s+4+(i<<3)+5>>0]|0;J=d[s+4+(i<<3)+4>>0]|0;I=d[s+4+(i<<3)+6>>0]|0}else{C=0;F=0;J=0;I=0}E=(C|0)==16;s=E?J:I;if((F|0)==16|E){A=c[ba>>2]|0;A=(s|0)>(A|0)?A:s}s=(C|0)==17;c:do if((F|0)==17|s){t=(z|0)==0;y=s?J:I;while(1){if(y|0)break;if(t){z=0;break c}else y=z}t=y>>>4&15;s=y&15;w=c[ca>>2]|0;if(!(w&32)){s=t-s|0;if(!(w&64)){A=(O(s,g+-1|0)|0)+A|0;z=y;break}else{A=(O(s,g)|0)+A|0;z=y;break}}if((s|0)==15&(t|0)!=0){A=t+A|0;z=y;break}if((s|0)!=0&(t|0)==15){A=A-s|0;z=y;break}s=t-s|0;if(!(w&64)){A=(O(s,g+-1|0)|0)+A|0;z=y;break}else{A=(O(s,g)|0)+A|0;z=y;break}}while(0);s=(C|0)==15;E=(J|0)!=0;if(!(E&s)?!((I|0)!=0&(F|0)==15):0){y=p;t=H}else ka=56;do if((ka|0)==56){ka=0;w=s?J:I;s=q+(O(O(H,ia)|0,g)|0)|0;if(!w){q=s;y=p;t=0;break}if(w>>>0<32|(c[aa>>2]&1|0)!=0){q=s;y=p;t=0;g=w;break}q=0;y=w;o=o+ +(s|0)*+h[ja>>3]/+(p|0);t=0}while(0);H=(C|0)==126?163:C;F=(F|0)==126?163:F;p=(H|0)==163;if(!(!(E&p)?!((I|0)!=0&(F|0)==163):0)){q=(O(O(t,ia)|0,g)|0)+q|0;t=0;g=p?J:I}p=(H|0)==171;if(!(E&p)?!((I|0)!=0&(F|0)==171):0)p=y;else ka=64;do if((ka|0)==64){ka=0;p=p?J:I;if(p>>>0<=31){p=y;break}G=+((O(O(t,ia)|0,g)|0)+q|0);q=0;o=o+G*+h[ja>>3]/+(y|0);t=0}while(0);s=(H|0)==135;if(!(E&s)?!((I|0)!=0&(F|0)==135):0)C=t;else ka=68;d:do if((ka|0)==68){ka=0;s=s?J:I;E=q+(O(O(g,ia)|0,t)|0)|0;G=+h[ja>>3];u=+(p|0);o=o+ +(E|0)*G/u;switch(s>>>4&15){case 0:{v=Z*G;o=v/u+o;if((g|0)>1){s=s&15;q=1;do{p=p-s|0;p=(p|0)>32?p:32;o=o+v/+(p|0);q=q+1|0}while((q|0)!=(g|0));s=p}else s=p;q=0;p=s;o=o-Z*(+(g|0)*G)/+(s|0);C=0;break d}case 1:{v=Z*G;o=v/u+o;if((g|0)>1){s=s&15;q=1;do{p=p+s|0;p=(p|0)<255?p:255;o=o+v/+(p|0);q=q+1|0}while((q|0)!=(g|0));s=p}else s=p;q=0;p=s;o=o-Z*(+(g|0)*G)/+(s|0);C=0;break d}default:{q=0;p=s;C=0;break d}}}while(0);s=(H|0)==11;w=(F|0)==11|s;x=w?(s?J:I):x;s=(H|0)==13;E=(F|0)==13|s;s=s?J:I;w=E|w?0:K;B=E?((s>>>4)*10|0)+(s&15)|0:B;s=(H|0)==14;if(!((F|0)==14|s)){s=C;C=M;t=D;y=L;break}K=s?J:I;y=K&15;switch(K>>>4&15){case 14:{q=q+(O(O(y,ia)|0,g)|0)|0;s=C;C=M;t=D;break b}case 6:break;default:{s=C;C=M;t=D;y=L;break b}}if(!y){c[ga+(N<<2)>>2]=i;s=C;C=M;t=D;y=L;break}t=ha+(N<<2)|0;s=c[t>>2]|0;if(!s){if((c[ga+(N<<2)>>2]|0)>(i|0)){s=C;C=M;t=D;y=L;break}c[t>>2]=y;s=C;C=N+1|0;t=D+1|0;y=L;break}K=s+-1|0;c[t>>2]=K;if(K|0){s=C;C=N+1|0;t=D;y=L;break}t=D+-1|0;if(!(c[ca>>2]&1)){s=C;C=M;y=L;break}c[ga+(N<<2)>>2]=P;s=C;C=M;y=L}else{s=H;w=K;C=M;t=D;y=L}while(0);N=N+1|0;if((N|0)==(R|0))break;else{H=s;K=w;M=C;D=t;L=y}}if(C)i=(c[ga+(C+-1<<2)>>2]|0)+-1|0}else{s=C;w=y;t=D;y=0}i=i+1|0;s=s+1|0;if((i|0)<(w|0)){C=s;y=w;D=t;w=0}else{w=0;break}}}else{B=0;s=0;t=D;y=C}C=(x|0)>-1;q=(O(O(s,ia)|0,g)|0)+q|0;i=B;D=t;r=C?x+-1|0:r;x=C?-1:x;C=y;w=(B|0)!=0&(y|0)!=0?1:w}if((ka|0)==31){m=C+-1|0;j=r}c[b+368+(f<<4)+12>>2]=a[(c[(c[k>>2]|0)+(j<<2)>>2]|0)+i>>0];c[b+368+(f<<4)+8>>2]=i;c[b+368+(f<<4)+4>>2]=j;ka=(O(O(m,ia)|0,g)|0)+q|0;ka=~~(o-n+ +(ka|0)*+h[ja>>3]/+(p|0));l=la;return ka|0}function Cj(){var a=0;a=Qm(1,8144)|0;if(!a){a=0;return a|0}c[a+2844>>2]=100;return a|0}function Dj(a){a=a|0;if((c[a+8140>>2]|0)<=0){Pm(a);return}vl(a);Pm(a);return}function Ej(b,e){b=b|0;e=e|0;var f=0,g=0,h=0;h=zj(b,e)|0;if((h|0)==255)return;g=c[b+7972+(h<<3)>>2]|0;if((h|0)<=-1)return;c[b+52>>2]=h;if((e|0)>-1){f=a[b+2504+e>>0]|0;if(f<<24>>24==-1)return;if((g|0)<(e|0)&f<<24>>24==-2){f=e;do f=f+1|0;while((g|0)<=(e|0)?(a[b+2504+f>>0]|0)==-2:0);e=f}if((e|0)>(c[b+368+(h<<4)+4>>2]|0))f=0;else{c[b+352>>2]=c[c[(c[b+1720>>2]|0)+(d[(c[b>>2]|0)+(b+2504)>>0]<<2)>>2]>>2];f=c[b+368+(h<<4)+12>>2]|0}c[b+356>>2]=f}if((e|0)>=(c[b+1708>>2]|0))return;c[b+4>>2]=(e|0)==0?-1:e;return}function Fj(a,b){a=a|0;b=b|0;if((c[a+8140>>2]|0)<2)return;if((c[a+1708>>2]|0)<=(b|0))return;Ej(a,b);return}function Gj(a){a=a|0;var b=0,d=0,e=0;e=c[a+400>>2]|0;b=e+68|0;d=c[b>>2]|0;a=(O(c[e+60>>2]|0,c[4656+(d>>5<<2)>>2]|0)|0)>>10;c[b>>2]=((c[e+64>>2]|0)+d|0)%1024|0;return a|0}function Hj(b,e){b=b|0;e=e|0;var f=0,g=0,h=0;f=c[e+400>>2]|0;h=c[f+48>>2]|0;if(!h){h=0;return h|0}b=c[(c[(c[b+8104>>2]|0)+8>>2]|0)+(c[e+44>>2]<<2)>>2]|0;g=b+h|0;if((a[g>>0]|0)==-3){h=0;return h|0}e=f+52|0;f=c[e>>2]|0;c[e>>2]=f+1;b=a[b+f>>0]|0;if(b<<24>>24==-3){c[e>>2]=h+1;b=d[g>>0]|0}else b=b&255;h=b*12800|0;return h|0}function Ij(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;k=c[b+8104>>2]|0;if(!k)return;if((c[k>>2]|0)!=133303461)return;v=c[e+400>>2]|0;q=c[b+1728>>2]|0;r=c[e+44>>2]|0;m=c[q+(r*764|0)+760>>2]|0;j=v+84|0;if(!(c[j>>2]|0)){o=c[m+12>>2]|0;if((o|0?(c[b+12>>2]|0)>=(o|0):0)?(c[v+80>>2]|0)==0:0){o=e+8|0;c[o>>2]=c[o>>2]|1}}else if((c[v+80>>2]|0)==0?(c[b+12>>2]|0)>=(c[m+12>>2]|0):0){o=e+8|0;c[o>>2]=c[o>>2]|1;c[j>>2]=0}if((c[b+12>>2]|0)==((c[b+16>>2]|0)+-1|0)?(i=v+80|0,(c[i>>2]|0)!=2):0)c[i>>2]=0;o=c[(c[k+4>>2]|0)+(r<<2)>>2]|0;if(o|0?(p=c[(c[k+8>>2]|0)+(r<<2)>>2]|0,p|0):0){if((g|0)==0?(l=c[e>>2]|0,l&65536|0):0){c[v+52>>2]=0;c[v+48>>2]=0;c[v+44>>2]=~~+h[e+24>>3];if(l&2048|0){c[v+20>>2]=0;c[v+16>>2]=0;c[v+4>>2]=0;c[v+40>>2]=0;c[v+36>>2]=0;c[v+24>>2]=0}c[v+8>>2]=0;c[v+28>>2]=0;c[v+12>>2]=c[m+4>>2];c[v+32>>2]=c[m+8>>2]}n=v+12|0;i=c[n>>2]|0;if((i|0)<=0)return;j=v+16|0;g=c[j>>2]|0;c[j>>2]=g+-1;if(g|0)return;c[j>>2]=i+-1;g=v+20|0;i=c[g>>2]|0;do if((i|0)<=0){m=v+4|0;i=c[m>>2]|0;l=0;a:while(1){k=i+1|0;c[m>>2]=k;j=a[o+i>>0]|0;switch(j<<24>>24){case -5:case -1:{u=28;break a}case -6:{u=31;break a}case -12:case -11:{u=32;break a}case -13:{u=33;break a}case -14:{u=34;break a}case -15:{u=35;break a}case -16:{u=36;break a}case -2:break;default:{u=37;break a}}if(l|0){i=0;break}c[m>>2]=i+2;l=d[o+k>>0]|0;c[m>>2]=l;i=l;l=1}if((u|0)==28){c[m>>2]=i;i=0}else if((u|0)==31){c[m>>2]=i+2;i=d[o+k>>0]|0}else if((u|0)==32){c[m>>2]=i+2;i=0}else if((u|0)==33){c[m>>2]=i+2;c[v+8>>2]=d[o+k>>0];i=0}else if((u|0)==34){c[m>>2]=i+2;c[v+8>>2]=0-(d[o+k>>0]|0);i=0}else if((u|0)==35){c[m>>2]=i+2;c[g>>2]=d[o+k>>0];i=0}else if((u|0)==36){c[m>>2]=i+2;c[n>>2]=d[o+k>>0];i=0}else if((u|0)==37)if((j&255)<65){c[v+76>>2]=j&255;i=0}else i=0;k=v+76|0;j=(c[k>>2]|0)+(c[v+8>>2]|0)|0;c[k>>2]=j;if((j|0)<0){c[k>>2]=0;break}if((j|0)>64)c[k>>2]=64}else{c[g>>2]=i+-1;i=0}while(0);n=v+40|0;j=c[n>>2]|0;if((j|0)>0)c[n>>2]=j+-1;else{g=v+24|0;j=c[g>>2]|0;l=0;b:while(1){m=j+1|0;c[g>>2]=m;k=a[p+j>>0]|0;switch(k<<24>>24){case -5:case -1:{u=47;break b}case -3:break b;case -4:{u=52;break b}case -6:{u=54;break b}case -9:{u=55;break b}case -10:{u=56;break b}case -11:{u=57;break b}case -12:{u=58;break b}case -13:{u=59;break b}case -14:{u=60;break b}case -15:{u=61;break b}case -16:{u=62;break b}case -2:break;default:{u=63;break b}}if(l|0)break;c[g>>2]=j+2;j=a[p+m>>0]|0;if(j<<24>>24==-1){u=50;break}j=j&255;c[g>>2]=j;l=1}switch(u|0){case 47:{c[g>>2]=j;break}case 50:{c[g>>2]=m;break}case 52:{j=j+2|0;c[g>>2]=j;c[v+52>>2]=m;c[v+48>>2]=m;do{u=j;j=j+1|0;c[g>>2]=j}while((a[p+u>>0]|0)!=-3);break}case 54:{c[g>>2]=j+2;i=d[p+m>>0]|0;break}case 55:{c[g>>2]=j+2;c[v+56>>2]=d[p+m>>0];break}case 56:{h[e+24>>3]=+(c[v+44>>2]|0);break}case 57:{c[g>>2]=j+2;c[v+64>>2]=d[p+m>>0];break}case 58:{c[g>>2]=j+2;c[v+60>>2]=d[p+m>>0];break}case 59:{c[g>>2]=j+2;c[v+28>>2]=0-(d[p+m>>0]|0);break}case 60:{c[g>>2]=j+2;c[v+28>>2]=d[p+m>>0];break}case 61:{c[g>>2]=j+2;c[n>>2]=d[p+m>>0];break}case 62:{c[g>>2]=j+2;c[v+32>>2]=d[p+m>>0];break}case 63:{j=k&255;if((j|0)<(c[q+(r*764|0)+36>>2]|0)?(s=c[(c[q+(r*764|0)+756>>2]|0)+(j<<6)+40>>2]|0,t=e+56|0,(s|0)!=(c[t>>2]|0)):0){c[t>>2]=s;_h(b,f,s)}break}}e=e+24|0;h[e>>3]=+h[e>>3]+ +(c[v+28>>2]|0)}if(!i)return;c[v+24>>2]=i;return}c[v+76>>2]=64;return}function Jj(a){a=a|0;var b=0;b=Qm(1,16)|0;c[a+760>>2]=b;if(!b){a=-1;return a|0}c[b>>2]=133303461;a=0;return a|0}function Kj(a){a=a|0;var b=0;b=Qm(1,88)|0;c[a+400>>2]=b;if(!b){a=-1;return a|0}c[b>>2]=133303461;a=0;return a|0}function Lj(b){b=b|0;var c=0;b=b+4|0;c=b+84|0;do{a[b>>0]=0;b=b+1|0}while((b|0)<(c|0));return}function Mj(a){a=a|0;Pm(a);return}function Nj(a){a=a|0;var b=0,d=0;b=Qm(1,12)|0;c[a+6552>>2]=b;if(!b){b=-1;return b|0}c[b>>2]=133303461;a=c[a+140>>2]|0;d=Qm(4,a)|0;c[b+4>>2]=d;if(!d){d=-1;return d|0}d=Qm(4,a)|0;c[b+8>>2]=d;d=((d|0)==0)<<31>>31;return d|0}function Oj(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;h=a+6552|0;g=c[h>>2]|0;f=g+4|0;b=c[f>>2]|0;if(b|0){e=a+140|0;if((c[e>>2]|0)>0){d=0;do{Pm(c[b+(d<<2)>>2]|0);d=d+1|0;b=c[f>>2]|0}while((d|0)<(c[e>>2]|0))}Pm(b)}f=g+8|0;b=c[f>>2]|0;if(!b){h=c[h>>2]|0;Pm(h);return}e=a+140|0;if((c[e>>2]|0)>0){d=0;do{Pm(c[b+(d<<2)>>2]|0);d=d+1|0;b=c[f>>2]|0}while((d|0)<(c[e>>2]|0))}Pm(b);h=c[h>>2]|0;Pm(h);return}function Pj(a,b){a=a|0;b=b|0;if(b<<24>>24!=-79)return;a=c[a+400>>2]|0;b=a+84|0;c[b>>2]=(c[b>>2]|0)+1;c[a+80>>2]=1;return}function Qj(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0;g=c[(c[b+1724>>2]|0)+(c[(c[(c[b+1720>>2]|0)+(d<<2)>>2]|0)+4+(e<<2)>>2]<<2)>>2]|0;d=f+1|0;if((d|0)>=(c[g>>2]|0))return;if((a[g+4+(d<<3)+5>>0]|0)!=-79)return;c[(c[(c[b+624>>2]|0)+(e*440|0)+400>>2]|0)+80>>2]=2;return}function Rj(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var i=0.0,j=0.0,k=0.0,l=0.0;k=6.28318530717958/+(a|0)*+g[4784+(((b|0)<0?0:(b|0)<255?b:255)<<2)>>2];l=+g[5808+(((d|0)<0?0:((d|0)<255?d:255)>>1)<<2)>>2];i=(1.0-l)*k;j=1.0/(k*k);k=j+(l-(i>2.0?2.0:i))/k;i=k+1.0;c[e>>2]=~~(1.0/i*65536.0);c[f>>2]=~~((j+k)/i*65536.0);c[h>>2]=~~(-j/i*65536.0);return}function Sj(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;w=b+4792|0;j=c[w>>2]|0;x=b+4800|0;i=c[x>>2]|0;k=a[b+60>>0]&32;v=b+4836|0;l=b+37628|0;if((b|0)!=(c[l>>2]|0)){c[l>>2]=b;u=c[b+52>>2]|0;c[b+37632>>2]=u;c[b+37636>>2]=u+1800;c[b+37640>>2]=u+1400;c[b+37644>>2]=u+1480;c[b+37648>>2]=u+1600;c[b+37652>>2]=u+1680;c[b+37676>>2]=c[b+4796>>2];c[b+37680>>2]=c[b+4804>>2];c[b+37668>>2]=c[b+4784>>2];c[b+37672>>2]=c[b+4788>>2]}if(!(k<<24>>24))r=c[b+37636>>2]|0;else r=(c[b+37632>>2]|0)+1200|0;if(!e){f=j;g=i;c[w>>2]=f;c[x>>2]=g;return}p=b+37668|0;o=b+37676|0;n=b+37660|0;u=b+37672|0;t=b+37680|0;s=b+37664|0;q=b+37656|0;m=b+37632|0;b=(h|0)==0;while(1){e=e+-1|0;j=(c[o>>2]|0)+j|0;c[n>>2]=c[(c[p>>2]|0)+(j>>>23<<2)>>2];i=(c[t>>2]|0)+i|0;c[s>>2]=c[(c[u>>2]|0)+(i>>>23<<2)>>2];c[q>>2]=0;k=c[m>>2]|0;if(k>>>0>>0){do{Tj(k,v);k=k+200|0}while(k>>>0>>0);k=c[q>>2]|0}else k=0;l=(Uj(k)|0)>>13;if(b)k=d;else{k=O(l,g)|0;c[d>>2]=(c[d>>2]|0)+k;k=d+4|0}d=O(l,f)|0;c[k>>2]=(c[k>>2]|0)+d;if(!e)break;else d=k+4|0}c[w>>2]=j;c[x>>2]=i;return}function Tj(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;j=d+32848|0;c[j>>2]=0;i=Vj(b,d)|0;do if(i>>>0<4095){e=c[b+40>>2]|0;if(a[b+73>>0]|0)e=(O(c[d+32828>>2]|0,e)|0)>>>8;f=b+36|0;h=(c[f>>2]|0)+e|0;c[f>>2]=h;e=a[b+161>>0]|0;f=c[b+76>>2]|0;g=c[b+164>>2]|0;if(!(e<<24>>24)){c[g>>2]=(c[g>>2]|0)+(c[(c[f+((h>>>13&2047)<<2)>>2]|0)+(i<<2)>>2]|0);break}else{k=b+172|0;m=c[k>>2]|0;l=b+176|0;e=(c[l>>2]|0)+m>>(e&255);c[l>>2]=m;i=c[(c[f+(((h+e|0)>>>13&2047)<<2)>>2]|0)+(i<<2)>>2]|0;c[k>>2]=i;c[g>>2]=(c[g>>2]|0)+i;break}}else{m=b+172|0;c[b+176>>2]=c[m>>2];c[m>>2]=0}while(0);f=Vj(b+80|0,d)|0;if(f>>>0>=4095)return;e=c[b+120>>2]|0;if(a[b+153>>0]|0)e=(O(c[d+32828>>2]|0,e)|0)>>>8;m=b+116|0;l=(c[m>>2]|0)+e|0;c[m>>2]=l;m=d+32820|0;c[m>>2]=(c[m>>2]|0)+(c[(c[(c[b+156>>2]|0)+((((c[j>>2]|0)+l|0)>>>13&2047)<<2)>>2]|0)+(f<<2)>>2]|0);return}function Uj(a){a=a|0;if((a|0)>268427264)return 268427264;else return ((a|0)>-268435456?a:-268435456)|0;return 0}function Vj(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;i=b+56|0;f=b+48|0;e=(c[f>>2]|0)+(c[i>>2]|0)|0;c[f>>2]=e;g=b+52|0;a:do if((e|0)>=(c[g>>2]|0)){h=b+45|0;switch(a[h>>0]|0){case 2:{a[h>>0]=1;c[f>>2]=268435456;c[g>>2]=c[b+20>>2];f=c[b+64>>2]|0;e=268435456;break}case 1:{e=c[b+20>>2]|0;c[f>>2]=e;c[g>>2]=536870912;if(!(a[b+44>>0]|0)){a[h>>0]=0;f=c[b+68>>2]|0}else f=0;break}case 0:{c[f>>2]=536870912;c[g>>2]=536870913;f=0;e=536870912;break}default:break a}c[i>>2]=f}while(0);e=(c[d+16+(e>>16<<2)>>2]|0)+(c[b+4>>2]|0)|0;if(!(a[b+72>>0]|0)){d=0;d=e+d|0;return d|0}d=c[d+32824>>2]|0;d=e+d|0;return d|0}function Wj(a){a=a|0;var b=0,d=0,e=0;c[a+36>>2]=0;Xj(a,1,0);Xj(a,2,0);Xj(a,3,0);Xj(a,4,0);b=255;do{Xj(a,b,0);b=b+-1|0}while((b|0)>31);d=c[a+56>>2]|0;if((d|0)<=0)return;e=c[a+52>>2]|0;b=c[a+4840>>2]|0;a=0;do{c[e+(a*200|0)+76>>2]=b;c[e+(a*200|0)+48>>2]=536870912;c[e+(a*200|0)+52>>2]=536870913;c[e+(a*200|0)+56>>2]=0;c[e+(a*200|0)+156>>2]=b;c[e+(a*200|0)+128>>2]=536870912;c[e+(a*200|0)+132>>2]=536870913;c[e+(a*200|0)+136>>2]=0;a=a+1|0}while((a|0)!=(d|0));return}function Xj(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0;g=b+4836|0;switch(e>>>5&7){case 0:switch(e&31){case 1:{if(!(a[b>>0]&1))return;k=f&32;a[b+4808>>0]=k;if(k<<24>>24)return;f=c[b+56>>2]|0;if((f|0)<=0)return;h=c[b+4840>>2]|0;e=c[b+52>>2]|0;g=0;do{c[e+(g*200|0)+76>>2]=h;c[e+(g*200|0)+156>>2]=h;g=g+1|0}while((g|0)!=(f|0));return}case 2:{c[b+40>>2]=256-f<<2;return}case 3:{c[b+44>>2]=256-f<<4;return}default:return}case 1:{e=e&31;if(-4144960>>>e&1|0)return;Yj(c[b+52>>2]|0,c[6320+(e<<2)>>2]|0,f);return}case 2:{e=e&31;if(-4144960>>>e&1|0)return;Zj(c[b+36>>2]|0,c[b+52>>2]|0,c[6320+(e<<2)>>2]|0,f);return}case 3:{e=e&31;if(-4144960>>>e&1|0)return;_j(b,c[6320+(e<<2)>>2]|0,f);return}case 4:{e=e&31;if(-4144960>>>e&1|0)return;$j(b,c[6320+(e<<2)>>2]|0,f);return}case 5:{if((e|0)==189){c[b+4784>>2]=(c[b+4844>>2]|0)+((f<<2&512)<<2);c[b+4788>>2]=(c[b+4848>>2]|0)+((f<<3&512)<<2);a[b+60>>0]=f&63;return}j=e&15;if(j>>>0>8)return;i=c[b+52>>2]|0;k=i+(j*200|0)|0;do if(e&16){h=f>>>5&1;e=i+(j*200|0)+180|0;f=c[e>>2]&255|f<<8&7936;g=i+(j*200|0)+196|0;if((d[g>>0]|0)!=(h|0)){h=h&255;a[g>>0]=h;if(!(h<<24>>24)){bk(k);bk(i+(j*200|0)+80|0);break}else{c[i+(j*200|0)+176>>2]=0;c[i+(j*200|0)+172>>2]=0;ak(k);ak(i+(j*200|0)+80|0);break}}}else{e=i+(j*200|0)+180|0;f=c[e>>2]&7936|f}while(0);if((c[e>>2]|0)==(f|0))return;c[e>>2]=f;c[i+(j*200|0)+192>>2]=c[6448+(f>>6<<2)>>2];c[i+(j*200|0)+188>>2]=(c[b+688+((f&1023)<<2)>>2]|0)>>>(7-(f>>10)|0);g=f>>>9;e=i+(j*200|0)+184|0;a[e>>0]=g;if(!((f&256|0)==0?1:(c[b+36>>2]&64|0)==0))a[e>>0]=g|1;ck(k,k);ck(k,i+(j*200|0)+80|0);return}case 6:{e=e&15;if(e>>>0>8)return;b=c[b+52>>2]|0;k=f>>>1&7;a[b+(e*200|0)+161>>0]=k|0?9-k&255:0;a[b+(e*200|0)+160>>0]=f&1;dk(b+(e*200|0)|0,g);return}case 7:{k=e&31;e=c[6320+(k<<2)>>2]|0;if(-4144960>>>k&1|0)return;if(!(a[b+4808>>0]|0))return;c[(c[b+52>>2]|0)+(((e|0)/2|0)*200|0)+((e&1)*80|0)+76>>2]=(c[b+4840>>2]|0)+((f<<11&6144)<<2);return}default:{}}}function Yj(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;f=(d|0)/2|0;d=d&1;c[b+(f*200|0)+(d*80|0)+32>>2]=c[7024+((e&15)<<2)>>2];a[b+(f*200|0)+(d*80|0)+8>>0]=e>>>3&2^2;a[b+(f*200|0)+(d*80|0)+44>>0]=e>>>5&1;a[b+(f*200|0)+(d*80|0)+73>>0]=e&64;a[b+(f*200|0)+(d*80|0)+72>>0]=e&128;ck(b+(f*200|0)|0,b+(f*200|0)+(d*80|0)|0);return}function Zj(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0;i=(e|0)/2|0;g=e&1;h=f>>6;h=h|0?3-h&255:31;a[d+(i*200|0)+(g*80|0)+28>>0]=h;e=f<<5&2016;c[d+(i*200|0)+(g*80|0)>>2]=e;if(b&128|0)return;c[d+(i*200|0)+(g*80|0)+4>>2]=((c[d+(i*200|0)+192>>2]|0)>>>(h&255))+e;return}function _j(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0;j=c[b+52>>2]|0;k=(e|0)/2|0;i=e&1;e=f>>4;f=f&15;e=(e|0)==0?25192:b+88+(e<<2<<2)|0;c[j+(k*200|0)+(i*80|0)+12>>2]=e;g=d[j+(k*200|0)+(i*80|0)+29>>0]|0;e=c[e+(g<<2)>>2]|0;c[j+(k*200|0)+(i*80|0)+60>>2]=e;h=a[j+(k*200|0)+(i*80|0)+45>>0]|0;if(h<<24>>24==2)c[j+(k*200|0)+(i*80|0)+56>>2]=e;e=(f|0)==0?25192:b+388+(f<<2<<2)|0;c[j+(k*200|0)+(i*80|0)+16>>2]=e;e=c[e+(g<<2)>>2]|0;c[j+(k*200|0)+(i*80|0)+64>>2]=e;if(h<<24>>24!=1)return;c[j+(k*200|0)+(i*80|0)+56>>2]=e;return}function $j(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0;i=c[b+52>>2]|0;j=(e|0)/2|0;h=e&1;e=c[6960+(f>>4<<2)>>2]|0;c[i+(j*200|0)+(h*80|0)+20>>2]=e;g=a[i+(j*200|0)+(h*80|0)+45>>0]|0;if(g<<24>>24==1)c[i+(j*200|0)+(h*80|0)+52>>2]=e;e=b+388+((f<<2&60)<<2)|0;c[i+(j*200|0)+(h*80|0)+24>>2]=e;e=c[e+((d[i+(j*200|0)+(h*80|0)+29>>0]|0)<<2)>>2]|0;c[i+(j*200|0)+(h*80|0)+68>>2]=e;if(g<<24>>24)return;c[i+(j*200|0)+(h*80|0)+56>>2]=e;return}function ak(b){b=b|0;c[b+36>>2]=0;a[b+45>>0]=2;c[b+56>>2]=c[b+60>>2];c[b+48>>2]=0;c[b+52>>2]=268435456;return}function bk(b){b=b|0;var d=0;d=b+45|0;if(!(a[d>>0]|0))return;a[d>>0]=0;d=b+48|0;if(!(c[d>>2]&268435456))c[d>>2]=268435456;c[b+52>>2]=536870912;c[b+56>>2]=c[b+68>>2];return}function ck(b,e){b=b|0;e=e|0;var f=0,g=0;c[e+40>>2]=O(c[e+32>>2]|0,c[b+188>>2]|0)|0;g=(d[b+184>>0]|0)>>>(d[e+8>>0]|0);f=e+29|0;if((d[f>>0]|0|0)!=(g|0)){a[f>>0]=g;c[e+60>>2]=c[(c[e+12>>2]|0)+(g<<2)>>2];c[e+64>>2]=c[(c[e+16>>2]|0)+(g<<2)>>2];c[e+68>>2]=c[(c[e+24>>2]|0)+(g<<2)>>2]}c[e+4>>2]=((c[b+192>>2]|0)>>>(d[e+28>>0]|0))+(c[e>>2]|0);return}function dk(b,d){b=b|0;d=d|0;var e=0;e=d+32820|0;c[b+164>>2]=a[b+160>>0]|0?e:d+32848|0;c[b+168>>2]=e;return}function ek(b){b=b|0;var d=0;d=Om(39488)|0;if(!d){b=0;return b|0}cp(d|0,0,39488)|0;if((fk(d+4836|0)|0)==-1){Pm(d);b=0;return b|0}else{c[d+52>>2]=d+37688;a[d>>0]=8;c[d+4>>2]=3579545;c[d+8>>2]=b;c[d+56>>2]=9;gk(d);Wj(d);b=d;return b|0}return 0}function fk(a){a=a|0;var b=0,d=0;b=a+32788|0;d=c[b>>2]|0;c[b>>2]=d+1;if((d|0)>0){d=0;return d|0}c[a+32792>>2]=0;if(ik(a)|0){d=0;return d|0}c[b>>2]=(c[b>>2]|0)+-1;d=-1;return d|0}function gk(a){a=a|0;var b=0,d=0.0,e=0.0,f=0,g=0,i=0;g=a+8|0;b=c[g>>2]|0;i=a+4|0;e=+(c[i>>2]|0);if(!b)d=0.0;else d=e/+(b|0)/72.0;f=a+16|0;h[f>>3]=d;h[a+24>>3]=1.0/(e/72.0);hk(a);b=0;do{c[a+688+(b<<2)>>2]=~~(+(b|0)*+h[f>>3]*16.0*128.0*.5)>>>0;b=b+1|0}while((b|0)!=1024);b=c[g>>2]|0;if(!b){i=0;f=0;g=a+4796|0;c[g>>2]=f;a=a+4804|0;c[a>>2]=i;return}d=4294967296.0/+(b|0);e=+(c[i>>2]|0)/36.0e5;i=~~(d*6.4*e);f=~~(d*3.7*e);g=a+4796|0;c[g>>2]=f;a=a+4804|0;c[a>>2]=i;return}function hk(a){a=a|0;var b=0,d=0,e=0,f=0.0;d=a+388|0;e=a+88|0;b=a+16|0;c[e>>2]=0;c[e+4>>2]=0;c[e+8>>2]=0;c[e+12>>2]=0;c[d>>2]=0;c[d+4>>2]=0;c[d+8>>2]=0;c[d+12>>2]=0;d=4;do{f=+h[b>>3];f=+(1<<(d>>2)+-1|0)*((d|0)==60?f:(+(d&3|0)*.25+1.0)*f)*268435456.0;c[a+88+(d<<2)>>2]=~~(f/141280.0);c[a+388+(d<<2)>>2]=~~(f/1956.0e3);d=d+1|0}while((d|0)!=61);c[a+328>>2]=268435455;e=c[a+628>>2]|0;c[a+332>>2]=268435455;c[a+632>>2]=e;c[a+336>>2]=268435455;c[a+636>>2]=e;c[a+340>>2]=268435455;c[a+640>>2]=e;c[a+344>>2]=268435455;c[a+644>>2]=e;c[a+348>>2]=268435455;c[a+648>>2]=e;c[a+352>>2]=268435455;c[a+652>>2]=e;c[a+356>>2]=268435455;c[a+656>>2]=e;c[a+360>>2]=268435455;c[a+660>>2]=e;c[a+364>>2]=268435455;c[a+664>>2]=e;c[a+368>>2]=268435455;c[a+668>>2]=e;c[a+372>>2]=268435455;c[a+672>>2]=e;c[a+376>>2]=268435455;c[a+676>>2]=e;c[a+380>>2]=268435455;c[a+680>>2]=e;c[a+384>>2]=268435455;c[a+684>>2]=e;c[a+388>>2]=268435455;c[a+688>>2]=e;return}function ik(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0.0;d=Om(65536)|0;c[a>>2]=d;if(!d){h=0;return h|0}e=Om(32768)|0;f=a+4|0;c[f>>2]=e;if(!e){Pm(d);h=0;return h|0}h=Om(4096)|0;g=a+8|0;c[g>>2]=h;if(!h){Pm(d);Pm(c[f>>2]|0);h=0;return h|0}b=Om(4096)|0;h=a+12|0;c[h>>2]=b;if(!b){Pm(d);Pm(c[f>>2]|0);Pm(c[g>>2]|0);h=0;return h|0}else b=0;do{i=~~(67108863.0/+D(10.0,+(+(b|0)*.0234375/20.0)));c[d+(b<<2)>>2]=i;c[d+(b+8192<<2)>>2]=0-i;b=b+1|0}while((b|0)!=4095);b=4095;do{c[d+(b+8192<<2)>>2]=0;c[d+(b<<2)>>2]=0;b=b+1|0}while((b|0)!=8192);b=d+16380|0;c[e+4096>>2]=b;c[c[f>>2]>>2]=b;b=1;do{i=~~(+bo(1.0/+F(+(+(b|0)*6.283185307179586*.00048828125)))*20.0/.0234375);e=(c[a>>2]|0)+(i<<2)|0;c[(c[f>>2]|0)+(1024-b<<2)>>2]=e;c[(c[f>>2]|0)+(b<<2)>>2]=e;i=(c[a>>2]|0)+(i+8192<<2)|0;c[(c[f>>2]|0)+(2048-b<<2)>>2]=i;c[(c[f>>2]|0)+(b+1024<<2)>>2]=i;b=b+1|0}while((b|0)!=513);e=0;do{b=c[f>>2]|0;if((e|0)<1024)d=c[b+(e<<2)>>2]|0;else d=(c[a>>2]|0)+16384|0;c[b+(e+2048<<2)>>2]=d;d=c[f>>2]|0;b=e+4096|0;c[d+(b<<2)>>2]=c[d+(((e|0)%1024|0)<<2)>>2];d=c[f>>2]|0;if(!(((e|0)/512|0)&1))b=c[d+(b<<2)>>2]|0;else b=(c[a>>2]|0)+16384|0;c[d+(e+6144<<2)>>2]=b;e=e+1|0}while((e|0)!=2048);b=0;do{c[a+16+(b<<2)>>2]=~~(+D(+(+(4095-b|0)*.000244140625),8.0)*4096.0);c[a+16+(b+4096<<2)>>2]=b;b=b+1|0}while((b|0)!=4096);c[a+32784>>2]=4095;b=c[g>>2]|0;d=0;do{j=(+F(+(+(d|0)*6.283185307179586*.001953125))+1.0)*.5;c[b+(d<<2)>>2]=~~(j*42.666666666666664);c[b+(d+512<<2)>>2]=~~(j*204.79999999999998);d=d+1|0}while((d|0)!=512);b=c[h>>2]|0;d=0;do{j=+F(+(+(d|0)*6.283185307179586*.001953125))*15.36;c[b+(d<<2)>>2]=~~(j*.07+256.0);c[b+(d+512<<2)>>2]=~~(j*.14+256.0);d=d+1|0}while((d|0)!=512);b=1;return b|0}function jk(a){a=a|0;kk(a+4836|0);Pm(a);return}function kk(a){a=a|0;var b=0,d=0,e=0;d=a+32788|0;e=c[d>>2]|0;b=e+-1|0;if(e|0?(c[d>>2]=b,b|0):0)return;c[a+32792>>2]=0;lk(a);return}function lk(a){a=a|0;Pm(c[a>>2]|0);Pm(c[a+4>>2]|0);Pm(c[a+8>>2]|0);Pm(c[a+12>>2]|0);return}function mk(b,e,f){b=b|0;e=e|0;f=f|0;if(!(e&1)){a[b+32>>0]=f;return}e=c[b+4828>>2]|0;if(e|0)La[e&1](c[b+4832>>2]|0,0);Xj(b,d[b+32>>0]|0,f);return}function nk(d,e,f,g,i,j,k){d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;var l=0,m=0.0,n=0,o=0,p=0,q=0;p=d+1552|0;o=d+324|0;a:do switch(i<<24>>24){case 0:{q=6;break}case -76:{o=j&255;n=j<<24>>24==0;if(!(c[d+2832>>2]&268435456)){l=e+188|0;if(n){j=l;q=5}else q=7}else{l=e+248|0;if(n){j=l;q=5}else q=7}if((q|0)==5){j=c[j>>2]&255;q=6;break a}else if((q|0)==7){c[l>>2]=o;q=8;break a}break}case 112:{l=j&255;if(!(j<<24>>24))return;a[e+164>>0]=0-(l>>>4);a[e+165>>0]=0;a[e+166>>0]=l&15;c[e+180>>2]=3;return}case 113:{l=j&255;if(!(j<<24>>24))return;a[e+164>>0]=0;a[e+165>>0]=l&15;a[e+166>>0]=0;a[e+167>>0]=0-(l>>>4);c[e+180>>2]=4;return}case 114:{l=j&15;if(!(j<<24>>24))return;a[e+164>>0]=l;a[e+165>>0]=l;a[e+166>>0]=0;c[e+180>>2]=3;return}case 1:{i=c[d+2832>>2]|0;o=j&255;n=j<<24>>24==0;do if(!(i&268435456)){l=e+304|0;if(n){j=c[l>>2]&255;break}else{c[l>>2]=o;break}}else{l=e+248|0;if(n){j=c[l>>2]&255;break}else{c[l>>2]=o;break}}while(0);b:do if(i&32|0?(k|0)==0|(i&2048|0)==0:0){l=j&255;switch((j&255)>>>4&15){case 15:{j=l&15;q=194;break a}case 14:{j=(l&15|16)&255;q=254;break a}default:break b}}while(0);c[e>>2]=c[e>>2]|8;l=j&255;if(!(j<<24>>24)){l=e+288|0;j=c[l>>2]|0;if((j|0)<=0)return;c[l>>2]=0-j;return}else{c[e+288>>2]=0-l;if(!(i&1024))return;c[e+328>>2]=l;return}}case 2:{i=c[d+2832>>2]|0;o=j&255;n=j<<24>>24==0;do if(!(i&268435456)){l=e+304|0;if(n){j=c[l>>2]&255;break}else{c[l>>2]=o;break}}else{l=e+248|0;if(n){j=c[l>>2]&255;break}else{c[l>>2]=o;break}}while(0);c:do if(i&32|0?(k|0)==0|(i&2048|0)==0:0){l=j&255;switch((j&255)>>>4&15){case 15:{j=l&15;q=197;break a}case 14:{j=(l&15|32)&255;q=254;break a}default:break c}}while(0);c[e>>2]=c[e>>2]|8;l=j&255;n=e+288|0;if(!(j<<24>>24)){j=c[n>>2]|0;if((j|0)>=0)return;c[n>>2]=0-j;return}else{c[n>>2]=l;if(!(i&1024))return;c[e+328>>2]=l;return}}case 3:{n=d+2832|0;if(g<<24>>24==0&(c[n>>2]&131072|0)!=0?(c[e+320>>2]|0)==0:0)return;l=c[e+44>>2]|0;if(l>>>0>=(c[d+1692>>2]|0)>>>0)return;if((c[(c[d+1728>>2]|0)+(l*764|0)+36>>2]|0)<=0)return;ok(p,e,g&255);if(!(j<<24>>24))j=c[e+328>>2]&255;else c[e+328>>2]=j&255;l=c[n>>2]|0;n=j&255;j=j<<24>>24!=0;if(!((l&268435456|0)==0|j^1))c[e+248>>2]=n;if(j){if(l&1024|0)c[e+304>>2]=n;c[e+324>>2]=n}c[e>>2]=c[e>>2]|4;return}case 4:{if(!(j<<24>>24))j=c[e+120>>2]&255;else c[e+120>>2]=j&255;l=j&255;if(!(j<<24>>24==0?1:(c[d+2832>>2]&268435456|0)==0))c[e+248>>2]=l;c[e>>2]=c[e>>2]|16;j=l<<2&60;if(j|0)tj(e+104|0,j);j=l>>>4;if(!j)return;uj(e+104|0,j);return}case -84:{if(!(j<<24>>24))j=c[e+120>>2]&255;else c[e+120>>2]=j&255;l=j&255;if(!(j<<24>>24==0?1:(c[d+2832>>2]&268435456|0)==0))c[e+248>>2]=l;c[e>>2]=c[e>>2]|16;j=l&15;if(j|0)tj(e+104|0,j);j=l>>>4;if(!j)return;uj(e+104|0,j);return}case 5:{l=c[e+44>>2]|0;if(l>>>0>=(c[d+1692>>2]|0)>>>0)return;if((c[(c[d+1728>>2]|0)+(l*764|0)+36>>2]|0)>0){ok(p,e,g&255);l=4;q=3;break a}else return}case 6:{l=16;q=3;break}case 7:{if(!(j<<24>>24))j=c[e+140>>2]&255;else c[e+140>>2]=j&255;l=j&255;if(!(j<<24>>24==0?1:(c[d+2832>>2]&268435456|0)==0))c[e+248>>2]=l;c[e>>2]=c[e>>2]|32;j=l&15;if(j|0)tj(e+124|0,j);j=l>>>4;if(!j)return;uj(e+124|0,j);return}case 8:{c[e+344>>2]=j&255;return}case 9:{c[e>>2]=c[e>>2]|256;if(!(j<<24>>24))j=c[e+88>>2]|0;else{j=(j&255)<<8;c[e+88>>2]=j}c[e+92>>2]=j;return}case 10:{q=4;break}case -92:{n=c[e>>2]|0;c[e>>2]=n|8192;if(!(j<<24>>24))return;j=j&255;l=j>>>4;j=j&15;if(!j){c[e+244>>2]=l;return}if(!l){c[e+244>>2]=0-j;return}else{c[e>>2]=n&-8193;return}}case 11:{c[o>>2]=1;c[d+328>>2]=j&255;c[d+340>>2]=0;return}case 12:{c[e>>2]=c[e>>2]|4096;c[e+80>>2]=j&255;return}case 13:{c[o>>2]=1;e=j&255;c[d+340>>2]=((e>>>4)*10|0)+(e&15);return}case 14:{i=c[d+2832>>2]|0;p=(i&268435456|0)==0;do if(!p)if(!(j<<24>>24)){l=c[e+248>>2]&255;break}else{c[e+248>>2]=j&255;l=j;break}else l=j;while(0);j=l&15;do switch((l&255)>>>4&15){case 14:{q=199;break a}case 1:{n=j&255;l=j<<24>>24==0;if(p){j=e+336|0;if(l){j=c[j>>2]&255;q=194;break a}else{c[j>>2]=n;j=n;q=195;break a}}else{j=e+248|0;if(l){j=c[j>>2]&255;q=194;break a}else{c[j>>2]=n;j=n;q=195;break a}}}case 2:{o=j&255;n=j<<24>>24==0;if(p){l=e+340|0;if(n){j=c[l>>2]&255;q=197;break a}}else{l=e+248|0;if(n){j=c[l>>2]&255;q=197;break a}}c[l>>2]=o;q=198;break a}case 3:{c[e+76>>2]=j&255;return}case 4:{d=l&3;vj(e+104|0,(d<<24>>24==2&(i&8388608|0)!=0?d|16:d)&255);return}case 5:{if(!(g<<24>>24==0&(i&536870912|0)!=0)){j=l<<4&255;q=177;break a}return}case 6:{o=j&255;n=c[d+348>>2]|0;if(!(j<<24>>24)){c[n+(f<<3)>>2]=c[d+8>>2];return}l=n+(f<<3)+4|0;j=c[l>>2]|0;if(!j){if((c[n+(f<<3)>>2]|0)>(c[d+8>>2]|0))return;c[l>>2]=o;c[d+344>>2]=f+1;return}e=j+-1|0;c[l>>2]=e;if(e|0){c[d+344>>2]=f+1;return}if(!(i&1))return;c[n+(f<<3)>>2]=(c[d+8>>2]|0)+1;return}case 7:{vj(e+124|0,l&3);return}case 9:{c[e>>2]=c[e>>2]|262144;d=j&255;c[e+212>>2]=d;c[e+216>>2]=d+1;c[e+220>>2]=0;return}case 10:{o=j&255;n=j<<24>>24==0;if(p){l=e+252|0;if(n){j=c[l>>2]&255;q=185;break a}else{c[l>>2]=o;q=185;break a}}else{l=e+248|0;if(n){j=c[l>>2]&255;q=185;break a}else{c[l>>2]=o;q=185;break a}}}case 11:{o=j&255;n=j<<24>>24==0;if(p){l=e+256|0;if(n){j=c[l>>2]&255;q=193;break a}else{c[l>>2]=o;q=193;break a}}else{l=e+248|0;if(n){j=c[l>>2]&255;q=193;break a}else{c[l>>2]=o;q=193;break a}}}case 12:{c[e>>2]=c[e>>2]|262144;d=e+8|0;c[d>>2]=c[d>>2]|8;d=j+1&255;c[e+212>>2]=d;c[e+216>>2]=d;c[e+220>>2]=16;return}case 15:{c[e+360>>2]=j&255;return}default:return}while(0)}case 15:{if((j&255)<32?1:(c[d+28>>2]&1|0)!=0)q=204;else q=206;break}case -90:{q=177;break}case -83:{o=j&255;n=j<<24>>24==0;if(!(c[d+2832>>2]&268435456)){l=e+252|0;if(n){j=c[l>>2]&255;q=185;break a}else{c[l>>2]=o;q=185;break a}}else{l=e+248|0;if(n){j=c[l>>2]&255;q=185;break a}else{c[l>>2]=o;q=185;break a}}}case -82:{o=j&255;n=j<<24>>24==0;if(!(c[d+2832>>2]&268435456)){l=e+252|0;if(n){j=c[l>>2]&255;q=193;break a}else{c[l>>2]=o;q=193;break a}}else{l=e+248|0;if(n){j=c[l>>2]&255;q=193;break a}else{c[l>>2]=o;q=193;break a}}}case -81:{q=194;break}case -80:{q=197;break}case -77:{q=199;break}case -93:{if(c[d+2832>>2]&268435456)if(!(j<<24>>24)){j=c[e+248>>2]&255;q=204;break a}else{j=j&255;c[e+248>>2]=j;q=205;break a}else q=204;break}case -85:{q=206;break}case -121:{l=j&255;switch((j&255)>>>4&15){case 0:{c[e>>2]=c[e>>2]|2097152;c[e+372>>2]=0-(l&15);break}case 1:{c[e>>2]=c[e>>2]|2097152;c[e+372>>2]=l&15;break}default:c[d+20>>2]=((j&255)>20?j:20)&255}h[d+40>>3]=+h[d+2808>>3]*+h[d+2800>>3]/+(c[d+20>>2]|0);return}case -120:{l=d+364|0;if(c[l>>2]|0)return;c[d+360>>2]=j&255;c[l>>2]=1;return}case 16:{e=j&255;q=c[d+2824>>2]|0;c[d+320>>2]=(e|0)>(q|0)?q:e;return}case 17:{l=e+268|0;while(1){if(j<<24>>24)break;j=c[l>>2]|0;if(!(j&255)){q=341;break}else j=j&255}if((q|0)==341)return;c[e>>2]=c[e>>2]|1048576;q=j&255;n=e+260|0;c[l>>2]=q;j=q>>>4;l=q&15;do if(c[d+2832>>2]&32){if((l|0)==15&(j|0)!=0){c[n>>2]=0;break}if((j|0)==15&(l|0)!=0){c[n>>2]=0;j=0-l|0;break}else{c[n>>2]=j-l;j=0;break}}else{c[n>>2]=j-l;j=0}while(0);c[e+264>>2]=j;return}case 20:{c[e+68>>2]=(j&255)+1;return}case 21:{d=j&255;b[e+96>>1]=d;b[e+100>>1]=d;b[e+98>>1]=d;return}case 25:{c[e>>2]=c[e>>2]|2;l=j&255;if(!(j<<24>>24))return;c[e+348>>2]=(l&15)-(l>>>4);return}case -119:{c[e>>2]=c[e>>2]|2;if(!(j<<24>>24))return;j=j&255;l=j>>>4;j=j&15;do if((l|0)!=15)if((j|0)==15){c[e+348>>2]=0;j=0-l|0;break}else{c[e+348>>2]=j-l;j=0;break}else c[e+348>>2]=0;while(0);c[e+352>>2]=j;return}case 27:{do if(c[d+2832>>2]&268435456)if(!(j<<24>>24)){j=c[e+248>>2]&255;q=241;break}else{j=j&255;c[e+248>>2]=j;q=242;break}else q=241;while(0);if((q|0)==241?j<<24>>24:0){j=j&255;q=242}if((q|0)==242)c[e+212>>2]=j;if(g<<24>>24){d=c[e+212>>2]|0;c[e+216>>2]=(d&15)+1;c[e+220>>2]=d>>>4&15}c[e>>2]=c[e>>2]|262144;return}case 29:{o=j&255;n=j<<24>>24==0;do if(!(c[d+2832>>2]&268435456)){l=e+232|0;if(n){j=c[l>>2]&255;break}else{c[l>>2]=o;break}}else{l=e+248|0;if(n){j=c[l>>2]&255;break}else{c[l>>2]=o;break}}while(0);d=j&255;d=(d&240|0)==0?(d|16)&255:j;q=d&255;c[e+224>>2]=((q&15|0)==0?(q|1)&255:d)&255;return}case 33:{q=254;break}case -128:{j=j&255;if((j|0)>(c[d+2820>>2]|0))return;c[e+60>>2]=j;return}case -127:{if(!(j<<24>>24)){j=c[e+280>>2]|0;if(!(j&255))return;else j=j&255}do if(c[d+2832>>2]&32|0){o=j&255;n=o>>>4;l=o&15;if(!((n|0)==15&(l|0)!=0))if((l|0)==15&(n|0)!=0)j=o&240;else break;else j=l;c[e+280>>2]=o;j=j&255;q=271;break a}while(0);o=c[e>>2]|0;c[e>>2]=o|512;if(!(j<<24>>24))return;d=j&255;l=d>>>4;j=d&15;n=e+272|0;c[e+280>>2]=d;if(!j){c[n>>2]=l;return}if(!l){c[n>>2]=0-j;return}else{c[e>>2]=o&-513;return}}case -126:{q=271;break}case -125:switch(j<<24>>24){case 0:{gi(d,f,0);return}case 1:{gi(d,f,2);return}case 2:{gi(d,f,3);return}case 3:{$h(d,f,0);return}case 4:{$h(d,f,1);return}case 5:{$h(d,f,2);return}case 6:{$h(d,f,3);return}default:return}case -124:{c[e+376>>2]=j&255;return}case -123:{c[e+380>>2]=j&255;return}case -118:{c[e>>2]=c[e>>2]|524288;j=j&255;l=j<<4&240;if(l|0)tj(e+144|0,l);j=j>>>4;if(!j)return;uj(e+144|0,j);return}case -117:{vj(e+144|0,j&3);return}case -96:{if(c[d+2832>>2]&32|0?(d=j&255,l=d&15,(d&240|0)==240&(l|0)!=0):0){j=l&255;q=185;break a}if(j<<24>>24)c[e+236>>2]=j&255;c[e>>2]=c[e>>2]|1;return}case -95:{if(c[d+2832>>2]&32|0?(d=j&255,n=d&15,(d&240|0)==240&(n|0)!=0):0){j=n&255;q=193;break a}if(j<<24>>24)c[e+236>>2]=0-(j&255);c[e>>2]=c[e>>2]|1;return}case -91:{n=c[e>>2]|0;c[e>>2]=n|64;if(!(j<<24>>24))return;j=j&255;l=j>>>4;j=j&15;if(!j){c[e+240>>2]=l;return}if(!l){c[e+240>>2]=0-j;return}else{c[e>>2]=n&-65;return}}case -98:case -97:case -99:case -100:{l=j&255;n=i&-2;if(j<<24>>24){j=l>>>4;if(n<<24>>24==-98){c[e+212>>2]=j;c[e+216>>2]=j+1;c[e+220>>2]=0}d=l&15;c[e+384>>2]=(i+99&255)<2?d:0-d|0;c[e+392>>2]=j;c[e+396>>2]=j}j=c[e>>2]|0;if(n<<24>>24==-98){j=j|262144;c[e>>2]=j}c[e>>2]=j|16384;return}case 115:{c[e>>2]=c[e>>2]|16384;c[e+384>>2]=0-(j&255);c[e+392>>2]=1;c[e+396>>2]=1;return}case 116:{c[e>>2]=c[e>>2]|16384;c[e+384>>2]=j&255;c[e+392>>2]=1;c[e+396>>2]=1;return}case 117:{c[e>>2]=c[e>>2]|32768;c[e+388>>2]=0-(j&255);return}case 118:{c[e>>2]=c[e>>2]|32768;c[e+388>>2]=j&255;return}case 123:{l=j&255;j=l&15;d=e+4|0;q=c[d>>2]|0;c[d>>2]=j|0?q|16:q&-17;if(j|0)tj(e+104|0,j<<2);j=l>>>4;if(!j)return;uj(e+104|0,j);return}case 121:{n=e+4|0;l=c[n>>2]|0;c[n>>2]=l|8;d=j&255;c[e+288>>2]=0-d;c[e+304>>2]=d;if(j<<24>>24)return;c[n>>2]=l&-9;return}case 120:{n=e+4|0;l=c[n>>2]|0;c[n>>2]=l|8;d=j&255;c[e+288>>2]=d;c[e+304>>2]=d;if(j<<24>>24)return;c[n>>2]=l&-9;return}case 122:{l=c[e+44>>2]|0;if(l>>>0>=(c[d+1692>>2]|0)>>>0)return;if((c[(c[d+1728>>2]|0)+(l*764|0)+36>>2]|0)<=0)return;l=e+4|0;c[l>>2]=c[l>>2]|4;ok(p,e,g&255);c[e+324>>2]=j&255;if(j<<24>>24)return;c[l>>2]=c[l>>2]&-5;return}case 124:{n=e+4|0;l=c[n>>2]|0;c[n>>2]=l|1;c[e+236>>2]=j&255;if(j<<24>>24)return;c[n>>2]=l&-2;return}case 125:{n=e+4|0;l=c[n>>2]|0;c[n>>2]=l|1;c[e+236>>2]=0-(j&255);if(j<<24>>24)return;c[n>>2]=l&-2;return}case -110:{c[e>>2]=c[e>>2]|16;j=j&255;l=j<<3&120;if(l|0)tj(e+104|0,l);j=j>>>4;if(!j)return;uj(e+104|0,j);return}case 126:{if(!(j<<24>>24))q=339;else{c[d+16>>2]=j&255;q=339}break}case 127:{q=339;break}default:{wm(e,i,j);return}}while(0);switch(q|0){case 3:{c[e>>2]=c[e>>2]|l;q=4;break}case 6:{if(!(j<<24>>24))return;else q=8;break}case 177:{c[e+40>>2]=((j&255)<<16)+-8388608>>16;return}case 194:{if(!(j<<24>>24))return;else{j=j&255;q=195}break}case 197:{if(!(j<<24>>24))return;else q=198;break}case 199:{c[d+332>>2]=j&255;return}case 204:{if(!(j<<24>>24))return;else{j=j&255;q=205}break}case 206:{if((j&255)<=31)return;c[d+20>>2]=j&255;h[d+40>>3]=+h[d+2808>>3]*+h[d+2800>>3]/+(j&255);return}case 254:{c[e>>2]=c[e>>2]|128;switch((j&255)>>>4&15){case 1:{m=-.25;break}case 2:{m=.25;break}default:return}h[e+296>>3]=+(j&15)*m;return}case 271:{c[e>>2]=c[e>>2]|1024;l=j&255;if(!(j<<24>>24))return;c[e+276>>2]=(l>>>4)-(l&15);return}case 339:{c[e+4>>2]=0;return}}do if((q|0)==4){g=c[d+2832>>2]|0;k=(g&32|0)==0;f=e+248|0;while(1){o=j&255;if(!k){l=o>>>4;n=o&15;if((n|0)==15&(l|0)!=0){q=103;break}if((l|0)==15&(n|0)!=0){q=105;break}}if(j<<24>>24){q=107;break}n=c[f>>2]|0;j=n&255;if(!(n&255)){q=109;break}}if((q|0)==103){c[f>>2]=o;j=(j&255)>>>4;q=185;break}else if((q|0)==105){c[f>>2]=o;j=n&255;q=193;break}else if((q|0)==107){l=c[e>>2]|1;c[e>>2]=l;p=e;q=110}else if((q|0)==109){l=c[e>>2]|1;c[e>>2]=l;if(!(j<<24>>24))j=e;else{p=e;q=110}}do if((q|0)==110){n=j&255;i=e+236|0;c[f>>2]=n;o=n>>>4;j=n&15;if(g&512|0){c[i>>2]=j|0?0-j|0:o;j=p;break}if(!j){c[i>>2]=o;j=p;break}if(!o){c[i>>2]=0-j;j=p;break}else{l=l&-2;c[p>>2]=l;j=p;break}}while(0);if(k)return;if(!((n&240|0)==240|(n&15|0)==15))return;c[j>>2]=l|64;c[e+240>>2]=c[e+236>>2];return}else if((q|0)==8){a[e+164>>0]=0;a[e+165>>0]=(j&255)>>>4;a[e+166>>0]=j&15;c[e+180>>2]=3;return}else if((q|0)==195){c[e>>2]=c[e>>2]|128;h[e+296>>3]=+(0-j|0);return}else if((q|0)==198){c[e>>2]=c[e>>2]|128;h[e+296>>3]=+(j&255);return}else if((q|0)==205){c[d+16>>2]=j;return}while(0);if((q|0)==185){c[e>>2]=c[e>>2]|64;c[e+240>>2]=j&255;return}else if((q|0)==193){c[e>>2]=c[e>>2]|64;c[e+240>>2]=0-(j&255);return}}function ok(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,i=0,j=0,k=0,l=0;g=c[b+176>>2]|0;i=c[e+44>>2]|0;j=c[e+16>>2]|0;l=d[g+(i*764|0)+512+(j<<1)>>0]|0;k=c[g+(i*764|0)+756>>2]|0;f=f+-1|0;if(f>>>0<128?i>>>0<(c[b+140>>2]|0)>>>0:0)h[e+312>>3]=+ii((c[k+(l<<6)+12>>2]|0)+f+(a[g+(i*764|0)+512+(j<<1)+1>>0]|0)|0,c[e+40>>2]|0,c[b+1280>>2]&4096,+h[e+32>>3]);c[e+320>>2]=+h[e+24>>3]<+h[e+312>>3]?1:-1;return}function pk(a){a=a|0;var b=0;b=~~(+(c[a+1496>>2]|0)*+h[a+2808>>3]*+h[a+2800>>3]/+(c[a+20>>2]|0)/1.0e3);c[a+1532>>2]=b;cp(c[a+1524>>2]|0,0,b<<((c[a+1500>>2]|0)>>>2&1^3)|0)|0;return}function qk(a){a=a|0;var b=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0;switch(c[a+1512>>2]|0){case 0:{J=7152;break}case 1:{J=7088;break}case 2:{J=7120;break}default:J=7088}pk(a);rk(a,-1,0,0);I=a+960|0;if((c[I>>2]|0)>0){P=a+968|0;i=a+1524|0;K=a+1544|0;L=a+1696|0;Q=a+1732|0;H=a+28|0;b=a+1532|0;e=a+1500|0;R=a+8136|0;M=a+8108|0;f=1;N=0;do{j=c[P>>2]|0;B=j+(N*116|0)|0;a:do if((c[B>>2]|0)>=0){g=c[j+(N*116|0)+24>>2]|0;if((g|0)<1){Ph(a,N,1);break}F=j+(N*116|0)+28|0;l=c[F>>2]|0;c[j+(N*116|0)+32>>2]=l;m=c[i>>2]|0;G=j+(N*116|0)+20|0;E=c[G>>2]|0;C=c[j+(N*116|0)+16>>2]|0;D=O(128-C|0,E)|0;E=O(C+128|0,E)|0;C=j+(N*116|0)+40|0;h=c[C>>2]|0;if(h&32|0){if(!f){f=0;break}Oa[c[(c[M>>2]|0)+24>>2]&31](a,m,c[b>>2]|0,E>>7,D>>7,h&2);f=0;break}A=c[K>>2]|0;A=_o(A|0,((A|0)<0)<<31>>31|0,24)|0;A=Uo(A|0,z|0,g|0,((g|0)<0)<<31>>31|0)|0;if(A){g=c[j+(N*116|0)+48>>2]|0;h=c[L>>2]|0;if((g|0)<(h|0))g=(c[Q>>2]|0)+(g*52|0)|0;else g=(c[R>>2]|0)+((g-h|0)*52|0)|0;u=c[g+40>>2]|0;k=c[b>>2]|0;if((k|0)>0){w=j+(N*116|0)+52|0;y=j+(N*116|0)+36|0;v=((A|0)<0)<<31>>31;x=g+44|0;t=u-(c[g+36>>2]>>((c[H>>2]|0)>>>2&1))|0;r=j+(N*116|0)+112|0;q=j+(N*116|0)+100|0;s=j+(N*116|0)+64|0;p=j+(N*116|0)+60|0;o=u+t|0;g=c[w>>2]|0;h=l;n=m;while(1){if(g>>>0>h>>>0){m=_o(g-h|0,0,16)|0;g=c[y>>2]|0;g=Ro(m|0,z|0,g|0,((g|0)<0)<<31>>31|0)|0;g=Uo(g|0,z|0,A|0,v|0)|0;g=Qo(g|0,z|0,1,0)|0}else g=0;m=(g|0)>(k|0)?k:g;if(c[G>>2]|0){g=m<<((c[e>>2]|0)>>>2&1^1);h=(g|0)>1;if(h){j=c[n+(g+-1<<2)>>2]|0;l=c[n+(g+-2<<2)>>2]|0}else{j=0;l=0}if((m|0)>-1){S=J+((((c[q>>2]|0)>253?3:7)&c[C>>2])<<2)|0;Oa[(d[S>>0]|d[S+1>>0]<<8|d[S+2>>0]<<16|d[S+3>>0]<<24)&31](B,n,m,E,D,A);g=n+(g<<2)|0}else g=n;if(h){c[s>>2]=(c[g+-8>>2]|0)-l;c[p>>2]=(c[g+-4>>2]|0)-j;j=g}else j=g}else j=n;S=O(m,A)|0;S=(c[y>>2]|0)+S|0;h=(c[F>>2]|0)+(S>>16)|0;c[F>>2]=h;c[y>>2]=S&65535;k=k-m|0;if((k|0)<1)break a;g=c[x>>2]|0;if(!(g&2))break;h=h-t|0;c[F>>2]=h;c[w>>2]=u;c[r>>2]=1;if(!(g&4)){g=u;n=j;continue}c[w>>2]=o;h=h-t|0;c[F>>2]=h;g=o;n=j}sk(a,N,0,0,j,k);Ph(a,N,0)}}}while(0);N=N+1|0}while((N|0)<(c[I>>2]|0))}else{i=a+1524|0;e=a+1500|0;b=a+1532|0}S=c[e>>2]|0;h=c[b>>2]<<(S>>>2&1^1);h=(h|0)<24585?h:24585;e=c[a+1520>>2]|0;g=S&2;f=c[a+1504>>2]|0;b=c[i>>2]|0;if(!(S&1)){uk(e,b,h,f,g<<14);S=a+1540|0;c[S>>2]=0;S=a+1536|0;c[S>>2]=0;return}else{tk(e,b,h,f,g<<6);S=a+1540|0;c[S>>2]=0;S=a+1536|0;c[S>>2]=0;return}}function rk(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;if((b|0)<0){b=c[a+1540>>2]|0;f=c[a+1536>>2]|0}else{j=c[a+968>>2]|0;k=j+(b*116|0)+64|0;f=c[k>>2]|0;j=j+(b*116|0)+60|0;b=c[j>>2]|0;c[j>>2]=0;c[k>>2]=0}if(!(b|f))return;if(d){if((e|0)<1)return}else{d=c[a+1524>>2]|0;e=16}j=(f|0)/(e|0)|0;k=(b|0)/(e|0)|0;i=a+1500|0;g=(j|0)>0;h=(k|0)>0;a=f;while(1){if(!e){b=23;break}e=e+-1|0;if(!(c[i>>2]&4)){if(g){f=a-j|0;if((a|0)>(j|0)){c[d>>2]=(c[d>>2]|0)+f;a=f}else a=0}else{f=a-j|0;if((a|0)<(j|0)){c[d>>2]=(c[d>>2]|0)+f;a=f}else a=0}d=d+4|0}if(h){f=b-k|0;if((b|0)>(k|0)){c[d>>2]=(c[d>>2]|0)+f;b=f}else b=0}else{f=b-k|0;if((b|0)<(k|0)){c[d>>2]=(c[d>>2]|0)+f;b=f}else b=0}if(!(b|a)){b=23;break}else d=d+4|0}if((b|0)==23)return}function sk(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;i=c[a+968>>2]|0;h=c[i+(b*116|0)+16>>2]|0;h=(h|0)>-127?h:-127;j=c[i+(b*116|0)+20>>2]|0;if(j|0){l=O(128-h|0,j)|0;o=O(128-e|0,d)|0;k=i+(b*116|0)+64|0;n=c[k>>2]|0;m=((n|0)<0)<<31>>31;o=Wo(n|0,m|0,o|0,((o|0)<0)<<31>>31|0)|0;l=Uo(o|0,z|0,l|0,((l|0)<0)<<31>>31|0)|0;l=Ro(n|0,m|0,l|0,z|0)|0;c[k>>2]=l;k=O(h+128|0,j)|0;e=O(e+128|0,d)|0;d=i+(b*116|0)+60|0;h=c[d>>2]|0;j=((h|0)<0)<<31>>31;e=Wo(h|0,j|0,e|0,((e|0)<0)<<31>>31|0)|0;e=Uo(e|0,z|0,k|0,((k|0)<0)<<31>>31|0)|0;e=Ro(h|0,j|0,e|0,z|0)|0;c[d>>2]=e}if(!f){o=i+(b*116|0)+64|0;n=a+1536|0;c[n>>2]=(c[n>>2]|0)+(c[o>>2]|0);n=i+(b*116|0)+60|0;m=a+1540|0;c[m>>2]=(c[m>>2]|0)+(c[n>>2]|0);c[n>>2]=0;c[o>>2]=0;return}else{rk(a,b,f,g);return}}function tk(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0;h=20-f|0;if(!e)return;i=(g|0)==0;while(1){e=e+-1|0;f=c[d>>2]>>h;f=(f|0)>127?127:((f|0)>-128?f:-128)&255;if(!i)f=(f&255)+g&255;a[b>>0]=f;if(!e)break;else{b=b+1|0;d=d+4|0}}return}function uk(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0;h=12-f|0;if(!e)return;i=(g|0)==0;while(1){e=e+-1|0;f=c[d>>2]>>h;f=(f|0)>32767?32767:((f|0)>-32768?f:-32768)&65535;if(!i)f=(f&65535)+g&65535;b[a>>1]=f;if(!e)break;else{a=a+2|0;d=d+4|0}}return}function vk(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;j=c[a+968>>2]|0;f=c[j+(b*116|0)+48>>2]|0;g=c[a+1696>>2]|0;if((f|0)<(g|0))i=(c[a+1732>>2]|0)+(f*52|0)|0;else i=(c[a+8136>>2]|0)+((f-g|0)*52|0)|0;h=c[i+44>>2]|0;if(h&32768|0)return;do if(!(h&2))f=i+32|0;else{if(h&16|0?(c[j+(b*116|0)+112>>2]|0)==0:0){f=i+32|0;break}f=i+40|0}while(0);f=c[f>>2]|0;g=j+(b*116|0)+52|0;c[g>>2]=f;c[j+(b*116|0)+28>>2]=(f|0)>(d|0)?d:0;c[j+(b*116|0)+36>>2]=e;if(h&4|0)c[g>>2]=(c[i+40>>2]|0)-(c[i+36>>2]>>((c[a+28>>2]|0)>>>2&1))+f;c[j+(b*116|0)+108>>2]=16;return}function wk(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=c[a+968>>2]|0;f=ym(a,c[d+(b*116|0)+48>>2]|0)|0;e=c[f+44>>2]|0;if(e&32768|0){b=0;return b|0}a=c[d+(b*116|0)+28>>2]|0;if(!(e&4)){b=a;return b|0}else{b=c[f+40>>2]|0;return (b>>>0>a>>>0?a:(b<<1)+~a|0)|0}return 0}function xk(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=c[a+968>>2]|0;f=ym(a,d)|0;c[e+(b*116|0)+48>>2]=d;c[e+(b*116|0)+20>>2]=0;c[e+(b*116|0)+16>>2]=0;c[e+(b*116|0)+112>>2]=0;g=e+(b*116|0)+40|0;c[g>>2]=0;d=(c[a+1500>>2]|0)>>>1&2^2;c[g>>2]=d;h=f+44|0;if(c[h>>2]&32768|0){c[g>>2]=d|32;Ma[c[(c[a+8108>>2]|0)+12>>2]&3](a,b,c[f+48>>2]|0);return}yk(a,b,0);c[e+(b*116|0)+68>>2]=c[f+48>>2];e=c[g>>2]|0;d=e|16;c[g>>2]=d;if((c[a+2832>>2]&65536|0)!=0?(c[a+1516>>2]&1|0)!=0:0){d=e|20;c[g>>2]=d}if(c[h>>2]&1|0)c[g>>2]=d|1;vk(a,b,0,0);return}function yk(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=c[a+968>>2]|0;if((c[a+1512>>2]|0)>0)sk(a,b,d,c[e+(b*116|0)+16>>2]|0,0,0);c[e+(b*116|0)+20>>2]=d;if(!(c[e+(b*116|0)+40>>2]&32))return;Ma[c[(c[a+8108>>2]|0)+20>>2]&3](a,b,d>>4);return}function zk(a,b,d){a=a|0;b=b|0;d=d|0;c[a+(b*116|0)+12>>2]=d;c[a+(b*116|0)+24>>2]=ji(d,0)|0;c[a+(b*116|0)+108>>2]=16;return}function Ak(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;f=c[a+968>>2]|0;e=c[f+(b*116|0)+12>>2]|0;c[f+(b*116|0)+24>>2]=ji(e,d)|0;if(!(c[f+(b*116|0)+40>>2]&32))return;Na[c[(c[a+8108>>2]|0)+16>>2]&1](a,b,e,d>>7);return}function Bk(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;switch(d|0){case 2:{a=a+(b*116|0)+100|0;break}case 3:{a=a+(b*116|0)+104|0;break}case 176:{a=a+(b*116|0)+88|0;break}case 177:{a=a+(b*116|0)+92|0;break}case 178:{a=a+(b*116|0)+96|0;break}default:return}c[a>>2]=e;return}function Ck(a,b,d){a=a|0;b=b|0;d=d|0;c[a+(b*116|0)+16>>2]=d;return}function Dk(a,b){a=a|0;b=b|0;return ((b|0)<0|(a|0)<(b|0)?a:b)|0}function Ek(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;e=Qm(2,24585)|0;c[a+1520>>2]=e;if(!e){b=-1;return b|0}f=Qm(4,24585)|0;c[a+1524>>2]=f;if(!f){Pm(e);f=-1;return f|0}else{c[a+1496>>2]=b;c[a+1500>>2]=0;c[a+1504>>2]=1;c[a+1508>>2]=70;c[a+1544>>2]=(d*6864|0)/(b|0)|0;c[a+1512>>2]=1;c[a+1516>>2]=1;c[a+1528>>2]=128;c[a+1540>>2]=0;c[a+1536>>2]=0;f=0;return f|0}return 0}function Fk(a){a=a|0;var b=0;b=a+1520|0;Pm(c[b>>2]|0);a=a+1524|0;Pm(c[a>>2]|0);c[a>>2]=0;c[b>>2]=0;return}function Gk(a,b){a=a|0;b=b|0;return 0}function Hk(a){a=a|0;return 0}function Ik(a){a=a|0;return 0}function Jk(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;p=c[b+68>>2]|0;if(!e)return;q=b+108|0;o=c[b+36>>2]|0;n=c[b+28>>2]|0;while(1){e=e+-1|0;k=a[p+n>>0]|0;k=((O((a[p+(n+1)>>0]|0)-k|0,o)|0)>>16)+k|0;b=c[q>>2]|0;m=O(k,f)|0;k=O(k,g)|0;j=c[d>>2]|0;i=d+4|0;l=c[i>>2]|0;if(!b){c[d>>2]=k+j;b=m+l|0}else{b=16-b|0;c[d>>2]=((O(k,b)|0)>>4)+j;c[i>>2]=((O(m,b)|0)>>4)+l;i=q;b=(c[q>>2]|0)+-1|0}c[i>>2]=b;b=o+h|0;if(!e)break;else{d=d+8|0;o=b&65535;n=(b>>16)+n|0}}return}function Kk(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=c[a+68>>2]|0;p=f>>8;o=g>>8;if(!e)return;n=a+108|0;m=c[a+36>>2]|0;l=c[a+28>>2]|0;while(1){e=e+-1|0;i=b[q+(l<<1)>>1]|0;i=((O((b[q+(l+1<<1)>>1]|0)-i|0,m)|0)>>16)+i|0;f=c[n>>2]|0;k=O(i,p)|0;i=O(i,o)|0;a=c[d>>2]|0;g=d+4|0;j=c[g>>2]|0;if(!f){c[d>>2]=i+a;f=k+j|0}else{f=16-f|0;c[d>>2]=((O(i,f)|0)>>4)+a;c[g>>2]=((O(k,f)|0)>>4)+j;g=n;f=(c[n>>2]|0)+-1|0}c[g>>2]=f;f=m+h|0;if(!e)break;else{d=d+8|0;m=f&65535;l=(f>>16)+l|0}}return}function Lk(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0;k=c[b+68>>2]|0;if(!e)return;j=c[b+36>>2]|0;i=c[b+28>>2]|0;while(1){e=e+-1|0;l=a[k+i>>0]|0;m=O(l,g)|0;b=d+4|0;c[d>>2]=m+(c[d>>2]|0);l=O(l,f)|0;c[b>>2]=(c[b>>2]|0)+l;b=j+h|0;if(!e)break;else{d=d+8|0;j=b&65535;i=(b>>16)+i|0}}return}function Mk(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0;l=c[a+68>>2]|0;k=f>>8;j=g>>8;if(!e)return;i=c[a+36>>2]|0;g=c[a+28>>2]|0;while(1){e=e+-1|0;a=b[l+(g<<1)>>1]|0;m=O(a,j)|0;f=d+4|0;c[d>>2]=m+(c[d>>2]|0);a=O(a,k)|0;c[f>>2]=(c[f>>2]|0)+a;f=i+h|0;if(!e)break;else{d=d+8|0;i=f&65535;g=(f>>16)+g|0}}return}function Nk(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0;l=c[b+68>>2]|0;if(!e)return;m=b+108|0;k=c[b+36>>2]|0;j=c[b+28>>2]|0;while(1){e=e+-1|0;i=a[l+j>>0]|0;i=((O((a[l+(j+1)>>0]|0)-i|0,k)|0)>>16)+i|0;g=c[m>>2]|0;i=O(i,f)|0;if(!g){b=d;g=i}else{b=(O(i,16-g|0)|0)>>4;c[d>>2]=(c[d>>2]|0)+b;b=m;g=-1}c[b>>2]=(c[b>>2]|0)+g;g=k+h|0;if(!e)break;else{d=d+4|0;k=g&65535;j=(g>>16)+j|0}}return}function Ok(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0;m=c[a+68>>2]|0;l=f>>8;if(!e)return;k=a+108|0;j=c[a+36>>2]|0;i=c[a+28>>2]|0;while(1){e=e+-1|0;a=b[m+(i<<1)>>1]|0;a=((O((b[m+(i+1<<1)>>1]|0)-a|0,j)|0)>>16)+a|0;g=c[k>>2]|0;a=O(a,l)|0;if(!g){f=d;g=a}else{f=(O(a,16-g|0)|0)>>4;c[d>>2]=(c[d>>2]|0)+f;f=k;g=-1}c[f>>2]=(c[f>>2]|0)+g;g=j+h|0;if(!e)break;else{d=d+4|0;j=g&65535;i=(g>>16)+i|0}}return}function Pk(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0;j=c[b+68>>2]|0;if(!e)return;i=c[b+36>>2]|0;b=c[b+28>>2]|0;while(1){e=e+-1|0;g=O(a[j+b>>0]|0,f)|0;c[d>>2]=g+(c[d>>2]|0);g=i+h|0;if(!e)break;else{d=d+4|0;i=g&65535;b=(g>>16)+b|0}}return}function Qk(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0;k=c[a+68>>2]|0;j=f>>8;if(!e)return;i=c[a+36>>2]|0;f=c[a+28>>2]|0;while(1){e=e+-1|0;g=O(b[k+(f<<1)>>1]|0,j)|0;c[d>>2]=g+(c[d>>2]|0);g=i+h|0;if(!e)break;else{d=d+4|0;i=g&65535;f=(g>>16)+f|0}}return}function Rk(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;r=c[b+68>>2]|0;C=b+80|0;j=c[C>>2]|0;D=b+84|0;k=c[D>>2]|0;v=c[b+88>>2]|0;w=((v|0)<0)<<31>>31;x=c[b+92>>2]|0;y=((x|0)<0)<<31>>31;A=c[b+96>>2]|0;s=((A|0)<0)<<31>>31;E=b+72|0;i=c[E>>2]|0;F=b+76|0;l=c[F>>2]|0;if(!e){B=j;h=k;f=i;g=l;c[C>>2]=B;c[D>>2]=h;c[E>>2]=f;c[F>>2]=g;return}t=((g|0)<0)<<31>>31;u=((f|0)<0)<<31>>31;B=b+108|0;q=d;p=e;d=l;o=c[b+36>>2]|0;n=c[b+28>>2]|0;while(1){p=p+-1|0;e=a[r+n>>0]|0;e=((O((a[r+(n+1)>>0]|0)-e|0,o)|0)>>16)+e|0;e=Wo(e|0,((e|0)<0)<<31>>31|0,v|0,w|0)|0;b=z;l=Wo(e|0,b|0,g|0,t|0)|0;m=z;H=Wo(i|0,((i|0)<0)<<31>>31|0,x|0,y|0)|0;G=z;d=Wo(d|0,((d|0)<0)<<31>>31|0,A|0,s|0)|0;d=Qo(d|0,z|0,H|0,G|0)|0;d=Qo(d|0,z|0,l|0,m|0)|0;d=Zo(d|0,z|0,16)|0;b=Wo(e|0,b|0,f|0,u|0)|0;e=z;m=Wo(j|0,((j|0)<0)<<31>>31|0,x|0,y|0)|0;l=z;k=Wo(k|0,((k|0)<0)<<31>>31|0,A|0,s|0)|0;k=Qo(m|0,l|0,k|0,z|0)|0;e=Qo(k|0,z|0,b|0,e|0)|0;e=Zo(e|0,z|0,16)|0;k=c[B>>2]|0;b=c[q>>2]|0;l=q+4|0;m=c[l>>2]|0;if(!k){c[q>>2]=d+b;k=e+m|0}else{k=16-k|0;c[q>>2]=((O(d,k)|0)>>4)+b;c[l>>2]=((O(e,k)|0)>>4)+m;l=B;k=(c[B>>2]|0)+-1|0}c[l>>2]=k;k=o+h|0;if(!p)break;else{G=i;H=j;q=q+8|0;j=e;i=d;o=k&65535;n=(k>>16)+n|0;d=G;k=H}}c[C>>2]=e;c[D>>2]=j;c[E>>2]=d;c[F>>2]=i;return}function Sk(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;u=c[a+68>>2]|0;C=a+80|0;j=c[C>>2]|0;D=a+84|0;k=c[D>>2]|0;w=c[a+88>>2]|0;x=((w|0)<0)<<31>>31;y=c[a+92>>2]|0;A=((y|0)<0)<<31>>31;B=c[a+96>>2]|0;v=((B|0)<0)<<31>>31;E=a+72|0;i=c[E>>2]|0;F=a+76|0;l=c[F>>2]|0;if(!e){y=j;A=k;B=i;h=l;c[C>>2]=y;c[D>>2]=A;c[E>>2]=B;c[F>>2]=h;return}t=g>>8;s=f>>8;p=((t|0)<0)<<31>>31;q=((s|0)<0)<<31>>31;r=a+108|0;o=d;g=l;n=c[a+36>>2]|0;m=c[a+28>>2]|0;while(1){e=e+-1|0;f=b[u+(m<<1)>>1]|0;f=((O((b[u+(m+1<<1)>>1]|0)-f|0,n)|0)>>16)+f|0;f=Wo(f|0,((f|0)<0)<<31>>31|0,w|0,x|0)|0;d=z;l=Wo(f|0,d|0,t|0,p|0)|0;a=z;H=Wo(i|0,((i|0)<0)<<31>>31|0,y|0,A|0)|0;G=z;g=Wo(g|0,((g|0)<0)<<31>>31|0,B|0,v|0)|0;g=Qo(g|0,z|0,H|0,G|0)|0;g=Qo(g|0,z|0,l|0,a|0)|0;g=Zo(g|0,z|0,16)|0;d=Wo(f|0,d|0,s|0,q|0)|0;f=z;a=Wo(j|0,((j|0)<0)<<31>>31|0,y|0,A|0)|0;l=z;k=Wo(k|0,((k|0)<0)<<31>>31|0,B|0,v|0)|0;l=Qo(k|0,z|0,a|0,l|0)|0;f=Qo(l|0,z|0,d|0,f|0)|0;f=Zo(f|0,z|0,16)|0;d=c[r>>2]|0;l=c[o>>2]|0;k=o+4|0;a=c[k>>2]|0;if(!d){c[o>>2]=g+l;d=f+a|0}else{d=16-d|0;c[o>>2]=((O(g,d)|0)>>4)+l;c[k>>2]=((O(f,d)|0)>>4)+a;k=r;d=(c[r>>2]|0)+-1|0}c[k>>2]=d;d=n+h|0;if(!e)break;else{H=i;k=j;o=o+8|0;j=f;i=g;n=d&65535;m=(d>>16)+m|0;g=H}}c[C>>2]=f;c[D>>2]=j;c[E>>2]=g;c[F>>2]=i;return}function Tk(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;o=c[b+68>>2]|0;t=b+80|0;g=c[t>>2]|0;u=b+84|0;i=c[u>>2]|0;p=c[b+92>>2]|0;q=((p|0)<0)<<31>>31;r=c[b+96>>2]|0;s=((r|0)<0)<<31>>31;if(!e){s=g;h=i;c[t>>2]=s;c[u>>2]=h;return}m=c[b+88>>2]|0;v=c[b+36>>2]|0;j=c[b+28>>2]|0;m=Wo(m|0,((m|0)<0)<<31>>31|0,f|0,((f|0)<0)<<31>>31|0)|0;n=z;l=b+108|0;k=e;f=i;i=v;while(1){k=k+-1|0;v=a[o+j>>0]|0;v=((O((a[o+(j+1)>>0]|0)-v|0,i)|0)>>16)+v|0;v=Wo(m|0,n|0,v|0,((v|0)<0)<<31>>31|0)|0;b=z;w=Wo(g|0,((g|0)<0)<<31>>31|0,p|0,q|0)|0;e=z;f=Wo(f|0,((f|0)<0)<<31>>31|0,r|0,s|0)|0;f=Qo(f|0,z|0,w|0,e|0)|0;f=Qo(f|0,z|0,v|0,b|0)|0;f=Zo(f|0,z|0,16)|0;b=c[l>>2]|0;if(!b){b=f;e=d}else{b=(O(f,16-b|0)|0)>>4;c[d>>2]=(c[d>>2]|0)+b;b=-1;e=l}c[e>>2]=(c[e>>2]|0)+b;b=i+h|0;if(!k)break;else{w=g;d=d+4|0;g=f;i=b&65535;j=(b>>16)+j|0;f=w}}c[t>>2]=f;c[u>>2]=g;return}function Uk(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;o=c[a+68>>2]|0;t=a+80|0;g=c[t>>2]|0;u=a+84|0;i=c[u>>2]|0;p=c[a+92>>2]|0;q=((p|0)<0)<<31>>31;r=c[a+96>>2]|0;s=((r|0)<0)<<31>>31;if(!e){s=g;h=i;c[t>>2]=s;c[u>>2]=h;return}m=f>>8;n=c[a+88>>2]|0;v=c[a+36>>2]|0;j=c[a+28>>2]|0;m=Wo(n|0,((n|0)<0)<<31>>31|0,m|0,((m|0)<0)<<31>>31|0)|0;n=z;l=a+108|0;k=e;f=i;i=v;while(1){k=k+-1|0;v=b[o+(j<<1)>>1]|0;v=((O((b[o+(j+1<<1)>>1]|0)-v|0,i)|0)>>16)+v|0;v=Wo(m|0,n|0,v|0,((v|0)<0)<<31>>31|0)|0;a=z;w=Wo(g|0,((g|0)<0)<<31>>31|0,p|0,q|0)|0;e=z;f=Wo(f|0,((f|0)<0)<<31>>31|0,r|0,s|0)|0;f=Qo(f|0,z|0,w|0,e|0)|0;f=Qo(f|0,z|0,v|0,a|0)|0;f=Zo(f|0,z|0,16)|0;a=c[l>>2]|0;if(!a){a=f;e=d}else{a=(O(f,16-a|0)|0)>>4;c[d>>2]=(c[d>>2]|0)+a;a=-1;e=l}c[e>>2]=(c[e>>2]|0)+a;a=i+h|0;if(!k)break;else{w=g;d=d+4|0;g=f;i=a&65535;j=j+(a>>16)|0;f=w}}c[t>>2]=f;c[u>>2]=g;return}function Vk(d,e,f,g,h,i){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;q=c[d+68>>2]|0;if(!f)return;r=d+108|0;p=c[d+36>>2]|0;o=c[d+28>>2]|0;while(1){f=f+-1|0;l=p>>6;d=O(a[q+(o+-1)>>0]|0,b[9280+(l<<1)>>1]|0)|0;d=(O(a[q+o>>0]|0,b[11328+(l<<1)>>1]|0)|0)+d|0;d=d+(O(a[q+(o+2)>>0]|0,b[13376+(l<<1)>>1]|0)|0)|0;l=d+(O(a[q+(o+1)>>0]|0,b[15424+(l<<1)>>1]|0)|0)>>14;d=c[r>>2]|0;n=O(l,g)|0;l=O(l,h)|0;k=c[e>>2]|0;j=e+4|0;m=c[j>>2]|0;if(!d){c[e>>2]=l+k;d=n+m|0}else{d=16-d|0;c[e>>2]=((O(l,d)|0)>>4)+k;c[j>>2]=((O(n,d)|0)>>4)+m;j=r;d=(c[r>>2]|0)+-1|0}c[j>>2]=d;d=p+i|0;if(!f)break;else{e=e+8|0;p=d&65535;o=(d>>16)+o|0}}return}function Wk(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=c[a+68>>2]|0;p=f>>8;o=g>>8;if(!e)return;n=a+108|0;m=c[a+36>>2]|0;l=c[a+28>>2]|0;while(1){e=e+-1|0;i=m>>6;f=O(b[q+(l+-1<<1)>>1]|0,b[9280+(i<<1)>>1]|0)|0;f=(O(b[q+(l<<1)>>1]|0,b[11328+(i<<1)>>1]|0)|0)+f|0;f=f+(O(b[q+(l+2<<1)>>1]|0,b[13376+(i<<1)>>1]|0)|0)|0;i=f+(O(b[q+(l+1<<1)>>1]|0,b[15424+(i<<1)>>1]|0)|0)>>14;f=c[n>>2]|0;k=O(i,p)|0;i=O(i,o)|0;a=c[d>>2]|0;g=d+4|0;j=c[g>>2]|0;if(!f){c[d>>2]=i+a;f=k+j|0}else{f=16-f|0;c[d>>2]=((O(i,f)|0)>>4)+a;c[g>>2]=((O(k,f)|0)>>4)+j;g=n;f=(c[n>>2]|0)+-1|0}c[g>>2]=f;f=m+h|0;if(!e)break;else{d=d+8|0;m=f&65535;l=(f>>16)+l|0}}return}function Xk(d,e,f,g,h,i){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0;m=c[d+68>>2]|0;if(!f)return;n=d+108|0;l=c[d+36>>2]|0;k=c[d+28>>2]|0;while(1){f=f+-1|0;j=l>>6;h=O(a[m+(k+-1)>>0]|0,b[9280+(j<<1)>>1]|0)|0;h=(O(a[m+k>>0]|0,b[11328+(j<<1)>>1]|0)|0)+h|0;h=h+(O(a[m+(k+2)>>0]|0,b[13376+(j<<1)>>1]|0)|0)|0;j=h+(O(a[m+(k+1)>>0]|0,b[15424+(j<<1)>>1]|0)|0)>>14;h=c[n>>2]|0;j=O(j,g)|0;if(!h){d=e;h=j}else{d=(O(j,16-h|0)|0)>>4;c[e>>2]=(c[e>>2]|0)+d;d=n;h=-1}c[d>>2]=(c[d>>2]|0)+h;h=l+i|0;if(!f)break;else{e=e+4|0;l=h&65535;k=(h>>16)+k|0}}return}function Yk(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0;m=c[a+68>>2]|0;l=f>>8;if(!e)return;k=a+108|0;j=c[a+36>>2]|0;i=c[a+28>>2]|0;while(1){e=e+-1|0;a=j>>6;g=O(b[m+(i+-1<<1)>>1]|0,b[9280+(a<<1)>>1]|0)|0;g=(O(b[m+(i<<1)>>1]|0,b[11328+(a<<1)>>1]|0)|0)+g|0;g=g+(O(b[m+(i+2<<1)>>1]|0,b[13376+(a<<1)>>1]|0)|0)|0;a=g+(O(b[m+(i+1<<1)>>1]|0,b[15424+(a<<1)>>1]|0)|0)>>14;g=c[k>>2]|0;a=O(a,l)|0;if(!g){f=d;g=a}else{f=(O(a,16-g|0)|0)>>4;c[d>>2]=(c[d>>2]|0)+f;f=k;g=-1}c[f>>2]=(c[f>>2]|0)+g;g=j+h|0;if(!e)break;else{d=d+4|0;j=g&65535;i=(g>>16)+i|0}}return}function Zk(d,e,f,g,h,i){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;s=c[d+68>>2]|0;D=d+80|0;k=c[D>>2]|0;E=d+84|0;l=c[E>>2]|0;w=c[d+88>>2]|0;x=((w|0)<0)<<31>>31;y=c[d+92>>2]|0;A=((y|0)<0)<<31>>31;B=c[d+96>>2]|0;t=((B|0)<0)<<31>>31;F=d+72|0;j=c[F>>2]|0;G=d+76|0;m=c[G>>2]|0;if(!f){C=k;i=l;g=j;h=m;c[D>>2]=C;c[E>>2]=i;c[F>>2]=g;c[G>>2]=h;return}u=((h|0)<0)<<31>>31;v=((g|0)<0)<<31>>31;C=d+108|0;r=e;q=f;e=m;p=c[d+36>>2]|0;o=c[d+28>>2]|0;while(1){q=q+-1|0;f=p>>6;d=O(a[s+(o+-1)>>0]|0,b[9280+(f<<1)>>1]|0)|0;d=(O(a[s+o>>0]|0,b[11328+(f<<1)>>1]|0)|0)+d|0;d=d+(O(a[s+(o+2)>>0]|0,b[13376+(f<<1)>>1]|0)|0)|0;f=d+(O(a[s+(o+1)>>0]|0,b[15424+(f<<1)>>1]|0)|0)>>14;f=Wo(f|0,((f|0)<0)<<31>>31|0,w|0,x|0)|0;d=z;m=Wo(f|0,d|0,h|0,u|0)|0;n=z;I=Wo(j|0,((j|0)<0)<<31>>31|0,y|0,A|0)|0;H=z;e=Wo(e|0,((e|0)<0)<<31>>31|0,B|0,t|0)|0;e=Qo(e|0,z|0,I|0,H|0)|0;e=Qo(e|0,z|0,m|0,n|0)|0;e=Zo(e|0,z|0,16)|0;d=Wo(f|0,d|0,g|0,v|0)|0;f=z;n=Wo(k|0,((k|0)<0)<<31>>31|0,y|0,A|0)|0;m=z;l=Wo(l|0,((l|0)<0)<<31>>31|0,B|0,t|0)|0;l=Qo(n|0,m|0,l|0,z|0)|0;f=Qo(l|0,z|0,d|0,f|0)|0;f=Zo(f|0,z|0,16)|0;l=c[C>>2]|0;d=c[r>>2]|0;m=r+4|0;n=c[m>>2]|0;if(!l){c[r>>2]=e+d;l=f+n|0}else{l=16-l|0;c[r>>2]=((O(e,l)|0)>>4)+d;c[m>>2]=((O(f,l)|0)>>4)+n;m=C;l=(c[C>>2]|0)+-1|0}c[m>>2]=l;l=p+i|0;if(!q)break;else{H=j;I=k;r=r+8|0;k=f;j=e;p=l&65535;o=o+(l>>16)|0;e=H;l=I}}c[D>>2]=f;c[E>>2]=k;c[F>>2]=e;c[G>>2]=j;return}function _k(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;u=c[a+68>>2]|0;C=a+80|0;j=c[C>>2]|0;D=a+84|0;k=c[D>>2]|0;w=c[a+88>>2]|0;x=((w|0)<0)<<31>>31;y=c[a+92>>2]|0;A=((y|0)<0)<<31>>31;B=c[a+96>>2]|0;v=((B|0)<0)<<31>>31;E=a+72|0;i=c[E>>2]|0;F=a+76|0;l=c[F>>2]|0;if(!e){y=j;A=k;B=i;h=l;c[C>>2]=y;c[D>>2]=A;c[E>>2]=B;c[F>>2]=h;return}t=g>>8;s=f>>8;p=((t|0)<0)<<31>>31;q=((s|0)<0)<<31>>31;r=a+108|0;o=d;g=l;n=c[a+36>>2]|0;m=c[a+28>>2]|0;while(1){e=e+-1|0;f=n>>6;d=O(b[u+(m+-1<<1)>>1]|0,b[9280+(f<<1)>>1]|0)|0;d=(O(b[u+(m<<1)>>1]|0,b[11328+(f<<1)>>1]|0)|0)+d|0;d=d+(O(b[u+(m+2<<1)>>1]|0,b[13376+(f<<1)>>1]|0)|0)|0;f=d+(O(b[u+(m+1<<1)>>1]|0,b[15424+(f<<1)>>1]|0)|0)>>14;f=Wo(f|0,((f|0)<0)<<31>>31|0,w|0,x|0)|0;d=z;a=Wo(f|0,d|0,t|0,p|0)|0;l=z;H=Wo(i|0,((i|0)<0)<<31>>31|0,y|0,A|0)|0;G=z;g=Wo(g|0,((g|0)<0)<<31>>31|0,B|0,v|0)|0;g=Qo(g|0,z|0,H|0,G|0)|0;g=Qo(g|0,z|0,a|0,l|0)|0;g=Zo(g|0,z|0,16)|0;d=Wo(f|0,d|0,s|0,q|0)|0;f=z;l=Wo(j|0,((j|0)<0)<<31>>31|0,y|0,A|0)|0;a=z;k=Wo(k|0,((k|0)<0)<<31>>31|0,B|0,v|0)|0;k=Qo(l|0,a|0,k|0,z|0)|0;f=Qo(k|0,z|0,d|0,f|0)|0;f=Zo(f|0,z|0,16)|0;d=c[r>>2]|0;k=o+4|0;a=c[k>>2]|0;l=c[o>>2]|0;if(!d){c[o>>2]=g+l;d=f+a|0}else{d=16-d|0;c[o>>2]=((O(g,d)|0)>>4)+l;c[k>>2]=((O(f,d)|0)>>4)+a;k=r;d=(c[r>>2]|0)+-1|0}c[k>>2]=d;d=n+h|0;if(!e)break;else{H=i;k=j;o=o+8|0;j=f;i=g;n=d&65535;m=(d>>16)+m|0;g=H}}c[C>>2]=f;c[D>>2]=j;c[E>>2]=g;c[F>>2]=i;return}function $k(d,e,f,g,h,i){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;p=c[d+68>>2]|0;u=d+80|0;h=c[u>>2]|0;v=d+84|0;j=c[v>>2]|0;q=c[d+92>>2]|0;r=((q|0)<0)<<31>>31;s=c[d+96>>2]|0;t=((s|0)<0)<<31>>31;if(!f){t=h;i=j;c[u>>2]=t;c[v>>2]=i;return}n=c[d+88>>2]|0;w=c[d+36>>2]|0;k=c[d+28>>2]|0;n=Wo(n|0,((n|0)<0)<<31>>31|0,g|0,((g|0)<0)<<31>>31|0)|0;o=z;m=d+108|0;l=f;g=j;j=w;while(1){l=l+-1|0;w=j>>6;d=O(a[p+(k+-1)>>0]|0,b[9280+(w<<1)>>1]|0)|0;d=(O(a[p+k>>0]|0,b[11328+(w<<1)>>1]|0)|0)+d|0;d=d+(O(a[p+(k+2)>>0]|0,b[13376+(w<<1)>>1]|0)|0)|0;w=d+(O(a[p+(k+1)>>0]|0,b[15424+(w<<1)>>1]|0)|0)>>14;w=Wo(n|0,o|0,w|0,((w|0)<0)<<31>>31|0)|0;d=z;x=Wo(h|0,((h|0)<0)<<31>>31|0,q|0,r|0)|0;f=z;g=Wo(g|0,((g|0)<0)<<31>>31|0,s|0,t|0)|0;g=Qo(x|0,f|0,g|0,z|0)|0;g=Qo(g|0,z|0,w|0,d|0)|0;g=Zo(g|0,z|0,16)|0;d=c[m>>2]|0;if(!d){d=g;f=e}else{d=(O(g,16-d|0)|0)>>4;c[e>>2]=(c[e>>2]|0)+d;d=-1;f=m}c[f>>2]=(c[f>>2]|0)+d;d=j+i|0;if(!l)break;else{x=h;e=e+4|0;h=g;j=d&65535;k=(d>>16)+k|0;g=x}}c[u>>2]=g;c[v>>2]=h;return}function al(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;o=c[a+68>>2]|0;t=a+80|0;g=c[t>>2]|0;u=a+84|0;i=c[u>>2]|0;p=c[a+92>>2]|0;q=((p|0)<0)<<31>>31;r=c[a+96>>2]|0;s=((r|0)<0)<<31>>31;if(!e){s=g;h=i;c[t>>2]=s;c[u>>2]=h;return}m=f>>8;n=c[a+88>>2]|0;v=c[a+36>>2]|0;j=c[a+28>>2]|0;m=Wo(n|0,((n|0)<0)<<31>>31|0,m|0,((m|0)<0)<<31>>31|0)|0;n=z;l=a+108|0;k=e;f=i;i=v;while(1){k=k+-1|0;v=i>>6;a=O(b[o+(j+-1<<1)>>1]|0,b[9280+(v<<1)>>1]|0)|0;a=(O(b[o+(j<<1)>>1]|0,b[11328+(v<<1)>>1]|0)|0)+a|0;a=a+(O(b[o+(j+2<<1)>>1]|0,b[13376+(v<<1)>>1]|0)|0)|0;v=a+(O(b[o+(j+1<<1)>>1]|0,b[15424+(v<<1)>>1]|0)|0)>>14;v=Wo(m|0,n|0,v|0,((v|0)<0)<<31>>31|0)|0;a=z;w=Wo(g|0,((g|0)<0)<<31>>31|0,p|0,q|0)|0;e=z;f=Wo(f|0,((f|0)<0)<<31>>31|0,r|0,s|0)|0;f=Qo(f|0,z|0,w|0,e|0)|0;f=Qo(f|0,z|0,v|0,a|0)|0;f=Zo(f|0,z|0,16)|0;a=c[l>>2]|0;if(!a){a=f;e=d}else{a=(O(f,16-a|0)|0)>>4;c[d>>2]=(c[d>>2]|0)+a;a=-1;e=l}c[e>>2]=(c[e>>2]|0)+a;a=i+h|0;if(!k)break;else{w=g;d=d+4|0;g=f;i=a&65535;j=(a>>16)+j|0;f=w}}c[t>>2]=f;c[u>>2]=g;return}function bl(a,b){a=a|0;b=b|0;var d=0,e=0;e=nl()|0;d=a+8112|0;c[d>>2]=e;if(!e){e=-1;return e|0}ll(a);e=ek(b)|0;c[c[d>>2]>>2]=e;e=(e|0)!=0&1;return e|0}function cl(a){a=a|0;var b=0;b=c[a+8112>>2]|0;dl(a)|0;jk(c[b>>2]|0);ml(b);return 0}function dl(a){a=a|0;Wj(c[c[a+8112>>2]>>2]|0);ll(a);return 0}function el(a,b,e){a=a|0;b=b|0;e=e|0;var f=0;f=c[a+8112>>2]|0;b=il(a,b)|0;if((b|0)<0)return;else a=0;do{kl(f,(c[7240+(((a|0)%2|0)*36|0)+(b<<2)>>2]|0)+(c[7364+(a<<2)>>2]|0)|0,d[e+a>>0]|0);a=a+1|0}while((a|0)!=10);kl(f,b+192|0,d[e+10>>0]|0);e=b+176|0;jl(c[f>>2]|0,e);kl(f,e,0);return}function fl(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;f=c[a+8112>>2]|0;b=il(a,b)|0;if((b|0)<0)return;g=(d|0)%12|0;a=c[7312+(g<<2)>>2]|0;e=((O((c[7312+(g+1<<2)>>2]|0)-a|0,e)|0)/100|0)+a|0;d=((d|0)/12|0)+-2|0;kl(f,b+160|0,e&255);kl(f,b+176|0,((d|0)>0?d:0)<<2&28|e>>>8&3|32);return}function gl(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=c[a+8112>>2]|0;b=il(a,b)|0;if((b|0)<0)return;jl(c[e>>2]|0,b+200|0);a=(c[7276+(b<<2)>>2]|0)+64|0;jl(c[e>>2]|0,a);kl(e,a,63-((d|0)<63?d:63)|0);return}function hl(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;if(!b)return;Sj(c[c[a+8112>>2]>>2]|0,b,d,e,f,g);return} -function Fg(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;x=l;l=l+2944|0;w=x+1920|0;p=x+1792|0;o=x+1280|0;t=x+768|0;v=x;e=p;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));cp(o|0,0,512)|0;cp(t|0,0,512)|0;ro(b,2,0)|0;jg(c,b,13);kg(c,7);ro(b,32,0)|0;e=0;u=0;do{kg(c,22);ro(b,20,1)|0;s=Yi(b)|0;r=s&65535;ij(c,(s&65535)>>>1);u=r+u|0;hj(c,0);hj(c,Vi(b)|0);Vi(b)|0;s=Yi(b)|0;ij(c,(s&65535)>>>1);ij(c,s<<16>>16==0?1:((r-(s&65535)|0)/2|0)&65535);ro(b,6,1)|0;e=e+1|0}while((e|0)!=15);e=w;f=e+29|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));a[w+29>>0]=1;co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);co(w,30,1,c);ro(b,512,0)|0;e=0;f=0;k=0;while(1){g=o+(k<<2)|0;Go(g,1,1,b)|0;h=o+(k<<2)+1|0;Go(h,1,1,b)|0;i=o+(k<<2)+2|0;Go(i,1,1,b)|0;j=o+(k<<2)+3|0;Go(j,1,1,b)|0;g=a[g>>0]|0;if(g<<24>>24==-1){s=e;e=k&255;break}e=(g&255)>(e&255)?g:e;g=a[h>>0]|0;e=(g&255)>(e&255)?g:e;g=a[i>>0]|0;e=(g&255)>(e&255)?g:e;g=a[j>>0]|0;e=(g&255)>(e&255)?g:e;g=k+1|0;f=f+1<<24>>24;if((g&255)<<24>>24>-1)k=g;else{s=e;e=f;k=g;break}}hj(c,e);hj(c,127);if((k|0)>0){e=0;m=0;do{do if(m){if((m|0)>0){g=a[o+(m<<2)>>0]|0;h=o+(m<<2)+1|0;i=o+(m<<2)+2|0;j=o+(m<<2)+3|0;f=0;while(1){if((((a[o+(f<<2)>>0]|0)==g<<24>>24?(a[o+(f<<2)+1>>0]|0)==(a[h>>0]|0):0)?(a[o+(f<<2)+2>>0]|0)==(a[i>>0]|0):0)?(a[o+(f<<2)+3>>0]|0)==(a[j>>0]|0):0){n=40;break}f=f+1|0;if((f|0)>=(m|0)){n=13;break}}if((n|0)==13){f=p+m|0;n=14;break}else if((n|0)==40){n=0;a[p+m>>0]=a[p+f>>0]|0;break}}}else{f=p;n=14}while(0);if((n|0)==14){n=0;a[f>>0]=e;e=(e&255)+1&255}m=m+1|0}while((m|0)!=(k|0));f=1;g=0;i=0;do{a:do if(!i)n=22;else{if((i|0)<=0)if(f<<24>>24==2){f=2;break}else{f=1;n=22;break}f=a[p+i>>0]|0;h=0;while(1){if(f<<24>>24==(a[p+h>>0]|0)){f=2;break a}h=h+1|0;if((h|0)>=(i|0)){f=1;n=22;break}}}while(0);if((n|0)==22){n=0;g=g&255;a[t+(g<<2)>>0]=a[o+(i<<2)>>0]|0;a[t+(g<<2)+1>>0]=a[o+(i<<2)+1>>0]|0;a[t+(g<<2)+2>>0]=a[o+(i<<2)+2>>0]|0;a[t+(g<<2)+3>>0]=a[o+(i<<2)+3>>0]|0;g=g+1&255}i=i+1|0}while((i|0)!=(k|0))}else e=0;co(p,128,1,c);jj(c,1294879534);r=e&255;if(!(e<<24>>24)){w=s&255;w=w*192|0;w=w+1728|0;ro(b,w,0)|0;jg(c,b,u);l=x;return 0}k=v+192|0;m=v+384|0;n=v+576|0;o=0;do{cp(w|0,0,1024)|0;cp(v|0,0,768)|0;ro(b,((d[t+(o<<2)>>0]|0)*192|0)+1536|0,0)|0;Go(v,192,1,b)|0;ro(b,((d[t+(o<<2)+1>>0]|0)*192|0)+1536|0,0)|0;Go(k,192,1,b)|0;ro(b,((d[t+(o<<2)+2>>0]|0)*192|0)+1536|0,0)|0;Go(m,192,1,b)|0;ro(b,((d[t+(o<<2)+3>>0]|0)*192|0)+1536|0,0)|0;Go(n,192,1,b)|0;p=0;do{q=p<<4;j=p*3|0;h=d[v+j>>0]|0;a[w+q>>0]=a[21653+(h<<1)>>0]|0;a[w+(q|1)>>0]=a[21653+(h<<1)+1>>0]|0;h=j+1|0;f=v+h|0;e=a[f>>0]|0;g=e&255;if((g&15|0)==13){e=g+253&255;a[f>>0]=e}a[w+(q|2)>>0]=e;i=j+2|0;a[w+(q|3)>>0]=a[v+i>>0]|0;f=d[v+192+j>>0]|0;a[w+(q|4)>>0]=a[21653+(f<<1)>>0]|0;a[w+(q|5)>>0]=a[21653+(f<<1)+1>>0]|0;f=v+192+h|0;e=a[f>>0]|0;g=e&255;if((g&15|0)==13){e=g+253&255;a[f>>0]=e}a[w+(q|6)>>0]=e;a[w+(q|7)>>0]=a[v+192+i>>0]|0;f=d[v+384+j>>0]|0;a[w+(q|8)>>0]=a[21653+(f<<1)>>0]|0;a[w+(q|9)>>0]=a[21653+(f<<1)+1>>0]|0;f=v+384+h|0;e=a[f>>0]|0;g=e&255;if((g&15|0)==13){e=g+253&255;a[f>>0]=e}a[w+(q|10)>>0]=e;a[w+(q|11)>>0]=a[v+384+i>>0]|0;f=d[v+576+j>>0]|0;a[w+(q|12)>>0]=a[21653+(f<<1)>>0]|0;a[w+(q|13)>>0]=a[21653+(f<<1)+1>>0]|0;f=v+576+h|0;e=a[f>>0]|0;g=e&255;if((g&15|0)==13){e=g+253&255;a[f>>0]=e}a[w+(q|14)>>0]=e;a[w+(q|15)>>0]=a[v+576+i>>0]|0;p=p+1|0}while((p|0)!=64);co(w,1024,1,c);o=o+1|0}while((o|0)!=(r|0));w=s&255;w=w*192|0;w=w+1728|0;ro(b,w,0)|0;jg(c,b,u);l=x;return 0}function Gg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;if((gj(b)|0)==1414679345)e=0;else{c=-1;return c|0}do{if((d[b+(e<<3|6)>>0]|0)>15){h=-1;i=11;break}e=e+1|0}while((e|0)<31);if((i|0)==11)return h|0;if((a[b+252>>0]|0)<1){c=-1;return c|0}else{f=0;g=0}do{j=a[b+(f+254)>>0]|0;e=j&255;if(j<<24>>24<0){h=-1;i=11;break}g=(e|0)>(g|0)?e:g;f=f+1|0}while((f|0)<128);if((i|0)==11)return h|0;f=(g<<8)+256|0;a:do if((f|0)>0){e=0;while(1){if((d[b+((e<<2)+382)>>0]|0)>19){h=-1;break}e=e+1|0;if((e|0)>=(f|0))break a}return h|0}while(0);ng(0,c,0);j=0;return j|0}function Hg(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;kg(b,20);if((aj(a)|0)==1414679345){c=0;e=0}else{ro(a,-4,1)|0;c=0;e=0}do{kg(b,22);d=Yi(a)|0;ij(b,d);e=((d&65535)<<1)+e|0;hj(b,Vi(a)|0);hj(b,Vi(a)|0);ij(b,Yi(a)|0);ij(b,Yi(a)|0);c=c+1|0}while((c|0)!=31);hj(b,Vi(a)|0);hj(b,Vi(a)|0);c=0;d=0;do{f=Vi(a)|0;hj(b,f);d=(f&255)>(d&255)?f:d;c=c+1|0}while((c|0)!=128);c=d+1<<24>>24;jj(b,1294879534);if(!(aj(a)|0)){f=c&255;f=f<<10;jg(b,a,f);jg(b,a,e);return 0}ro(a,-4,1)|0;f=c&255;f=f<<10;jg(b,a,f);jg(b,a,e);return 0}function Ig(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;h=0;k=0;while(1){n=h<<3;g=b+n|0;e=cj(a[g>>0]|0,a[g+1>>0]|0)|0;i=(e&65535)<<1;f=g+4|0;f=cj(a[f>>0]|0,a[f+1>>0]|0)|0;g=g+6|0;g=cj(a[g>>0]|0,a[g+1>>0]|0)|0;j=(g&65535)<<1;k=i+k|0;if((d[b+(n|2)>>0]|0)>15){m=-1;j=20;break}if(j>>>0>(i+2|0)>>>0|(g<<16>>16!=1?(j+((f&65535)<<1)|0)>>>0>i>>>0:0)){m=-1;j=20;break}if(f<<16>>16!=0&(g&65535)<2){m=-1;j=20;break}h=h+1|0;if(!(e<<16>>16==0|g<<16>>16!=0)){m=-1;j=20;break}if((h|0)>=31){j=7;break}}if((j|0)==7){if((k|0)<3){n=-1;return n|0}e=a[b+248>>0]|0;if(e<<24>>24<1){n=-1;return n|0}f=(e&255)+3|0;h=0;i=0;while(1){e=a[b+(h+250)>>0]|0;g=e&255;if(e<<24>>24<0){m=-1;j=20;break}i=(g|0)>(i|0)?g:i;if(!((h|0)<=(f|0)|e<<24>>24==0)){m=-1;j=20;break}h=h+1|0;if((h|0)>=128){j=11;break}}if((j|0)==11){h=(i<<8)+256|0;a:do if((h|0)>0){f=0;while(1){g=f<<2;e=a[b+(g+378)>>0]|0;if((e&255)>19&e<<24>>24!=74){m=-1;j=20;break}f=f+1|0;if(((d[b+(g+379)>>0]|0|(e&15)<<8)+-1|0)>>>0<=111){m=-1;j=20;break}if((f|0)>=(h|0)){l=0;break a}}if((j|0)==20)return m|0}else l=0;while(0);do{i=b+(l<<3)|0;n=((cj(a[i>>0]|0,a[i+1>>0]|0)|0)&65535)<<1;k=i+4|0;k=(cj(a[k>>0]|0,a[k+1>>0]|0)|0)&65535;i=i+6|0;l=l+1|0;if(((cj(a[i>>0]|0,a[i+1>>0]|0)|0)&65535)+k<<1>>>0>(n+2|0)>>>0){m=-1;j=20;break}}while((l|0)<31);if((j|0)==20)return m|0;ng(0,c,0);n=0;return n|0}else if((j|0)==20)return m|0}else if((j|0)==20)return m|0;return 0}function Jg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;j=cj(a[b+2>>0]|0,a[b+3>>0]|0)|0;m=j&65535;if(j<<16>>16==0|(j&1)!=0){c=-1;return c|0}f=d[b+1>>0]|0;if((f&15|0)!=12){c=-1;return c|0}j=(d[b>>0]|0)<<4&240|f>>>4;if((j+-1|0)>>>0>30){c=-1;return c|0}i=j<<4;f=i|15;if((f|0)>(e|0)){c=f-e|0;return c|0}else f=0;while(1){if((d[b+(f<<4|15)>>0]|0)>64){o=-1;n=22;break}f=f+1|0;if((f|0)>=(j|0)){k=0;l=0;break}}if((n|0)==22)return o|0;while(1){g=b+(k<<4)|0;n=g+12|0;n=cj(a[n>>0]|0,a[n+1>>0]|0)|0;h=(n&65535)<<1;f=g+20|0;f=cj(a[f>>0]|0,a[f+1>>0]|0)|0;g=g+22|0;g=cj(a[g>>0]|0,a[g+1>>0]|0)|0;if((f|n)<<16>>16<0){o=-1;n=22;break}if((((f&65535)<<1)+(g&65535)|0)>>>0>(h+2|0)>>>0){o=-1;n=22;break}if(f<<16>>16==0&g<<16>>16!=0){o=-1;n=22;break}l=h+l|0;k=k+1|0;if((k|0)>=(j|0)){n=12;break}}if((n|0)==12){if((l|0)<5){c=-1;return c|0}g=i|12;f=b+g|0;i=0;j=0;do{l=f+i|0;l=cj(a[l>>0]|0,a[l+1>>0]|0)|0;h=l&65535;if(l&7){o=-1;n=22;break}j=(h|0)>(j|0)?h:j;i=i+2|0}while((i|0)<(m|0));if((n|0)==22)return o|0;g=m+8+g+j|0;m=cj(a[b+6>>0]|0,a[b+7>>0]|0)|0;h=m&65535;if(!((m&65535)>191?((m&65535)%192|0)<<16>>16==0:0)){c=-1;return c|0}f=h+g|0;if((f|0)>(e|0)){c=f-e|0;return c|0}else f=0;do{if((d[b+(f+g)>>0]|0)>73){o=-1;n=22;break}f=f+3|0}while((f|0)<(h|0));if((n|0)==22)return o|0;ng(0,c,0);c=0;return c|0}else if((n|0)==22)return o|0;return 0}function Kg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;v=l;l=l+3200|0;t=v+2176|0;m=v+2048|0;s=v;g=m;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));cp(s|0,0,2048)|0;r=Vi(b)|0;g=((Vi(b)|0)&255)>>>4;kg(e,20);k=((Yi(b)|0)&65535)>>>1;j=k&255;Yi(b)|0;Yi(b)|0;g=(r&255)<<4&240|g;if(g){f=0;i=0;do{aj(b)|0;kg(e,22);r=Yi(b)|0;ij(e,r);i=((r&65535)<<1)+i|0;hj(e,Vi(b)|0);hj(e,Vi(b)|0);aj(b)|0;r=Yi(b)|0;ij(e,((Yi(b)|0)&65535)>>>1);ij(e,r);f=f+1|0}while((f|0)<(g|0));g=t;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[t+29>>0]=1;if((f|0)<31){g=i;u=5}}else{g=t;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[t+29>>0]=1;f=0;g=0;u=5}if((u|0)==5){do{co(t,30,1,e);f=f+1|0}while((f|0)!=31);i=g}hj(e,j);hj(e,127);Yi(b)|0;Yi(b)|0;r=k&255;f=r&65535;if(!(r<<16>>16))f=1;else{g=0;h=0;do{q=Yi(b)|0;r=q&255;a[m+g>>0]=r;h=(q&255)>>>0>(h&255)>>>0?r:h;g=g+1|0}while((g|0)<(f|0));f=h+1<<24>>24}co(m,128,1,e);jj(e,1294879534);r=f&255;if(!(f<<24>>24)){u=Ho(b)|0;t=192;u=t+u|0;ro(b,u,0)|0;jg(e,b,i);l=v;return 0}else{f=0;g=0}do{q=(Yi(b)|0)&65535;c[s+(f<<4)>>2]=q;q=(q|0)>(g|0)?q:g;p=(Yi(b)|0)&65535;c[s+(f<<4)+4>>2]=p;q=(p|0)>(q|0)?p:q;p=(Yi(b)|0)&65535;c[s+(f<<4)+8>>2]=p;q=(p|0)>(q|0)?p:q;p=(Yi(b)|0)&65535;c[s+(f<<4)+12>>2]=p;g=(p|0)>(q|0)?p:q;f=f+1|0}while((f|0)!=(r|0));f=g+192|0;g=Ho(b)|0;n=0;do{cp(t|0,0,1024)|0;o=0;do{ro(b,(c[s+(n<<4)+(3-o<<2)>>2]|0)+g|0,0)|0;q=o<<2;p=0;do{m=(p<<4)+q|0;w=Vi(b)|0;h=Vi(b)|0;j=Vi(b)|0;k=(w&255)>>>1&255;a[t+m>>0]=d[21653+(k<<1)>>0]|0|(w&255)<<4&16;a[t+(m|1)>>0]=a[21653+(k<<1)+1>>0]|0;k=h&255;switch(h&15){case 8:{h=k&240;break}case 7:{h=(k&240|10)&255;u=19;break}case 5:case 6:{u=19;break}case 11:{j=((j&255)+4|0)>>>1&255;break}default:{}}if((u|0)==19){u=0;w=j&255;j=((j&255)>128?256-w|0:w<<4)&255}a[t+(m|2)>>0]=h;a[t+(m|3)>>0]=j;p=p+1|0}while((p|0)!=64);o=o+1|0}while((o|0)!=4);co(t,1024,1,e);n=n+1|0}while((n|0)!=(r|0));w=f+g|0;ro(b,w,0)|0;jg(e,b,i);l=v;return 0}function Lg(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;t=l;l=l+32|0;s=t+16|0;r=t+8|0;q=t;if((f|0)<1024){s=1024-f|0;l=t;return s|0}p=d[b+3>>0]|0;n=d[b+2>>0]<<8|p;if((p&1|0)!=0|(n|0)==0){s=-1;l=t;return s|0}g=d[b+1>>0]|0;if((g&15|0)!=12){s=-1;l=t;return s|0}p=d[b>>0]<<4&240|g>>>4;if((p+-1|0)>>>0>30){s=-1;l=t;return s|0}else g=0;while(1){if((d[b+(g<<4|15)>>0]|0)>64){o=-1;m=27;break}g=g+1|0;if((g|0)>=(p|0)){j=0;k=0;break}}if((m|0)==27){l=t;return o|0}while(1){h=j<<4;m=d[b+(h|12)>>0]<<8;i=(m|d[b+(h|13)>>0])<<1;u=d[b+(h+20)>>0]<<8;g=u|d[b+(h+21)>>0];h=d[b+(h+22)>>0]<<8|d[b+(h+23)>>0];if(((u|m)&32768|0)!=0|h>>>0>32767){o=-1;m=27;break}if((g|0)==0&(h|0)!=0|h+g<<1>>>0>(i+2|0)>>>0){o=-1;m=27;break}k=i+k|0;j=j+1|0;if((j|0)>=(p|0)){m=11;break}}if((m|0)==11){if((k|0)<5){u=-1;l=t;return u|0}g=p<<4|12;i=0;j=0;do{h=i+g|0;h=d[b+h>>0]<<8|d[b+(h|1)>>0];if((h&65528|0)!=(h|0)){o=-1;m=27;break}j=(h|0)>(j|0)?h:j;i=i+2|0}while((i|0)<(n|0));if((m|0)==27){l=t;return o|0}k=n+8+g+j|0;m=d[b+6>>0]<<8|d[b+7>>0];if(!(m>>>0>191&((m>>>0)%192|0|0)==0)){u=-1;l=t;return u|0}g=k+16+m|0;if((g|0)>(f|0)){u=g-f|0;l=t;return u|0}else j=0;while(1){h=j+k|0;g=a[b+h>>0]|0;if((g&255)>73){m=19;break}i=d[b+(h+1)>>0]|0;if((i>>>4|(g&255)<<4&16)>>>0>p>>>0){m=21;break}if((i&15|0)==0?a[b+(h+2)>>0]|0:0){m=24;break}g=j+3|0;if((g|0)<(m|0))j=g;else{m=26;break}}if((m|0)==19){c[q>>2]=j;Jo(21936,q);u=-1;l=t;return u|0}else if((m|0)==21){c[r>>2]=j;Jo(21954,r);u=-1;l=t;return u|0}else if((m|0)==24){c[s>>2]=j;Jo(21971,s);u=-1;l=t;return u|0}else if((m|0)==26){ng(0,e,0);u=0;l=t;return u|0}}else if((m|0)==27){l=t;return o|0}return 0}function Mg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;v=l;l=l+3200|0;s=v+2176|0;m=v+2048|0;t=v;g=m;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));cp(t|0,0,2048)|0;g=Vi(b)|0;g=(g&255)<<4&240|((Vi(b)|0)&255)>>>4;kg(e,20);Vi(b)|0;j=((Vi(b)|0)&255)>>>1;k=j&255;Yi(b)|0;Yi(b)|0;if(g){f=0;i=0;do{aj(b)|0;kg(e,22);r=Yi(b)|0;ij(e,r);i=((r&65535)<<1)+i|0;hj(e,Vi(b)|0);hj(e,Vi(b)|0);aj(b)|0;r=Yi(b)|0;ij(e,Yi(b)|0);ij(e,r);f=f+1|0}while((f|0)<(g|0));g=s;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[s+29>>0]=1;if((f|0)<31){g=i;u=5}}else{g=s;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[s+29>>0]=1;f=0;g=0;u=5}if((u|0)==5){do{co(s,30,1,e);f=f+1|0}while((f|0)!=31);i=g}hj(e,j);hj(e,127);ro(b,2,1)|0;ro(b,2,1)|0;if(!(j<<24>>24))r=0;else{g=0;f=0;do{r=((Yi(b)|0)&65535)>>>3;a[m+g>>0]=r;r=r&255;f=(r|0)>(f|0)?r:f;g=g+1|0}while((g|0)<(k|0));r=f}co(m,128,1,e);jj(e,1294879534);f=0;q=0;while(1){p=(Yi(b)|0)&65535;c[t+(f<<4)>>2]=p;p=(p|0)>(q|0)?p:q;o=(Yi(b)|0)&65535;c[t+(f<<4)+4>>2]=o;p=(o|0)>(p|0)?o:p;o=(Yi(b)|0)&65535;c[t+(f<<4)+8>>2]=o;p=(o|0)>(p|0)?o:p;o=(Yi(b)|0)&65535;c[t+(f<<4)+12>>2]=o;q=(o|0)>(p|0)?o:p;if((f|0)>=(r|0))break;else f=f+1|0}k=Ho(b)|0;m=0;while(1){cp(s|0,0,1024)|0;n=0;do{ro(b,(c[t+(m<<4)+(3-n<<2)>>2]|0)+k|0,0)|0;p=n<<2;o=0;do{j=(o<<4)+p|0;w=Vi(b)|0;f=Vi(b)|0;g=Vi(b)|0;h=(w&255)>>>1&255;a[s+j>>0]=d[21653+(h<<1)>>0]|0|(w&255)<<4&16;a[s+(j|1)>>0]=a[21653+(h<<1)+1>>0]|0;h=f&255;switch(f&15){case 8:{f=h&240;break}case 7:{f=(h&240|10)&255;u=17;break}case 5:case 6:{u=17;break}case 14:{g=g+-1<<24>>24;break}case 11:{g=((g&255)+4|0)>>>1&255;break}default:{}}if((u|0)==17){u=0;w=g&255;g=((g&255)>128?256-w|0:w<<4)&255}a[s+(j|2)>>0]=f;a[s+(j|3)>>0]=g;o=o+1|0}while((o|0)!=64);n=n+1|0}while((n|0)!=4);co(s,1024,1,e);if((m|0)<(r|0))m=m+1|0;else break}ro(b,q+192+k|0,0)|0;jg(e,b,i);l=v;return 0}function Ng(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if((e|0)<10){c=10-e|0;return c|0}n=cj(a[b+2>>0]|0,a[b+3>>0]|0)|0;l=n&65535;if(n<<16>>16==0|(l&1|0)!=0){c=-1;return c|0}f=d[b+1>>0]|0;if((f&15|0)!=12){c=-1;return c|0}n=d[b>>0]<<4&240|f>>>4;if((n+-1|0)>>>0>30){c=-1;return c|0}else f=0;while(1){if((d[b+(f<<4|9)>>0]|0)>64){o=-1;k=30;break}f=f+1|0;if((f|0)>=(n|0)){i=0;j=0;break}}if((k|0)==30)return o|0;while(1){g=b+(i<<4)|0;m=g+14|0;m=cj(a[m>>0]|0,a[m+1>>0]|0)|0;h=(m&65535)<<1;f=g+20|0;f=cj(a[f>>0]|0,a[f+1>>0]|0)|0;g=g+22|0;g=cj(a[g>>0]|0,a[g+1>>0]|0)|0;if((f|m|g)<<16>>16<0){o=-1;k=30;break}if((g&65535)+(f&65535)<<1>>>0>(h+2|0)>>>0){o=-1;k=30;break}if(f<<16>>16==0&g<<16>>16!=0){o=-1;k=30;break}j=h+j|0;i=i+1|0;if((i|0)>=(n|0)){k=12;break}}if((k|0)==12){if((j|0)<5){c=-1;return c|0}g=n<<4|12;f=b+g|0;i=0;j=0;do{h=f+i|0;h=(cj(a[h>>0]|0,a[h+1>>0]|0)|0)&65535;if(h&7|0){o=-1;k=30;break}j=(h|0)>(j|0)?h:j;i=i+2|0}while((i|0)<(l|0));if((k|0)==30)return o|0;l=l+8+g+j|0;k=cj(a[b+6>>0]|0,a[b+7>>0]|0)|0;m=k&65535;if((k&65535)<64){c=-1;return c|0}f=m+l|0;if((f|0)>(e|0)){c=f-e|0;return c|0}k=m+-3|0;f=0;a:while(1){h=f+l|0;g=a[b+h>>0]|0;if(g<<24>>24>-1){if((g&255)>73){o=-1;k=30;break}j=a[b+(h+1)>>0]|0;i=j&255;switch(j&15){case 10:{o=-1;k=30;break a}case 13:{if((d[b+(h+2)>>0]|0)>64){o=-1;k=30;break a}break}default:{}}if(((g&255)<<4&16|i>>>4)>>>0>n>>>0){o=-1;k=30;break}if((g|j)<<24>>24==0?((f|0)<(k|0)?(a[b+(h+2)>>0]|0)==0:0):0){o=-1;k=30;break}f=f+2|0}f=f+1|0;if((f|0)>=(m|0)){k=29;break}}if((k|0)==29){ng(0,c,0);c=0;return c|0}else if((k|0)==30)return o|0}else if((k|0)==30)return o|0;return 0}function Og(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+3200|0;t=w+2176|0;q=w+2048|0;u=w;h=q;i=h+128|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));cp(u|0,0,2048)|0;n=Vi(b)|0;n=(n&255)<<4&240|((Vi(b)|0)&255)>>>4;kg(e,20);Vi(b)|0;o=((Vi(b)|0)&255)>>>1;p=o&255;Yi(b)|0;Yi(b)|0;if(n){h=t+6|0;m=t+1|0;j=t+14|0;k=t+12|0;i=t+7|0;f=0;g=0;do{Go(t,1,16,b)|0;kg(e,22);s=cj(a[h>>0]|0,a[i>>0]|0)|0;ij(e,s);g=((s&65535)<<1)+g|0;hj(e,a[t>>0]|0);hj(e,a[m>>0]|0);co(j,2,1,e);co(k,2,1,e);f=f+1|0}while((f|0)<(n|0));h=t;i=h+29|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));a[t+29>>0]=1;if((f|0)<31)v=6;else s=g}else{h=t;i=h+29|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));a[t+29>>0]=1;f=0;g=0;v=6}if((v|0)==6){do{co(t,30,1,e);f=f+1|0}while((f|0)!=31);s=g}hj(e,o);hj(e,127);Yi(b)|0;Yi(b)|0;if(!(o<<24>>24))r=0;else{g=0;f=0;do{r=((Yi(b)|0)&65535)>>>3;a[q+g>>0]=r;r=r&255;f=(r|0)>(f|0)?r:f;g=g+1|0}while((g|0)<(p|0));r=f}co(q,128,1,e);jj(e,1294879534);f=0;while(1){c[u+(f<<4)>>2]=(Yi(b)|0)&65535;c[u+(f<<4)+4>>2]=(Yi(b)|0)&65535;c[u+(f<<4)+8>>2]=(Yi(b)|0)&65535;c[u+(f<<4)+12>>2]=(Yi(b)|0)&65535;if((f|0)<(r|0))f=f+1|0;else break}o=Ho(b)|0;p=0;f=0;while(1){cp(t|0,0,1024)|0;q=0;do{ro(b,(c[u+(p<<4)+(3-q<<2)>>2]|0)+o|0,0)|0;n=q<<2;g=0;do{m=(g<<4)+n|0;j=Vi(b)|0;k=j&255;if(j<<24>>24>=0){h=Vi(b)|0;i=Vi(b)|0;j=(j&255)>>>1&255;a[t+m>>0]=d[21653+(j<<1)>>0]|0|k<<4&16;a[t+(m|1)>>0]=a[21653+(j<<1)+1>>0]|0;j=h&255;switch(h&15){case 8:{h=j&240;break}case 7:{h=(j&240|10)&255;v=20;break}case 5:case 6:{v=20;break}case 14:{i=1;break}case 11:{i=((i&255)+4|0)>>>1&255;break}default:{}}if((v|0)==20){v=0;k=i&255;i=((i&255)>128?256-k|0:k<<4)&255}a[t+(m|2)>>0]=h;a[t+(m|3)>>0]=i;if((h&15)==13)break}else g=g+255-k|0;g=g+1|0}while((g|0)<64);if((Ho(b)|0)>(f|0))f=Ho(b)|0;q=q+1|0}while((q|0)!=4);co(t,1024,1,e);if((p|0)<(r|0))p=p+1|0;else break}ro(b,(f&1)+f|0,0)|0;jg(e,b,s);l=w;return 0}function Pg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;j=a[b+2>>0]|0;h=j&255;if(j<<24>>24<1){b=-1;return b|0}p=a[b+3>>0]&63;q=p&255;if((p+-1&255)>30){b=-1;return b|0}else c=0;while(1){f=c*6|0;if((d[b+(f+7)>>0]|0)>64){l=-1;n=38;break}c=c+1|0;if((d[b+(f+6)>>0]|0)>15){l=-1;n=38;break}if((c|0)>=(q|0)){g=0;n=7;break}}if((n|0)==7){while(1){c=b+(g*6|0)|0;f=c+4|0;f=cj(a[f>>0]|0,a[f+1>>0]|0)|0;if(f<<16>>16==0|(f+32767&65535)<32734){l=-1;n=38;break}n=c+8|0;n=cj(a[n>>0]|0,a[n+1>>0]|0)|0;if(!(n<<16>>16==-1|(n&65535)<(f&65535))){l=-1;n=38;break}g=g+1|0;if((f&65535)>65503&(~f&65535)>>>0>q>>>0){l=-1;n=38;break}if((g|0)>=(q|0)){n=10;break}}if((n|0)==10){m=(cj(a[b>>0]|0,a[b+1>>0]|0)|0)&65535;c=q*6|0;i=(h<<3|4)+c|0;if(m>>>0>>0){b=-1;return b|0}g=h<<2;a:do if(j<<24>>24){c=b+4+c|0;f=0;while(1){h=c+(f<<1)|0;f=f+1|0;if((i+((cj(a[h>>0]|0,a[h+1>>0]|0)|0)&65535)|0)>>>0>m>>>0){l=-1;break}if((f|0)>=(g|0))break a}return l|0}while(0);if((i|0)>(e|0)){b=i-e|0;return b|0}c=a[b+i>>0]|0;if(c<<24>>24==-1){b=-1;return b|0}else f=0;do{if((c&255)>=(j&255)){l=-1;n=38;break}f=f+1|0;k=f+i|0;c=a[b+k>>0]|0}while((f|0)<128&c<<24>>24!=-1);if((n|0)==38)return l|0;if((k|0)>(m|0)|(f|128|0)==128){b=-1;return b|0}if((m|0)>=(e|0)){b=1-e+m|0;return b|0}c=(i|1)+f|0;if((c|0)>=(m|0)){b=0;return b|0}b:while(1){e=a[b+c>>0]|0;h=c+1|0;f=a[b+h>>0]|0;g=e&255;c:do switch(e<<24>>24){case -1:{switch((f&-64)<<24>>24){case 0:{o=h;break c}case 64:{o=c+2|0;break c}default:{}}if((f&255)>191)o=c+3|0;else n=29;break}case 127:{o=c;break}default:n=29}while(0);d:do if((n|0)==29){n=0;e:do switch(((g&240)+-96|0)>>>4&268435455|0){case 0:{o=h;break d}case 9:{o=(f&31)>(p&255);g=o?1:19;c=o?c:c+2|0;break}case 1:{o=(f&31)>(p&255);g=o?1:19;c=o?c:h;break}case 8:{o=c+2|0;break d}default:{f=(g<<4&16|(f&255)>>>4)>>>0>q>>>0;if(!(g&128)){g=f&1;c=f?c:c+2|0;break e}else{g=f?1:19;c=f?c:c+3|0;break e}}}while(0);switch(g&31){case 19:case 0:{o=c;break}default:{l=-1;n=38;break b}}}while(0);c=o+1|0;if((c|0)>=(m|0)){l=0;n=38;break}}if((n|0)==38)return l|0}else if((n|0)==38)return l|0}else if((n|0)==38)return l|0;return 0}function Qg(e,f){e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;L=l;l=l+134656|0;G=L+133624|0;F=L+2552|0;o=L+2424|0;m=L+2296|0;A=L+248|0;K=L+124|0;J=L;cp(A|0,0,2048)|0;cp(F|0,0,131072)|0;g=o;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));g=K;h=g+124|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));g=m;h=g+60|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));b[m+60>>1]=0;c[J>>2]=0;I=(Yi(e)|0)&65535;n=Vi(e)|0;D=n&255;E=(Vi(e)|0)&255;if(E&64|0){K=-1;l=L;return K|0}H=E&63;kg(f,20);C=(H|0)==0;if(!C){k=0;do{kg(f,22);z=Yi(e)|0;h=z&65535;g=m+(k<<2)|0;c[g>>2]=h;if((z&65535)>65280){i=h^65535;j=c[K+(i<<2)>>2]|0;c[K+(k<<2)>>2]=j;h=c[m+(i<<2)>>2]|0;c[g>>2]=h;g=c[J+(i<<2)>>2]|0;i=J}else{g=k+-1|0;if((k|0)>0)c[J+(k<<2)>>2]=(c[K+(g<<2)>>2]|0)+(c[J+(g<<2)>>2]|0);g=h<<1;j=g;i=K}c[i+(k<<2)>>2]=g;ij(f,h&65535);hj(f,(Vi(e)|0)&63);hj(f,Vi(e)|0);g=Yi(e)|0;if(g<<16>>16==-1){ij(f,0);ij(f,1)}else{ij(f,g);ij(f,((j|0)/2|0)-(g&65535)&65535)}k=k+1|0}while((k|0)!=(H|0));g=G;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[G+29>>0]=1;if(H>>>0<31){g=H;B=15}}else{g=G;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[G+29>>0]=1;g=0;B=15}if((B|0)==15)while(1){B=0;co(G,30,1,f);g=g+1|0;if((g|0)==31)break;else B=15}i=n<<24>>24==0;if(i)g=0;else{g=0;do{c[A+(g<<4)>>2]=(Yi(e)|0)&65535;c[A+(g<<4)+4>>2]=(Yi(e)|0)&65535;c[A+(g<<4)+8>>2]=(Yi(e)|0)&65535;c[A+(g<<4)+12>>2]=(Yi(e)|0)&65535;g=g+1|0}while((g|0)!=(D|0));g=0}do{h=Vi(e)|0;if(h<<24>>24==-1)break;a[o+g>>0]=h;g=g+1|0}while((g|0)<128);hj(f,g&255);hj(f,127);co(o,128,1,f);jj(f,1294879534);z=Ho(e)|0;if(!i){w=0;while(1){y=w<<2;x=0;v=63;while(1){ro(e,(c[A+(w<<4)+(x<<2)>>2]|0)+z|0,0)|0;a:do if((v|0)<0)g=v;else{u=x+y|0;g=0;while(1){q=(g<<2)+(F+(u<<8))|0;n=Vi(e)|0;o=n&255;h=o&112;b:do if((h|0)==112){switch(n<<24>>24){case 127:case -1:{i=n<<24>>24==-1;B=40;break b}default:{}}n=(Vi(e)|0)&255;k=n>>>5|o<<3&120;m=(n&16|(d[21653+(k<<1)>>0]|0))&255;a[q>>0]=m;k=a[21653+(k<<1)+1>>0]|0;a[q+1>>0]=k;n=n<<4&255;a[q+2>>0]=n;if(o&128){t=Vi(e)|0;h=t&255;if(t<<24>>24>-1){g=h+g|0;break}h=h+128&255;if(h){i=g;j=0;do{i=i+1|0;t=(i<<2)+(F+(u<<8))|0;a[t>>0]=m;a[t+1>>0]=k;a[t+2>>0]=n;j=j+1|0}while((j|0)!=(h|0));g=g+h|0}}}else{i=n<<24>>24==-1;if(!(i|(h|0)!=96)){h=Vi(e)|0;i=((o&15|0)==8?o+248&255:n)&255;m=i&15;j=q+3|0;a[q+2>>0]=m;switch(n&15){case 10:case 6:case 5:{k=h&255;k=(h<<24>>24<0?256-k<<4:k)&255;break}default:k=h}a[j>>0]=k;switch(n&15){case 11:case 13:break a;default:{}}if(i&128){t=Vi(e)|0;h=t&255;if(t<<24>>24>-1){g=h+g|0;break}h=h+128&255;if(h){i=g;j=0;do{i=i+1|0;t=(i<<2)+(F+(u<<8))|0;a[t+2>>0]=m;a[t+3>>0]=k;j=j+1|0}while((j|0)!=(h|0));g=g+h|0}}}else B=40}while(0);c:do if((B|0)==40){B=0;h=(o&128|0)==0;if(!(h|i)){k=Vi(e)|0;i=Vi(e)|0;m=Vi(e)|0;j=o>>>1&63;p=(d[21653+(j<<1)>>0]|0|o<<4&16)&255;a[q>>0]=p;o=a[21653+(j<<1)+1>>0]|0;a[q+1>>0]=o;j=k&255;j=(j&15|0)==8?j+248&255:k;h=q+3|0;a[q+2>>0]=j;switch(k&15){case 10:case 6:case 5:{t=i&255;i=(i<<24>>24<0?256-t<<4:t)&255;break}default:{}}a[h>>0]=i;switch(k&15){case 11:case 13:break a;default:{}}h=m&255;if(m<<24>>24>-1){g=h+g|0;break}n=h+128&255;if(!n)break;else{h=i;k=g;m=0}do{k=k+1|0;s=(k<<2)+(F+(u<<8))|0;a[s>>0]=p;a[s+1>>0]=o;i=j&255;t=j;j=(i&15|0)==8?i+248&255:j;i=s+3|0;a[s+2>>0]=j;switch(t&15){case 10:case 6:case 5:{t=h&255;h=(h<<24>>24<0?256-t<<4:t)&255;break}default:{}}a[i>>0]=h;m=m+1|0}while((m|0)!=(n|0));g=g+n|0;break}if((o&127|0)!=127){j=Vi(e)|0;h=Vi(e)|0;t=(n&255)>>>1&255;a[q>>0]=d[21653+(t<<1)>>0]|0|o<<4&16;a[q+1>>0]=a[21653+(t<<1)+1>>0]|0;t=j&255;i=q+3|0;a[q+2>>0]=(t&15|0)==8?t+248&255:j;switch(j&15){case 10:case 6:case 5:{t=h&255;h=(h<<24>>24<0?256-t<<4:t)&255;break}default:{}}a[i>>0]=h;switch(j&15){case 11:case 13:break a;default:break c}}if(!h){t=Vi(e)|0;h=t&255;if((t&255)<64){g=h+g|0;break}i=h+192|0;j=(Vi(e)|0)&255;h=i&255;if(h>>>0>127){i=h+-128|0;h=(Vi(e)|0)&255|j<<8}else h=j;t=Ho(e)|0;ro(e,0-h|0,1)|0;s=i&255;if((g|0)<=(v|0)){r=0;while(1){m=Vi(e)|0;q=(g<<2)+(F+(u<<8))|0;i=m&255;d:do if((i&112|0)==112){switch(m<<24>>24){case 127:case -1:{B=64;break d}default:{}}n=(Vi(e)|0)&255;k=n>>>5|i<<3&120;m=(n&16|(d[21653+(k<<1)>>0]|0))&255;a[q>>0]=m;k=a[21653+(k<<1)+1>>0]|0;a[q+1>>0]=k;n=n<<4&255;a[q+2>>0]=n;if(!(i&128)){h=g;break}q=Vi(e)|0;h=q&255;if(q<<24>>24>-1){h=h+g|0;break}i=h+128&255;if(!i){h=g;break}else{h=0;j=g}do{j=j+1|0;q=(j<<2)+(F+(u<<8))|0;a[q>>0]=m;a[q+1>>0]=k;a[q+2>>0]=n;h=h+1|0}while((h|0)!=(i|0));h=g+i|0}else B=64;while(0);e:do if((B|0)==64){B=0;f:do if((i&96|0)==96){switch(m<<24>>24){case 127:case -1:break f;default:{}}h=Vi(e)|0;i=((i&15|0)==8?i+248&255:m)&255;n=i&15;j=q+3|0;a[q+2>>0]=n;switch(m&15){case 10:case 6:case 5:{k=h&255;k=(h<<24>>24<0?256-k<<4:k)&255;break}default:k=h}a[j>>0]=k;switch(m&15){case 11:case 13:break a;default:{}}if(!(i&128)){h=g;break e}q=Vi(e)|0;h=q&255;if(q<<24>>24>-1){h=h+g|0;break e}i=h+128&255;if(!i){h=g;break e}else{h=0;j=g}do{j=j+1|0;q=(j<<2)+(F+(u<<8))|0;a[q+2>>0]=n;a[q+3>>0]=k;h=h+1|0}while((h|0)!=(i|0));h=g+i|0;break e}while(0);h=(i&128|0)==0;if((m&127)==127|h){if((i&127|0)==127){if(h){h=g;break}h=Vi(e)|0;h=((h&255)<64?h&255:0)+g|0;break}p=Vi(e)|0;h=Vi(e)|0;o=(m&255)>>>1&255;a[q>>0]=d[21653+(o<<1)>>0]|0|i<<4&16;a[q+1>>0]=a[21653+(o<<1)+1>>0]|0;o=p&255;i=q+3|0;a[q+2>>0]=(o&15|0)==8?o+248&255:p;switch(p&15){case 10:case 6:case 5:{q=h&255;h=(h<<24>>24<0?256-q<<4:q)&255;break}default:{}}a[i>>0]=h;h=g;break}m=Vi(e)|0;h=Vi(e)|0;n=Vi(e)|0;o=i>>>1&63;p=(d[21653+(o<<1)>>0]|0|i<<4&16)&255;a[q>>0]=p;o=a[21653+(o<<1)+1>>0]|0;a[q+1>>0]=o;j=m&255;j=(j&15|0)==8?j+248&255:m;i=q+3|0;a[q+2>>0]=j;switch(m&15){case 10:case 6:case 5:{k=h&255;k=(h<<24>>24<0?256-k<<4:k)&255;break}default:k=h}a[i>>0]=k;switch(m&15){case 11:case 13:break a;default:{}}h=n&255;if(n<<24>>24>-1){h=h+g|0;break}n=h+128&255;if(!n){h=g;break}else{m=0;h=k;k=g}do{k=k+1|0;M=(k<<2)+(F+(u<<8))|0;a[M>>0]=p;a[M+1>>0]=o;i=j&255;q=j;j=(i&15|0)==8?i+248&255:j;i=M+3|0;a[M+2>>0]=j;switch(q&15){case 10:case 6:case 5:{M=h&255;h=(h<<24>>24<0?256-M<<4:M)&255;break}default:{}}a[i>>0]=h;m=m+1|0}while((m|0)!=(n|0));h=g+n|0}while(0);g=h+1|0;if((h|0)<(v|0)&(r|0)<(s|0))r=r+1|0;else break}}ro(e,t,0)|0;g=g+-1|0}}while(0);if((g|0)<(v|0))g=g+1|0;else{g=v;break}}}while(0);x=x+1|0;if((x|0)==4)break;else v=g}w=w+1|0;if((w|0)==(D|0)){j=0;break}}do{cp(G|0,0,1024)|0;m=j<<2;g=m|1;h=m|2;i=m|3;k=0;do{M=k<<4;B=k<<2;A=G+M|0;z=F+(m<<8)+B|0;z=d[z>>0]|d[z+1>>0]<<8|d[z+2>>0]<<16|d[z+3>>0]<<24;a[A>>0]=z;a[A+1>>0]=z>>8;a[A+2>>0]=z>>16;a[A+3>>0]=z>>24;A=G+(M|4)|0;z=F+(g<<8)+B|0;z=d[z>>0]|d[z+1>>0]<<8|d[z+2>>0]<<16|d[z+3>>0]<<24;a[A>>0]=z;a[A+1>>0]=z>>8;a[A+2>>0]=z>>16;a[A+3>>0]=z>>24;A=G+(M|8)|0;z=F+(h<<8)+B|0;z=d[z>>0]|d[z+1>>0]<<8|d[z+2>>0]<<16|d[z+3>>0]<<24;a[A>>0]=z;a[A+1>>0]=z>>8;a[A+2>>0]=z>>16;a[A+3>>0]=z>>24;M=G+(M|12)|0;B=F+(i<<8)+B|0;B=d[B>>0]|d[B+1>>0]<<8|d[B+2>>0]<<16|d[B+3>>0]<<24;a[M>>0]=B;a[M+1>>0]=B>>8;a[M+2>>0]=B>>16;a[M+3>>0]=B>>24;k=k+1|0}while((k|0)!=64);co(G,1024,1,f);j=j+1|0}while((j|0)!=(D|0))}ro(e,I,0)|0;if(C){M=0;l=L;return M|0}j=(E&128|0)!=0;k=0;do{ro(e,(c[J+(k<<2)>>2]|0)+I|0,0)|0;g=c[K+(k<<2)>>2]|0;i=Om(g)|0;cp(i|0,0,g|0)|0;Go(i,g,1,e)|0;if(j&(g|0)>1){h=0;m=1;do{M=i+m|0;h=(0-(d[M>>0]|0)&255)+(h&255)|0;a[M>>0]=h;m=m+1|0}while((m|0)!=(g|0))}co(i,g,1,f);Pm(i);k=k+1|0}while((k|0)!=(H|0));g=0;l=L;return g|0}function Rg(b,c,d){b=b|0;c=c|0;d=d|0;do if((d|0)>=22)if((en(b,22033,16)|0)==0?(a[b+21>>0]|0)==-50:0){if((d|0)<4714){b=4714-d|0;break}if((((cj(a[b+4712>>0]|0,a[b+4713>>0]|0)|0)&3)==0?(a[b+36>>0]|0)==16:0)?(a[b+37>>0]|0)==-4:0){ng(0,c,0);b=0}else b=-1}else b=-1;else b=22-d|0;while(0);return b|0}function Sg(d,e){d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;D=l;l=l+132896|0;t=D+132768|0;s=D+132640|0;q=D+1024|0;o=D+512|0;r=D;C=D+1568|0;B=D+1536|0;f=t;g=f+128|0;do{a[f>>0]=0;f=f+1|0}while((f|0)<(g|0));f=s;g=f+128|0;do{a[f>>0]=0;f=f+1|0}while((f|0)<(g|0));cp(C|0,0,131072)|0;f=B;g=f+31|0;do{a[f>>0]=0;f=f+1|0}while((f|0)<(g|0));cp(q|0,0,512)|0;cp(o|0,0,512)|0;f=0;do{c[r+(f<<2)>>2]=9999;f=f+1|0}while((f|0)!=128);kg(e,20);ro(d,4460,0)|0;f=0;w=0;do{kg(e,22);v=Yi(d)|0;ij(e,v);w=((v&65535)<<1)+w|0;v=Vi(d)|0;a[B+f>>0]=v;hj(e,v);hj(e,Vi(d)|0);ij(e,Yi(d)|0);ij(e,Yi(d)|0);f=f+1|0}while((f|0)!=31);f=((Yi(d)|0)&65535)>>>2;hj(e,f&255);hj(e,127);g=0;do{c[q+(g<<2)>>2]=aj(d)|0;g=g+1|0}while((g|0)!=128);h=f&255;n=h&65535;if(!(h<<16>>16))i=0;else{j=0;i=0;do{if(j){a:do if((j|0)>0){g=c[q+(j<<2)>>2]|0;f=0;while(1){if((g|0)==(c[q+(f<<2)>>2]|0))break;f=f+1|0;if((f|0)>=(j|0))break a}a[t+j>>0]=a[t+f>>0]|0}else f=0;while(0);if((f|0)==(j|0)){a[t+j>>0]=i;i=i+1|0}}else{a[t>>0]=0;i=i+1|0}j=j+1|0}while((j|0)<(n|0));ap(o|0,q|0,h<<2&65535|0)|0;b:while(1){f=0;c:while(1){if((f|0)>0){m=o+(f<<2)|0;k=c[m>>2]|0;g=0;do{j=o+(g<<2)|0;h=c[j>>2]|0;if((k|0)<(h|0))break c;g=g+1|0}while((g|0)<(f|0))}f=f+1|0;if((f|0)>=(n|0)){j=0;f=0;break b}}g=t+g|0;u=a[g>>0]|0;v=t+f|0;a[g>>0]=a[v>>0]|0;a[v>>0]=u;c[j>>2]=k;c[m>>2]=h}do{h=c[o+(j<<2)>>2]|0;g=r+(f<<2)|0;if(j){if((h|0)!=(c[g>>2]|0)){f=f+1|0;g=r+(f<<2)|0;p=29}}else p=29;if((p|0)==29){p=0;c[g>>2]=h}j=j+1|0}while((j|0)<(n|0));k=0;f=0;do{j=c[q+(f<<2)>>2]|0;f=s+f|0;g=0;h=0;do{if((j|0)==(c[r+(h<<2)>>2]|0))a[f>>0]=g;g=g+1<<24>>24;h=g&255}while(h>>>0>>0);k=k+1<<24>>24;f=k&255}while(f>>>0>>0);ap(t|0,s|0,n|0)|0}f=0;do{Fo(a[t+f>>0]|0,e);f=f+1|0}while((f|0)!=128);jj(e,1294879534);ro(d,4456,0)|0;g=aj(d)|0;ro(d,5222,0)|0;if((g|0)>0){h=0;f=0;do{v=Yi(d)|0;f=(v&65535|0)>(f<<16>>16|0)?v:f;h=h+2|0}while((h|0)<(g|0))}else f=0;u=((f&65535)<<16)+65536>>14;v=Om(u)|0;Go(v,u,1,d)|0;ro(d,5222,0)|0;u=(i<<16)+-65536|0;t=u>>16;if((u|0)<0){Pm(v);ro(d,4452,0)|0;C=aj(d)|0;C=C+4456|0;ro(d,C,0)|0;jg(e,d,w);l=D;return 0}else{f=1;u=0;g=0;h=0;i=0;j=0}while(1){s=0;d:do{r=s<<4;k=((Yi(d)|0)&65535)<<2;p=a[v+k>>0]|0;n=C+(u<<10)+r|0;a[n>>0]=p;m=a[v+(k|1)>>0]|0;o=(r|1)+(C+(u<<10))|0;a[o>>0]=m;q=a[v+(k|2)>>0]|0;a[(r|2)+(C+(u<<10))>>0]=q;a[(r|3)+(C+(u<<10))>>0]=a[v+(k|3)>>0]|0;k=p&-16;E=k&255|(q&255)>>>4;g=(E|0)==0?g:E&255;m=(p&15)<<8|m&255;e:do if(m|0?(E=a[B+((g&255)+-1)>>0]|0,x=E&255,E<<24>>24):0){p=0;do{if((p|0)>=36)break e;E=p;p=p+1|0}while((b[8128+(x*72|0)+(E<<1)>>1]|0)!=(m|0));a[n>>0]=a[21653+(p<<1)>>0]|k;a[o>>0]=a[21653+(p<<1)+1>>0]|0}while(0);switch(q&15){case 11:case 13:{f=0;break}default:{}}k=((Yi(d)|0)&65535)<<2;E=a[v+k>>0]|0;n=(r|4)+(C+(u<<10))|0;a[n>>0]=E;m=a[v+(k|1)>>0]|0;o=(r|5)+(C+(u<<10))|0;a[o>>0]=m;q=a[v+(k|2)>>0]|0;a[(r|6)+(C+(u<<10))>>0]=q;a[(r|7)+(C+(u<<10))>>0]=a[v+(k|3)>>0]|0;k=E&-16;p=k&255|(q&255)>>>4;i=(p|0)==0?i:p&255;m=(E&15)<<8|m&255;f:do if(m|0?(E=a[B+((i&255)+-1)>>0]|0,y=E&255,E<<24>>24):0){p=0;do{if((p|0)>=36)break f;E=p;p=p+1|0}while((b[8128+(y*72|0)+(E<<1)>>1]|0)!=(m|0));a[n>>0]=a[21653+(p<<1)>>0]|k;a[o>>0]=a[21653+(p<<1)+1>>0]|0}while(0);switch(q&15){case 11:case 13:{f=0;break}default:{}}k=((Yi(d)|0)&65535)<<2;E=a[v+k>>0]|0;n=(r|8)+(C+(u<<10))|0;a[n>>0]=E;m=a[v+(k|1)>>0]|0;o=(r|9)+(C+(u<<10))|0;a[o>>0]=m;q=a[v+(k|2)>>0]|0;a[(r|10)+(C+(u<<10))>>0]=q;a[(r|11)+(C+(u<<10))>>0]=a[v+(k|3)>>0]|0;k=E&-16;p=k&255|(q&255)>>>4;j=(p|0)==0?j:p&255;m=(E&15)<<8|m&255;g:do if(m|0?(E=a[B+((j&255)+-1)>>0]|0,z=E&255,E<<24>>24):0){p=0;do{if((p|0)>=36)break g;E=p;p=p+1|0}while((b[8128+(z*72|0)+(E<<1)>>1]|0)!=(m|0));a[n>>0]=a[21653+(p<<1)>>0]|k;a[o>>0]=a[21653+(p<<1)+1>>0]|0}while(0);switch(q&15){case 11:case 13:{f=0;break}default:{}}k=((Yi(d)|0)&65535)<<2;E=a[v+k>>0]|0;o=(r|12)+(C+(u<<10))|0;a[o>>0]=E;m=a[v+(k|1)>>0]|0;p=(r|13)+(C+(u<<10))|0;a[p>>0]=m;q=a[v+(k|2)>>0]|0;a[(r|14)+(C+(u<<10))>>0]=q;a[(r|15)+(C+(u<<10))>>0]=a[v+(k|3)>>0]|0;k=E&-16;r=k&255|(q&255)>>>4;h=(r|0)==0?h:r&255;m=(E&15)<<8|m&255;h:do if(m|0?(E=a[B+((h&255)+-1)>>0]|0,A=E&255,E<<24>>24):0){n=0;do{if((n|0)>=36)break h;E=n;n=n+1|0}while((b[8128+(A*72|0)+(E<<1)>>1]|0)!=(m|0));a[o>>0]=a[21653+(n<<1)>>0]|k;a[p>>0]=a[21653+(n<<1)+1>>0]|0}while(0);switch(q&15){case 11:case 13:{f=1;break d}default:{}}E=f<<24>>24==0;f=E?1:f;s=s+1|0}while((s|0)<64&(E^1));co(C+(u<<10)|0,1024,1,e);if((u|0)<(t|0))u=u+1|0;else break}Pm(v);ro(d,4452,0)|0;E=aj(d)|0;E=E+4456|0;ro(d,E,0)|0;jg(e,d,w);l=D;return 0}function Tg(b,c,d){b=b|0;c=c|0;d=d|0;do if((d|0)>=22)if(((((((((((((((((a[b>>0]|0)==96?(a[b+1>>0]|0)==56:0)?(a[b+2>>0]|0)==96:0)?(a[b+3>>0]|0)==0:0)?(a[b+4>>0]|0)==0:0)?(a[b+5>>0]|0)==-96:0)?(a[b+6>>0]|0)==96:0)?(a[b+7>>0]|0)==0:0)?(a[b+8>>0]|0)==1:0)?(a[b+9>>0]|0)==62:0)?(a[b+10>>0]|0)==96:0)?(a[b+11>>0]|0)==0:0)?(a[b+12>>0]|0)==1:0)?(a[b+13>>0]|0)==12:0)?(a[b+14>>0]|0)==72:0)?(a[b+15>>0]|0)==-25:0)?(a[b+21>>0]|0)==-46:0){if((d|0)<4460){b=4460-d|0;break}if((d|0)<4714){b=4714-d|0;break}if((cj(a[b+4712>>0]|0,a[b+4713>>0]|0)|0)&3){b=-1;break}if((a[b+36>>0]|0)!=17){b=-1;break}if(a[b+37>>0]|0){b=-1;break}ng(0,c,0);b=0}else b=-1;else b=22-d|0;while(0);return b|0}function Ug(d,e){d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;E=l;l=l+131744|0;k=E+131616|0;C=E;D=E+544|0;B=E+512|0;f=k;g=f+128|0;do{a[f>>0]=0;f=f+1|0}while((f|0)<(g|0));cp(D|0,0,131072)|0;f=B;g=f+31|0;do{a[f>>0]=0;f=f+1|0}while((f|0)<(g|0));cp(C|0,0,512)|0;kg(e,20);ro(d,4464,0)|0;f=0;w=0;do{kg(e,22);v=Yi(d)|0;ij(e,v);w=((v&65535)<<1)+w|0;v=Vi(d)|0;a[B+f>>0]=v;hj(e,v);hj(e,Vi(d)|0);ij(e,Yi(d)|0);ij(e,Yi(d)|0);f=f+1|0}while((f|0)!=31);f=((Yi(d)|0)&65535)>>>2;hj(e,f&255);hj(e,127);g=0;do{c[C+(g<<2)>>2]=aj(d)|0;g=g+1|0}while((g|0)!=128);v=f&255;i=v&65535;if(!(v<<16>>16))i=0;else{j=0;f=0;while(1){if(j){a:do if((j|0)>0){h=c[C+(j<<2)>>2]|0;g=0;while(1){if((h|0)==(c[C+(g<<2)>>2]|0))break;g=g+1|0;if((g|0)>=(j|0))break a}a[k+j>>0]=a[k+g>>0]|0}else g=0;while(0);if((g|0)==(j|0)){a[k+j>>0]=f;f=f+1|0}}else{a[k>>0]=0;f=f+1|0}j=j+1|0;if((j|0)>=(i|0)){i=f;break}}}co(k,128,1,e);jj(e,1294879534);ro(d,4460,0)|0;f=aj(d)|0;ro(d,5226,0)|0;if((f|0)>0){g=0;h=0;do{v=(Yi(d)|0)&65535;h=(v|0)>(h|0)?v:h;g=g+2|0}while((g|0)<(f|0));f=(h<<2)+4|0}else f=4;v=Om(f)|0;Go(v,f,1,d)|0;ro(d,5226,0)|0;u=(i<<16)+-65536|0;t=u>>16;if((u|0)<0){Pm(v);ro(d,4456,0)|0;D=aj(d)|0;D=D+4460|0;ro(d,D,0)|0;jg(e,d,w);l=E;return 0}else{f=1;u=0;g=0;h=0;i=0;j=0}while(1){ro(d,(c[C+(u<<2)>>2]|0)+5226|0,0)|0;s=0;b:do{k=((Yi(d)|0)&65535)<<2;r=s<<4;p=a[v+k>>0]|0;n=D+(u<<10)+r|0;a[n>>0]=p;m=a[v+(k|1)>>0]|0;o=(r|1)+(D+(u<<10))|0;a[o>>0]=m;q=a[v+(k|2)>>0]|0;a[(r|2)+(D+(u<<10))>>0]=q;a[(r|3)+(D+(u<<10))>>0]=a[v+(k|3)>>0]|0;k=p&-16;F=(k&255|(q&255)>>>4)&255;g=F<<24>>24==0?g:F;m=(p&15)<<8|m&255;c:do if(m|0?(F=a[B+((g&255)+-1)>>0]|0,x=F&255,F<<24>>24):0){p=0;do{if((p|0)>=36)break c;F=p;p=p+1|0}while((b[8128+(x*72|0)+(F<<1)>>1]|0)!=(m|0));a[n>>0]=a[21653+(p<<1)>>0]|k;a[o>>0]=a[21653+(p<<1)+1>>0]|0}while(0);switch(q&15){case 11:case 13:{f=0;break}default:{}}k=((Yi(d)|0)&65535)<<2;F=a[v+k>>0]|0;n=(r|4)+(D+(u<<10))|0;a[n>>0]=F;m=a[v+(k|1)>>0]|0;o=(r|5)+(D+(u<<10))|0;a[o>>0]=m;q=a[v+(k|2)>>0]|0;a[(r|6)+(D+(u<<10))>>0]=q;a[(r|7)+(D+(u<<10))>>0]=a[v+(k|3)>>0]|0;k=F&-16;p=(k&255|(q&255)>>>4)&255;i=p<<24>>24==0?i:p;m=(F&15)<<8|m&255;d:do if(m|0?(F=a[B+((i&255)+-1)>>0]|0,y=F&255,F<<24>>24):0){p=0;do{if((p|0)>=36)break d;F=p;p=p+1|0}while((b[8128+(y*72|0)+(F<<1)>>1]|0)!=(m|0));a[n>>0]=a[21653+(p<<1)>>0]|k;a[o>>0]=a[21653+(p<<1)+1>>0]|0}while(0);switch(q&15){case 11:case 13:{f=0;break}default:{}}k=((Yi(d)|0)&65535)<<2;F=a[v+k>>0]|0;n=(r|8)+(D+(u<<10))|0;a[n>>0]=F;m=a[v+(k|1)>>0]|0;o=(r|9)+(D+(u<<10))|0;a[o>>0]=m;q=a[v+(k|2)>>0]|0;a[(r|10)+(D+(u<<10))>>0]=q;a[(r|11)+(D+(u<<10))>>0]=a[v+(k|3)>>0]|0;k=F&-16;p=(k&255|(q&255)>>>4)&255;j=p<<24>>24==0?j:p;m=(F&15)<<8|m&255;e:do if(m|0?(F=a[B+((j&255)+-1)>>0]|0,z=F&255,F<<24>>24):0){p=0;do{if((p|0)>=36)break e;F=p;p=p+1|0}while((b[8128+(z*72|0)+(F<<1)>>1]|0)!=(m|0));a[n>>0]=a[21653+(p<<1)>>0]|k;a[o>>0]=a[21653+(p<<1)+1>>0]|0}while(0);switch(q&15){case 11:case 13:{f=0;break}default:{}}k=((Yi(d)|0)&65535)<<2;F=a[v+k>>0]|0;o=(r|12)+(D+(u<<10))|0;a[o>>0]=F;m=a[v+(k|1)>>0]|0;p=(r|13)+(D+(u<<10))|0;a[p>>0]=m;q=a[v+(k|2)>>0]|0;a[(r|14)+(D+(u<<10))>>0]=q;a[(r|15)+(D+(u<<10))>>0]=a[v+(k|3)>>0]|0;k=F&-16;r=k&255|(q&255)>>>4;h=(r|0)==0?h:r&255;m=(F&15)<<8|m&255;f:do if(m|0?(F=a[B+((h&255)+-1)>>0]|0,A=F&255,F<<24>>24):0){n=0;do{if((n|0)>=36)break f;F=n;n=n+1|0}while((b[8128+(A*72|0)+(F<<1)>>1]|0)!=(m|0));a[o>>0]=a[21653+(n<<1)>>0]|k;a[p>>0]=a[21653+(n<<1)+1>>0]|0}while(0);switch(q&15){case 11:case 13:{f=1;break b}default:{}}F=f<<24>>24==0;f=F?1:f;s=s+1|0}while((s|0)<64&(F^1));co(D+(u<<10)|0,1024,1,e);if((u|0)<(t|0))u=u+1|0;else break}Pm(v);ro(d,4456,0)|0;F=aj(d)|0;F=F+4460|0;ro(d,F,0)|0;jg(e,d,w);l=E;return 0}function Vg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0;if((e|0)<963){c=963-e|0;return c|0}if((a[b+10>>0]|0)!=3){c=-1;return c|0}if((a[b+11>>0]|0)==-64){f=0;g=0}else{c=-1;return c|0}while(1){h=f*14|0;e=b+h|0;g=(((cj(a[e>>0]|0,a[e+1>>0]|0)|0)&65535)<<1)+g|0;if((d[b+(h+3)>>0]|0)>64){i=-1;h=14;break}h=e+4|0;if((((cj(a[h>>0]|0,a[h+1>>0]|0)|0)&65535)<<1|0)>(g|0)){i=-1;h=14;break}f=f+1|0;if((gj(e+8|0)|0)<960){i=-1;h=14;break}if((f|0)>=31){h=9;break}}if((h|0)==9){if((g+-3|0)>>>0>2031582){c=-1;return c|0}b=b+448|0;e=g+958|0;f=0;do{if((gj(b+(f<<2)|0)|0)<(e|0)){i=-1;h=14;break}f=f+1|0}while((f|0)<128);if((h|0)==14)return i|0;ng(0,c,0);c=0;return c|0}else if((h|0)==14)return i|0;return 0}function Wg(e,f){e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0;B=l;l=l+1824|0;s=B+1688|0;g=B+1560|0;z=B+1544|0;r=B+1032|0;q=B+520|0;p=B+8|0;y=B;cp(r|0,0,512)|0;cp(q|0,0,512)|0;cp(p|0,0,512)|0;h=s;i=h+128|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));h=g;i=h+128|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));h=z;i=h+16|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));h=y;c[h>>2]=0;c[h+4>>2]=0;kg(f,20);h=0;A=0;do{kg(f,22);x=Yi(e)|0;ij(f,x);A=((x&65535)<<1)+A|0;Vi(e)|0;hj(f,0);hj(f,Vi(e)|0);ij(f,Yi(e)|0);ij(f,Yi(e)|0);aj(e)|0;x=Vi(e)|0;ro(f,-6,2)|0;hj(f,x<<24>>24==0?0:(x&255)+11&255);ro(f,0,2)|0;ro(e,1,1)|0;h=h+1|0}while((h|0)!=31);ro(e,14,1)|0;h=0;do{c[r+(h<<2)>>2]=aj(e)|0;h=h+1|0}while((h|0)!=128);k=0;h=0;while(1){if(!k){a[s>>0]=0;k=1;h=h+1|0;continue}a:do if((k|0)>0){j=c[r+(k<<2)>>2]|0;i=0;while(1){if((j|0)==(c[r+(i<<2)>>2]|0))break;i=i+1|0;if((i|0)>=(k|0))break a}a[s+k>>0]=a[s+i>>0]|0}else i=0;while(0);if((i|0)==(k|0)){a[s+k>>0]=h;h=h+1|0}k=k+1|0;if((k|0)==128)break}ap(q|0,r|0,512)|0;b:while(1){h=0;c:while(1){if((h|0)>0){n=q+(h<<2)|0;m=c[n>>2]|0;i=0;do{k=q+(i<<2)|0;j=c[k>>2]|0;if((m|0)<(j|0))break c;i=i+1|0}while((i|0)<(h|0))}h=h+1|0;if((h|0)>=128){k=0;h=0;break b}}v=s+i|0;w=a[v>>0]|0;x=s+h|0;a[v>>0]=a[x>>0]|0;a[x>>0]=w;c[k>>2]=m;c[n>>2]=j}do{j=c[q+(k<<2)>>2]|0;i=p+(h<<2)|0;if(k){if((j|0)!=(c[i>>2]|0)){h=h+1|0;i=p+(h<<2)|0;o=27}}else o=27;if((o|0)==27){o=0;c[i>>2]=j}k=k+1|0}while((k|0)!=128);cp(q|0,0,512)|0;n=c[r>>2]|0;k=c[p>>2]|0;m=0;j=0;while(1){c[q+(j<<2)>>2]=k;h=j+1|0;m=m+1|0;i=k;k=c[p+(m<<2)>>2]|0;if((k-i|0)>1024){c[q+(h<<2)>>2]=i+1024;h=j+2|0}if((m|0)==120){k=n;h=0;break}else j=h}while(1){i=g+h|0;j=0;do{if((k|0)==(c[q+(j<<2)>>2]|0))a[i>>0]=j;j=j+1|0}while((j|0)!=128);h=h+1|0;if((h|0)==128)break;k=c[r+(h<<2)>>2]|0}h=s;i=h+128|0;do{a[h>>0]=a[g>>0]|0;h=h+1|0;g=g+1|0}while((h|0)<(i|0));j=(n|0)<999999?n:999999;g=1;do{x=c[r+(g<<2)>>2]|0;j=(x|0)<(j|0)?x:j;g=g+1|0}while((g|0)!=128);g=128;h=-128;while(1){if(a[s+(g+-1)>>0]|0)break;h=h+-1<<24>>24;g=h&255;if(!(h<<24>>24)){h=0;break}}hj(f,h);if((g|0)>0){i=0;h=0;do{x=a[s+i>>0]|0;h=(x&255)>(h&255)?x:h;i=i+1|0}while((i|0)!=(g|0))}else h=0;hj(f,127);g=0;do{hj(f,a[s+g>>0]|0);g=g+1|0}while((g|0)!=128);jj(f,1294879534);x=Ho(e)|0;ro(e,j,0)|0;w=(h&255)<<10;t=Om(w)|0;u=Go(t,1,w,e)|0;w=w+1024&261120;v=Om(w)|0;cp(v|0,0,w|0)|0;if((u|0)>0){r=0;s=0;g=n}else{co(v,w,1,f);Pm(t);Pm(v);ro(e,x,0)|0;jg(f,e,A);l=B;return 0}while(1){j=a[t+r>>0]|0;p=j&255;do if(j<<24>>24!=-1){q=(g|0)%4|0;o=y+(q<<1)|0;k=b[o>>1]|0;m=s+1|0;n=s+3|0;g=g+1|0;h=s+4|0;i=s+2|0;if(!(k<<16>>16)){C=a[t+(r+1)>>0]|0;k=a[t+(r+2)>>0]|0;r=r+3|0;o=a[t+r>>0]|0;a[z+(q<<2)>>0]=j;a[z+(q<<2)+1>>0]=C;a[z+(q<<2)+2>>0]=k;a[z+(q<<2)+3>>0]=o;q=(C&255)>>>1&255;a[v+s>>0]=d[21653+(q<<1)>>0]|p&240;a[v+m>>0]=a[21653+(q<<1)+1>>0]|0;a[v+i>>0]=k&255|p<<4;a[v+n>>0]=o;i=r;break}else{D=a[z+(q<<2)>>0]|0;j=a[z+(q<<2)+1>>0]|0;p=a[z+(q<<2)+2>>0]|0;C=a[z+(q<<2)+3>>0]|0;b[o>>1]=(k&65535)+65535;q=D&255;o=(j&255)>>>1&255;a[v+s>>0]=d[21653+(o<<1)>>0]|q&240;a[v+m>>0]=a[21653+(o<<1)+1>>0]|0;a[v+i>>0]=p&255|q<<4;a[v+n>>0]=C;i=r+-1|0;break}}else{i=r+1|0;b[y+(((g+3|0)%4|0)<<1)>>1]=~a[t+i>>0]&255;h=s}while(0);if((h|0)<(u|0)){r=i+1|0;s=h}else break}co(v,w,1,f);Pm(t);Pm(v);ro(e,x,0)|0;jg(f,e,A);l=B;return 0}function Xg(b,c,d){b=b|0;c=c|0;d=d|0;if((d|0)>=1080)if((((((a[b+1080>>0]|0)==83?(a[b+1081>>0]|0)==78:0)?(a[b+1082>>0]|0)==84:0)?(a[b+1083>>0]|0)==46:0)?(a[b+951>>0]|0)==127:0)?(a[b+950>>0]|0)>=0:0){ng(b,c,20);b=0}else b=-1;else b=1080-d|0;return b|0}function Yg(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;n=l;l=l+2048|0;k=n;cp(k|0,0,2048)|0;Go(k,950,1,b)|0;co(k,950,1,c);e=0;m=0;do{j=k+(e*30|0)|0;m=(((cj(a[j+42>>0]|0,a[j+43>>0]|0)|0)&65535)<<1)+m|0;e=e+1|0}while((e|0)!=31);hj(c,Vi(b)|0);cp(k|0,0,2048)|0;Go(k,129,1,b)|0;co(k,129,1,c);jj(c,1294879534);e=1;f=0;do{j=a[k+e>>0]|0;f=(j&255)>(f&255)?j:f;e=e+1|0}while((e|0)!=129);ro(b,1084,0)|0;h=f&255;e=k+1|0;f=k+2|0;g=k+3|0;i=0;while(1){j=0;do{a[k>>0]=Vi(b)|0;a[e>>0]=Vi(b)|0;a[f>>0]=Vi(b)|0;o=Vi(b)|0;a[g>>0]=o;r=d[k>>0]|0;p=(r<<4|(d[f>>0]|0))&255;s=d[e>>0]|0;q=a[21653+(s<<1)+1>>0]|0;hj(c,(d[21653+(s<<1)>>0]|0|r&240)&255);hj(c,q);hj(c,p);hj(c,o);j=j+1|0}while((j|0)!=256);if((i|0)==(h|0))break;else i=i+1|0}jg(c,b,m);l=n;return 0}function Zg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0;if((e|0)<260){h=260-e|0;return h|0}if((a[b>>0]|0)!=83){h=-1;return h|0}if((a[b+1>>0]|0)!=78){h=-1;return h|0}if((a[b+2>>0]|0)!=84){h=-1;return h|0}if((a[b+3>>0]|0)==33)e=0;else{h=-1;return h|0}while(1){if((d[b+((e<<3)+11)>>0]|0)>64){g=-1;h=12;break}e=e+1|0;if((e|0)>=31){f=0;break}}if((h|0)==12)return g|0;do{if((d[b+((f<<3)+10)>>0]|0)>15){g=-1;h=12;break}f=f+1|0}while((f|0)<31);if((h|0)==12)return g|0;ng(0,c,0);h=0;return h|0}function _g(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0;Q=l;l=l+16|0;P=Q;kg(c,20);ro(b,8,0)|0;e=0;O=0;do{kg(c,22);N=Yi(b)|0;ij(c,N);O=((N&65535)<<1)+O|0;hj(c,Vi(b)|0);hj(c,Vi(b)|0);ij(c,Yi(b)|0);ij(c,Yi(b)|0);e=e+1|0}while((e|0)!=31);hj(c,Vi(b)|0);hj(c,Vi(b)|0);e=0;f=0;do{N=Vi(b)|0;hj(c,N);f=(N&255)>(f&255)?N:f;e=e+1|0}while((e|0)!=128);jj(c,1294879534);ro(b,770,0)|0;M=f&255;x=P+4|0;y=P+5|0;z=P+1|0;A=P+6|0;B=P+2|0;C=P+7|0;D=P+3|0;E=P+8|0;F=P+9|0;G=P+10|0;H=P+11|0;I=P+12|0;J=P+13|0;K=P+14|0;L=P+15|0;f=0;i=0;k=0;e=0;n=0;o=0;p=0;m=0;q=0;g=0;h=0;j=0;N=0;while(1){r=e;s=q;t=0;while(1){w=Vi(b)|0;e=w&255;switch(w<<24>>24){case -128:{jj(c,0);w=m;v=p;u=o;q=n;m=r;p=k;o=i;n=f;e=s;r=0;k=0;i=0;f=0;break}case -64:{co(P,4,1,c);w=a[E>>0]|0;v=a[F>>0]|0;u=a[G>>0]|0;q=a[H>>0]|0;m=a[I>>0]|0;p=a[J>>0]|0;o=a[K>>0]|0;n=a[L>>0]|0;j=a[x>>0]|0;h=a[y>>0]|0;g=a[A>>0]|0;e=a[C>>0]|0;r=a[P>>0]|0;k=a[z>>0]|0;i=a[B>>0]|0;f=a[D>>0]|0;break}default:{S=Vi(b)|0;R=Vi(b)|0;S=S&255;T=e>>>1;U=(S>>>3&16|(d[21653+(T<<1)>>0]|0))&255;T=a[21653+(T<<1)+1>>0]|0;S=(S&15|e<<4&16|S<<1&224)&255;hj(c,U);hj(c,T);hj(c,S);hj(c,R);w=m;v=p;u=o;q=n;m=r;p=k;o=i;n=f;e=s;r=U;k=T;i=S;f=R}}a[P>>0]=j;a[z>>0]=h;a[B>>0]=g;a[D>>0]=e;a[x>>0]=w;a[y>>0]=v;a[A>>0]=u;a[C>>0]=q;a[E>>0]=m;a[F>>0]=p;a[G>>0]=o;a[H>>0]=n;a[I>>0]=r;a[J>>0]=k;a[K>>0]=i;a[L>>0]=f;t=t+1|0;if((t|0)==256)break;else{s=q;g=u;h=v;j=w}}if((N|0)==(M|0))break;else{e=r;g=u;h=v;j=w;N=N+1|0}}jg(c,b,O);l=Q;return 0}function $g(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;if((e|0)<564){c=564-e|0;return c|0}else{i=0;k=0}while(1){l=i*14|0;h=b+l|0;e=gj(h+130|0)|0;g=h+134|0;g=(cj(a[g>>0]|0,a[g+1>>0]|0)|0)&65535;f=gj(h+138|0)|0;h=h+142|0;h=(cj(a[h>>0]|0,a[h+1>>0]|0)|0)&65535;if((f|0)<(e|0)?1:(d[b+(l+137)>>0]|0)>64){j=-1;h=22;break}if((e|0)<564|(f|0)<564){j=-1;h=22;break}l=f-e|0;if((l|0)>(g|0)|(h+l|0)>(g+2|0)){j=-1;h=22;break}k=g+k|0;i=i+1|0;if((i|0)>=31){h=7;break}}if((h|0)==7){if((k+-3|0)>>>0>2031582){l=-1;return l|0}i=a[b>>0]|0;if(i<<24>>24<1){l=-1;return l|0}else{f=0;g=0}do{l=a[b+(f+2)>>0]|0;e=l&255;if(l<<24>>24<0){j=-1;h=22;break}g=(e|0)>(g|0)?e:g;f=f+1|0}while((f|0)<128);if((h|0)==22)return j|0;h=(g<<10)+1024|0;e=(i&255)+2|0;a:do if(e>>>0<128){while(1){if(a[b+(e+2)>>0]|0){j=-1;break}e=e+1|0;if((e|0)>=128)break a}return j|0}while(0);e=k+564|0;b:do if((h|0)>0){g=0;c:while(1){f=e+g|0;if((d[b+f>>0]|0)>31){j=-1;h=22;break}l=a[b+(f+1)>>0]|0;if(!((l&255)<73&(l&1)==0)){j=-1;h=22;break}switch(a[b+(f+2)>>0]&15){case 11:{j=-1;h=22;break c}case 12:{if((d[b+(f+3)>>0]|0)>64){j=-1;h=22;break c}break}case 13:{if((d[b+(f+3)>>0]|0)>64){j=-1;h=22;break c}break}default:{}}g=g+4|0;if((g|0)>=(h|0))break b}if((h|0)==22)return j|0}while(0);ng(0,c,0);l=-1;return l|0}else if((h|0)==22)return j|0;return 0}function ah(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;n=l;l=l+1280|0;j=n+248|0;k=n+124|0;m=n;f=k;g=f+124|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));f=m;g=f+124|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));kg(e,1080);f=Om(130)|0;cp(f|0,0,130)|0;ro(e,950,0)|0;Go(f,130,1,b)|0;co(f,130,1,e);g=0;h=0;do{i=a[f+(g+2)>>0]|0;h=(i&255)>(h&255)?i:h;g=g+1|0}while((g|0)!=128);Pm(f);f=0;g=0;do{ro(e,(f*30|0)+42|0,0)|0;i=aj(b)|0;c[k+(f<<2)>>2]=i;p=Yi(b)|0;o=p&65535;ij(e,p);g=o+g|0;c[m+(f<<2)>>2]=o;hj(e,Vi(b)|0);hj(e,Vi(b)|0);ij(e,((aj(b)|0)-i|0)>>>1&65535);ij(e,Yi(b)|0);f=f+1|0}while((f|0)!=31);ro(b,g,1)|0;ro(e,0,2)|0;jj(e,1294879534);i=Om(1024)|0;f=h&255;g=0;while(1){cp(i|0,0,1024)|0;cp(j|0,0,1024)|0;Go(i,1024,1,b)|0;h=0;do{p=h<<4;s=p|3;a[j+s>>0]=a[i+s>>0]|0;s=p|2;o=a[i+p>>0]|0;a[j+s>>0]=a[i+s>>0]&15|(o&255)<<4;s=p|1;r=(d[i+s>>0]|0)>>>1&255;a[j+p>>0]=o&-16|a[21653+(r<<1)>>0];a[j+s>>0]=a[21653+(r<<1)+1>>0]|0;s=p|4;r=p|7;a[j+r>>0]=a[i+r>>0]|0;r=p|6;o=a[i+s>>0]|0;a[j+r>>0]=a[i+r>>0]&15|(o&255)<<4;r=p|5;q=(d[i+r>>0]|0)>>>1&255;a[j+s>>0]=o&-16|a[21653+(q<<1)>>0];a[j+r>>0]=a[21653+(q<<1)+1>>0]|0;r=p|8;q=p|11;a[j+q>>0]=a[i+q>>0]|0;q=p|10;s=a[i+r>>0]|0;a[j+q>>0]=a[i+q>>0]&15|(s&255)<<4;q=p|9;o=(d[i+q>>0]|0)>>>1&255;a[j+r>>0]=s&-16|a[21653+(o<<1)>>0];a[j+q>>0]=a[21653+(o<<1)+1>>0]|0;q=p|12;o=p|15;a[j+o>>0]=a[i+o>>0]|0;o=p|14;r=a[i+q>>0]|0;a[j+o>>0]=a[i+o>>0]&15|(r&255)<<4;p=p|13;o=(d[i+p>>0]|0)>>>1&255;a[j+q>>0]=r&-16|a[21653+(o<<1)>>0];a[j+p>>0]=a[21653+(o<<1)+1>>0]|0;h=h+1|0}while((h|0)!=64);co(j,1024,1,e);if((g|0)==(f|0))break;else g=g+1|0}Pm(i);g=0;do{f=c[m+(g<<2)>>2]|0;if(f|0){ro(b,c[k+(g<<2)>>2]|0,0)|0;jg(e,b,f)}g=g+1|0}while((g|0)!=31);l=n;return 0}function bh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;if((e|0)<1084){c=1084-e|0;return c|0}if((gj(b+1080|0)|0)==1294879534){f=0;h=0}else{c=-1;return c|0}do{l=b+(f*30|0)|0;g=l+42|0;g=((cj(a[g>>0]|0,a[g+1>>0]|0)|0)&65535)<<1;i=l+46|0;i=(cj(a[i>>0]|0,a[i+1>>0]|0)|0)&65535;l=l+48|0;if((g+2|0)>>>0<((cj(a[l>>0]|0,a[l+1>>0]|0)|0)&65535)+i<<1>>>0){k=-1;j=23;break}h=g+h|0;f=f+1|0}while((f|0)<31);if((j|0)==23)return k|0;if((h|0)<3){l=-1;return l|0}else f=0;while(1){g=f*30|0;if((d[b+(g+40)>>0]|0)>15){k=-1;j=23;break}if(a[b+(g+44)>>0]|0){k=-1;j=23;break}f=f+1|0;if((d[b+(g+45)>>0]|0)>64){k=-1;j=23;break}if((f|0)>=31){j=11;break}}if((j|0)==11){l=a[b+950>>0]|0;g=l&255;if(l<<24>>24<1){l=-1;return l|0}else{f=0;i=0}do{l=a[b+(f+952)>>0]|0;h=l&255;if(l<<24>>24<0){k=-1;j=23;break}i=(h|0)>(i|0)?h:i;f=f+1|0}while((f|0)<(g|0));if((j|0)==23)return k|0;g=i+1|0;a:do if((f|0)!=128){while(1){if(a[b+(f+952)>>0]|0){k=-1;break}f=f+1|0;if((f|0)==128)break a}return k|0}while(0);f=(g*768|0)+1084|0;if((f|0)>(e|0)){l=f-e|0;return l|0}g=g<<8;b:do if((g|0)>0){f=0;while(1){if((d[b+((f*3|0)+1084)>>0]|0)>116){k=-1;break}f=f+1|0;if((f|0)>=(g|0))break b}return k|0}while(0);ng(b,c,20);l=0;return l|0}else if((j|0)==23)return k|0;return 0}function ch(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0;o=l;l=l+1040|0;n=o;jg(c,b,20);g=0;m=0;do{jg(c,b,20);hj(c,0);hj(c,0);e=Vi(b)|0;f=(Vi(b)|0)&255;e=(e&255)<<8|f;do if(e)if(e>>>0<256){e=16-f&255;break}else{e=256-f&255;break}else e=0;while(0);j=Yi(b)|0;f=j&65535;ij(c,j);m=(f<<1)+m|0;Vi(b)|0;hj(c,e);hj(c,Vi(b)|0);e=Yi(b)|0;j=e&65535;k=Yi(b)|0;i=j<<1;ij(c,(e<<16>>16!=0&(i+(k&65535)|0)>>>0<=f>>>0?i:j)&65535);ij(c,k);g=g+1|0}while((g|0)!=31);hj(c,Vi(b)|0);hj(c,127);Vi(b)|0;Go(n,128,1,b)|0;co(n,128,1,c);e=0;f=0;do{k=a[n+e>>0]|0;f=(k&255)>(f&255)?k:f;e=e+1|0}while((e|0)!=128);f=f+1<<24>>24;jj(c,1294879534);ro(b,1080,0)|0;e=aj(b)|0;a:do if((e|0)>=1294879534)if((e|0)<1431193923)switch(e|0){case 1294879534:break a;default:{h=10;break a}}else switch(e|0){case 1431193923:break a;default:{h=10;break a}}else switch(e|0){case 0:break;default:h=10}while(0);if((h|0)==10)ro(b,-4,1)|0;k=f&255;if(!(f<<24>>24)){jg(c,b,m);l=o;return 0}else i=0;do{j=0;do{h=Vi(b)|0;g=Vi(b)|0;e=Vi(b)|0;h=h&255;f=h&63;if((g&15)==13)e=((((e&255)/10|0)&255)<<4|((e&255)%10|0)&255)&255;p=j<<2;a[n+p>>0]=d[21653+(f<<1)>>0]|0|h>>>2&16;a[n+(p|1)>>0]=a[21653+(f<<1)+1>>0]|0;a[n+(p|2)>>0]=g;a[n+(p|3)>>0]=e;j=j+1|0}while((j|0)!=256);co(n,1024,1,c);i=i+1|0}while((i|0)!=(k|0));jg(c,b,m);l=o;return 0}function dh(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if((d|0)<1084){c=1084-d|0;return c|0}if(!(gj(b+1080|0)|0)){c=-1;return c|0}else{k=0;o=0;m=0}while(1){e=k*30|0;g=b+e|0;h=g+42|0;h=cj(a[h>>0]|0,a[h+1>>0]|0)|0;l=(h&65535)<<1;i=g+46|0;i=cj(a[i>>0]|0,a[i+1>>0]|0)|0;j=g+48|0;j=cj(a[j>>0]|0,a[j+1>>0]|0)|0;m=l+m|0;if(j<<16>>16?(l+2|0)>>>0<(j&65535)+(i&65535)<<1>>>0:0){n=-1;i=31;break}if((i|h|j)<<16>>16<0){n=-1;i=31;break}f=a[b+(e+45)>>0]|0;if((f&255)>64){n=-1;i=31;break}g=g+40|0;g=cj(a[g>>0]|0,a[g+1>>0]|0)|0;e=h<<16>>16==0;if(e&g<<16>>16!=0|(g+-9&65535)<238){n=-1;i=31;break}if(i<<16>>16!=0&(j&65535)<2|e&f<<24>>24!=0){n=-1;i=31;break}o=e?o:l|1;k=k+1|0;if((k|0)>=31){i=11;break}}if((i|0)==11){if((m|0)<3){c=-1;return c|0}m=a[b+950>>0]|0;g=m&255;if(m<<24>>24<1){c=-1;return c|0}else{e=0;h=0}do{m=a[b+(e+952)>>0]|0;f=m&255;if(m<<24>>24<0){n=-1;i=31;break}h=(f|0)>(h|0)?f:h;e=e+1|0}while((e|0)<(g|0));if((i|0)==31)return n|0;a:do if((e|0)!=128){while(1){if(a[b+(e+952)>>0]|0){n=-1;break}e=e+1|0;if((e|0)==128)break a}return n|0}while(0);e=h+1|0;f=(e*768|0)+1082|0;if((f|0)>(d|0)){c=f-d|0;return c|0}h=e<<8;b:do if((h|0)>0){g=0;c:while(1){e=g*3|0;f=a[b+(e+1080)>>0]|0;if((f&255)>116|(f&63)>36){n=-1;i=31;break}switch(a[b+(e+1081)>>0]&15){case 12:{e=a[b+(e+1082)>>0]|0;if((e&255)>64){n=-1;i=31;break c}break}case 11:{e=a[b+(e+1082)>>0]|0;if(e<<24>>24<0){n=-1;i=31;break c}break}case 13:{e=a[b+(e+1082)>>0]|0;if((e&255)>64){n=-1;i=31;break c}break}default:e=a[b+(e+1082)>>0]|0}g=g+1|0;if(((f&255)>>>2&48|(e&255)>>>4|0)>(o|0)){n=-1;i=31;break}if((g|0)>=(h|0))break b}if((i|0)==31)return n|0}while(0);o=a[b>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+1>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+2>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+3>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+4>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+5>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+6>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+7>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+8>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+9>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+10>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+11>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+12>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+13>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+14>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+15>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+16>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+17>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+18>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}o=a[b+19>>0]|0;if((o&255)>180|(o+-1&255)<31){c=-1;return c|0}ng(b,c,20);c=0;return c|0}else if((i|0)==31)return n|0;return 0}function eh(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if((d|0)<1084){c=1084-d|0;return c|0}if(!(gj(b+1080|0)|0)){k=0;o=0;m=0}else{c=-1;return c|0}while(1){e=k*30|0;g=b+e|0;h=g+42|0;h=cj(a[h>>0]|0,a[h+1>>0]|0)|0;l=(h&65535)<<1;i=g+46|0;i=cj(a[i>>0]|0,a[i+1>>0]|0)|0;j=g+48|0;j=cj(a[j>>0]|0,a[j+1>>0]|0)|0;m=l+m|0;if(j<<16>>16?(l+2|0)>>>0<(j&65535)+(i&65535)<<1>>>0:0){n=-1;i=30;break}if((i|h|j)<<16>>16<0){n=-1;i=30;break}f=a[b+(e+45)>>0]|0;if((f&255)>64){n=-1;i=30;break}g=g+40|0;g=cj(a[g>>0]|0,a[g+1>>0]|0)|0;e=h<<16>>16==0;if(e&g<<16>>16!=0|(g+-9&65535)<238){n=-1;i=30;break}if(i<<16>>16!=0&(j&65535)<2|e&f<<24>>24!=0){n=-1;i=30;break}o=e?o:l|1;k=k+1|0;if((k|0)>=31){i=11;break}}if((i|0)==11){if((m|0)<3){c=-1;return c|0}m=a[b+950>>0]|0;g=m&255;if(m<<24>>24<1){c=-1;return c|0}else{e=0;h=0}do{m=a[b+(e+952)>>0]|0;f=m&255;if(m<<24>>24<0){n=-1;i=30;break}h=(f|0)>(h|0)?f:h;e=e+1|0}while((e|0)<(g|0));if((i|0)==30)return n|0;f=h+1|0;a:do if((e|0)!=128){while(1){if(a[b+(e+952)>>0]|0){n=-1;break}e=e+1|0;if((e|0)==128)break a}return n|0}while(0);e=(f*768|0)+1086|0;if((e|0)>(d|0)){c=e-d|0;return c|0}h=f<<8;b:do if((h|0)>0){g=0;c:while(1){e=g*3|0;f=a[b+(e+1084)>>0]|0;if((f&255)>116|(f&63)>36){n=-1;i=30;break}switch(a[b+(e+1085)>>0]&15){case 12:{e=a[b+(e+1086)>>0]|0;if((e&255)>64){n=-1;i=30;break c}break}case 11:{e=a[b+(e+1086)>>0]|0;if(e<<24>>24<0){n=-1;i=30;break c}break}case 13:{e=a[b+(e+1086)>>0]|0;if((e&255)>64){n=-1;i=30;break c}break}default:e=a[b+(e+1086)>>0]|0}g=g+1|0;if(((f&255)>>>2&48|(e&255)>>>4|0)>(o|0)){n=-1;i=30;break}if((g|0)>=(h|0))break b}if((i|0)==30)return n|0}while(0);ng(b,c,20);c=0;return c|0}else if((i|0)==30)return n|0;return 0}function fh(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;if((d|0)<1084){c=1084-d|0;return c|0}if(!(gj(b+1080|0)|0)){c=-1;return c|0}else{j=0;n=0;l=0}while(1){g=j*30|0;h=b+g|0;i=h+22|0;i=cj(a[i>>0]|0,a[i+1>>0]|0)|0;k=(i&65535)<<1;e=h+26|0;e=cj(a[e>>0]|0,a[e+1>>0]|0)|0;f=h+28|0;f=cj(a[f>>0]|0,a[f+1>>0]|0)|0;l=k+l|0;if((k+2|0)>>>0<(f&65535)+(e&65535)<<1>>>0){m=-1;i=25;break}if((e|i|f)<<16>>16<0){m=-1;i=25;break}f=a[b+(g+25)>>0]|0;if((f&255)>64){m=-1;i=25;break}h=h+20|0;e=i<<16>>16==0;if(e&((cj(a[h>>0]|0,a[h+1>>0]|0)|0)<<16>>16!=0|f<<24>>24!=0)){m=-1;i=25;break}n=e?n:k|1;j=j+1|0;if((j|0)>=31){i=9;break}}if((i|0)==9){if((l|0)<3){c=-1;return c|0}l=a[b+930>>0]|0;f=l&255;if(l<<24>>24<1){c=-1;return c|0}else{g=0;h=0}while(1){l=a[b+(g+932)>>0]|0;e=l&255;if(l<<24>>24<0){m=-1;i=25;break}h=(e|0)>(h|0)?e:h;e=g+1|0;if((e|0)>=(f|0))break;else g=e}if((i|0)==25)return m|0;e=g+3|0;f=h+1|0;a:do if((e|0)!=128){while(1){if(a[b+(e+932)>>0]|0){m=-1;break}e=e+1|0;if((e|0)==128)break a}return m|0}while(0);e=(f*768|0)+1062|0;if((e|0)>(d|0)){c=e-d|0;return c|0}j=f<<8;b:do if((j|0)>0){i=0;while(1){e=i*3|0;h=a[b+(e+1060)>>0]|0;if((h&255)>116|(h&63)>36){m=-1;i=25;break}g=a[b+(e+1061)>>0]&15;e=a[b+(e+1062)>>0]|0;f=(e&255)>64;if(g<<24>>24==12&f){m=-1;i=25;break}if(g<<24>>24==11&e<<24>>24<0|g<<24>>24==13&f){m=-1;i=25;break}i=i+1|0;if(((e&255)>>>4|(h&255)>>>2&48|0)>(n|0)){m=-1;i=25;break}if((i|0)>=(j|0))break b}if((i|0)==25)return m|0}while(0);ng(0,c,0);c=0;return c|0}else if((i|0)==25)return m|0;return 0}function gh(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0;o=l;l=l+1040|0;n=o;kg(c,20);g=0;m=0;do{jg(c,b,20);hj(c,0);hj(c,0);e=Vi(b)|0;f=(Vi(b)|0)&255;e=(e&255)<<8|f;do if(e)if(e>>>0<256){e=16-f&255;break}else{e=256-f&255;break}else e=0;while(0);f=Yi(b)|0;h=f&65535;ij(c,f);m=(h<<1)+m|0;Vi(b)|0;hj(c,e);hj(c,Vi(b)|0);f=Yi(b)|0;j=f&65535;k=Yi(b)|0;i=j<<1;ij(c,(f<<16>>16!=0&(i+(k&65535)|0)>>>0<=h>>>0?i:j)&65535);ij(c,k);g=g+1|0}while((g|0)!=31);hj(c,Vi(b)|0);hj(c,127);Vi(b)|0;Go(n,128,1,b)|0;co(n,128,1,c);e=0;f=0;do{k=a[n+e>>0]|0;f=(k&255)>(f&255)?k:f;e=e+1|0}while((e|0)!=128);k=f+1<<24>>24;jj(c,1294879534);h=k&255;if(!(k<<24>>24)){jg(c,b,m);l=o;return 0}else j=0;do{k=0;do{i=Vi(b)|0;g=Vi(b)|0;e=Vi(b)|0;i=i&255;f=i&63;if((g&15)==13)e=((((e&255)/10|0)&255)<<4|((e&255)%10|0)&255)&255;p=k<<2;a[n+p>>0]=d[21653+(f<<1)>>0]|0|i>>>2&16;a[n+(p|1)>>0]=a[21653+(f<<1)+1>>0]|0;a[n+(p|2)>>0]=g;a[n+(p|3)>>0]=e;k=k+1|0}while((k|0)!=256);co(n,1024,1,c);j=j+1|0}while((j|0)!=(h|0));jg(c,b,m);l=o;return 0}function hh(b,c,d){b=b|0;c=c|0;d=d|0;if((d|0)>=1082)if((((a[b+1080>>0]|0)==87?(a[b+1081>>0]|0)==78:0)?(a[b+951>>0]|0)==127:0)?(a[b+950>>0]|0)>=0:0){ng(b,c,20);b=0}else b=-1;else b=1082-d|0;return b|0}function ih(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0;i=l;l=l+1024|0;g=i;jg(c,b,950);e=0;h=0;do{ro(b,(e*30|0)+42|0,0)|0;h=(((Yi(b)|0)&65535)<<1)+h|0;e=e+1|0}while((e|0)!=31);ro(b,950,0)|0;hj(c,Vi(b)|0);Go(g,129,1,b)|0;co(g,129,1,c);jj(c,1294879534);e=0;f=0;do{e=e+1|0;j=a[g+e>>0]|0;f=(j&255)>(f&255)?j:f}while((e|0)!=128);j=f+1<<24>>24;ro(b,1084,0)|0;e=j&255;if(!(j<<24>>24)){jg(c,b,h);l=i;return 0}else f=0;do{g=0;do{o=Vi(b)|0;m=Vi(b)|0;k=Vi(b)|0;j=Vi(b)|0;n=(o&255)>>>1&255;hj(c,(d[21653+(n<<1)>>0]|0|(o&255)*240)&255);hj(c,a[21653+(n<<1)+1>>0]|0);hj(c,((m&255)<<4|k&255)&255);hj(c,j);g=g+1|0}while((g|0)!=256);f=f+1|0}while((f|0)!=(e|0));jg(c,b,h);l=i;return 0}function jh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if((e|0)<505){c=505-e|0;return c|0}l=gj(b)|0;if((l+-502|0)>>>0>2162688){c=-1;return c|0}f=b+6|0;g=0;while(1){h=g<<4;if((d[b+(h|9)>>0]|0)>64){k=-1;j=16;break}j=f+h|0;g=g+1|0;if((((cj(a[j>>0]|0,a[j+1>>0]|0)|0)&65535)%72|0)<<16>>16){k=-1;j=16;break}if((g|0)>=31){j=6;break}}if((j|0)==6){f=b+10|0;g=b+12|0;h=b+14|0;i=0;do{m=i<<4;n=f+m|0;n=cj(a[n>>0]|0,a[n+1>>0]|0)|0;o=g+m|0;o=cj(a[o>>0]|0,a[o+1>>0]|0)|0;if((o|n)<<16>>16<0|(gj(h+m|0)|0)<(l|0)){k=-1;j=16;break}i=i+1|0}while((i|0)<31);if((j|0)==16)return k|0;f=a[b+5>>0]|0;if(f<<24>>24<1){o=-1;return o|0}g=(f&255)<<2;f=l+4+g|0;if((f|0)>(e|0)){o=f-e|0;return o|0}if((gj(b+l+g|0)|0)!=-1){o=-1;return o|0}ng(0,c,0);o=0;return o|0}else if((j|0)==16)return k|0;return 0}function kh(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+2176|0;s=t+1152|0;o=t+1024|0;n=t+512|0;r=t;cp(n|0,0,512)|0;cp(r|0,0,512)|0;f=o;g=f+128|0;do{a[f>>0]=0;f=f+1|0}while((f|0)<(g|0));f=aj(b)|0;m=Vi(b)|0;h=Vi(b)|0;kg(e,20);g=0;p=999999;q=0;do{kg(e,22);j=(((Yi(b)|0)&65535)/72|0)&255;Vi(b)|0;k=Vi(b)|0;i=Yi(b)|0;ij(e,i);q=((i&65535)<<1)+q|0;hj(e,j);hj(e,k);k=Yi(b)|0;j=aj(b)|0;p=(j|0)<(p|0)?j:p;ij(e,((aj(b)|0)-j|0)>>>1&65535);ij(e,k);g=g+1|0}while((g|0)!=31);hj(e,h);hj(e,127);ro(b,f,0)|0;k=h&255;if(h<<24>>24){f=0;do{c[n+(f<<2)>>2]=aj(b)|0;f=f+1|0}while((f|0)!=(k|0));i=c[n>>2]|0;f=0;j=0;do{if(j){a:do if((j|0)>0){h=c[n+(j<<2)>>2]|0;g=0;while(1){if((h|0)==(c[n+(g<<2)>>2]|0))break;g=g+1|0;if((g|0)>=(j|0))break a}a[o+j>>0]=a[o+g>>0]|0}else g=0;while(0);if((g|0)==(j|0)){c[r+((f&255)<<2)>>2]=c[n+(j<<2)>>2];a[o+j>>0]=f;f=f+1<<24>>24}}else{a[o>>0]=0;c[r>>2]=i;f=f+1<<24>>24}j=j+1|0}while((j|0)!=(k|0))}co(o,128,1,e);jj(e,1294879534);f=m&255;g=0;while(1){cp(s|0,0,1024)|0;ro(b,c[r+(g<<2)>>2]|0,0)|0;do{o=Vi(b)|0;i=Vi(b)|0;k=Vi(b)|0;m=Vi(b)|0;i=i&255;j=i>>>1&63;o=o&255;n=o<<2;a[s+n>>0]=d[21653+(j<<1)>>0]|0|i<<4&16;a[s+(n|1)>>0]=a[21653+(j<<1)+1>>0]|0;a[s+(n|2)>>0]=k;a[s+(n|3)>>0]=m}while((o+1|0)>>>0<256);co(s,1024,1,e);if((g|0)==(f|0))break;else g=g+1|0}ro(b,p,0)|0;jg(e,b,q);l=t;return 0}function lh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;if((e|0)<1024){c=1024-e|0;return c|0}if(en(b,22223,8)|0){c=-1;return c|0}h=cj(a[b+28>>0]|0,a[b+29>>0]|0)|0;if(h<<16>>16==0|(h&7)!=0){c=-1;return c|0}e=(h&65535)>>>3;i=e&65535;if(!(e<<16>>16)){c=-1;return c|0}else e=0;while(1){if((d[b+((e<<3)+30)>>0]|0)>15){k=-1;g=15;break}e=e+1|0;if((e|0)>=(i|0)){f=0;break}}if((g|0)==15)return k|0;while(1){if((d[b+((f<<3)+31)>>0]|0)>64){k=-1;g=15;break}f=f+1|0;if((f|0)>=(i|0)){j=0;l=0;break}}if((g|0)==15)return k|0;while(1){f=b+(j<<3)|0;m=f+32|0;m=cj(a[m>>0]|0,a[m+1>>0]|0)|0;g=(m&65535)<<1;e=f+34|0;e=cj(a[e>>0]|0,a[e+1>>0]|0)|0;f=f+36|0;f=cj(a[f>>0]|0,a[f+1>>0]|0)|0;if((e|m|f)<<16>>16<0){k=-1;g=15;break}if(e<<16>>16!=0&f<<16>>16==0|(f&65535)+(e&65535)<<1>>>0>(g+2|0)>>>0){k=-1;g=15;break}l=g+l|0;j=j+1|0;if((j|0)>=(i|0)){g=13;break}}if((g|0)==13){if((l|0)<5|(h&65535)>1031){m=-1;return m|0}ng(b+8|0,c,20);m=0;return m|0}else if((g|0)==15)return k|0;return 0}function mh(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;x=l;l=l+3264|0;n=x+3128|0;v=x+2104|0;k=x+2048|0;w=x;cp(w|0,0,2048)|0;h=n;i=h+128|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));ro(b,8,1)|0;jg(e,b,20);j=((Yi(b)|0)&65535)>>>3&255;f=j&65535;if(j<<16>>16){h=0;g=0;do{kg(e,22);t=Vi(b)|0;u=Vi(b)|0;s=Yi(b)|0;ij(e,s);g=((s&65535)<<1)+g|0;hj(e,t);hj(e,u);ij(e,Yi(b)|0);ij(e,Yi(b)|0);h=h+1|0}while((h|0)<(f|0));h=k;i=h+29|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));a[k+29>>0]=1;if((j&65535)<31)m=5;else u=g}else{h=k;i=h+29|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));a[k+29>>0]=1;f=0;g=0;m=5}if((m|0)==5){do{co(k,30,1,e);f=f+1|0}while((f|0)!=31);u=g}Vi(b)|0;t=Vi(b)|0;hj(e,t);hj(e,127);g=t&255;if(!(t<<24>>24))f=0;else{h=0;f=0;do{s=((Yi(b)|0)&65535)>>>3;t=s&255;a[n+h>>0]=t;f=(s&255)>>>0>(f&255)>>>0?t:f;h=h+1|0}while((h|0)!=(g|0))}t=(f&255)+1|0;f=0;g=0;do{s=(Yi(b)|0)&65535;c[w+(f<<4)>>2]=s;s=(s|0)>(g|0)?s:g;r=(Yi(b)|0)&65535;c[w+(f<<4)+4>>2]=r;s=(r|0)>(s|0)?r:s;r=(Yi(b)|0)&65535;c[w+(f<<4)+8>>2]=r;s=(r|0)>(s|0)?r:s;r=(Yi(b)|0)&65535;c[w+(f<<4)+12>>2]=r;g=(r|0)>(s|0)?r:s;f=f+1|0}while((f|0)!=(t|0));co(n,128,1,e);jj(e,1294879534);r=(Ho(b)|0)+2|0;s=0;f=g;do{cp(v|0,0,1024)|0;q=0;do{ro(b,r+(c[w+(s<<4)+(q<<2)>>2]|0)|0,0)|0;p=q<<2;g=0;do{o=(g<<4)+p|0;i=(Vi(b)|0)&255;h=i&192;do if((h|0)==192)g=g+255-i|0;else{k=Vi(b)|0;if((h|0)==128){n=i>>>1;i=n&15;j=i&255;a:do switch(n&15){case 10:case 6:case 5:{h=k&255;if((k&255)>128){h=256-h&255;break a}else{h=h<<4&255;break a}}default:h=k}while(0);a[v+(o|2)>>0]=(i|0)==8?0:j;a[v+(o|3)>>0]=h;break}m=k&255;n=i>>>2;k=(i&64|0)==0?i&63:127-i|0;h=m&15;if(!h){k=k&255;a[v+o>>0]=d[21653+(k<<1)>>0]|0|n&16;a[v+(o|1)>>0]=a[21653+(k<<1)+1>>0]|0;a[v+(o|2)>>0]=m&240;break}j=Vi(b)|0;i=(h|0)==8?0:h;b:do switch(i&15){case 10:case 6:case 5:{h=j&255;if((j&255)>128){h=256-h&255;break b}else{h=h<<4&255;break b}}default:h=j}while(0);k=k&255;a[v+o>>0]=d[21653+(k<<1)>>0]|0|n&16;a[v+(o|1)>>0]=a[21653+(k<<1)+1>>0]|0;a[v+(o|2)>>0]=i|m&240;a[v+(o|3)>>0]=h}while(0);g=g+1|0}while((g|0)<64);p=Ho(b)|0;f=(p|0)>(f|0)?p:f;q=q+1|0}while((q|0)!=4);co(v,1024,1,e);s=s+1|0}while((s|0)!=(t|0));ro(b,(f&1)+f|0,0)|0;jg(e,b,u);l=x;return 0}function nh(a,b,c){a=a|0;b=b|0;c=c|0;switch(gj(a)|0){case 1345597505:case 1345597506:case 1345597761:{ng(0,b,0);a=0;break}default:a=-1}return a|0}function oh(d,e){d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;H=l;l=l+133376|0;B=H+132344|0;C=H+1272|0;z=H+248|0;D=H+124|0;E=H;cp(z|0,0,1024)|0;cp(C|0,0,131072)|0;g=D;h=g+124|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));g=E;h=g+124|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));g=aj(d)|0;Vi(d)|0;f=Vi(d)|0;q=Vi(d)|0;Vi(d)|0;s=aj(d)|0;r=aj(d)|0;F=aj(d)|0;kg(e,20);G=q&255;A=q<<24>>24==0;if(!A){p=(g+-1345597505|0)>>>0<2;n=(g|0)==1345597761;o=0;do{h=aj(d)|0;c[D+(o<<2)>>2]=h;i=Yi(d)|0;c[E+(o<<2)>>2]=(i&65535)<<1;j=aj(d)|0;k=Yi(d)|0;if(p)g=Yi(d)|0;else g=0;Vi(d)|0;m=Vi(d)|0;if(n)g=Yi(d)|0;kg(e,22);ij(e,i);hj(e,((g<<16>>16)/74|0)&255);hj(e,m);ij(e,((j-h|0)/2|0)&65535);ij(e,k);o=o+1|0}while((o|0)!=(G|0));g=B;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[B+29>>0]=1;if((q&255)<31){g=G;t=10}}else{g=B;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[B+29>>0]=1;g=0;t=10}if((t|0)==10)while(1){t=0;co(B,30,1,e);g=g+1|0;if((g|0)==31)break;else t=10}hj(e,f);hj(e,127);ro(d,r+4|0,0)|0;y=f&255;h=f<<24>>24==0;if(!h){g=0;do{hj(e,g);g=g+1<<24>>24}while((g&255)<(f&255));if(f<<24>>24>-1)t=14}else{f=0;t=14}if((t|0)==14)while(1){hj(e,0);f=f+1<<24>>24;if(f<<24>>24<=-1)break;else t=14}jj(e,1294879534);x=s+4|0;if(h)ro(d,x,0)|0;else{f=0;do{b[z+(f<<3)>>1]=x+((Yi(d)|0)&65535);b[z+(f<<3)+2>>1]=x+((Yi(d)|0)&65535);b[z+(f<<3)+4>>1]=x+((Yi(d)|0)&65535);b[z+(f<<3)+6>>1]=x+((Yi(d)|0)&65535);f=f+1|0}while((f|0)!=(y|0));ro(d,x,0)|0;u=0;do{w=u<<2;v=0;do{t=v+w|0;ro(d,b[z+(u<<3)+(v<<1)>>1]|0,0)|0;p=0;do{s=Vi(d)|0;g=Vi(d)|0;i=Vi(d)|0;n=Vi(d)|0;f=s&255;if(s<<24>>24!=-128){h=f<<4&16;o=f>>>1&63;f=a[21653+(o<<1)>>0]|0;o=a[21653+(o<<1)+1>>0]|0;switch(g&15){case 8:{m=(g&255)+248&255;break}case 10:case 6:case 5:{if(i<<24>>24<0){m=g;i=(i&255)<<4&255}else m=g;break}default:m=g}k=p<<2;j=(f&15|h)&255;a[C+(t<<8)+k>>0]=j;a[(k|1)+(C+(t<<8))>>0]=o;a[(k|2)+(C+(t<<8))>>0]=m;a[(k|3)+(C+(t<<8))>>0]=i;k=n&255;g=n<<24>>24>0?k:0;f=g+p|0;if(n<<24>>24<0){h=g|256;g=256;do{f=f+1|0;s=f<<2;a[C+(t<<8)+s>>0]=j;a[(s|1)+(C+(t<<8))>>0]=o;a[(s|2)+(C+(t<<8))>>0]=m;a[(s|3)+(C+(t<<8))>>0]=i;g=g+-1|0}while((g|0)>(k|0));f=h+p-k|0}}else{s=Ho(d)|0;ro(d,x+((i&255)<<8|n&255)|0,0)|0;r=g&255;q=0;while(1){o=Vi(d)|0;f=Vi(d)|0;g=Vi(d)|0;m=Vi(d)|0;o=o&255;i=o<<4&16;o=o>>>1&63;h=a[21653+(o<<1)>>0]|0;o=a[21653+(o<<1)+1>>0]|0;switch(f&15){case 8:{n=(f&255)+248&255;break}case 10:case 6:case 5:{if(g<<24>>24<0){n=f;g=(g&255)<<4&255}else n=f;break}default:n=f}j=(h&15|i)&255;k=p<<2;a[C+(t<<8)+k>>0]=j;a[(k|1)+(C+(t<<8))>>0]=o;a[(k|2)+(C+(t<<8))>>0]=n;a[(k|3)+(C+(t<<8))>>0]=g;k=m&255;h=m<<24>>24>0?k:0;f=h+p|0;if(m<<24>>24<0){i=h|256;h=256;do{f=f+1|0;m=f<<2;a[C+(t<<8)+m>>0]=j;a[(m|1)+(C+(t<<8))>>0]=o;a[(m|2)+(C+(t<<8))>>0]=n;a[(m|3)+(C+(t<<8))>>0]=g;h=h+-1|0}while((h|0)>(k|0));f=i+p-k|0}if((q|0)==(r|0))break;else{q=q+1|0;p=f+1|0}}ro(d,s,0)|0}p=f+1|0}while((p|0)<64);v=v+1|0}while((v|0)!=4);u=u+1|0}while((u|0)!=(y|0));i=0;do{cp(B|0,0,1024)|0;k=i<<2;f=k|1;g=k|2;h=k|3;j=0;do{z=j<<4;u=j<<2;v=u|1;w=u|2;x=u|3;a[B+z>>0]=a[C+(k<<8)+u>>0]|0;a[B+(z|1)>>0]=a[C+(k<<8)+v>>0]|0;a[B+(z|2)>>0]=a[C+(k<<8)+w>>0]|0;a[B+(z|3)>>0]=a[C+(k<<8)+x>>0]|0;a[B+(z|4)>>0]=a[C+(f<<8)+u>>0]|0;a[B+(z|5)>>0]=a[C+(f<<8)+v>>0]|0;a[B+(z|6)>>0]=a[C+(f<<8)+w>>0]|0;a[B+(z|7)>>0]=a[C+(f<<8)+x>>0]|0;a[B+(z|8)>>0]=a[C+(g<<8)+u>>0]|0;a[B+(z|9)>>0]=a[C+(g<<8)+v>>0]|0;a[B+(z|10)>>0]=a[C+(g<<8)+w>>0]|0;a[B+(z|11)>>0]=a[C+(g<<8)+x>>0]|0;a[B+(z|12)>>0]=a[C+(h<<8)+u>>0]|0;a[B+(z|13)>>0]=a[C+(h<<8)+v>>0]|0;a[B+(z|14)>>0]=a[C+(h<<8)+w>>0]|0;a[B+(z|15)>>0]=a[C+(h<<8)+x>>0]|0;j=j+1|0}while((j|0)!=64);co(B,1024,1,e);i=i+1|0}while((i|0)!=(y|0))}if(A){l=H;return 0}else f=0;do{ro(d,(c[D+(f<<2)>>2]|0)+F|0,0)|0;jg(e,d,c[E+(f<<2)>>2]|0);f=f+1|0}while((f|0)!=(G|0));l=H;return 0}function ph(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;if((e|0)<2048){i=2048-e|0;return i|0}if((a[b+3>>0]|0)==60)e=0;else{i=-1;return i|0}while(1){j=e<<2;j=d[b+(j|1)>>0]<<16|d[b+j>>0]<<24|d[b+(j|2)>>0]<<8|d[b+(j|3)>>0];e=e+1|0;if((j|0)>132156?1:(((j|0)/4|0)<<2|0)!=(j|0)){h=-1;i=14;break}if((e|0)>=128){f=0;break}}if((i|0)==14)return h|0;a:while(1){switch(a[b+(f<<2|3)>>0]|0){case 0:case 60:break;default:{h=-1;i=14;break a}}f=f+1|0;if((f|0)>=64){g=0;break}}if((i|0)==14)return h|0;do{if((d[b+((g<<4)+519)>>0]|0)>64){h=-1;i=14;break}g=g+1|0}while((g|0)<31);if((i|0)==14)return h|0;g=b+526|0;e=b+520|0;f=0;while(1){if((f|0)>=30)break;b=gj(g+(f<<4)|0)|0;f=f+1|0;j=gj(e+(f<<4)|0)|0;if((b|0)>(j|0)|((b|0)<2108|(j|0)<2108)){h=-1;i=14;break}}if((i|0)==14)return h|0;ng(0,c,0);j=0;return j|0}function qh(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0;o=l;l=l+1168|0;i=o+1032|0;n=o;e=i;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));cp(n|0,0,1025)|0;kg(c,20);ro(b,518,0)|0;e=0;m=0;do{kg(c,22);f=Vi(b)|0;g=Vi(b)|0;h=aj(b)|0;k=Yi(b)|0;j=aj(b)|0;p=Yi(b)|0;ij(c,p);m=((p&65535)<<1)+m|0;hj(c,f);hj(c,g);ij(c,((h-j|0)/2|0)&65535);ij(c,k);Yi(b)|0;e=e+1|0}while((e|0)!=31);ro(b,0,0)|0;f=0;h=0;e=0;do{g=aj(b)|0;if(!g){f=h&255;break}k=((g+-60|0)/1024|0)+255|0;p=k&255;a[i+h>>0]=p;e=(k&255)>>>0>(e&255)>>>0?p:e;h=h+1|0;f=f+1<<24>>24}while((h&255)<<24>>24>-1);p=e+1<<24>>24;hj(c,f);hj(c,127);co(i,128,1,c);jj(c,1294879534);ro(b,1084,0)|0;h=p&255;if(!(p<<24>>24)){jg(c,b,m);l=o;return 0}else i=0;do{j=0;do{k=((Vi(b)|0)&255)>>>3;g=Vi(b)|0;p=Vi(b)|0;e=Vi(b)|0;p=p&255;do switch(p>>>2|p<<30|0){case 1:case 0:{f=0;break}case 2:{f=1;break}case 3:{f=2;break}case 4:{f=3;break}case 5:{f=3;break}case 6:{f=4;break}case 7:{f=4;break}case 9:{f=5;break}case 10:{e=((e&255)<<4|(e&255)>>>4&255)&255;f=6;break}case 11:{f=6;break}case 14:{f=9;break}case 15:{e=((e&255)<<4|(e&255)>>>4&255)&255;f=10;break}case 16:{f=10;break}case 17:{f=11;break}case 18:{f=12;break}case 19:{f=13;break}case 20:{f=15;break}case 22:{e=1;f=14;break}case 23:{e=e|16;f=14;break}case 24:{e=e|32;f=14;break}case 33:{e=e|-112;f=14;break}case 34:{e=e|-96;f=14;break}case 35:{e=e|-80;f=14;break}case 37:{e=e|-48;f=14;break}case 38:{e=e|-32;f=14;break}default:{e=0;f=0}}while(0);k=k&255;p=j<<2;g=(g&255)>>>1&255;a[n+p>>0]=d[21653+(g<<1)>>0]|0|k&16;a[n+(p|1)>>0]=a[21653+(g<<1)+1>>0]|0;a[n+(p|2)>>0]=f|k<<4;a[n+(p|3)>>0]=e;j=j+1|0}while((j|0)!=256);co(n,1024,1,c);i=i+1|0}while((i|0)!=(h|0));jg(c,b,m);l=o;return 0}function rh(a,b,c){a=a|0;b=b|0;c=c|0;return wh(a,b,c,80)|0}function sh(a,b){a=a|0;b=b|0;return th(a,b,80)|0}function th(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;A=l;l=l+3584|0;p=A+3448|0;k=A+2296|0;q=A+248|0;z=A+124|0;y=A;s=A+2424|0;t=Qm(512,256)|0;if(!t){z=-1;l=A;return z|0}cp(q|0,0,2048)|0;g=p;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));g=z;h=g+124|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));g=k;h=g+124|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));c[y>>2]=0;x=(Yi(b)|0)&65535;m=Vi(b)|0;u=m&255;v=(Vi(b)|0)&255;o=(f|0)<96;if(!(o|(v&64|0)==0)){Pm(t);z=-1;l=A;return z|0}w=v&63;kg(e,20);r=(w|0)==0;if(!r){j=0;do{kg(e,22);i=Yi(b)|0;g=i&65535;f=k+(j<<2)|0;c[f>>2]=g;if((i&65535)>65280){h=g^65535;i=c[z+(h<<2)>>2]|0;c[z+(j<<2)>>2]=i;g=c[k+(h<<2)>>2]|0;c[f>>2]=g;f=c[y+(h<<2)>>2]|0;h=y}else{f=j+-1|0;if((j|0)>0)c[y+(j<<2)>>2]=(c[z+(f<<2)>>2]|0)+(c[y+(f<<2)>>2]|0);f=g<<1;i=f;h=z}c[h+(j<<2)>>2]=f;ij(e,g&65535);hj(e,(Vi(b)|0)&63);hj(e,Vi(b)|0);f=Yi(b)|0;if(f<<16>>16==-1){ij(e,0);ij(e,1)}else{ij(e,f);ij(e,((i|0)/2|0)-(f&65535)&65535)}j=j+1|0}while((j|0)!=(w|0));g=s;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[s+29>>0]=1;if(w>>>0<31){f=w;n=17}}else{g=s;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[s+29>>0]=1;f=0;n=17}if((n|0)==17)while(1){co(s,30,1,e);f=f+1|0;if((f|0)==31)break;else n=17}i=m<<24>>24==0;if(!i){f=0;do{c[q+(f<<4)>>2]=(Yi(b)|0)&65535;c[q+(f<<4)+4>>2]=(Yi(b)|0)&65535;c[q+(f<<4)+8>>2]=(Yi(b)|0)&65535;c[q+(f<<4)+12>>2]=(Yi(b)|0)&65535;f=f+1|0}while((f|0)!=(u|0))}h=o&1;f=0;do{g=Vi(b)|0;if(g<<24>>24==-1)break;a[p+f>>0]=(g&255)>>>h;f=f+1|0}while((f|0)<128);hj(e,f&255);hj(e,127);co(p,128,1,e);jj(e,1294879534);uh(b,u,t,Ho(b)|0,q);if(!i){g=0;do{cp(s|0,0,1024)|0;i=g<<11;j=i|512;k=i|1024;f=i|1536;h=0;do{q=h<<4;p=h<<2;o=s+q|0;n=t+(i+p)|0;n=d[n>>0]|d[n+1>>0]<<8|d[n+2>>0]<<16|d[n+3>>0]<<24;a[o>>0]=n;a[o+1>>0]=n>>8;a[o+2>>0]=n>>16;a[o+3>>0]=n>>24;o=s+(q|4)|0;n=t+(j+p)|0;n=d[n>>0]|d[n+1>>0]<<8|d[n+2>>0]<<16|d[n+3>>0]<<24;a[o>>0]=n;a[o+1>>0]=n>>8;a[o+2>>0]=n>>16;a[o+3>>0]=n>>24;o=s+(q|8)|0;n=t+(k+p)|0;n=d[n>>0]|d[n+1>>0]<<8|d[n+2>>0]<<16|d[n+3>>0]<<24;a[o>>0]=n;a[o+1>>0]=n>>8;a[o+2>>0]=n>>16;a[o+3>>0]=n>>24;q=s+(q|12)|0;p=t+(f+p)|0;p=d[p>>0]|d[p+1>>0]<<8|d[p+2>>0]<<16|d[p+3>>0]<<24;a[q>>0]=p;a[q+1>>0]=p>>8;a[q+2>>0]=p>>16;a[q+3>>0]=p>>24;h=h+1|0}while((h|0)!=64);co(s,1024,1,e);g=g+1|0}while((g|0)!=(u|0))}Pm(t);if(r){z=0;l=A;return z|0}i=(v&128|0)!=0;j=0;do{ro(b,(c[y+(j<<2)>>2]|0)+x|0,0)|0;f=c[z+(j<<2)>>2]|0;h=Om(f)|0;cp(h|0,0,f|0)|0;Go(h,f,1,b)|0;if(i&(f|0)>1){g=a[h>>0]|0;k=1;do{v=h+k|0;g=256-(d[v>>0]|0)+(g&255)&255;a[v>>0]=g;k=k+1|0}while((k|0)!=(f|0))}co(h,f,1,e);Pm(h);j=j+1|0}while((j|0)!=(w|0));f=0;l=A;return f|0}function uh(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;if((b|0)<=0)return;t=0;do{v=t<<2;u=0;h=63;while(1){ro(a,(c[f+(t<<4)+(u<<2)>>2]|0)+e|0,0)|0;a:do if((h|0)<0)g=h;else{s=u+v<<9;g=0;while(1){l=d+((g<<2)+s)|0;i=Vi(a)|0;n=Vi(a)|0;o=Vi(a)|0;k=i&255;j=i<<24>>24==-128;b:do if(!(j|(k&128|0)==0)){j=Vi(a)|0;m=(k^255)&255;switch((vh(l,m,n,o)|0)<<24>>24){case 11:case 13:break a;default:{}}i=j&255;if(j<<24>>24>-1){i=i+g|0;break}k=0-i&255;if(!k)i=g;else{j=0;while(1){i=g+1|0;if((g|0)>62)break b;vh(d+((i<<2)+s)|0,m,n,o)|0;j=j+1|0;if((j|0)>=(k|0))break;else g=i}}}else{if(!j)switch((vh(l,i,n,o)|0)<<24>>24){case 11:case 13:break a;default:{i=g;break b}}i=Vi(a)|0;q=Ho(a)|0;p=n&255;ro(a,0-(i&255|(o&255)<<8)|0,1)|0;i=0;c:while(1){l=d+((g<<2)+s)|0;j=Vi(a)|0;n=Vi(a)|0;o=Vi(a)|0;k=j&255;d:do if(!(j<<24>>24==-128|(k&128|0)==0)){m=Vi(a)|0;j=(k^255)&255;if((g|0)<=63){switch((vh(l,j,n,o)|0)<<24>>24){case 11:case 13:{i=9999;break c}default:{}}k=m&255;if(m<<24>>24>-1){g=k+g|0;break}k=0-k&255;if(!k){i=0;r=23}else{i=0;while(1){l=g+1|0;if((g|0)>62){g=l;r=23;break d}vh(d+((l<<2)+s)|0,j,n,o)|0;i=i+1|0;if((i|0)<(k|0))g=l;else{g=l;r=23;break}}}}}else r=23;while(0);if((r|0)==23){r=0;vh(d+((g<<2)+s)|0,j,n,o)|0}if((i|0)<(p|0)){g=g+1|0;i=i+1|0}else{i=g;g=h;break}}ro(a,q,0)|0;h=g}while(0);if((i|0)<(h|0))g=i+1|0;else{g=h;break}}}while(0);u=u+1|0;if((u|0)==4)break;else h=g}t=t+1|0}while((t|0)!=(b|0));return}function vh(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;var g=0,h=0,i=0;h=(c&255)>>>1&255;a[b>>0]=d[21653+(h<<1)>>0]|0|(c&255)<<4&16;a[b+1>>0]=a[21653+(h<<1)+1>>0]|0;h=e&255;i=h&15;c=i&255;g=b+3|0;a[b+2>>0]=(i|0)==8?h+248&255:e;switch(e&15){case 10:case 6:case 5:break;default:{i=f;a[g>>0]=i;return c|0}}i=f&255;i=(f<<24>>24<0?256-i<<4:i)&255;a[g>>0]=i;return c|0}function wh(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;n=a[b+2>>0]|0;l=n&255;if(n<<24>>24<1){c=-1;return c|0}m=a[b+3>>0]&63;r=m&255;if((m+-1&255)>30){c=-1;return c|0}else g=0;while(1){h=g*6|0;if((d[b+(h+7)>>0]|0)>64){q=-1;g=33;break}g=g+1|0;if((d[b+(h+6)>>0]|0)>15){q=-1;g=33;break}if((g|0)>=(r|0)){g=4;break}}if((g|0)==4){g=b+8|0;j=0;while(1){i=j*6|0;h=b+i+4|0;h=cj(a[h>>0]|0,a[h+1>>0]|0)|0;if(h<<16>>16==0|(h+32767&65535)<32734){q=-1;g=33;break}m=g+i|0;m=cj(a[m>>0]|0,a[m+1>>0]|0)|0;if(!(m<<16>>16==-1|(m&65535)<(h&65535))){q=-1;g=33;break}j=j+1|0;if((h&65535)>65503&(~h&65535)>>>0>r>>>0){q=-1;g=33;break}if((j|0)>=(r|0)){g=11;break}}if((g|0)==11){m=(cj(a[b>>0]|0,a[b+1>>0]|0)|0)&65535;g=r*6|0;k=(l<<3|4)+g|0;if(m>>>0>>0){c=-1;return c|0}i=l<<2;a:do if(n<<24>>24){g=b+4+g|0;h=0;while(1){j=g+(h<<1)|0;h=h+1|0;if((k+((cj(a[j>>0]|0,a[j+1>>0]|0)|0)&65535)|0)>>>0>m>>>0){q=-1;break}if((h|0)>=(i|0))break a}return q|0}while(0);if((k|0)>(e|0)){c=k-e|0;return c|0}g=a[b+k>>0]|0;if(g<<24>>24==-1){c=-1;return c|0}f=(f|0)>95;j=l<<1;h=g;g=g&255;i=0;while(1){if(f){if((h&255)>=(n&255)){q=-1;g=33;break}}else if(g>>>0>j>>>0|(g&1|0)!=0){q=-1;g=33;break}p=i+1|0;o=p+k|0;g=a[b+o>>0]|0;if((p|0)<128&g<<24>>24!=-1){h=g;g=g&255;i=p}else{g=24;break}}if((g|0)==24){if((o|0)>(m|0)|(p|128|0)==128){c=-1;return c|0}if((m|0)>=(e|0)){c=1-e+m|0;return c|0}g=k+(i+2)|0;b:do if((g|0)<(m|0)){while(1){h=a[b+g>>0]|0;i=h&255;if(!(i&128)){if((h&255)>73){q=-1;g=33;break}if(((d[b+(g+1)>>0]|0)>>>4|i<<4&16)>>>0>r>>>0){q=-1;g=33;break}else h=2}else h=3;g=h+g+1|0;if((g|0)>=(m|0))break b}if((g|0)==33)return q|0}while(0);ng(0,c,0);c=0;return c|0}else if((g|0)==33)return q|0}else if((g|0)==33)return q|0}else if((g|0)==33)return q|0;return 0}function xh(a,b,c){a=a|0;b=b|0;c=c|0;return wh(a,b,c,96)|0}function yh(a,b){a=a|0;b=b|0;return th(a,b,96)|0}function zh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;e=0;h=0;while(1){f=e<<3;g=(d[b+f>>0]<<8|d[b+(f|1)>>0])<<1;if((d[b+(f|2)>>0]|0)>15){i=-1;e=14;break}h=g+h|0;e=e+1|0;if((d[b+(f|4)>>0]<<8|d[b+(f|5)>>0])<<1>>>0>g>>>0){i=-1;e=14;break}if((e|0)>=31){e=5;break}}if((e|0)==5){if((h|0)<3){c=-1;return c|0}if((a[b+248>>0]|0)<1){c=-1;return c|0}else{e=0;f=0}do{h=d[b+(e+250)>>0]|0;f=(h|0)>(f|0)?h:f;e=e+1|0}while((e|0)!=512);g=(f<<6)+64|0;do if((g|0)>0){f=0;h=0;while(1){e=f<<1;e=d[b+(e+762)>>0]<<8|d[b+(e+763)>>0];if(e>>>0>16384){i=-1;e=14;break}h=(e|0)>(h|0)?e:h;f=f+1|0;if((f|0)>=(g|0)){e=11;break}}if((e|0)==11){j=(h<<2)+4|0;break}else if((e|0)==14)return i|0}else j=4;while(0);i=g<<1;if((d[b+(i+763)>>0]<<16|d[b+(i+762)>>0]<<24|d[b+(i+764)>>0]<<8|d[b+(i+765)>>0]|0)!=(j|0)){c=-1;return c|0}ng(0,c,0);c=0;return c|0}else if((e|0)==14)return i|0;return 0}function Ah(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;s=l;l=l+132608|0;r=s+132096|0;q=s;o=s+131072|0;cp(r|0,0,512)|0;cp(q|0,0,65536)|0;kg(e,20);f=0;p=0;do{kg(e,22);n=Yi(b)|0;ij(e,n);p=((n&65535)<<1)+p|0;hj(e,Vi(b)|0);hj(e,Vi(b)|0);ij(e,Yi(b)|0);ij(e,Yi(b)|0);f=f+1|0}while((f|0)!=31);h=Vi(b)|0;hj(e,h);hj(e,Vi(b)|0);g=0;f=0;do{n=Vi(b)|0;a[r+g>>0]=n;n=n&255;f=(n|0)>(f|0)?n:f;g=g+1|0}while((g|0)!=128);g=0;do{n=Vi(b)|0;a[r+128+g>>0]=n;n=n&255;f=(n|0)>(f|0)?n:f;g=g+1|0}while((g|0)!=128);g=0;do{n=Vi(b)|0;a[r+256+g>>0]=n;n=n&255;f=(n|0)>(f|0)?n:f;g=g+1|0}while((g|0)!=128);g=0;do{n=Vi(b)|0;a[r+384+g>>0]=n;n=n&255;f=(n|0)>(f|0)?n:f;g=g+1|0}while((g|0)!=128);n=h&255;i=h<<24>>24==0;if(i)g=0;else{g=0;do{hj(e,g&255);g=g+1|0}while((g|0)!=(n|0));g=n}kg(e,128-g|0);jj(e,1294879534);h=0;while(1){g=0;do{c[q+(h<<8)+(g<<2)>>2]=(Yi(b)|0)&65535;g=g+1|0}while((g|0)!=64);if((h|0)<(f|0))h=h+1|0;else break}k=aj(b)|0;m=Om(k)|0;Go(m,k,1,b)|0;if(i){Pm(m);jg(e,b,p);l=s;return 0}else f=0;do{cp(o|0,0,1024)|0;g=d[r+f>>0]|0;i=d[r+128+f>>0]|0;j=d[r+256+f>>0]|0;h=d[r+384+f>>0]|0;k=0;do{t=o+(k<<4)|0;u=m+(c[q+(g<<8)+(k<<2)>>2]<<2)|0;u=d[u>>0]|d[u+1>>0]<<8|d[u+2>>0]<<16|d[u+3>>0]<<24;a[t>>0]=u;a[t+1>>0]=u>>8;a[t+2>>0]=u>>16;a[t+3>>0]=u>>24;u=t+4|0;v=m+(c[q+(i<<8)+(k<<2)>>2]<<2)|0;v=d[v>>0]|d[v+1>>0]<<8|d[v+2>>0]<<16|d[v+3>>0]<<24;a[u>>0]=v;a[u+1>>0]=v>>8;a[u+2>>0]=v>>16;a[u+3>>0]=v>>24;u=t+8|0;v=m+(c[q+(j<<8)+(k<<2)>>2]<<2)|0;v=d[v>>0]|d[v+1>>0]<<8|d[v+2>>0]<<16|d[v+3>>0]<<24;a[u>>0]=v;a[u+1>>0]=v>>8;a[u+2>>0]=v>>16;a[u+3>>0]=v>>24;t=t+12|0;u=m+(c[q+(h<<8)+(k<<2)>>2]<<2)|0;u=d[u>>0]|d[u+1>>0]<<8|d[u+2>>0]<<16|d[u+3>>0]<<24;a[t>>0]=u;a[t+1>>0]=u>>8;a[t+2>>0]=u>>16;a[t+3>>0]=u>>24;k=k+1|0}while((k|0)!=64);co(o,1024,1,e);f=f+1|0}while((f|0)!=(n|0));Pm(m);jg(e,b,p);l=s;return 0}function Bh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;e=d[b+269>>0]|0;g=d[b+268>>0]<<8|e;if(e&3|0){c=-1;return c|0}if(g>>>0>511|(g&65532|0)==0){c=-1;return c|0}if(!(a[b+784>>0]|0))e=0;else{c=-1;return c|0}while(1){k=e<<3;e=e+1|0;if((((d[b+(k+20)>>0]<<8|d[b+(k+21)>>0])<<1)+2|0)>>>0<(d[b+(k+26)>>0]<<8|d[b+(k+27)>>0])+(d[b+(k+24)>>0]<<8|d[b+(k+25)>>0])<<1>>>0){h=-1;i=28;break}if((e|0)>=31){f=0;break}}if((i|0)==28)return h|0;while(1){e=f<<3;if((d[b+(e+22)>>0]|0)>15){h=-1;i=28;break}f=f+1|0;if((d[b+(e+23)>>0]|0)>64){h=-1;i=28;break}if((f|0)>=31){i=9;break}}if((i|0)==9){f=d[b+785>>0]<<16|d[b+786>>0]<<8|d[b+787>>0];if(f>>>0<788){k=-1;return k|0}do if(g){e=0;while(1){if((d[b+(e+273)>>0]<<16|d[b+(e+272)>>0]<<24|d[b+(e+274)>>0]<<8|d[b+(e+275)>>0]|0)>(f|0)){h=-1;i=28;break}e=e+4|0;if((e|0)>=(g|0)){i=13;break}}if((i|0)==13){e=e|2;if((e|0)<128){j=e;i=16;break}else break}else if((i|0)==28)return h|0}else{j=2;i=16}while(0);a:do if((i|0)==16){while(1){k=j<<2;j=j+1|0;if(d[b+(k+273)>>0]<<16|d[b+(k+272)>>0]<<24|d[b+(k+274)>>0]<<8|d[b+(k+275)>>0]|0){h=-1;break}if((j|0)>=128)break a}return h|0}while(0);g=f+-4|0;b:do if((g|0)>788){f=788;c:while(1){e=a[b+f>>0]|0;d:do if(e<<24>>24==-128)e=1;else{if((e&255)>128){h=-1;i=28;break c}if(((e<<24>>24==0?(a[b+(f+1)>>0]|0)==0:0)?(a[b+(f+2)>>0]|0)==0:0)?(a[b+(f+3)>>0]|0)==0:0){h=-1;i=28;break c}switch((d[b+(f+2)>>0]|0)*15&4095){case 12:if((d[b+(f+3)>>0]|0)>64){h=-1;i=28;break c}else{e=4;break d}case 13:if((d[b+(f+3)>>0]|0)>64){h=-1;i=28;break c}else{e=4;break d}default:{e=4;break d}}}while(0);f=f+e|0;if((f|0)>=(g|0))break b}if((i|0)==28)return h|0}while(0);ng(b,c,20);k=0;return k|0}else if((i|0)==28)return h|0;return 0}function Ch(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;x=l;l=l+2816|0;u=x+2688|0;s=x+2560|0;v=x+1536|0;q=x+1024|0;r=x+512|0;m=x;e=u;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));e=s;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));cp(q|0,0,512)|0;cp(r|0,0,512)|0;cp(m|0,0,512)|0;jg(d,b,20);e=0;w=0;do{kg(d,22);p=Yi(b)|0;ij(d,p);w=((p&65535)<<1)+w|0;hj(d,Vi(b)|0);hj(d,Vi(b)|0);ij(d,Yi(b)|0);ij(d,Yi(b)|0);e=e+1|0}while((e|0)!=31);f=Yi(b)|0;ro(b,2,1)|0;e=0;do{c[q+(e<<2)>>2]=aj(b)|0;e=e+1|0}while((e|0)!=128);o=f&255;k=f&255;p=k&65535;n=k<<16>>16==0;a:do if(n){ap(r|0,q|0,512)|0;h=0;e=0}else{h=0;e=0;do{if(h){b:do if((h|0)>0){g=c[q+(h<<2)>>2]|0;f=0;while(1){if((g|0)==(c[q+(f<<2)>>2]|0))break;f=f+1|0;if((f|0)>=(h|0))break b}a[u+h>>0]=a[u+f>>0]|0}else f=0;while(0);if((f|0)==(h|0)){a[u+h>>0]=e;e=e+1|0}}else{a[u>>0]=0;e=e+1|0}h=h+1|0}while((h|0)!=(p|0));ap(r|0,q|0,512)|0;while(1){e=0;c:while(1){if((e|0)>0){j=r+(e<<2)|0;i=c[j>>2]|0;f=0;do{h=r+(f<<2)|0;g=c[h>>2]|0;if((i|0)<(g|0))break c;f=f+1|0}while((f|0)<(e|0))}e=e+1|0;if((e|0)>=(p|0)){h=0;e=0;break a}}z=u+f|0;y=a[z>>0]|0;f=u+e|0;a[z>>0]=a[f>>0]|0;a[f>>0]=y;c[h>>2]=i;c[j>>2]=g}}while(0);do{g=c[r+(h<<2)>>2]|0;f=m+(e<<2)|0;if(h){if((g|0)!=(c[f>>2]|0)){e=e+1|0;f=m+(e<<2)|0;t=30}}else t=30;if((t|0)==30){t=0;c[f>>2]=g}h=h+1|0}while((h|0)!=128);j=p+-1|0;if((k&65535)>1){h=c[m>>2]|0;i=0;g=0;while(1){c[r+(g<<2)>>2]=h;e=g+1|0;i=i+1|0;f=h;h=c[m+(i<<2)>>2]|0;if((h-f|0)>1024){c[r+(e<<2)>>2]=f+1024;e=g+2|0}if((i|0)==(j|0)){g=0;break}else g=e}}else g=0;do{f=c[q+(g<<2)>>2]|0;e=0;do{if((f|0)==(c[r+(e<<2)>>2]|0)){t=37;break}e=e+1|0}while((e|0)<128);if((t|0)==37){t=0;a[s+g>>0]=e}g=g+1|0}while((g|0)!=128);e=u;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));if(n){hj(d,o);e=0}else{ap(u|0,s|0,p|0)|0;hj(d,o);f=0;e=0;do{z=a[u+f>>0]|0;e=(z&255)>(e&255)?z:e;f=f+1|0}while((f|0)!=(p|0))}hj(d,127);co(u,128,1,d);jj(d,1294879534);ro(b,784,0)|0;j=(aj(b)|0)+788|0;f=(e&255)+1&255;if(!f){ro(b,j,0)|0;jg(d,b,w);l=x;return 0}else g=0;do{cp(v|0,0,1024)|0;h=0;do{i=h<<4;z=Vi(b)|0;e=z&255;if(z<<24>>24!=-128){u=Vi(b)|0;y=Vi(b)|0;z=Vi(b)|0;a[v+(i|1)>>0]=u;y=y&255;a[v+(i|3)>>0]=z;z=(y>>>4|e&240)>>>2;a[v+i>>0]=e&15|z&48;a[v+(i|2)>>0]=y&15|z<<4}z=Vi(b)|0;e=z&255;if(z<<24>>24!=-128){u=Vi(b)|0;y=Vi(b)|0;z=Vi(b)|0;a[v+(i|5)>>0]=u;y=y&255;a[v+(i|7)>>0]=z;z=(y>>>4|e&240)>>>2;a[v+(i|4)>>0]=e&15|z&48;a[v+(i|6)>>0]=y&15|z<<4}z=Vi(b)|0;e=z&255;if(z<<24>>24!=-128){u=Vi(b)|0;y=Vi(b)|0;z=Vi(b)|0;a[v+(i|9)>>0]=u;y=y&255;a[v+(i|11)>>0]=z;z=(y>>>4|e&240)>>>2;a[v+(i|8)>>0]=e&15|z&48;a[v+(i|10)>>0]=y&15|z<<4}z=Vi(b)|0;e=z&255;if(z<<24>>24!=-128){u=Vi(b)|0;y=Vi(b)|0;z=Vi(b)|0;a[v+(i|13)>>0]=u;y=y&255;a[v+(i|15)>>0]=z;z=(y>>>4|e&240)>>>2;a[v+(i|12)>>0]=e&15|z&48;a[v+(i|14)>>0]=y&15|z<<4}h=h+1|0}while((h|0)!=64);co(v,1024,1,d);g=g+1|0}while((g|0)!=(f|0));ro(b,j,0)|0;jg(d,b,w);l=x;return 0}function Dh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;if((e|0)<182){c=182-e|0;return c|0}else{i=0;j=0}while(1){e=i*12|0;if((d[b+(e+7)>>0]|0)>64){k=-1;e=16;break}if(a[b+(e+6)>>0]|0){k=-1;e=16;break}e=b+e|0;h=gj(e)|0;if((h|0)<180&(h|0)!=0){k=-1;e=16;break}f=e+4|0;f=cj(a[f>>0]|0,a[f+1>>0]|0)|0;h=f&65535;g=e+8|0;g=cj(a[g>>0]|0,a[g+1>>0]|0)|0;e=e+10|0;e=cj(a[e>>0]|0,a[e+1>>0]|0)|0;if((g&65535)>(f&65535)){k=-1;e=16;break}if(e<<16>>16==0|((f&65535)>32768|(e&65535)>>>0>(h+1|0)>>>0)){k=-1;e=16;break}if(f<<16>>16==0?g<<16>>16!=0|e<<16>>16!=1:0){k=-1;e=16;break}j=h+j|0;i=i+1|0;if((i|0)>=15){e=11;break}}if((e|0)==11){if((j|0)<2){c=-1;return c|0}else f=0;while(1){e=b+f+180|0;e=cj(a[e>>0]|0,a[e+1>>0]|0)|0;if(e<<16>>16==-1){e=15;break}if((e&65535)<180){k=-1;e=16;break}f=f+2|0;if((f|0)>=256){k=-1;e=16;break}}if((e|0)==15){ng(0,c,0);c=0;return c|0}else if((e|0)==16)return k|0}else if((e|0)==16)return k|0;return 0}function Eh(d,f){d=d|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;s=l;l=l+2656|0;o=s+1632|0;n=s+1088|0;k=s+576|0;p=s+64|0;q=s;r=s+1600|0;cp(p|0,0,512)|0;cp(k|0,0,512)|0;cp(n|0,0,512)|0;kg(f,20);g=0;do{c[q+(g<<2)>>2]=aj(d)|0;kg(f,22);m=Yi(d)|0;ij(f,m);b[r+(g<<1)>>1]=(m&65535)<<1;hj(f,Vi(d)|0);hj(f,Vi(d)|0);ij(f,Yi(d)|0);ij(f,Yi(d)|0);g=g+1|0}while((g|0)!=15);g=15;do{kg(f,22);ij(f,0);hj(f,0);hj(f,64);ij(f,0);ij(f,1);g=g+1|0}while((g|0)!=31);Go(o,2,128,d)|0;h=0;g=0;while(1){j=o+(h<<1)|0;i=a[j>>0]|0;if(i<<24>>24==-1){m=h;g=h&255;break}m=(cj(i,a[j+1>>0]|0)|0)&65535;c[n+(h<<2)>>2]=m;c[k+(h<<2)>>2]=m;h=h+1|0;g=g+1<<24>>24;if((h&255)<<24>>24<=-1){m=h;break}}hj(f,g);hj(f,127);Qn(k,m);if((m|0)>0){i=c[k>>2]|0;g=0;j=0;while(1){c[p+(j<<2)>>2]=i;do{t=g;g=g+1|0;h=c[k+(g<<2)>>2]|0}while((t|0)<(m|0)&(h|0)==(i|0));if((g|0)<(m|0)){i=h;j=j+1|0}else break}g=o;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));j=0;g=0;do{h=c[n+(j<<2)>>2]|0;i=0;while(1)if((h|0)==(c[p+(i<<2)>>2]|0))break;else i=i+1|0;a[o+j>>0]=i;g=(i|0)>(g|0)?i:g;j=j+1|0}while((j|0)!=(m|0))}else{g=o;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));g=0}co(o,128,1,f);jj(f,1294879534);if((g|0)<0)h=0;else{j=0;while(1){ro(d,c[p+(j<<2)>>2]|0,0)|0;cp(o|0,0,1024)|0;k=0;m=Vi(d)|0;do{h=(Vi(d)|0)&255;i=h&63;h=h>>>6<<2|k<<4;if(i>>>0<37){a[o+h>>0]=a[21653+(i<<1)>>0]|0;a[o+(h|1)>>0]=a[21653+(i<<1)+1>>0]|0}a[o+(h|2)>>0]=Vi(d)|0;a[o+(h|3)>>0]=Vi(d)|0;if(m<<24>>24<0)break;m=Vi(d)|0;k=(m&127)+k|0}while((k|0)<64);co(o,1024,1,f);if((j|0)==(g|0)){h=0;break}else j=j+1|0}}do{g=c[q+(h<<2)>>2]|0;if(g|0){ro(d,g,0)|0;jg(f,d,e[r+(h<<1)>>1]|0)}h=h+1|0}while((h|0)!=15);l=s;return 0}function Fh(a,b){a=a|0;b=b|0;a=c[a>>2]|0;b=c[b>>2]|0;return ((a|0)==(b|0)?0:(a|0)>(b|0)?1:-1)|0}function Gh(a,b,c){a=a|0;b=b|0;c=c|0;var e=0;if((c|0)<260){e=260-c|0;return e|0}else c=0;do{if((d[a+(c<<3|4)>>0]|0)>64){c=-1;e=7;break}c=c+1|0}while((c|0)<31);if((e|0)==7)return c|0;if((gj(a+256|0)|0)!=1397446996){e=-1;return e|0}ng(0,b,0);e=0;return e|0}function Hh(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;p=l;l=l+3072|0;m=p+2048|0;o=p;cp(o|0,0,512)|0;kg(e,20);f=0;n=0;do{kg(e,22);k=Yi(b)|0;ij(e,k);n=((k&65535)<<1)+n|0;hj(e,Vi(b)|0);hj(e,Vi(b)|0);ij(e,Yi(b)|0);ij(e,Yi(b)|0);f=f+1|0}while((f|0)!=31);aj(b)|0;aj(b)|0;aj(b)|0;k=((Vi(b)|0)&255)+1|0;hj(e,k&255);hj(e,127);k=k&255;g=(k|0)==0;if(g)f=0;else{f=0;do{c[o+(f<<4)>>2]=(Yi(b)|0)&65535;c[o+(f<<4)+4>>2]=(Yi(b)|0)&65535;c[o+(f<<4)+8>>2]=(Yi(b)|0)&65535;c[o+(f<<4)+12>>2]=(Yi(b)|0)&65535;f=f+1|0}while((f|0)!=(k|0));f=0}do{hj(e,(f|0)<(k|0)?f&255:0);f=f+1|0}while((f|0)!=128);jj(e,1294879534);Vi(b)|0;f=Ho(b)|0;if(g){jg(e,b,n);l=p;return 0}j=f+-256|0;f=0;do{cp(m|0,0,1024)|0;g=0;do{ro(b,j+(c[o+(f<<4)+(g<<2)>>2]<<8)|0,0)|0;i=g<<2;h=0;do{q=(h<<4)+i|0;u=Vi(b)|0;t=Vi(b)|0;s=Vi(b)|0;r=Vi(b)|0;t=t&255;u=u&255;a[m+q>>0]=d[21653+(u<<1)>>0]|0|t&240;a[m+(q|1)>>0]=a[21653+(u<<1)+1>>0]|0;a[m+(q|2)>>0]=t<<4|s&255;a[m+(q|3)>>0]=r;h=h+1|0}while((h|0)!=64);g=g+1|0}while((g|0)!=4);co(m,1024,1,e);f=f+1|0}while((f|0)!=(k|0));jg(e,b,n);l=p;return 0}function Ih(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0;if((d|0)<64){c=64-d|0;return c|0}if((gj(b)|0)!=1297040469){c=-1;return c|0}f=(cj(a[b+20>>0]|0,a[b+21>>0]|0)|0)&65535;e=f+4|0;g=((cj(a[b+28>>0]|0,a[b+29>>0]|0)|0)&65535)+e|0;f=f+8|0;if((f|0)>(d|0)){c=f-d|0;return c|0}if((gj(b+e|0)|0)!=1112491097){c=-1;return c|0}e=g+8|0;if((e|0)>(d|0)){c=e-d|0;return c|0}if((gj(b+(g+4)|0)|0)!=1396788560){c=-1;return c|0}ng(b+4|0,c,16);c=0;return c|0}function Jh(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0;q=l;l=l+1536|0;o=q+512|0;p=q;aj(b)|0;jg(d,b,16);jj(d,0);m=(Yi(b)|0)&65535;k=Yi(b)|0;i=Yi(b)|0;j=Yi(b)|0;m=(m<<16)+262144>>16;n=((Yi(b)|0)&65535)+m|0;cp(o|0,0,930)|0;g=k<<16>>16;if(k<<16>>16>0){h=0;e=0;do{f=Vi(b)|0;if((f&255)>30)ro(b,7,1)|0;else{f=(f&255)*30|0;a[o+(f+25)>>0]=Vi(b)|0;k=Yi(b)|0;a[o+(f+22)>>0]=(k&65535)>>>8;a[o+(f+23)>>0]=k;a[o+(f+26)>>0]=Vi(b)|0;a[o+(f+27)>>0]=Vi(b)|0;a[o+(f+28)>>0]=Vi(b)|0;a[o+(f+29)>>0]=Vi(b)|0;e=((k&65535)<<1)+e|0}h=h+1|0}while((h|0)!=(g|0));k=e}else k=0;co(o,930,1,d);hj(d,i&255);hj(d,127);e=o;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));f=i<<16>>16;if(i<<16>>16>0){e=0;do{a[o+e>>0]=Yi(b)|0;e=e+1|0}while((e|0)!=(f|0))}co(o,128,1,d);cp(p|0,0,256)|0;i=j<<16>>16;if(j<<16>>16>0)e=0;else{jj(d,1294879534);p=n<<16;p=p+262144|0;p=p>>16;ro(b,p,0)|0;jg(d,b,k);l=q;return 0}do{c[p+(e<<2)>>2]=(Yi(b)|0)&65535;e=e+1|0}while((e|0)!=(i|0));jj(d,1294879534);e=m+4|0;g=0;do{ro(b,e+(c[p+(g<<2)>>2]|0)|0,0)|0;cp(o|0,0,1024)|0;h=0;do{f=(Yi(b)|0)&65535;if(f&1|0)Go(o+(h<<4)|0,1,4,b)|0;if(f&2|0)Go(o+(h<<4)+4|0,1,4,b)|0;if(f&4|0)Go(o+(h<<4)+8|0,1,4,b)|0;if(f&8|0)Go(o+(h<<4)+12|0,1,4,b)|0;h=h+1|0}while((h|0)!=64);co(o,1024,1,d);g=g+1|0}while((g|0)!=(i|0));p=n<<16;p=p+262144|0;p=p>>16;ro(b,p,0)|0;jg(d,b,k);l=q;return 0}function Kh(a,b,c){a=a|0;b=b|0;c=c|0;var e=0;if((c|0)<1084){b=1084-c|0;return b|0}if((gj(a+1080|0)|0)==1213355041)c=0;else{b=-1;return b|0}while(1){e=c*30|0;if((d[a+(e+44)>>0]|0)>15){c=-1;e=8;break}c=c+1|0;if((d[a+(e+45)>>0]|0)>64){c=-1;e=8;break}if((c|0)>=31){e=7;break}}if((e|0)==7){ng(a,b,20);b=0;return b|0}else if((e|0)==8)return c|0;return 0}function Lh(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;s=l;l=l+1024|0;q=s;cp(q|0,0,950)|0;Go(q,950,1,b)|0;c[q+38>>2]=0;c[q+68>>2]=0;c[q+98>>2]=0;c[q+128>>2]=0;c[q+158>>2]=0;c[q+188>>2]=0;c[q+218>>2]=0;c[q+248>>2]=0;c[q+278>>2]=0;c[q+308>>2]=0;c[q+338>>2]=0;c[q+368>>2]=0;c[q+398>>2]=0;c[q+428>>2]=0;c[q+458>>2]=0;c[q+488>>2]=0;c[q+518>>2]=0;c[q+548>>2]=0;c[q+578>>2]=0;c[q+608>>2]=0;c[q+638>>2]=0;c[q+668>>2]=0;c[q+698>>2]=0;c[q+728>>2]=0;c[q+758>>2]=0;c[q+788>>2]=0;c[q+818>>2]=0;c[q+848>>2]=0;c[q+878>>2]=0;c[q+908>>2]=0;c[q+938>>2]=0;co(q,950,1,e);f=q+42|0;g=0;r=0;do{p=f+(g*30|0)|0;r=(((cj(a[p>>0]|0,a[p+1>>0]|0)|0)&65535)<<1)+r|0;g=g+1|0}while((g|0)!=31);hj(e,Vi(b)|0);hj(e,Vi(b)|0);Go(q,1,128,b)|0;f=0;p=0;do{o=d[q+f>>0]|0;p=(o|0)>(p|0)?o:p;f=f+1|0}while((f|0)!=128);jj(e,1294879534);ro(b,1084,0)|0;h=q+1|0;i=q+2|0;j=q+3|0;n=0;while(1){o=0;do{a[q>>0]=Vi(b)|0;a[h>>0]=Vi(b)|0;a[i>>0]=Vi(b)|0;k=Vi(b)|0;a[j>>0]=k;m=(d[q>>0]|0)>>>1;a[q>>0]=m;f=m&112;t=a[h>>0]|0;g=(t&255)>>>1&255;if(!(t<<24>>24))g=0;else{f=a[21653+(g<<1)>>0]|f;g=a[21653+(g<<1)+1>>0]|0}t=((m&255)<<4|(d[i>>0]|0))&255;hj(e,f);hj(e,g);hj(e,t);hj(e,k);o=o+1|0}while((o|0)!=256);if((n|0)<(p|0))n=n+1|0;else break}jg(e,b,r);l=s;return 0}function Mh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;if((e|0)<1500){c=1500-e|0;return c|0}if((gj(b+1080|0)|0)!=1294879534){c=-1;return c|0}e=b+6|0;f=0;g=0;do{h=e+(f<<4)|0;g=(((cj(a[h>>0]|0,a[h+1>>0]|0)|0)&65535)<<1)+g|0;f=f+1|0}while((f|0)!=31);if(!g){c=-1;return c|0}else e=0;do{if((d[b+(e<<4|1)>>0]|0)>64){i=-1;j=21;break}e=e+1|0}while((e|0)<31);if((j|0)==21)return i|0;h=a[b+950>>0]|0;f=h&255;if(h<<24>>24<1){c=-1;return c|0}else{e=0;h=0}do{k=a[b+(e+952)>>0]|0;g=k&255;if(k<<24>>24<0){i=-1;j=21;break}h=(g|0)>(h|0)?g:h;e=e+1|0}while((e|0)<(f|0));if((j|0)==21)return i|0;g=(h<<8)+256|0;a:do if((e|0)!=128){while(1){if(a[b+(e+952)>>0]|0){i=-1;break}e=e+1|0;if((e|0)==128)break a}return i|0}while(0);b:do if((g|0)>0){e=0;while(1){f=e<<2;if((d[b+(f+1086)>>0]|0)>72){i=-1;j=21;break}if(a[b+(f+1087)>>0]&7){i=-1;j=21;break}e=e+1|0;if(a[b+(f+1084)>>0]&3){i=-1;j=21;break}if((e|0)>=(g|0))break b}if((j|0)==21)return i|0}while(0);ng(0,c,0);k=0;return k|0}function Nh(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+2192|0;s=t+1160|0;k=t+1032|0;q=t;kg(c,20);j=0;r=0;do{kg(c,22);Vi(b)|0;f=Vi(b)|0;g=aj(b)|0;h=Yi(b)|0;ij(c,h);r=((h&65535)<<1)+r|0;h=aj(b)|0;i=Yi(b)|0;do switch((Yi(b)|0)<<16>>16){case -1080:{e=15;break}case -72:{e=1;break}case -144:{e=2;break}case -216:{e=3;break}case -288:{e=4;break}case -360:{e=5;break}case -432:{e=6;break}case -504:{e=7;break}case -576:{e=8;break}case -648:{e=9;break}case -720:{e=10;break}case -792:{e=11;break}case -864:{e=12;break}case -936:{e=13;break}case -1008:{e=14;break}default:e=0}while(0);hj(c,e);hj(c,f);ij(c,((h-g|0)/2|0)&65535);ij(c,i);j=j+1|0}while((j|0)!=31);ro(b,950,0)|0;hj(c,Vi(b)|0);hj(c,Vi(b)|0);Go(k,128,1,b)|0;co(k,128,1,c);e=0;p=0;do{o=d[k+e>>0]|0;p=(o|0)>(p|0)?o:p;e=e+1|0}while((e|0)!=128);jj(c,1294879534);ro(b,1084,0)|0;k=0;while(1){cp(q|0,0,1025)|0;Go(s,1024,1,b)|0;m=0;do{n=m<<2;h=n|3;o=(d[s+h>>0]|0)>>>3;i=n|2;f=a[s+i>>0]|0;e=a[s+n>>0]|0;j=n|1;g=a[s+j>>0]|0;switch(e<<24>>24){case 0:{e=3;break}case 12:{e=0;break}default:e=(e&255)>>>2}o=o&255;f=(f&255)>>>1&255;a[q+n>>0]=d[21653+(f<<1)>>0]|0|o&16;a[q+j>>0]=a[21653+(f<<1)+1>>0]|0;a[q+i>>0]=e|o<<4;a[q+h>>0]=g;m=m+1|0}while((m|0)!=256);co(q,1024,1,c);if((k|0)<(p|0))k=k+1|0;else break}jg(c,b,r);l=t;return 0}function Oh(a,b){a=a|0;b=b|0;b=c[(c[a+964>>2]|0)+(b<<3)+4>>2]|0;if((b|0)<0){a=-1;return a|0}a=c[(c[a+968>>2]|0)+(b*116|0)+4>>2]|0;return a|0}function Ph(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;e=c[a+968>>2]|0;if((c[a+960>>2]|0)>>>0<=b>>>0)return;if(d|0)yk(a,b,0);d=a+956|0;c[d>>2]=(c[d>>2]|0)+-1;d=c[a+964>>2]|0;f=e+(b*116|0)+4|0;a=d+(c[f>>2]<<3)|0;c[a>>2]=(c[a>>2]|0)+-1;a=e+(b*116|0)|0;c[d+(c[a>>2]<<3)+4>>2]=-1;d=f+4|0;e=d+108|0;do{c[d>>2]=0;d=d+4|0}while((d|0)<(e|0));c[f>>2]=-1;c[a>>2]=-1;return}function Qh(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;c[a+948>>2]=b;e=c[a+1528>>2]|0;d=Dk(e,-1)|0;g=a+952|0;c[g>>2]=b;if(!(c[a+2832>>2]&32768))d=(d|0)>(b|0)?b:d;else c[g>>2]=d+b;d=Dk(e,d)|0;c[a+960>>2]=d;f=Qm(d,116)|0;c[a+968>>2]=f;if(!f){a=-1;return a|0}if((d|0)>0){b=0;do{c[f+(b*116|0)>>2]=-1;c[f+(b*116|0)+4>>2]=-1;b=b+1|0}while((b|0)!=(d|0))}b=c[g>>2]|0;e=Om(b<<3)|0;c[a+964>>2]=e;if(!e){Pm(f);a=-1;return a|0}if((b|0)>0){d=0;do{c[e+(d<<3)+4>>2]=-1;c[e+(d<<3)>>2]=0;d=d+1|0}while((d|0)!=(b|0))}c[a+956>>2]=0;a=0;return a|0}function Rh(a){a=a|0;var b=0;if((c[a+952>>2]|0)<1)return;b=a+948|0;c[b>>2]=0;c[b+4>>2]=0;c[b+8>>2]=0;c[b+12>>2]=0;Pm(c[a+968>>2]|0);Pm(c[a+964>>2]|0);return}function Sh(a){a=a|0;var b=0,d=0,e=0,f=0;f=a+952|0;if((c[f>>2]|0)<1)return;e=a+960|0;b=a+968|0;cp(c[b>>2]|0,0,(c[e>>2]|0)*116|0)|0;e=c[e>>2]|0;if((e|0)>0){b=c[b>>2]|0;d=0;do{c[b+(d*116|0)>>2]=-1;c[b+(d*116|0)+4>>2]=-1;d=d+1|0}while((d|0)!=(e|0))}b=c[f>>2]|0;if((b|0)>0){d=c[a+964>>2]|0;e=0;do{c[d+(e<<3)+4>>2]=-1;c[d+(e<<3)>>2]=0;e=e+1|0}while((e|0)!=(b|0))}c[a+956>>2]=0;return}function Th(a,b){a=a|0;b=b|0;return Uh(a,b)|0}function Uh(a,b){a=a|0;b=b|0;if((c[a+952>>2]|0)>>>0<=b>>>0){a=-1;return a|0}b=c[(c[a+964>>2]|0)+(b<<3)+4>>2]|0;a=b>>>0<(c[a+960>>2]|0)>>>0?b:-1;return a|0}function Vh(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;e=Uh(a,b)|0;if((e|0)<0)return;yk(a,e,0);f=a+956|0;c[f>>2]=(c[f>>2]|0)+-1;f=c[a+964>>2]|0;d=a+968|0;a=c[d>>2]|0;g=f+(c[a+(e*116|0)+4>>2]<<3)|0;c[g>>2]=(c[g>>2]|0)+-1;c[f+(b<<3)+4>>2]=-1;a=a+(e*116|0)|0;b=a+116|0;do{c[a>>2]=0;a=a+4|0}while((a|0)<(b|0));g=c[d>>2]|0;c[g+(e*116|0)+4>>2]=-1;c[g+(e*116|0)>>2]=-1;return}function Wh(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;f=Uh(b,d)|0;if((f|0)<0)return;h=c[(c[b+968>>2]|0)+(f*116|0)+4>>2]|0;if((h|0)<64?(a[b+884+h>>0]|0)!=0:0)yk(b,f,0);else g=5;if((g|0)==5?(yk(b,f,e),e|0):0)return;if((c[b+948>>2]|0)>(d|0))return;Ph(b,f,1);return}function Xh(a,b,d){a=a|0;b=b|0;d=d|0;b=Uh(a,b)|0;if((b|0)<0)return;Ck(c[a+968>>2]|0,b,d);return}function Yh(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=Uh(a,b)|0;if((b|0)<0)return;Bk(c[a+968>>2]|0,b,d,e);return}function Zh(a,b){a=a|0;b=b|0;b=Uh(a,b)|0;if((b|0)<0){a=-1;return a|0}a=wk(a,b)|0;return a|0}function _h(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;e=Uh(a,b)|0;if((e|0)<0)return;b=c[a+968>>2]|0;if((c[b+(e*116|0)+48>>2]|0)==(d|0))return;f=c[b+(e*116|0)+28>>2]|0;b=c[b+(e*116|0)+36>>2]|0;xk(a,e,d);vk(a,e,f,b);return}function $h(a,b,d){a=a|0;b=b|0;d=d|0;b=Uh(a,b)|0;if((b|0)<0)return;c[(c[a+968>>2]|0)+(b*116|0)+56>>2]=d;return}function ai(a,b,d,e,f,g,h,i){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0;if((c[a+952>>2]|0)>>>0<=b>>>0){f=-1;return f|0}l=(d|0)<0?-1:e;if(h|0?(j=a+960|0,(c[j>>2]|0)>0):0){e=0;do{bi(a,e,b,d,l,f,h,i);e=e+1|0}while((e|0)<(c[j>>2]|0))}i=a+964|0;e=c[(c[i>>2]|0)+(b<<3)+4>>2]|0;if((e|0)>-1){k=a+968|0;if(!(c[(c[k>>2]|0)+(e*116|0)+56>>2]|0))i=b;else{b=ci(a,b)|0;h=c[i>>2]|0;i=c[a+948>>2]|0;while(1){j=h+(i<<3)+4|0;if((c[j>>2]|0)>-1)i=i+1|0;else break}c[(c[k>>2]|0)+(e*116|0)>>2]=i;c[j>>2]=e;e=b}}else{i=b;e=ci(a,b)|0}if((l|0)<0){Ph(a,e,1);f=i;return f|0}else{xk(a,e,l);a=a+968|0;zk(c[a>>2]|0,e,(f|0)<149?f:149);f=c[a>>2]|0;c[f+(e*116|0)+44>>2]=d;c[f+(e*116|0)+56>>2]=g;f=i;return f|0}return 0}function bi(a,b,d,e,f,g,h,i){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0;j=c[a+968>>2]|0;k=c[(c[a+964>>2]|0)+(d<<3)+4>>2]|0;if((c[j+(b*116|0)+4>>2]|0)!=(d|0))return;if((c[j+(b*116|0)+44>>2]|0)!=(e|0))return;switch(h|0){case 3:break;case 2:{if((c[j+(b*116|0)+48>>2]|0)!=(f|0))return;break}case 1:{if((c[j+(b*116|0)+12>>2]|0)!=(g|0))return;break}default:return}if(!i){Ph(a,b,1);return}j=j+(b*116|0)+56|0;if((k|0)==(b|0)?(c[j>>2]|0)==0:0)return;c[j>>2]=i;return}function ci(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=c[a+960>>2]|0;a:do if((f|0)>0){e=c[a+968>>2]|0;d=0;do{if((c[e+(d*116|0)>>2]|0)==-1)break a;d=d+1|0}while((d|0)<(f|0))}else d=0;while(0);if((d|0)==(f|0))d=di(a)|0;f=c[a+964>>2]|0;e=f+(b<<3)|0;c[e>>2]=(c[e>>2]|0)+1;e=a+956|0;c[e>>2]=(c[e>>2]|0)+1;a=c[a+968>>2]|0;c[a+(d*116|0)>>2]=b;c[a+(d*116|0)+4>>2]=b;c[f+(b<<3)+4>>2]=d;return d|0}function di(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;e=c[a+960>>2]|0;h=c[a+968>>2]|0;if((e|0)>0){f=c[a+948>>2]|0;g=0;b=-1;d=2147483647;do{if((c[h+(g*116|0)>>2]|0)>=(f|0)){i=c[h+(g*116|0)+20>>2]|0;j=(i|0)<(d|0);b=j?g:b;d=j?i:d}g=g+1|0}while((g|0)!=(e|0))}else b=-1;j=c[a+964>>2]|0;c[j+(c[h+(b*116|0)>>2]<<3)+4>>2]=-1;j=j+(c[h+(b*116|0)+4>>2]<<3)|0;c[j>>2]=(c[j>>2]|0)+-1;j=a+956|0;c[j>>2]=(c[j>>2]|0)+-1;return b|0}function ei(a,b,c){a=a|0;b=b|0;c=c|0;b=Uh(a,b)|0;if((b|0)<0)return;Ak(a,b,c);return}function fi(a,b,c){a=a|0;b=b|0;c=c|0;b=Uh(a,b)|0;if((b|0)<0)return;vk(a,b,c,0);return}function gi(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;e=c[a+948>>2]|0;h=a+952|0;if((e|0)>=(c[h>>2]|0))return;i=a+968|0;g=a+624|0;do{f=Uh(a,e)|0;a:do if((f|0)>=0?(c[(c[i>>2]|0)+(f*116|0)+4>>2]|0)==(b|0):0)switch(d|0){case 0:{Ph(a,f,1);break a}case 2:{ni(c[g>>2]|0,e);break a}case 3:{oi(c[g>>2]|0,e);break a}default:break a}while(0);e=e+1|0}while((e|0)<(c[h>>2]|0));return}function hi(a,b){a=a|0;b=b|0;var d=0;d=Uh(a,b)|0;if((d|0)<0){a=-1;return a|0}if((c[a+948>>2]|0)>(b|0)){a=256;return a|0}a=c[(c[a+968>>2]|0)+(d*116|0)+56>>2]|0;return a|0}function ii(a,b,c,d){a=a|0;b=b|0;c=c|0;d=+d;var e=0.0;e=+(a|0)+ +(b|0)*.0078125;if(!c)e=13694.0/+Ba(+(e/12.0));else e=(240.0-e)*16.0;return +(d>.1?e*d:e)}function ji(a,b){a=a|0;b=b|0;return ~~(56090624.0/+Ba(+((+(a|0)+ +(b|0)/12800.0)/12.0)))|0}function ki(a){a=a|0;var b=0,d=0,e=0,f=0;if(!a){f=0;return f|0}if((a|0)<3628){b=24;do{b=b+12|0;a=a<<1}while((a|0)<3628)}else b=24;if((a|0)>3842){d=4068;do{d=d+-32|0;b=b+-1|0;e=c[d>>2]|0}while((a|0)>(e|0));f=b}else{e=3842;f=b;d=4068}if(((e|0)>(a|0)?(c[d+4>>2]|0)>(a|0):0)?(c[d+8>>2]|0)>(a|0):0)b=(c[d+12>>2]|0)<=(a|0)&1;else b=1;f=f-b|0;return f|0}function li(a,b,c,d,e){a=+a;b=b|0;c=c|0;d=d|0;e=+e;if(!b){c=0;return c|0}if(!d){b=~~+dp(+(+M(+(+ii(b,0,0,e)/a))*1536.0/.6931471805599453*100.0));if(!c){c=b;return c|0}c=b-((b|0)%12800|0)|0;return c|0}else{b=~~((+(240-b<<4|0)-a)*8.0*100.0);if(!c){c=b;return c|0}c=b-((b|0)%12800|0)|0;return c|0}return 0}function mi(a,b,d){a=a|0;b=b|0;d=d|0;if(!a){c[d>>2]=0;c[b>>2]=0;return}else{a=~~(+M(+(+(a|0)/8363.0))*1536.0/.6931471805599453);c[b>>2]=(a|0)/128|0;c[d>>2]=(a|0)%128|0;return}}function ni(a,b){a=a|0;b=b|0;a=a+(b*440|0)+8|0;c[a>>2]=c[a>>2]|2;return}function oi(a,b){a=a|0;b=b|0;a=a+(b*440|0)+8|0;c[a>>2]=c[a>>2]|1;return}function pi(b,e){b=b|0;e=e|0;var f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;q=b+1496|0;p=b+8120|0;o=b+324|0;if((e+-4e3|0)>>>0>45170)return;r=b+8140|0;f=c[r>>2]|0;if((f|0)<1)return;if((f|0)!=1)qi(b);if((Ek(b,e,c[b+2816>>2]|0)|0)<0)return;c[b+316>>2]=100;c[b+312>>2]=100;n=b+320|0;c[n>>2]=c[b+2820>>2];c[b>>2]=0;c[b+4>>2]=0;c[b+12>>2]=-1;l=b+8|0;c[l>>2]=0;h[b+32>>3]=0.0;c[b+48>>2]=0;c[b+52>>2]=0;f=b+884|0;e=b+628|0;g=0;do{a[f+g>>0]=0;c[e+(g<<2)>>2]=100;g=g+1|0}while((g|0)!=64);f=c[b>>2]|0;j=b+1708|0;i=c[j>>2]|0;a:do if((f|0)<(i|0)){k=b+2504|0;g=c[b+1680>>2]|0;while(1){e=d[k+f>>0]|0;if((e|0)<(g|0))break;f=f+1|0;c[b>>2]=f;if((f|0)>=(i|0)){t=12;break a}}if((i|0)!=0?(m=b+1688|0,(c[m>>2]|0)!=0):0){c[b+352>>2]=c[c[(c[b+1720>>2]|0)+(e<<2)>>2]>>2];f=m;e=c[b+380>>2]|0;g=356}else t=15}else t=12;while(0);if((t|0)==12){c[j>>2]=0;t=15}if((t|0)==15){c[b+372>>2]=0;c[b>>2]=0;c[b+376>>2]=0;c[l>>2]=0;c[b+356>>2]=0;f=b+1688|0;e=0;g=352}c[b+g>>2]=e;l=b+2848|0;m=c[b>>2]|0;c[n>>2]=c[l+(m*20|0)+8>>2];n=c[l+(m*20|0)+4>>2]|0;c[b+20>>2]=n;c[b+16>>2]=c[l+(m*20|0)>>2];h[b+40>>3]=+h[b+2808>>3]*+h[b+2800>>3]/+(n|0);if(Qh(b,(c[p>>2]|0)+(c[f>>2]|0)|0)|0)return;c[b+340>>2]=0;c[b+328>>2]=-1;c[o>>2]=0;c[b+364>>2]=0;j=b+952|0;e=c[j>>2]|0;f=Qm(e,8)|0;i=b+348|0;c[i>>2]=f;if(!f)return;g=Qm(e,440)|0;k=b+624|0;c[k>>2]=g;if(g){b:do if((e|0)>0){e=b+8104|0;if((pm(c[e>>2]|0,g)|0)>=0){f=1;while(1){if((f|0)>=(c[j>>2]|0)){t=24;break b}if((pm(c[e>>2]|0,(c[k>>2]|0)+(f*440|0)|0)|0)<0)break;else f=f+1|0}}}else t=24;while(0);if((t|0)==24?(s=b+8108|0,(Ia[c[c[s>>2]>>2]&63](b,c[q>>2]|0)|0)>=0):0){Ha[c[(c[s>>2]|0)+8>>2]&7](b)|0;ri(b);c[r>>2]=2;return}Pm(c[k>>2]|0);f=c[i>>2]|0}Pm(f);return}function qi(a){a=a|0;var b=0,d=0,e=0,f=0;b=a+8140|0;if((c[b>>2]|0)<2)return;c[b>>2]=1;e=a+952|0;f=a+624|0;if((c[e>>2]|0)>0){b=a+8104|0;d=0;do{qm(c[b>>2]|0,(c[f>>2]|0)+(d*440|0)|0);d=d+1|0}while((d|0)<(c[e>>2]|0))}Rh(a);Ha[c[(c[a+8108>>2]|0)+4>>2]&7](a)|0;Pm(c[f>>2]|0);e=a+348|0;Pm(c[e>>2]|0);c[f>>2]=0;c[e>>2]=0;Fk(a);return}function ri(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;Ha[c[(c[a+8108>>2]|0)+8>>2]&7](a)|0;e=a+952|0;if((c[e>>2]|0)>0){f=a+624|0;b=a+8104|0;d=0;do{g=c[f>>2]|0;h=g+(d*440|0)|0;i=g+(d*440|0)+400|0;j=c[i>>2]|0;cp(h|0,0,440)|0;c[i>>2]=j;rm(c[b>>2]|0,h);c[g+(d*440|0)+16>>2]=-1;c[g+(d*440|0)+44>>2]=-1;d=d+1|0}while((d|0)<(c[e>>2]|0))}b=c[a+948>>2]|0;if((b|0)<=0)return;d=c[a+624>>2]|0;e=0;do{c[d+(e*440|0)+344>>2]=c[a+1736+(e*12|0)>>2];c[d+(e*440|0)+60>>2]=c[a+1736+(e*12|0)+4>>2];c[d+(e*440|0)+376>>2]=255;e=e+1|0}while((e|0)!=(b|0));return} -function Pa(a){a=a|0;var b=0;b=l;l=l+a|0;l=l+15&-16;return b|0}function Qa(){return l|0}function Ra(a){a=a|0;l=a}function Sa(a,b){a=a|0;b=b|0;l=a;m=b}function Ta(a,b){a=a|0;b=b|0;if(!o){o=a;p=b}}function Ua(a){a=a|0;z=a}function Va(){return z|0}function Wa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;g=d+4|0;if((a|0)==-1){c[g>>2]=0;c[d>>2]=0;return}if(!(c[g>>2]|0))if((a|0)==144){c[g>>2]=1;return}else{La[b&1](a,e);c[d>>2]=a;return}if(a){if((a|0)>1){f=1;do{La[b&1](c[d>>2]|0,e);f=f+1|0}while((f|0)!=(a|0))}}else La[b&1](144,e);c[g>>2]=0;return}function Xa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+16|0;r=t;s=e+786480|0;c[s>>2]=31;c[e+786448>>2]=0;q=e+786484|0;c[q>>2]=8192;n=Om(d)|0;if(!n){s=0;l=t;return s|0}p=e+786464|0;c[p>>2]=a;o=e+786468|0;c[o>>2]=a+b;c[e+786472>>2]=n;c[e+786476>>2]=n+d;c[e+786440>>2]=0;c[e+786436>>2]=0;c[e+786444>>2]=0;Wa(-1,0,e+786456|0,p);j=e+786452|0;c[j>>2]=0;Ya(e);c[r>>2]=0;if(c[s>>2]&32|0)c[p>>2]=(c[p>>2]|0)+1;if((c[q>>2]|0)>8192){s=0;l=t;return s|0}c[e+1065016>>2]=0;k=e+524288|0;a:do if(Za(r,9,e)|0){a=9;g=1;d=0;i=0;while(1){f=c[s>>2]|0;b=c[r>>2]|0;if((f&1|0)!=0&(b|0)==257)break a;if(!g)h=0;else{d=b;h=(c[j>>2]|0)!=0&1}if((b|0)==256)if(!(c[j>>2]|0)){c[k>>2]=(f>>>3&1)+255;_a(a,e);if(!(Za(r,9,e)|0))break a;b=c[r>>2]|0;a=9;g=13}else{b=256;g=15}else g=13;if((g|0)==13)if(!(c[j>>2]|0))if((b|0)>(c[k>>2]|0))g=17;else g=16;else g=15;if((g|0)==15)if((c[e+262144+(b<<2)>>2]|0)==-1)g=17;else g=16;if((g|0)==16){$a(b,e);f=b;d=ab(b,e)|0}else if((g|0)==17){$a(i,e);bb(d,e);f=b}if((!(h|0?1:(c[k>>2]|0)==((c[q>>2]|0)+-1|0))?(cb(i,d,e),m=c[k>>2]|0,(m|0)!=((c[q>>2]|0)+-1|0)):0)?(m|0)==((1<>2]&2|0){s=n;l=t;return s|0}if((c[p>>2]|0)==(c[o>>2]|0)){s=n;l=t;return s|0}Pm(n);s=0;l=t;return s|0}function Ya(a){a=a|0;var b=0;b=0;do{c[a+262144+(b<<2)>>2]=-1;c[a+(b<<2)>>2]=-1;c[a+524292+(b<<2)>>2]=-1;b=b+1|0}while((b|0)!=65536);cp(a+1048632|0,-1,16384)|0;if(!(c[a+786452>>2]|0)){b=0;do{c[a+262144+(b<<2)>>2]=b;b=b+1|0}while((b|0)!=256);c[a+524288>>2]=((c[a+786480>>2]|0)>>>3&1)+255;return}c[a+524288>>2]=-1;b=0;do{cb(65535,b,a);b=b+1|0}while((b|0)!=256);return}function Za(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;c[a>>2]=0;if((b|0)>0){m=e+786440|0;k=e+786464|0;j=e+786468|0;l=e+786436|0;n=e+1065016|0;o=e+786452|0;f=c[m>>2]|0;i=0;do{if(!f){f=c[k>>2]|0;if(f>>>0>=(c[j>>2]|0)>>>0){f=0;p=14;break}c[k>>2]=f+1;h=d[f>>0]|0;c[l>>2]=h;c[m>>2]=8;c[n>>2]=(c[n>>2]|0)+1;f=8}else h=c[l>>2]|0;g=b-i|0;f=(f|0)<(g|0)?f:g;g=i;i=f+i|0;if(!(c[o>>2]|0)){c[a>>2]=c[a>>2]|((1<>2]=c[l>>2]>>f}else{h=(h&255)<>2]=h;c[a>>2]=c[a>>2]|h>>8<>2]|0)-f|0;c[m>>2]=f}while((i|0)<(b|0));if((p|0)==14)return f|0;f=c[a>>2]|0;if((f|0)<0){e=0;return e|0}}else f=0;g=e+786444|0;if((f|0)>=(c[e+786484>>2]|0)){e=0;return e|0}c[g>>2]=(c[g>>2]|0)+1&7;e=1;return e|0}function _a(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=l;l=l+16|0;e=f;if(c[b+786480>>2]&4|0){l=f;return}d=b+786444|0;while(1){if(!(c[d>>2]|0)){d=5;break}if(!(Za(e,a,b)|0)){d=5;break}}if((d|0)==5){l=f;return}}function $a(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0;d=b+(a<<2)|0;a:do if((c[d>>2]|0)==-1){d=0;i=3}else{h=b+786484|0;g=d;f=0;e=b+786488|0;while(1){a=c[b+262144+(a<<2)>>2]|0;if((f|0)>=(c[h>>2]|0)){d=f;break a}d=f+1|0;c[e>>2]=a;a=c[g>>2]|0;g=b+(a<<2)|0;if((c[g>>2]|0)==-1){i=3;break}else{f=d;e=b+786488+(d<<2)|0}}}while(0);if((i|0)==3)a=c[b+262144+(a<<2)>>2]|0;bb(a,b);if((d|0)<=0)return;do{i=d;d=d+-1|0;bb(c[b+786488+(d<<2)>>2]|0,b)}while((i|0)>1);return}function ab(a,b){a=a|0;b=b|0;if((c[b+(a<<2)>>2]|0)!=-1)a=c[b+524292+(a<<2)>>2]|0;return c[b+262144+(a<<2)>>2]|0}function bb(a,b){a=a|0;b=b|0;if(!(c[b+786448>>2]|0)){eb(a,b+786464|0);return}else{Wa(a,1,b+786456|0,b+786464|0);return}}function cb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;g=d+524288|0;e=(c[g>>2]|0)+1|0;c[g>>2]=e;h=d+786484|0;f=c[h>>2]|0;if(f&e|0){c[g>>2]=f+-1;return}if(c[d+786452>>2]|0){e=db(a,b,d)|0;if((e|0)==-1)return}c[d+262144+(e<<2)>>2]=b;if((c[h>>2]|0)<=(a|0))return;c[d+(e<<2)>>2]=a;if((c[d+(a<<2)>>2]|0)!=-1)a=c[d+524292+(a<<2)>>2]|0;c[d+524292+(e<<2)>>2]=a;return}function db(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;b=b+a&63487|2048;b=(O(b,b)|0)>>>6&4095;while(1){if((c[d+262144+(b<<2)>>2]|0)==-1){e=10;break}f=d+1048632+(b<<2)|0;a=c[f>>2]|0;if((a|0)==-1)break;else b=a}if((e|0)==10)return b|0;b=b+101&4095;if((c[d+262144+(b<<2)>>2]|0)!=-1){e=c[d+786484>>2]|0;a:do if((e|0)>=1){a=0;do{a=a+1|0;b=b+1&4095;if((a|0)>=(e|0))break a}while((c[d+262144+(b<<2)>>2]|0)!=-1)}while(0);if((b|0)==(e|0)){d=-1;return d|0}}c[f>>2]=b;d=b;return d|0}function eb(b,d){b=b|0;d=d|0;var e=0,f=0;f=d+8|0;e=c[f>>2]|0;if(e>>>0>=(c[d+12>>2]|0)>>>0)return;c[f>>2]=e+1;a[e>>0]=b;return}function fb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;f=Om(1065020)|0;if(!f){e=0;return e|0}g=Om(d)|0;if(!g){e=0;return e|0}h=Ho(a)|0;Go(g,1,d,a)|0;d=Xa(g,d,e,f)|0;ap(b|0,d|0,e|0)|0;ro(a,((c[f+1065016>>2]|0)+3&-4)+h|0,0)|0;Pm(d);Pm(g);Pm(f);e=b;return e|0}function gb(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)!=1097679467){b=-1;return b|0}if((Pl(a)|0)<<16>>16!=3){b=-1;return b|0}_l(a,6,1)|0;b=Xl(a)|0;b=((Xl(a)|0)!=1663049760|(b|0)!=1299542889)<<31>>31;return b|0}function hb(d,f,g){d=d|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;w=l;l=l+64|0;o=w+16|0;u=w+8|0;_l(f,0,2)|0;$l(f)|0;_l(f,20,0)|0;h=Xl(f)|0;v=Xl(f)|0;n=Xl(f)|0;_l(f,g,0)|0;Eb(d,17472,w);if((ib(f,o,v+20|0)|0)<0){d=-1;l=w;return d|0}wb(d,o+18|0,16)|0;p=n+20|0;_l(f,p,0)|0;q=d+136|0;c[q>>2]=4;g=(Pl(f)|0)&65535;r=d+128|0;c[r>>2]=g;c[d+132>>2]=O(c[q>>2]|0,g)|0;g=h+20|0;_l(f,g,0)|0;t=(Pl(f)|0)&65535;v=d+140|0;c[v>>2]=t;c[d+144>>2]=t;if((nb(d)|0)<0){d=-1;l=w;return d|0}t=jb(f,c[v>>2]|0)|0;s=(c[t>>2]|0)+g|0;a:do if((c[v>>2]|0)>0){m=d+180|0;k=d+176|0;i=0;while(1){if((ob(d,i,1)|0)<0){g=-1;break}j=c[t+(i<<5)+4>>2]<<1;g=c[m>>2]|0;c[g+(i*52|0)+32>>2]=j;if((j|0)>0)c[(c[k>>2]|0)+(i*764|0)+36>>2]=1;h=c[t+(i<<5)+8>>2]|0;x=c[t+(i<<5)>>2]|0;c[g+(i*52|0)+36>>2]=h>>>0>x>>>0?h-x<<1:0;x=b[t+(i<<5)+12>>1]|0;h=x&65535;j=g+(i*52|0)+40|0;c[j>>2]=h;if((x&65535)>2){c[j>>2]=h<<1;c[g+(i*52|0)+44>>2]=2}x=c[k>>2]|0;j=c[x+(i*764|0)+756>>2]|0;c[j>>2]=e[t+(i<<5)+14>>1];c[j+8>>2]=128;c[j+40>>2]=i;vb(x,i,t+(i<<5)+16|0,16);i=i+1|0;if((i|0)>=(c[v>>2]|0))break a}l=w;return g|0}while(0);if((pb(d)|0)<0){x=-1;l=w;return x|0}kb(f,c[o>>2]|0,u);_l(f,n+22|0,0)|0;j=d+156|0;c[j>>2]=0;b:do if((c[r>>2]|0)>0){i=d+172|0;g=0;while(1){if((tb(d,g,64)|0)<0){g=-1;break}if((c[q>>2]|0)>0){h=0;do{x=Pl(f)|0;lb(f,(c[(c[i>>2]|0)+((O(c[q>>2]|0,g)|0)+h<<2)>>2]|0)+4|0,(x&65535)+p|0);h=h+1|0}while((h|0)<(c[q>>2]|0))}g=g+1|0;if((g|0)>=(c[r>>2]|0))break b}l=w;return g|0}while(0);g=b[u>>1]|0;if(g<<16>>16){i=c[u+4>>2]|0;g=g&65535;h=0;do{c[j>>2]=(c[j>>2]|0)+1;a[d+952+h>>0]=b[i+(h<<1)>>1];h=h+1|0}while((h|0)!=(g|0))}Pm(t);mb(u);_l(f,s,0)|0;g=c[v>>2]|0;if((g|0)<=0){x=0;l=w;return x|0}j=d+180|0;i=0;while(1){h=c[j>>2]|0;if((c[h+(i*52|0)+32>>2]|0)>=3){if((Ub(d,f,0,h+(i*52|0)|0,0)|0)<0){g=-1;h=27;break}g=c[v>>2]|0}i=i+1|0;if((i|0)>=(g|0)){g=0;h=27;break}}if((h|0)==27){l=w;return g|0}return 0}function ib(a,d,e){a=a|0;d=d|0;e=e|0;_l(a,e,0)|0;if((Pl(a)|0)<<16>>16!=1){e=-1;return e|0}e=(Xl(a)|0)+e|0;_l(a,e,0)|0;c[d>>2]=e+((Pl(a)|0)&65535);c[d+4>>2]=e+((Pl(a)|0)&65535);c[d+8>>2]=e+((Pl(a)|0)&65535);c[d+12>>2]=e+((Pl(a)|0)&65535);b[d+16>>1]=Pl(a)|0;Pl(a)|0;Zl(d+18|0,1,16,a)|0;e=0;return e|0}function jb(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;i=d<<5;e=Om(i)|0;cp(e|0,0,i|0)|0;if((d|0)>0){g=0;h=0}else return e|0;do{c[e+(g<<5)>>2]=Xl(a)|0;c[e+(g<<5)+8>>2]=Xl(a)|0;i=e+(g<<5)+4|0;c[i>>2]=(Pl(a)|0)&65535;b[e+(g<<5)+12>>1]=Pl(a)|0;b[e+(g<<5)+14>>1]=Pl(a)|0;f=Pl(a)|0;if((f&65535)>4)c[i>>2]=f&65535;Zl(e+(g<<5)+16|0,1,16,a)|0;h=h+1<<16>>16;g=h&65535}while((g|0)<(d|0));return e|0}function kb(a,d,e){a=a|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;b[e>>1]=0;_l(a,d,0)|0;i=e+4|0;c[i>>2]=Om(128)|0;d=Pl(a)|0;if((d&65535)>65533)return;else g=64;do{f=b[e>>1]|0;if((f&65535|0)<(g|0))h=c[i>>2]|0;else{h=Rm(c[i>>2]|0,g<<2)|0;c[i>>2]=h;f=b[e>>1]|0;g=g<<1}b[e>>1]=f+1<<16>>16;b[h+((f&65535)<<1)>>1]=d;d=Pl(a)|0}while((d&65535)<=65533);return}function lb(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;m=$l(b)|0;_l(b,d,0)|0;i=0;e=0;f=Pl(b)|0;h=0;j=0;d=0;a:while(1){l=f&65535;if(e<<24>>24)break;if(f<<16>>16<-28416)switch(f<<16>>16){case -32768:break a;default:{}}else switch(f<<16>>16){case -28416:break a;default:{}}b:do if(!(l&32768)){if(!(l&16384)){e=d&255;a[c+(e<<3)>>0]=ki(l&4095)|0;a[c+(e<<3)+1>>0]=i;e=0;g=j;break}e=Pl(b)|0;f=e<<16>>16==0;if((l&255|0)==0&f)break a;d=d&255;if(!f){a[c+(d<<3)>>0]=ki(e&4095)|0;a[c+(d<<3)+1>>0]=i}l=d+l|0;d=l&255;if((l&192)>>>0>63)break a;else{e=0;g=j}}else{e=l>>>8;k=l&127;g=k&255;f=e&255;switch(f&127){case 13:case 12:case 11:case 9:case 3:break;default:{e=(e&112)>>>0<16;h=e?0:h;j=e?0:j}}do switch(f&127){case 14:case 1:{e=d&255;a[c+(e<<3)+3>>0]=1;a[c+(e<<3)+4>>0]=g;e=0;g=j;break b}case 15:case 2:{e=d&255;a[c+(e<<3)+3>>0]=2;a[c+(e<<3)+4>>0]=g;e=0;g=j;break b}case 3:{e=d&255;a[c+(e<<3)+3>>0]=12;a[c+(e<<3)+4>>0]=g;e=0;g=j;break b}case 17:{e=d&255;a[c+(e<<3)+3>>0]=11;a[c+(e<<3)+4>>0]=g;e=1;g=j;break b}case 5:{e=d&255;a[c+(e<<3)+3>>0]=14;a[c+(e<<3)+4>>0]=(k|0)==0?80:(l&15|96)&255;e=0;g=j;break b}case 6:{e=d&255;a[c+(e<<3)+3>>0]=14;a[c+(e<<3)+4>>0]=0;e=0;g=j;break b}case 7:{e=d&255;a[c+(e<<3)+3>>0]=14;a[c+(e<<3)+4>>0]=1;e=0;g=j;break b}case 8:{e=d&255;if(!k){e=0;g=j;break b}a[c+(e<<3)+3>>0]=15;a[c+(e<<3)+4>>0]=100/(k>>>0)|0;e=0;g=j;break b}case 9:{i=k+1&255;e=0;g=j;break b}case 10:{e=0;h=0;break b}case 11:{e=0;h=3;break b}case 12:{e=0;h=4;break b}case 13:{e=0;h=(k|0)==0?0:10;break b}case 16:{if((j|h)<<24>>24){if((d&255)<64&(k|0)!=0){e=0;d=d&255;do{a[c+(d<<3)+3>>0]=h;a[c+(d<<3)+4>>0]=j;d=d+1|0;e=e+1|0}while(d>>>0<64&(e|0)<(k|0));d=d&255}}else d=(d&255)+k&255;e=(d&255)>63&1;g=j;break b}default:{e=0;g=j;break b}}while(0)}while(0);f=Pl(b)|0;if(am(b)|0)break;else j=g}if((d&255)>=64){_l(b,m,0)|0;return}a[c+((d&255)+-1<<3)+5>>0]=13;_l(b,m,0)|0;return}function mb(a){a=a|0;var d=0;d=c[a+4>>2]|0;if(d|0)Pm(d);b[a>>1]=0;return}function nb(a){a=a|0;var b=0;b=Qm(764,c[a+140>>2]|0)|0;c[a+176>>2]=b;if(!b){a=-1;return a|0}b=c[a+144>>2]|0;if(b|0?(b=Qm(52,b)|0,c[a+180>>2]=b,(b|0)==0):0){a=-1;return a|0}a=0;return a|0}function ob(a,b,d){a=a|0;b=b|0;d=d|0;if(!d){d=0;return d|0}d=Qm(64,d)|0;c[(c[a+176>>2]|0)+(b*764|0)+756>>2]=d;d=((d|0)==0)<<31>>31;return d|0}function pb(a){a=a|0;var b=0;b=Qm(4,c[a+132>>2]|0)|0;c[a+172>>2]=b;if(!b){b=-1;return b|0}b=Qm(4,c[a+128>>2]|0)|0;c[a+168>>2]=b;b=((b|0)==0)<<31>>31;return b|0}function qb(a,b){a=a|0;b=b|0;var d=0;d=Qm(1,(c[a+136>>2]<<2)+4|0)|0;a=a+168|0;c[(c[a>>2]|0)+(b<<2)>>2]=d;return ((c[(c[a>>2]|0)+(b<<2)>>2]|0)==0)<<31>>31|0}function rb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=Qm(d<<3|4,1)|0;a=a+172|0;c[(c[a>>2]|0)+(b<<2)>>2]=e;a=c[(c[a>>2]|0)+(b<<2)>>2]|0;if(!a){e=-1;return e|0}c[a>>2]=d;e=0;return e|0}function sb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;g=a+136|0;d=c[g>>2]|0;if((d|0)<=0){h=0;return h|0}h=a+168|0;e=c[(c[h>>2]|0)+(b<<2)>>2]|0;f=0;while(1){d=(O(d,b)|0)+f|0;if((rb(a,d,c[e>>2]|0)|0)<0){d=-1;e=5;break}e=c[(c[h>>2]|0)+(b<<2)>>2]|0;c[e+4+(f<<2)>>2]=d;f=f+1|0;d=c[g>>2]|0;if((f|0)>=(d|0)){d=0;e=5;break}}if((e|0)==5)return d|0;return 0}function tb(a,b,d){a=a|0;b=b|0;d=d|0;if((qb(a,b)|0)<0){d=-1;return d|0}c[c[(c[a+168>>2]|0)+(b<<2)>>2]>>2]=d;d=(sb(a,b)|0)>>31;return d|0}function ub(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=Rm(a,d*52|0)|0;if(!e){b=0;return b|0}a=c[b>>2]|0;if((a|0)<(d|0))cp(e+(a*52|0)|0,0,(d-a|0)*52|0)|0;c[b>>2]=d;b=e;return b|0}function vb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;wb(a+(b*764|0)|0,c,(d|0)<0?0:(d|0)<31?d:31)|0;return}function wb(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;cp(b|0,0,d+1|0)|0;yo(b,c,d)|0;c=a[b>>0]|0;if((d|0)>0&c<<24>>24!=0){e=b;f=0;do{if(c<<24>>24<0|(In(c<<24>>24)|0)==0)a[e>>0]=46;f=f+1|0;e=b+f|0;c=a[e>>0]|0}while((f|0)<(d|0)&c<<24>>24!=0);c=a[b>>0]|0}if(!(c<<24>>24))return b|0;while(1){c=b+((Zn(b)|0)+-1)|0;if((a[c>>0]|0)!=32){c=9;break}a[c>>0]=0;if(!(a[b>>0]|0)){c=9;break}}if((c|0)==9)return b|0;return 0}function xb(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;f=l;l=l+64|0;e=f;d=(d|0)<63?d:63;if(!c){l=f;return}cp(c|0,0,d+1|0)|0;Zl(e,1,d,b)|0;a[e+d>>0]=0;wb(c,e,d)|0;l=f;return}function yb(b,c){b=b|0;c=c|0;var d=0,e=0;a:do if((c|0)>0){e=0;while(1){d=a[b+e>>0]|0;if(d<<24>>24<0){d=-1;break a}e=e+1|0;if(!(d<<24>>24==8|(d+-1&255)>30)){d=-1;break a}if((e|0)>=(c|0)){d=0;break}}}else d=0;while(0);return d|0}function zb(b,c){b=b|0;c=c|0;var e=0,f=0;e=b;f=e;a[f>>0]=0;a[f+1>>0]=0;a[f+2>>0]=0;a[f+3>>0]=0;e=e+4|0;a[e>>0]=0;a[e+1>>0]=0;a[e+2>>0]=0;a[e+3>>0]=0;a[b>>0]=ki((a[c>>0]&15)<<8|(d[c+1>>0]|0))|0;e=c+2|0;a[b+1>>0]=(d[e>>0]|0)>>>4|a[c>>0]&-16&255;e=a[e>>0]&15;if((e&255)>=7?!((e&255)>9&e<<24>>24!=14):0){Ab(b);return}a[b+3>>0]=e;a[b+4>>0]=a[c+3>>0]|0;Ab(b);return}function Ab(b){b=b|0;var c=0;if(a[b+4>>0]|0)return;c=b+3|0;switch(a[c>>0]|0){case 5:{b=3;break}case 6:{b=4;break}case 10:case 2:case 1:{b=0;break}default:return}a[c>>0]=b;return}function Bb(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0;f=c+2|0;e=a[f>>0]&15;g=b;h=g;a[h>>0]=0;a[h+1>>0]=0;a[h+2>>0]=0;a[h+3>>0]=0;g=g+4|0;a[g>>0]=0;a[g+1>>0]=0;a[g+2>>0]=0;a[g+3>>0]=0;a[b>>0]=ki((a[c>>0]&15)<<8|(d[c+1>>0]|0))|0;a[b+1>>0]=(d[f>>0]|0)>>>4|a[c>>0]&-16&255;if(e<<24>>24==8){Ab(b);return}a[b+3>>0]=e;a[b+4>>0]=a[c+3>>0]|0;Ab(b);return}function Cb(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=Nn(a)|0;if(!d){e=0;return e|0}while(1){a=Pn(d)|0;if(!a){a=0;break}a=a+11|0;if(!(Yn(a,b)|0)){e=4;break}}if((e|0)==4){yo(c,a,256)|0;a=1}Jn(d);e=a;return e|0}function Db(a,b){a=a|0;b=b|0;if(a|0){yo(b,a,256)|0;return}a=za(17488)|0;if(!a){yo(b,23261,256)|0;return}else{yo(b,a,256)|0;return}}function Eb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;e=l;l=l+16|0;f=e;c[f>>2]=d;gn(a+64|0,64,b,f);l=e;return}function Fb(){var a=0;a=Om(16)|0;if(!a){a=0;return a|0}c[a>>2]=a;c[a+4>>2]=a;c[a+8>>2]=4;c[a+12>>2]=0;return a|0}function Gb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;while(1){if(am(c)|0){e=0;break}e=Hb(a,b,c,d)|0;if((e|0)>0){e=0;break}if((e|0)<0){e=-1;break}}return e|0}function Hb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0;k=l;l=l+32|0;j=k;g=j;h=g+17|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));i=b+8|0;h=Zl(j,1,c[i>>2]|0,e)|0;if((h|0)!=(c[i>>2]|0)){f=1;l=k;return f|0}h=b+12|0;g=c[h>>2]|0;if((g&16|0)!=0?(fn(j,17508,4)|0)==0:0){Xl(e)|0;Xl(e)|0;Zl(j,1,c[i>>2]|0,e)|0;g=c[h>>2]|0}if(!(g&1))g=Xl(e)|0;else g=Vl(e)|0;h=c[h>>2]|0;g=(h&4|0)==0?g:g+1&-2;g=(h&8|0)==0?g:g+3&-4;if(h&2)g=g+-4-(c[i>>2]|0)|0;if((g|0)<0){f=1;l=k;return f|0}f=Ib(b,d,j,g,e,f)|0;l=k;return f|0}function Ib(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0;j=$l(f)|0;h=c[a>>2]|0;a:do if((h|0)!=(a|0)){l=(d|0)==0;k=a+8|0;while(1){i=h+-12|0;if(!l?(fn(d,i,c[k>>2]|0)|0)==0:0)break;h=c[h>>2]|0;if((h|0)==(a|0))break a}if((Ka[c[i+8>>2]&127](b,e,f,g)|0)<0){l=-1;return l|0}}while(0);_l(f,j+e|0,0)|0;l=0;return l|0}function Jb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=Om(20)|0;if(!e){a=-1;return a|0}yo(e,b,5)|0;c[e+8>>2]=d;Kb(e+12|0,a);a=0;return a|0}function Kb(a,b){a=a|0;b=b|0;Lb(a,c[b+4>>2]|0,b);return}function Lb(a,b,d){a=a|0;b=b|0;d=d|0;c[d+4>>2]=a;c[a>>2]=d;c[a+4>>2]=b;c[b>>2]=a;return}function Mb(a){a=a|0;var b=0,d=0;b=c[a>>2]|0;if((b|0)==(a|0)){Pm(a);return}do{d=b+-12|0;Nb(c[d+12>>2]|0,c[d+16>>2]|0);b=c[b>>2]|0;Pm(d)}while((b|0)!=(a|0));Pm(a);return}function Nb(a,b){a=a|0;b=b|0;Ob(b,a);return}function Ob(a,b){a=a|0;b=b|0;c[b+4>>2]=a;c[a>>2]=b;return}function Pb(a){a=a|0;c[a+8>>2]=2;return}function Qb(a,b){a=a|0;b=b|0;a=a+12|0;c[a>>2]=c[a>>2]|b;return}function Rb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+16|0;s=w+4|0;t=w;c[s>>2]=0;c[t>>2]=0;if(!e){l=w;return}r=(f|0)!=0;i=0;f=0;g=0;h=0;a:while(1){if(!i){Ml(b)|0;c[t>>2]=0;c[s>>2]=0;q=32768;f=9;g=0;h=0}else q=i;p=q>>>0>e>>>0?e:q;n=f;o=0;while(1){m=n&255;f=Sb(b,s,t,m)|0;if(am(b)|0){v=24;break a}do if((n&255)<7){f=f&65535;if((1<>>0>>0?f:i+2|0)&255;i=o}else v=19}else{if((n&255)>=9){if(n<<24>>24!=9){v=21;break}if((f&65280)>>>0<=255){v=20;break}f=f+1&255;i=o;break}j=255>>>(9-m|0);k=j+65532|0;i=f&65535;if(i>>>0>(k&65535)>>>0?(u=f-k|0,i>>>0<=(j+4&65535)>>>0):0){f=((u&255)>>>0>=m>>>0&1)+u&255;i=o;break}if((n&255)<8){f=i;v=19}else v=20}while(0);if((v|0)==19){m=8-m&255;f=f<>24>>m;v=20}if((v|0)==20){m=(f&65535)+(g&255)|0;g=m&255;h=m+(h&255)&255;a[d+o>>0]=r?h:g;v=21}if((v|0)==21){v=0;f=n;i=o+1|0}if(i>>>0

>>0){n=f;o=i}else break}e=e-p|0;if(!e){v=24;break}else{i=q-p|0;d=d+p|0}}if((v|0)==24){l=w;return}}function Sb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;if((e|0)<=0){a=0;i=32-e|0;i=a>>>i;return i|0}f=c[b>>2]|0;g=c[d>>2]|0;h=e;i=0;do{if(!g){f=(Kl(a)|0)&255;g=8}i=f<<31|i>>>1;f=f>>1;g=g+-1|0;h=h+-1|0}while((h|0)!=0);c[d>>2]=g;c[b>>2]=f;a=i;i=32-e|0;i=a>>>i;return i|0}function Tb(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;u=l;l=l+16|0;r=u+4|0;s=u;c[r>>2]=0;c[s>>2]=0;if(!e){t=0;l=u;return t|0}q=(f|0)!=0;i=0;f=0;g=0;h=0;a:while(1){if(!i){Ml(a)|0;c[s>>2]=0;c[r>>2]=0;p=16384;f=17;g=0;h=0}else p=i;o=p>>>0>e>>>0?e:p;n=0;while(1){m=f&255;j=Sb(a,r,s,m)|0;if(am(a)|0){f=-1;t=22;break a}do if((f&255)<7)if((1<>>0>>0?f:i+2|0)&255;i=n}else t=18;else if((f&255)<17){k=65535>>>(17-m|0);i=k+65528&65535;if(j>>>0<=i>>>0){t=18;break}i=j-i|0;if(j>>>0>(k+8&65535)>>>0){t=18;break}f=((i&255)>>>0>=m>>>0&1)+i&255;i=n;break}else{if(f<<24>>24!=17){t=19;break}if(j>>>0<=65535){t=18;break}f=j+1&255;i=n;break}while(0);if((t|0)==18){m=16-m&255;m=((f&255)<16?j<>16>>m:j)+(g&65535)|0;g=m&65535;h=m+(h&65535)&65535;b[d+(n<<1)>>1]=q?h:g;t=19}if((t|0)==19){t=0;i=n+1|0}if(i>>>0>>0)n=i;else break}e=e-o|0;if((e|0)<=0){f=0;t=22;break}else{i=p-o|0;d=d+(o<<1)|0}}if((t|0)==22){l=u;return f|0}return 0}function Ub(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+16|0;k=t;if(e&4096|0){if(e&8192|0)Vb(g);b=Om(15)|0;h=f+48|0;c[h>>2]=b;if(!b){s=-1;l=t;return s|0}c[b>>2]=0;i=b+4|0;c[h>>2]=i;b=g;h=i+11|0;do{a[i>>0]=a[b>>0]|0;i=i+1|0;b=b+1|0}while((i|0)<(h|0));s=f+44|0;c[s>>2]=c[s>>2]|32768;c[f+32>>2]=11;s=0;l=t;return s|0}n=f+32|0;j=c[n>>2]|0;if(!j){s=0;l=t;return s|0}if(b|0?c[b+1288>>2]&1|0:0){if(e&16|0){s=0;l=t;return s|0}_l(d,j,1)|0;s=0;l=t;return s|0}s=f+40|0;b=c[s>>2]|0;if((b|0)>(j|0)){c[s>>2]=j;b=j}r=f+36|0;h=c[r>>2]|0;if((h|0)<(j|0)&(h|0)<(b|0)){q=f+44|0;i=c[q>>2]|0}else{c[s>>2]=0;c[r>>2]=0;q=f+44|0;i=c[q>>2]&-7;c[q>>2]=i;h=0;b=0}if((i&6|0)==4){i=i&-5;c[q>>2]=i}if(!(i&4))b=0;else{b=b-j+(b-h)|0;b=(b|0)>0?b:0}o=i&1;p=b<>2]=b;if(!b){s=-1;l=t;return s|0}c[b>>2]=0;b=b+4|0;c[o>>2]=b;do if(!(e&16)){if(e&16384|0){j=m+1>>1;Zl(k,1,16,d)|0;Zl((c[o>>2]|0)+j|0,1,j,d)|0;g=c[o>>2]|0;Wb(g+j|0,g,k,m);break}b=Zl(b,1,m,d)|0;if((m|0)!=(b|0))cp((c[o>>2]|0)+b|0,0,m-b|0)|0}else ap(b|0,g|0,m|0)|0;while(0);if(e&8|0)Xb(c[o>>2]|0,c[n>>2]|0);if(!((e&64|0)==0|(c[q>>2]&1|0)==0))Yb(c[o>>2]|0,c[n>>2]|0);if(!(e&1)){if(e&4|0)Zb(c[o>>2]|0,c[n>>2]<<(c[q>>2]&1),0)}else Zb(c[o>>2]|0,c[n>>2]|0,c[q>>2]&1);if(e&2|0)_b(c[o>>2]|0,c[n>>2]|0,c[q>>2]&1);if(e&128|0)$b(c[o>>2]|0,c[n>>2]|0);if((e&512|0?(c[r>>2]|0)==0:0)?(c[n>>2]|0)>(c[s>>2]|0):0)c[q>>2]=c[q>>2]|16;b=c[q>>2]|0;if(b&4){ac(f);b=c[q>>2]|0;m=p+m|0}if(!(b&1)){e=c[o>>2]|0;a[e+m>>0]=a[e+(m+-1)>>0]|0;e=c[o>>2]|0;b=3;h=2;i=2;j=1;d=e;k=1;e=e+m|0}else{f=c[o>>2]|0;a[f+m>>0]=a[f+(m+-2)>>0]|0;f=c[o>>2]|0;h=m+1|0;a[f+h>>0]=a[f+(m+-1)>>0]|0;f=c[o>>2]|0;b=m+2|0;a[f+b>>0]=a[f+m>>0]|0;f=c[o>>2]|0;e=m+3|0;a[f+e>>0]=a[f+h>>0]|0;f=c[o>>2]|0;a[f+(m+4)>>0]=a[f+b>>0]|0;f=c[o>>2]|0;b=7;h=5;i=6;j=4;d=f;k=5;e=f+e|0}a[d+(m+k)>>0]=a[e>>0]|0;f=c[o>>2]|0;a[f+(m+i)>>0]=a[f+(m+j)>>0]|0;f=c[o>>2]|0;a[f+(m+b)>>0]=a[f+(m+h)>>0]|0;b=c[o>>2]|0;h=a[b>>0]|0;if(c[q>>2]&1){a[b+-2>>0]=h;b=c[o>>2]|0;h=a[b+1>>0]|0}a[b+-1>>0]=h;i=c[q>>2]|0;if(!(i&2)){s=0;l=t;return s|0}h=c[r>>2]|0;b=c[s>>2]|0;if(!(i&1)){s=b+p|0;r=c[o>>2]|0;a[r+s>>0]=a[r+(s+-1)>>0]|0;r=c[o>>2]|0;a[r+(s+1)>>0]=a[r+h>>0]|0;r=c[o>>2]|0;a[r+(s+2)>>0]=a[r+(h+1)>>0]|0;r=c[o>>2]|0;a[r+(s+3)>>0]=a[r+(h+2)>>0]|0;s=0;l=t;return s|0}else{q=h<<1;s=((i&4|0)==0?0:b-h<<1)+(b<<1)|0;r=c[o>>2]|0;a[r+s>>0]=a[r+(s+-2)>>0]|0;r=c[o>>2]|0;a[r+(s|1)>>0]=a[r+(s+-1)>>0]|0;r=c[o>>2]|0;a[r+(s+2)>>0]=a[r+q>>0]|0;r=c[o>>2]|0;a[r+(s+3)>>0]=a[r+(q|1)>>0]|0;r=c[o>>2]|0;a[r+(s+4)>>0]=a[r+(q+2)>>0]|0;r=c[o>>2]|0;a[r+(s+5)>>0]=a[r+(q+3)>>0]|0;r=c[o>>2]|0;a[r+(s+6)>>0]=a[r+(q+4)>>0]|0;r=c[o>>2]|0;a[r+(s+7)>>0]=a[r+(q+5)>>0]|0;s=0;l=t;return s|0}return 0}function Vb(b){b=b|0;var c=0,d=0,e=0;c=a[b>>0]|0;e=b+1|0;a[b>>0]=a[e>>0]|0;a[e>>0]=c;e=b+2|0;c=a[e>>0]|0;d=b+3|0;a[e>>0]=a[d>>0]|0;a[d>>0]=c;d=b+4|0;c=a[d>>0]|0;e=b+5|0;a[d>>0]=a[e>>0]|0;a[e>>0]=c;e=b+6|0;c=a[e>>0]|0;d=b+7|0;a[e>>0]=a[d>>0]|0;a[d>>0]=c;d=b+8|0;c=a[d>>0]|0;b=b+10|0;a[d>>0]=a[b>>0]|0;a[b>>0]=c;return}function Wb(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0;i=(f+1|0)/2|0;if((f|0)>0){g=0;h=0;f=c}else return;while(1){c=a[b>>0]|0;j=(d[e+(c&15)>>0]|0)+g|0;a[f>>0]=j;g=(j<<24>>24)+(a[e+((c&255)>>>4&255)>>0]|0)|0;a[f+1>>0]=g;h=h+1|0;if((h|0)>=(i|0))break;else{b=b+1|0;f=f+2|0}}return}function Xb(b,c){b=b|0;c=c|0;if(!c)return;while(1){c=c+-1|0;a[b>>0]=(d[b>>0]|0)<<1;if(!c)break;else b=b+1|0}return}function Yb(b,c){b=b|0;c=c|0;var d=0,e=0,f=0;if((c|0)>0)d=0;else return;while(1){f=a[b>>0]|0;e=b+1|0;a[b>>0]=a[e>>0]|0;a[e>>0]=f;d=d+1|0;if((d|0)==(c|0))break;else b=b+2|0}return}function Zb(c,f,g){c=c|0;f=f|0;g=g|0;var h=0;h=(f|0)==0;if(!g){if(h)return;else g=0;while(1){f=f+-1|0;g=(d[c>>0]|0)+(g&65535)|0;a[c>>0]=g;if(!f)break;else c=c+1|0}return}if(h)return;g=0;while(1){f=f+-1|0;g=(e[c>>1]|0)+(g&65535)|0;b[c>>1]=g;if(!f)break;else c=c+2|0}return}function _b(c,f,g){c=c|0;f=f|0;g=g|0;var h=0;h=(f|0)==0;if(!g){if(h)return;while(1){f=f+-1|0;a[c>>0]=(d[c>>0]|0)+128;if(!f)break;else c=c+1|0}return}if(h)return;while(1){f=f+-1|0;b[c>>1]=(e[c>>1]|0)+32768;if(!f)break;else c=c+2|0}return}function $b(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0;if((c|0)>0)e=0;else return;do{f=b+e|0;h=d[f>>0]|0;g=a[17513+(h>>>1)>>0]|0;a[f>>0]=(h&1|0)==0?g:0-(g&255)&255;e=e+1|0}while((e|0)!=(c|0));return}function ac(d){d=d|0;var e=0,f=0,g=0;f=c[d+48>>2]|0;e=c[d+32>>2]|0;g=c[d+40>>2]|0;e=(e|0)>(g|0)?g:e;g=g-(c[d+36>>2]|0)|0;if(!(c[d+44>>2]&1)){e=f+e|0;if((g|0)>0)f=0;else return;do{a[e+f>>0]=a[e+(0-f)+-1>>0]|0;f=f+1|0}while((f|0)!=(g|0));return}else{e=f+(e<<1)|0;if((g|0)>0)f=0;else return;do{b[e+(f<<1)>>1]=b[e+(0-f<<1)+-2>>1]|0;f=f+1|0}while((f|0)!=(g|0));return}}function bc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+32|0;c=d;if((Zl(c,1,17,a)|0)>>>0>=17?(en(c,17752,17)|0)==0:0){xb(a,b,20);c=0}else c=-1;l=d;return c|0}function cc(d,f,g){d=d|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;v=l;l=l+384|0;p=v+8|0;j=v;x=v+24|0;o=v+360|0;_l(f,g,0)|0;Zl(x,17,1,f)|0;B=x+17|0;Zl(B,20,1,f)|0;Kl(f)|0;w=x+38|0;Zl(w,20,1,f)|0;q=x+58|0;b[q>>1]=Ml(f)|0;n=x+60|0;c[n>>2]=Vl(f)|0;h=x+64|0;b[h>>1]=Ml(f)|0;t=x+66|0;b[t>>1]=Ml(f)|0;s=x+68|0;b[s>>1]=Ml(f)|0;A=x+70|0;b[A>>1]=Ml(f)|0;z=x+72|0;b[z>>1]=Ml(f)|0;y=x+74|0;b[y>>1]=Ml(f)|0;m=x+76|0;b[m>>1]=Ml(f)|0;u=x+78|0;b[u>>1]=Ml(f)|0;x=x+80|0;Zl(x,(c[n>>2]|0)+-20|0,1,f)|0;yo(d,B,20)|0;h=e[h>>1]|0;c[d+156>>2]=h;c[d+160>>2]=e[t>>1];s=e[s>>1]|0;t=d+136|0;c[t>>2]=s;A=e[A>>1]|0;c[d+128>>2]=A;c[d+132>>2]=(O(A,s)|0)+1;s=d+140|0;c[s>>2]=e[z>>1];c[d+148>>2]=e[m>>1];m=d+152|0;c[m>>2]=e[u>>1];u=d+1280|0;c[u>>2]=b[y>>1]<<12&4096|c[u>>2];ap(d+952|0,x|0,h|0)|0;h=o+20|0;a[h>>0]=0;c[j>>2]=w;ao(o,20,17657,j);switch(a[h>>0]|0){case 32:{a[h>>0]=0;i=3;break}case 0:{i=3;break}default:{}}a:do if((i|0)==3){h=o+19|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+18|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+17|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+16|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+15|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+14|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+13|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+12|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+11|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+10|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+9|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+8|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+7|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+6|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+5|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+4|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+3|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+2|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=o+1|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}if((a[o>>0]|0)==32)a[o>>0]=0}while(0);if((c[n>>2]|0)!=275){if(!(a[o>>0]|0)){h=o;i=18559;j=h+12|0;do{a[h>>0]=a[i>>0]|0;h=h+1|0;i=i+1|0}while((h|0)<(j|0))}}else{h=o;i=19399;j=h+16|0;do{a[h>>0]=a[i>>0]|0;h=h+1|0;i=i+1|0}while((h|0)<(j|0))}if((fn(o,17666,19)|0)==0?(k=c[m>>2]|0,(k|0)<11):0)c[m>>2]=((53-(k<<1)|0)*125|0)/33|0;if(!(fn(o,17686,18)|0)){h=o;i=17705;j=h+20|0;do{a[h>>0]=a[i>>0]|0;h=h+1|0;i=i+1|0}while((h|0)<(j|0))}if(!(fn(o,17725,12)|0))c[u>>2]=c[u>>2]|67108864;B=e[q>>1]|0;c[p>>2]=o;c[p+4>>2]=B>>>8;c[p+8>>2]=B&255;Eb(d,17738,p);_l(f,g+60+(c[n>>2]|0)|0,0)|0;B=b[q>>1]|0;h=B&65535;if((B&65535)<260){if((dc(d,h,f)|0)<0){B=-1;l=v;return B|0}if((ec(d,e[q>>1]|0,f)|0)<0){B=-1;l=v;return B|0}}else{if((ec(d,h,f)|0)<0){B=-1;l=v;return B|0}if((dc(d,e[q>>1]|0,f)|0)<0){B=-1;l=v;return B|0}}b:do if((e[q>>1]|0)<260?(r=c[s>>2]|0,(r|0)>0):0){k=d+176|0;m=d+180|0;i=c[k>>2]|0;h=r;j=0;c:while(1){if((c[i+(j*764|0)+36>>2]|0)>0){h=0;do{if((Ub(d,f,1,(c[m>>2]|0)+((c[(c[i+(j*764|0)+756>>2]|0)+(h<<6)+40>>2]|0)*52|0)|0,0)|0)<=-1){h=-1;break c}h=h+1|0;i=c[k>>2]|0}while((h|0)<(c[i+(j*764|0)+36>>2]|0));h=c[s>>2]|0}j=j+1|0;if((j|0)>=(h|0))break b}l=v;return h|0}while(0);if((c[t>>2]|0)>0){h=0;do{c[d+184+(h*12|0)>>2]=128;h=h+1|0}while((h|0)<(c[t>>2]|0))}c[u>>2]=c[u>>2]|704643104;c[d+1284>>2]=1;B=0;l=v;return B|0}function dc(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0;Ra=l;l=l+896|0;Ia=Ra+640|0;Ha=Ra+680|0;Ja=Ra;Qa=f+144|0;c[Qa>>2]=1024;if((nb(f)|0)<0){Qa=-1;l=Ra;return Qa|0}Pa=f+140|0;a:do if((c[Pa>>2]|0)>0){Ka=f+176|0;qa=Ia+4|0;Aa=Ia+26|0;ya=Ia+28|0;za=Ia+32|0;Da=Ha+192|0;ua=Ha+193|0;Fa=Ha+194|0;Ea=Ha+195|0;Ba=Ha+196|0;wa=Ha+197|0;va=Ha+198|0;ta=Ha+199|0;Ga=Ha+200|0;xa=Ha+201|0;Oa=Ha+202|0;Na=Ha+203|0;La=Ha+204|0;Ma=Ha+205|0;Ca=Ha+206|0;sa=Ha+144|0;ra=Ha+96|0;oa=(g|0)>259;g=f+180|0;w=Ha+98|0;H=Ha+100|0;M=Ha+102|0;N=Ha+104|0;O=Ha+106|0;P=Ha+108|0;Q=Ha+110|0;R=Ha+112|0;S=Ha+114|0;x=Ha+116|0;y=Ha+118|0;z=Ha+120|0;A=Ha+122|0;B=Ha+124|0;C=Ha+126|0;D=Ha+128|0;E=Ha+130|0;F=Ha+132|0;G=Ha+134|0;I=Ha+136|0;J=Ha+138|0;K=Ha+140|0;L=Ha+142|0;T=Ha+146|0;ca=Ha+148|0;ha=Ha+150|0;ia=Ha+152|0;ja=Ha+154|0;ka=Ha+156|0;la=Ha+158|0;ma=Ha+160|0;na=Ha+162|0;U=Ha+164|0;V=Ha+166|0;W=Ha+168|0;X=Ha+170|0;Y=Ha+172|0;Z=Ha+174|0;_=Ha+176|0;$=Ha+178|0;aa=Ha+180|0;ba=Ha+182|0;da=Ha+184|0;ea=Ha+186|0;fa=Ha+188|0;ga=Ha+190|0;pa=0;i=0;b:while(1){q=c[Ka>>2]|0;c[Ia>>2]=Vl(h)|0;if(am(h)|0){j=34;break}Zl(qa,22,1,h)|0;a[Aa>>0]=Kl(h)|0;b[ya>>1]=Ml(h)|0;k=Vl(h)|0;c[za>>2]=k;j=b[ya>>1]|0;if((j&65535)>16){j=34;break}if(k>>>0>256&j<<16>>16!=0){j=34;break}vb(c[Ka>>2]|0,pa,qa,22);u=b[ya>>1]|0;v=q+(pa*764|0)+36|0;u=(u&65535)<16?u:16;j=u&65535;c[v>>2]=j;if(u<<16>>16){if((ob(f,pa,j)|0)<0){g=-1;j=36;break}j=c[Ia>>2]|0;if(j>>>0<33){g=-1;j=36;break}if(j>>>0<241){cp(Ha|0,0,208)|0;_l(h,j+-33|0,1)|0}else{Zl(Ha,96,1,h)|0;b[ra>>1]=Ml(h)|0;b[w>>1]=Ml(h)|0;b[H>>1]=Ml(h)|0;b[M>>1]=Ml(h)|0;b[N>>1]=Ml(h)|0;b[O>>1]=Ml(h)|0;b[P>>1]=Ml(h)|0;b[Q>>1]=Ml(h)|0;b[R>>1]=Ml(h)|0;b[S>>1]=Ml(h)|0;b[x>>1]=Ml(h)|0;b[y>>1]=Ml(h)|0;b[z>>1]=Ml(h)|0;b[A>>1]=Ml(h)|0;b[B>>1]=Ml(h)|0;b[C>>1]=Ml(h)|0;b[D>>1]=Ml(h)|0;b[E>>1]=Ml(h)|0;b[F>>1]=Ml(h)|0;b[G>>1]=Ml(h)|0;b[I>>1]=Ml(h)|0;b[J>>1]=Ml(h)|0;b[K>>1]=Ml(h)|0;b[L>>1]=Ml(h)|0;b[sa>>1]=Ml(h)|0;b[T>>1]=Ml(h)|0;b[ca>>1]=Ml(h)|0;b[ha>>1]=Ml(h)|0;b[ia>>1]=Ml(h)|0;b[ja>>1]=Ml(h)|0;b[ka>>1]=Ml(h)|0;b[la>>1]=Ml(h)|0;b[ma>>1]=Ml(h)|0;b[na>>1]=Ml(h)|0;b[U>>1]=Ml(h)|0;b[V>>1]=Ml(h)|0;b[W>>1]=Ml(h)|0;b[X>>1]=Ml(h)|0;b[Y>>1]=Ml(h)|0;b[Z>>1]=Ml(h)|0;b[_>>1]=Ml(h)|0;b[$>>1]=Ml(h)|0;b[aa>>1]=Ml(h)|0;b[ba>>1]=Ml(h)|0;b[da>>1]=Ml(h)|0;b[ea>>1]=Ml(h)|0;b[fa>>1]=Ml(h)|0;b[ga>>1]=Ml(h)|0;a[Da>>0]=Kl(h)|0;a[ua>>0]=Kl(h)|0;a[Fa>>0]=Kl(h)|0;a[Ea>>0]=Kl(h)|0;a[Ba>>0]=Kl(h)|0;a[wa>>0]=Kl(h)|0;a[va>>0]=Kl(h)|0;a[ta>>0]=Kl(h)|0;a[Ga>>0]=Kl(h)|0;a[xa>>0]=Kl(h)|0;a[Oa>>0]=Kl(h)|0;a[Na>>0]=Kl(h)|0;a[La>>0]=Kl(h)|0;a[Ma>>0]=Kl(h)|0;b[Ca>>1]=Ml(h)|0;_l(h,(c[Ia>>2]|0)+-241|0,1)|0;c[q+(pa*764|0)+40>>2]=e[Ca>>1]<<1;m=d[Da>>0]|0;c[q+(pa*764|0)+48>>2]=m;c[q+(pa*764|0)+56>>2]=d[Fa>>0];c[q+(pa*764|0)+64>>2]=d[Ea>>0];c[q+(pa*764|0)+68>>2]=d[Ba>>0];k=d[Ga>>0]|0;n=q+(pa*764|0)+44|0;c[n>>2]=k;j=d[ua>>0]|0;o=q+(pa*764|0)+204|0;c[o>>2]=j;c[q+(pa*764|0)+212>>2]=d[wa>>0];c[q+(pa*764|0)+220>>2]=d[va>>0];c[q+(pa*764|0)+224>>2]=d[ta>>0];p=q+(pa*764|0)+200|0;c[p>>2]=d[xa>>0];if((m+-1|0)>>>0>31)c[n>>2]=k&254;else{ap(q+(pa*764|0)+72|0,ra|0,m<<2|0)|0;j=c[o>>2]|0}if((j+-1|0)>>>0>31){c[p>>2]=c[p>>2]&-2;j=12}else{ap(q+(pa*764|0)+228|0,sa|0,j<<2|0)|0;j=12}do{t=a[Ha+(j+-12)>>0]|0;u=q+(pa*764|0)+512+(j<<1)|0;a[u>>0]=t;a[u>>0]=(t&255|0)<(c[v>>2]|0)?t:-1;j=j+1|0}while((j|0)!=108)}if((c[v>>2]|0)>0){u=q+(pa*764|0)+756|0;t=0;do{m=c[u>>2]|0;k=c[Qa>>2]|0;j=c[g>>2]|0;if((i|0)>=(k|0)){j=ub(j,Qa,(k*3|0)/2|0)|0;c[g>>2]=j;if(!j){g=-1;j=36;break b}}k=Ja+(t*40|0)|0;c[k>>2]=Vl(h)|0;s=Ja+(t*40|0)+4|0;c[s>>2]=Vl(h)|0;o=Ja+(t*40|0)+8|0;c[o>>2]=Vl(h)|0;Ta=Ja+(t*40|0)+12|0;a[Ta>>0]=Kl(h)|0;r=Ja+(t*40|0)+13|0;a[r>>0]=Il(h)|0;n=Ja+(t*40|0)+14|0;a[n>>0]=Kl(h)|0;Sa=Ja+(t*40|0)+15|0;a[Sa>>0]=Kl(h)|0;p=Ja+(t*40|0)+16|0;a[p>>0]=Il(h)|0;a[Ja+(t*40|0)+17>>0]=Kl(h)|0;q=Ja+(t*40|0)+18|0;Zl(q,22,1,h)|0;c[m+(t<<6)>>2]=d[Ta>>0];c[m+(t<<6)+8>>2]=d[Sa>>0];c[m+(t<<6)+12>>2]=a[p>>0];c[m+(t<<6)+16>>2]=a[r>>0];c[m+(t<<6)+20>>2]=d[Oa>>0];c[m+(t<<6)+24>>2]=d[La>>0];c[m+(t<<6)+28>>2]=d[Ma>>0];c[m+(t<<6)+32>>2]=d[Na>>0];c[m+(t<<6)+40>>2]=i;wb(j+(i*52|0)|0,q,22)|0;k=c[k>>2]|0;q=j+(i*52|0)+32|0;c[q>>2]=k;m=c[s>>2]|0;s=j+(i*52|0)+36|0;c[s>>2]=m;o=(c[o>>2]|0)+m|0;r=j+(i*52|0)+40|0;c[r>>2]=o;p=j+(i*52|0)+44|0;c[p>>2]=0;n=a[n>>0]|0;if(!(n&16))j=0;else{c[p>>2]=1;c[q>>2]=k>>1;c[s>>2]=m>>1;c[r>>2]=o>>1;j=1}Ta=n&255;c[p>>2]=Ta<<1&2|j|(Ta&2|0?6:0);t=t+1|0;i=i+1|0;j=c[v>>2]|0}while((t|0)<(j|0));if((j|0)>0){k=0;do{if(oa){if((Ub(f,h,(a[Ja+(k*40|0)+17>>0]|0)==-83?16384:1,(c[g>>2]|0)+((c[(c[u>>2]|0)+(k<<6)+40>>2]|0)*52|0)|0,0)|0)<0){g=-1;j=36;break b}j=c[v>>2]|0}k=k+1|0}while((k|0)<(j|0))}}}else _l(h,(c[Ia>>2]|0)+-33|0,1)|0;j=pa+1|0;if((j|0)<(c[Pa>>2]|0))pa=j;else break a}if((j|0)==34){c[Pa>>2]=pa;break}else if((j|0)==36){l=Ra;return g|0}}else{i=0;g=f+180|0}while(0);Ta=ub(c[g>>2]|0,Qa,i)|0;c[g>>2]=Ta;Ta=((Ta|0)==0)<<31>>31;l=Ra;return Ta|0}function ec(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;x=b+128|0;c[x>>2]=(c[x>>2]|0)+1;if((pb(b)|0)<0){b=-1;return b|0}a:do if((c[x>>2]|0)>1){t=(d|0)>258;u=t?9:8;h=b+136|0;w=b+172|0;v=b+168|0;f=0;while(1){d=Vl(e)|0;Kl(e)|0;if(t)g=(Ml(e)|0)&65535;else g=((Kl(e)|0)&255)+1|0;i=Ml(e)|0;_l(e,d-u|0,1)|0;d=g&65535;d=(d|0)==0?256:d;if((tb(b,f,d)|0)<0){d=-1;y=54;break}if(i<<16>>16){s=i&65535;r=Qm(1,s)|0;if(!r){d=-1;y=54;break}Zl(r,1,s,e)|0;q=c[h>>2]|0;o=O(q,d)|0;b:do if((o|0)>0){p=r;n=0;i=r;while(1){if((i-p|0)>=(s|0))break b;l=c[(c[w>>2]|0)+(c[(c[(c[v>>2]|0)+(f<<2)>>2]|0)+4+(((n|0)%(q|0)|0)<<2)>>2]<<2)>>2]|0;m=(n|0)/(q|0)|0;k=l+4+(m<<3)|0;d=i+1|0;g=a[i>>0]|0;j=g&255;if(j&128){if(j&1){a[k>>0]=a[d>>0]|0;d=i+2|0}if(j&2){a[l+4+(m<<3)+1>>0]=a[d>>0]|0;d=d+1|0}if(j&4){a[l+4+(m<<3)+2>>0]=a[d>>0]|0;d=d+1|0}if(j&8){a[l+4+(m<<3)+3>>0]=a[d>>0]|0;d=d+1|0}if(!(j&16))i=d;else{g=d;d=d+1|0;y=26}}else{a[k>>0]=g;a[l+4+(m<<3)+1>>0]=a[d>>0]|0;a[l+4+(m<<3)+2>>0]=a[i+2>>0]|0;a[l+4+(m<<3)+3>>0]=a[i+3>>0]|0;g=i+4|0;d=i+5|0;y=26}if((y|0)==26){y=0;a[l+4+(m<<3)+4>>0]=a[g>>0]|0;i=d}d=a[k>>0]|0;switch(d<<24>>24){case 97:{d=-127;y=29;break}case 0:break;default:{d=(d&255)+12&255;y=29}}if((y|0)==29){y=0;a[k>>0]=d}j=l+4+(m<<3)+2|0;d=a[j>>0]|0;if(d<<24>>24){g=d&255;c:do if((d+-16&255)<65)d=g+241&255;else{do switch((d&255)>>>4&15){case 6:{a[l+4+(m<<3)+5>>0]=-92;d=g+-96|0;break}case 7:{a[l+4+(m<<3)+5>>0]=-92;d=(g<<4)+-1792|0;break}case 8:{a[l+4+(m<<3)+5>>0]=14;d=g+-128|176;break}case 9:{a[l+4+(m<<3)+5>>0]=14;d=g+-144|160;break}case 10:{a[l+4+(m<<3)+5>>0]=4;d=(g<<4)+-2560|0;break}case 11:{a[l+4+(m<<3)+5>>0]=4;d=g+-176|0;break}case 12:{a[l+4+(m<<3)+5>>0]=8;d=(g<<4)+-3072|0;break}case 13:{a[l+4+(m<<3)+5>>0]=25;d=(g<<4)+-3328|0;break}case 14:{a[l+4+(m<<3)+5>>0]=25;d=g+-224|0;break}case 15:{a[l+4+(m<<3)+5>>0]=3;d=g<<4;break}default:{d=0;break c}}while(0);a[l+4+(m<<3)+6>>0]=d;d=0}while(0);a[j>>0]=d}n=n+1|0;if((n|0)>=(o|0))break b}}while(0);Pm(r)}f=f+1|0;if((f|0)>=((c[x>>2]|0)+-1|0))break a}if((y|0)==54)return d|0}else{h=b+136|0;f=0}while(0);g=O(c[h>>2]|0,f)|0;if((qb(b,f)|0)<0){b=-1;return b|0}d=b+168|0;c[c[(c[d>>2]|0)+(f<<2)>>2]>>2]=64;if((rb(b,g,64)|0)<0){b=-1;return b|0}if((c[h>>2]|0)<=0){b=0;return b|0}d=c[(c[d>>2]|0)+(f<<2)>>2]|0;f=0;do{c[d+4+(f<<2)>>2]=g;f=f+1|0}while((f|0)<(c[h>>2]|0));d=0;return d|0}function fc(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0;k=l;l=l+80|0;f=k+76|0;j=k;_l(b,e+1080|0,0)|0;if((Zl(f,1,4,b)|0)>>>0<4){d=-1;l=k;return d|0}if(!((((fn(f+2|0,17858,2)|0)==0?(g=a[f>>0]|0,(g+-48|0)>>>0<10):0)?(h=a[f+1>>0]|0,(h+-48|0)>>>0<10):0)?(h=(g*10|0)+-480+h|0,(h|0)>48&(h+-48|0)<33):0))i=6;do if((i|0)==6){if((fn(f+1|0,17861,3)|0)==0?(i=a[f>>0]|0,!(i<<24>>24==48|((i<<24>>24)+-48|0)>>>0>9)):0)break;if((((((((((((en(f,21197,4)|0?en(f,17770,4)|0:0)?en(f,17775,4)|0:0)?en(f,17780,4)|0:0)?en(f,17785,4)|0:0)?en(f,17790,4)|0:0)?en(f,17795,4)|0:0)?en(f,17800,4)|0:0)?en(f,17805,4)|0:0)?en(f,17810,4)|0:0)?en(f,17815,4)|0:0)?en(f,17820,4)|0:0)?en(f,17825,4)|0:0){d=-1;l=k;return d|0}g=e+20|0;_l(b,g,0)|0;f=0;while(1){_l(b,22,1)|0;if((Pl(b)|0)<<16>>16<0){f=-1;i=24;break}if(((Kl(b)|0)&255)>15){f=-1;i=24;break}if(((Kl(b)|0)&255)>64){f=-1;i=24;break}if((Pl(b)|0)<<16>>16<0){f=-1;i=24;break}f=f+1|0;if((Pl(b)|0)<<16>>16<0){f=-1;i=24;break}if((f|0)>=31){i=17;break}}if((i|0)==17){if(c[b>>2]|0)break;fm(b,j)|0;_l(b,g,0)|0;f=0;h=0;do{_l(b,22,1)|0;h=(((Pl(b)|0)&65535)<<1)+h|0;_l(b,6,1)|0;f=f+1|0}while((f|0)!=31);_l(b,e+952|0,0)|0;f=0;g=0;do{i=Kl(b)|0;m=i&255;i=i<<24>>24<0;g=i?g:(m|0)>(g|0)?m:g;f=f+1|0}while((f|0)<128&(i^1));if((e+1852+h+(g*768|0)|0)==(c[j+36>>2]|0))f=-1;else break;l=k;return f|0}else if((i|0)==24){l=k;return f|0}}while(0);_l(b,e,0)|0;xb(b,d,20);m=0;l=k;return m|0}function gc(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0;J=l;l=l+5520|0;I=J+24|0;B=J+16|0;z=J+8|0;v=J+32|0;x=J+5504|0;E=J+1408|0;A=J;s=J+1376|0;H=J+1120|0;cp(E|0,0,4096)|0;_l(g,h,0)|0;r=f+140|0;c[r>>2]=31;G=f+144|0;c[G>>2]=31;D=f+136|0;c[D>>2]=0;F=f+1280|0;c[F>>2]=c[F>>2]|8192;Zl(v,20,1,g)|0;i=0;t=0;do{Zl(v+20+(i*30|0)|0,22,1,g)|0;w=v+20+(i*30|0)+22|0;b[w>>1]=Pl(g)|0;a[v+20+(i*30|0)+24>>0]=Kl(g)|0;a[v+20+(i*30|0)+25>>0]=Kl(g)|0;b[v+20+(i*30|0)+26>>1]=Pl(g)|0;b[v+20+(i*30|0)+28>>1]=Pl(g)|0;t=(e[w>>1]<<1)+t|0;i=i+1|0}while((i|0)!=31);n=v+950|0;a[n>>0]=Kl(g)|0;u=v+951|0;a[u>>0]=Kl(g)|0;o=v+952|0;Zl(o,128,1,g)|0;w=A;c[w>>2]=0;c[w+4>>2]=0;Zl(A,4,1,g)|0;if(fn(A,21197,4)|0)if(fn(A,17770,4)|0)if(fn(A,17775,4)|0)if(fn(A,17780,4)|0)if(fn(A,17785,4)|0)if(fn(A,17790,4)|0)if(fn(A,17795,4)|0)if(fn(A,17800,4)|0)if(fn(A,17805,4)|0)if(fn(A,17810,4)|0)if(fn(A,17815,4)|0)if(fn(A,17820,4)|0)if(fn(A,17825,4)|0)if(!(c[D>>2]|0)){if(((fn(A+2|0,17858,2)|0)==0?(j=a[A>>0]|0,(j+-48|0)>>>0<10):0)?(k=a[A+1>>0]|0,(k+-48|0)>>>0<10):0)i=(j*10|0)+-480+k|0;else{if(fn(A+1|0,17861,3)|0){I=-1;l=J;return I|0}i=a[A>>0]|0;if((i+-48|0)>>>0>=10){I=-1;l=J;return I|0}}m=i+-48|0;c[D>>2]=m;c[F>>2]=c[F>>2]&-8193;p=1;m=m<<1&2|4}else{p=0;m=0}else{i=4;j=12;y=4}else{i=8;j=11;y=4}else{i=6;j=10;y=4}else{i=4;j=9;y=4}else{i=4;j=8;y=4}else{i=8;j=7;y=4}else{i=6;j=6;y=4}else{i=8;j=5;y=4}else{i=6;j=4;y=4}else{i=4;j=3;y=4}else{i=4;j=2;y=4}else{i=4;j=1;y=4}else{i=4;j=0;y=4}if((y|0)==4){c[D>>2]=i;p=c[1060+(j<<4)+4>>2]|0;m=c[1060+(j<<4)+8>>2]|0}yo(f,v,20)|0;y=d[n>>0]|0;c[f+156>>2]=y;q=f+160|0;if((c[q>>2]|0)>=(y|0))c[q>>2]=0;k=f+952|0;i=o;j=k+128|0;do{b[k>>1]=b[i>>1]|0;k=k+2|0;i=i+2|0}while((k|0)<(j|0));w=f+128|0;i=c[w>>2]|0;k=0;do{y=a[f+952+k>>0]|0;j=y&255;if(y<<24>>24<0)break;if((j|0)>(i|0)){c[w>>2]=j;i=j}k=k+1|0}while((k|0)<128);c[w>>2]=i+1;if((nb(f)|0)<0){I=-1;l=J;return I|0}a:do if((c[r>>2]|0)>0){k=f+180|0;j=f+176|0;i=0;while(1){if((ob(f,i,1)|0)<0){i=-1;break}K=e[v+20+(i*30|0)+22>>1]<<1;y=c[k>>2]|0;c[y+(i*52|0)+32>>2]=K;o=e[v+20+(i*30|0)+26>>1]<<1;c[y+(i*52|0)+36>>2]=o;n=b[v+20+(i*30|0)+28>>1]|0;o=((n&65535)<<1)+o|0;o=o>>>0>K>>>0?K:o;c[y+(i*52|0)+40>>2]=o;c[y+(i*52|0)+44>>2]=(n&65535)>1&(o|0)>3?2:0;y=c[j>>2]|0;o=c[y+(i*764|0)+756>>2]|0;c[o+16>>2]=d[v+20+(i*30|0)+24>>0]<<28>>24;c[o>>2]=a[v+20+(i*30|0)+25>>0];c[o+8>>2]=128;c[o+40>>2]=i;vb(y,i,v+20+(i*30|0)|0,22);if((c[(c[k>>2]|0)+(i*52|0)+32>>2]|0)>0)c[(c[j>>2]|0)+(i*764|0)+36>>2]=1;i=i+1|0;if((i|0)>=(c[r>>2]|0))break a}l=J;return i|0}while(0);b:do if(!p){K=t+1084+(O(c[w>>2]<<8,c[D>>2]|0)|0)|0;i=f+1240|0;if((K|0)<(c[i>>2]|0)?(K=$l(g)|0,_l(g,h+1084+t+(O(c[w>>2]<<8,c[D>>2]|0)|0)|0,0)|0,Zl(s,1,4,g)|0,_l(g,K+h|0,0)|0,(en(s,17865,4)|0)==0):0){r=0;m=8;break}if((fn(A,21197,4)|0)==0?((c[w>>2]<<11|1084)+t|0)==(c[i>>2]|0):0){c[D>>2]=8;r=0;m=9;break}if(!(fn(A,21197,4)|0)){K=((c[w>>2]<<10)+1084|0)==(c[i>>2]|0);i=K&1;if(K){r=i;m=0;break}else o=i}else o=0;n=c[D>>2]|0;j=(n|0)==4;k=a[u>>0]|0;if(j)if((k&255|0)!=(c[w>>2]|0))if(k<<24>>24==120){m=20;y=41}else y=39;else{m=2;y=41}else y=39;do if((y|0)==39){if((k&255)<127){c[q>>2]=k&255;m=j?1:99;y=41;break}i=k<<24>>24==127;if((n|0)!=4&i){c[F>>2]=c[F>>2]&-8193;c[f+1284>>2]=2;r=o;m=10;break b}}while(0);if((y|0)==41)i=k<<24>>24==127;c:do if(j&i){i=0;do{if(!(b[v+20+(i*30|0)+28>>1]|0)){m=98;break c}i=i+1|0}while((i|0)<31)}while(0);if(k<<24>>24!=120&(k&255)<127){i=0;while(1){if(!(b[v+20+(i*30|0)+28>>1]|0)){i=15;break}i=i+1|0;if((i|0)>=31){y=50;break}}if((y|0)==50)if((i|0)==31){i=0;while(1){if((b[v+20+(i*30|0)+22>>1]|0)==1?(a[v+20+(i*30|0)+25>>0]|0)==0:0){r=o;m=97;break b}i=i+1|0;if((i|0)>=31){i=0;break}}do{if(hc(v+20+(i*30|0)|0)|0){r=o;break b}i=i+1|0}while((i|0)<31);if((i|0)==31)i=0;else{r=o;break}while(1){if((b[v+20+(i*30|0)+22>>1]|0)==0?(b[v+20+(i*30|0)+28>>1]|0)==1:0){y=59;break}i=i+1|0;if((i|0)>=31){y=63;break}}if((y|0)==59)switch(n|0){case 4:{r=o;m=1;break b}case 8:case 6:{r=o;m=5;break b}default:{r=o;m=99;break b}}else if((y|0)==63)switch(n|0){case 4:{r=o;m=0;break b}case 8:case 6:{c[F>>2]=c[F>>2]&-8193;r=o;m=3;break b}default:{r=o;m=99;break b}}}else i=15;while(1){if(Zn(v+20+(i*30|0)|0)|0){i=0;break}if(b[v+20+(i*30|0)+22>>1]|0){i=0;break}i=i+1|0;if((i|0)>=31){y=69;break}}if((y|0)==69)if((i|0)==31?(hc(v+440|0)|0)!=0:0){r=o;m=96;break}else i=0;do{if(hc(v+20+(i*30|0)|0)|0){r=o;m=95;break b}i=i+1|0}while((i|0)<31);switch(n|0){case 8:case 6:case 4:break;default:{r=o;m=99;break b}}c[F>>2]=c[F>>2]&-8193;r=o;m=3}else r=o}else r=0;while(0);c[f+132>>2]=O(c[w>>2]|0,c[D>>2]|0)|0;if((pb(f)|0)<0){K=-1;l=J;return K|0}d:do if((c[w>>2]|0)>0){q=f+172|0;p=f+168|0;k=x+2|0;n=x+3|0;o=0;while(1){if((tb(f,o,64)|0)<0){i=-1;break}i=c[D>>2]|0;e:do if((i|0)>0){j=0;while(1){i=(c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+(((j|0)%(i|0)|0)<<2)>>2]<<2)>>2]|0)+4+(((j|0)/(i|0)|0)<<3)|0;Zl(x,1,4,g)|0;switch(m|0){case 20:{K=a[k>>0]&15;if((K+-7&255)>=3?K<<24>>24!=14|(a[n>>0]&14)==0:0){m=20;y=83}else{m=99;y=84}break}case 1:{m=1;y=83;break}default:y=84}if((y|0)==83)zb(i,x);else if((y|0)==84)Bb(i,x);j=j+1|0;i=c[D>>2]|0;if((j|0)>=(i<<6|0))break e}}while(0);o=o+1|0;if((o|0)>=(c[w>>2]|0))break d}l=J;return i|0}while(0);do switch(m|0){case 0:{i=1;j=17870;y=99;break}case 1:case 20:{i=1;j=17984;y=100;break}case 2:{i=1;j=19363;y=99;break}case 4:case 3:{i=0;j=17881;y=99;break}case 6:{i=0;j=17894;y=99;break}case 5:{i=0;j=17907;y=99;break}case 7:{i=0;j=20630;y=99;break}case 8:{i=0;j=17917;y=99;break}case 9:{k=f+64|0;i=0;j=17997;y=101;break}case 10:{i=0;j=17926;y=99;break}case 97:case 96:{i=0;j=17941;y=99;break}case 98:{i=0;j=17951;y=99;break}default:{i=0;j=17968;y=100}}while(0);if((y|0)==99){k=f+64|0;y=102}else if((y|0)==100){k=f+64|0;if((m|0)==9)y=101;else y=102}if((y|0)==101){c[z>>2]=j;ao(k,64,21202,z);k=i}else if((y|0)==102){c[B>>2]=j;c[B+4>>2]=A;ao(k,64,18009,B);k=i}i=c[f+1216>>2]|0;if(i|0?(C=vo(i,47)|0,C|0):0)yo(E,i,C-i|0)|0;f:do if((c[G>>2]|0)>0){q=f+180|0;p=k|0?512:0;n=(r|0)==0;m=p|16384;o=f+176|0;k=0;g:while(1){do if(c[(c[q>>2]|0)+(k*52|0)+32>>2]|0){if(!n){i=(c[o>>2]|0)+(k*764|0)|0;c[I>>2]=E;c[I+4>>2]=i;ao(H,64,21386,I);i=bm(H,21621)|0;if(i|0?(K=(Ub(f,i,p,(c[q>>2]|0)+(k*52|0)|0,0)|0)<0,dm(i),K):0)break g;break}i=$l(g)|0;if((Zl(H,1,5,g)|0)==5?(en(H,18015,5)|0)==0:0)i=m;else{_l(g,i,0)|0;i=p}if((Ub(f,g,i,(c[q>>2]|0)+(k*52|0)|0,0)|0)<=-1){i=-1;y=123;break g}}while(0);k=k+1|0;if((k|0)>=(c[G>>2]|0))break f}if((y|0)==123){l=J;return i|0}K=-1;l=J;return K|0}while(0);if((c[D>>2]|0)>4){c[F>>2]=c[F>>2]&-704651297|704643104;c[f+1284>>2]=1;K=0;l=J;return K|0}if(dn(j,17870)|0){K=0;l=J;return K|0}c[F>>2]=c[F>>2]|4;K=0;l=J;return K|0}function hc(b){b=b|0;switch(a[b>>0]|0){case 83:case 115:break;default:return 0}switch(a[b+1>>0]|0){case 84:case 116:break;default:return 0}if((a[b+2>>0]|0)!=45)return 0;if((a[b+5>>0]|0)!=58)return 0;if(((a[b+3>>0]|0)+-48|0)>>>0<10)return ((a[b+4>>0]|0)+-48|0)>>>0<10|0;else return 0;return 0}function ic(a,b,c){a=a|0;b=b|0;c=c|0;_l(a,c+44|0,0)|0;if((Xl(a)|0)!=1396920909){b=-1;return b|0}_l(a,c,0)|0;xb(a,b,28);b=0;return b|0}function jc(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0;ea=l;l=l+368|0;D=ea+56|0;A=ea+48|0;y=ea+40|0;x=ea+32|0;w=ea+24|0;B=ea+16|0;z=ea+8|0;v=ea;H=ea+360|0;o=ea+224|0;da=ea+144|0;ca=ea+64|0;C=ea+320|0;_l(g,h,0)|0;Zl(o,28,1,g)|0;Kl(g)|0;a[o+29>>0]=Kl(g)|0;Ml(g)|0;p=o+32|0;b[p>>1]=Ml(g)|0;q=o+34|0;b[q>>1]=Ml(g)|0;r=o+36|0;b[r>>1]=Ml(g)|0;k=o+38|0;b[k>>1]=Ml(g)|0;u=o+40|0;b[u>>1]=Ml(g)|0;ba=o+42|0;b[ba>>1]=Ml(g)|0;c[o+44>>2]=Xl(g)|0;a[o+48>>0]=Kl(g)|0;m=o+49|0;a[m>>0]=Kl(g)|0;n=o+50|0;a[n>>0]=Kl(g)|0;t=o+51|0;a[t>>0]=Kl(g)|0;a[o+52>>0]=Kl(g)|0;s=o+53|0;a[s>>0]=Kl(g)|0;Vl(g)|0;Vl(g)|0;b[o+62>>1]=Ml(g)|0;Zl(o+64|0,32,1,g)|0;if((b[u>>1]|0)==4865?(a[o+27>>0]|0)==-121:0){j=0;do{i=o+j|0;if((a[i>>0]|0)==-121)a[i>>0]=0;j=j+1|0}while((j|0)!=28);if((a[r>>0]|0)==-121)a[r>>0]=0;i=r+1|0;if((a[i>>0]|0)==-121)a[i>>0]=0;if((a[k>>0]|0)==-121)a[k>>0]=0;i=k+1|0;if((a[i>>0]|0)==-121){a[i>>0]=0;aa=1}else aa=1}else aa=0;wb(f,o,28)|0;_=Qm(2,e[q>>1]|0)|0;if(!_){h=-1;l=ea;return h|0}$=Qm(2,e[r>>1]|0)|0;if($|0){i=e[k>>1]|0;if(i&16|0){Z=f+1280|0;c[Z>>2]=c[Z>>2]|8192}if(i&64|0){Z=f+1280|0;c[Z>>2]=c[Z>>2]|64}c[f+148>>2]=d[m>>0];c[f+152>>2]=d[n>>0];G=f+136|0;m=(a[t>>0]|0)<0;j=0;do{i=a[o+64+j>>0]|0;k=j;j=j+1|0;if(i<<24>>24!=-1){c[G>>2]=j;c[f+184+(k*12|0)>>2]=m?((i&8)<8?48:192):128}}while((j|0)!=32);Z=b[p>>1]|0;i=Z&65535;j=f+156|0;if((Z&65535)<257){c[j>>2]=i;Zl(f+952|0,1,i,g)|0}else{c[j>>2]=256;Zl(f+952|0,1,256,g)|0;_l(g,(e[p>>1]|0)+-256|0,1)|0}F=f+128|0;c[F>>2]=-1;k=c[j>>2]|0;a:do if((k|0)>0){j=-1;m=0;do{i=a[f+952+m>>0]|0;if(i<<24>>24==-1)break a;i=i&255;if((i|0)>(j|0)){c[F>>2]=i;j=i}m=m+1|0}while((m|0)<(k|0))}else j=-1;while(0);i=b[r>>1]|0;Y=i&65535;Y=(j|0)<(Y|0)?j+1|0:Y;c[F>>2]=Y;c[f+132>>2]=O(Y,c[G>>2]|0)|0;Y=b[q>>1]|0;X=Y&65535;Z=f+140|0;c[Z>>2]=X;c[f+144>>2]=X;if(Y<<16>>16){i=0;do{b[_+(i<<1)>>1]=Ml(g)|0;i=i+1|0}while((i|0)<(e[q>>1]|0));i=b[r>>1]|0}if(i<<16>>16){i=0;do{b[$+(i<<1)>>1]=Ml(g)|0;i=i+1|0}while((i|0)<(e[r>>1]|0))}Y=(d[s>>0]|0)+4&255;a[s>>0]=Y;if(!(Y<<24>>24)){j=0;do{i=(Kl(g)|0)&255;if(!(i&32))i=(a[t>>0]&127)==0?128:(0-(j&1)&160)+48|0;else i=i<<4&240;c[f+184+(j*12|0)>>2]=i;j=j+1|0}while((j|0)<32&(a[s>>0]|0)==0)}c[f+1264>>2]=8363;i=b[u>>1]|0;j=i&65535;if(i<<16>>16==4864){Y=f+1280|0;c[Y>>2]=c[Y>>2]|64}b:do switch((i&65535)>>>12&15){case 1:{c[v>>2]=j>>>8&15;c[v+4>>2]=j&255;ao(C,40,18038,v);Y=f+1280|0;c[Y>>2]=c[Y>>2]|16;break}case 2:{c[z>>2]=j>>>8&15;c[z+4>>2]=j&255;ao(C,40,18061,z);break}case 3:switch(i<<16>>16){case 12822:{i=C;j=18682;k=i+23|0;do{a[i>>0]=a[j>>0]|0;i=i+1|0;j=j+1|0}while((i|0)<(k|0));break b}case 12823:{i=C;j=18705;k=i+23|0;do{a[i>>0]=a[j>>0]|0;i=i+1|0;j=j+1|0}while((i|0)<(k|0));break b}default:{c[B>>2]=j>>>8&15;c[B+4>>2]=j&255;ao(C,40,18747,B);break b}}case 5:{c[w>>2]=j>>>8&15;c[w+4>>2]=j&255;ao(C,40,18859,w);break}case 4:{if(i<<16>>16==16640)E=51;else{c[x>>2]=j>>>8&15;c[x+4>>2]=j&255;ao(C,40,18083,x)}break}case 6:{E=51;break}default:{c[A>>2]=j;ao(C,40,18794,A)}}while(0);if((E|0)==51){c[y>>2]=j>>>8&15;c[y+4>>2]=j&255;ao(C,40,18891,y)}c[D>>2]=C;Eb(f,18106,D);c:do if((pb(f)|0)>=0){if((c[F>>2]|0)>0){p=f+168|0;q=f+172|0;o=0;do{if((tb(f,o,64)|0)<0)break c;i=b[$+(o<<1)>>1]|0;d:do if(i<<16>>16){_l(g,((i&65535)<<4)+h|0,0)|0;i=((Ml(g)|0)&65535)+-2|0;if((i|0)>-1)j=0;else break;do{if((j|0)>=(c[c[(c[p>>2]|0)+(o<<2)>>2]>>2]|0))break d;while(1){k=Kl(g)|0;if(k<<24>>24)break;j=j+1|0;if((j|0)>=(c[c[(c[p>>2]|0)+(o<<2)>>2]>>2]|0))break d}n=k&255;k=n&31;if((k|0)<(c[G>>2]|0))m=(c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+(k<<2)>>2]<<2)>>2]|0)+4+(j<<3)|0;else m=H;if(n&32){Y=Kl(g)|0;k=Y&255;switch(Y<<24>>24){case -1:{k=0;break}case -2:{k=-127;break}default:k=(k&15)+13+((k>>>4)*12|0)&255}a[m>>0]=k;a[m+1>>0]=Kl(g)|0;i=i+-2|0}if(n&64){a[m+2>>0]=((Kl(g)|0)&255)+1;i=i+-1|0}if(n&128){a[m+3>>0]=Kl(g)|0;a[m+4>>0]=Kl(g)|0;kc(m);i=i+-2|0}}while((i|0)>-1)}while(0);o=o+1|0}while((o|0)<(c[F>>2]|0))}if((nb(f)|0)>=0){e:do if((c[Z>>2]|0)>0){X=f+176|0;Y=f+180|0;o=ca+12|0;p=ca+15|0;V=ca+27|0;F=ca+28|0;D=ca+32|0;q=ca+36|0;r=ca+48|0;P=ca+76|0;R=da+14|0;L=da+16|0;M=da+20|0;N=da+24|0;W=da+28|0;T=da+29|0;S=da+30|0;G=da+31|0;E=da+32|0;U=da+34|0;s=da+36|0;J=da+40|0;I=da+42|0;K=da+44|0;t=da+48|0;Q=da+76|0;u=L+1|0;v=L+2|0;w=L+3|0;x=M+1|0;y=M+2|0;z=M+3|0;A=N+1|0;B=N+2|0;C=N+3|0;H=0;f:while(1){j=c[X>>2]|0;k=c[Y>>2]|0;n=k+(H*52|0)|0;m=Qm(64,1)|0;c[j+(H*764|0)+756>>2]=m;if(!m)break c;_l(g,(e[_+(H<<1)>>1]<<4)+h|0,0)|0;i=Kl(g)|0;c[m+8>>2]=128;c[m+40>>2]=H;if((i&255)>1){Zl(ca,12,1,g)|0;Zl(o,3,1,g)|0;Zl(p,12,1,g)|0;a[V>>0]=Kl(g)|0;a[F>>0]=Kl(g)|0;Ml(g)|0;b[D>>1]=Ml(g)|0;Ml(g)|0;Zl(q,12,1,g)|0;Zl(r,28,1,g)|0;k=Xl(g)|0;c[P>>2]=k;if((k|0)!=1396920905)break c;c[P>>2]=0;vb(c[X>>2]|0,H,r,28);c[j+(H*764|0)+36>>2]=1;c[m>>2]=d[V>>0];j=m+12|0;mi(e[D>>1]|0,j,m+16|0);c[j>>2]=(c[j>>2]|0)+12;j=60;i=Ub(f,g,4096,n,p)|0}else{Zl(da,13,1,g)|0;b[R>>1]=Ml(g)|0;c[L>>2]=Vl(g)|0;c[M>>2]=Vl(g)|0;c[N>>2]=Vl(g)|0;a[W>>0]=Kl(g)|0;a[T>>0]=Kl(g)|0;a[S>>0]=Kl(g)|0;a[G>>0]=Kl(g)|0;b[E>>1]=Ml(g)|0;b[U>>1]=Ml(g)|0;Zl(s,4,1,g)|0;b[J>>1]=Ml(g)|0;b[I>>1]=Ml(g)|0;c[K>>2]=Vl(g)|0;Zl(t,28,1,g)|0;fa=Xl(g)|0;c[Q>>2]=fa;if(!(i<<24>>24!=1|(fa|0)==1396920915))break c;do if(aa){if((a[L>>0]|0)==-121)a[L>>0]=0;if((a[u>>0]|0)==-121)a[u>>0]=0;if((a[v>>0]|0)==-121)a[v>>0]=0;if((a[w>>0]|0)==-121)a[w>>0]=0;if((a[M>>0]|0)==-121)a[M>>0]=0;if((a[x>>0]|0)==-121)a[x>>0]=0;if((a[y>>0]|0)==-121)a[y>>0]=0;if((a[z>>0]|0)==-121)a[z>>0]=0;if((a[N>>0]|0)==-121)a[N>>0]=0;if((a[A>>0]|0)==-121)a[A>>0]=0;if((a[B>>0]|0)==-121)a[B>>0]=0;if((a[C>>0]|0)==-121)a[C>>0]=0;i=a[G>>0]|0;if(i<<24>>24!=-121)break;a[G>>0]=0;i=0}else i=a[G>>0]|0;while(0);fa=c[L>>2]|0;c[k+(H*52|0)+32>>2]=fa;c[j+(H*764|0)+36>>2]=(fa|0)!=0&1;c[k+(H*52|0)+36>>2]=c[M>>2];c[k+(H*52|0)+40>>2]=c[N>>2];c[k+(H*52|0)+44>>2]=((i&255)>>>2&1|i<<1&2)&255;c[m>>2]=d[W>>0];c[Q>>2]=0;vb(c[X>>2]|0,H,t,28);mi(e[E>>1]|0,m+12|0,m+16|0);_l(g,(e[R>>1]<<4)+h|0,0)|0;j=0;i=Ub(f,g,(e[ba>>1]<<1)+-2|0,n,0)|0}switch(((i|0)<0?43:j)&63){case 43:break c;case 60:case 0:break;default:{i=0;break f}}H=H+1|0;if((H|0)>=(c[Z>>2]|0))break e}l=ea;return i|0}while(0);Pm($);Pm(_);c[f+6556>>2]=7212;fa=f+1280|0;c[fa>>2]=c[fa>>2]|293601825;c[f+1284>>2]=2;fa=0;l=ea;return fa|0}}while(0);Pm($)}Pm(_);fa=-1;l=ea;return fa|0}function kc(b){b=b|0;var c=0,e=0,f=0,g=0,h=0;g=b+4|0;c=a[g>>0]|0;f=c&255;e=f&15;b=b+3|0;h=a[18113+(d[b>>0]|0)>>0]|0;a[b>>0]=h;switch(h<<24>>24){case -2:{a[b>>0]=14;switch((c&255)>>>4&15){case 1:{a[g>>0]=e|48;return}case 2:{a[g>>0]=e|80;return}case 3:{a[g>>0]=e|64;return}case 4:{a[g>>0]=e|112;return}case 10:case 9:case 7:case 6:case 5:{a[g>>0]=0;a[b>>0]=0;return}case 8:{a[b>>0]=8;a[g>>0]=f<<4;return}case 11:{a[g>>0]=e|96;return}case 12:{if(e|0)return;a[g>>0]=0;a[b>>0]=0;return}default:return}}case -1:{a[g>>0]=0;a[b>>0]=0;return}default:return}}function lc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;e=l;l=l+16|0;d=e;_l(a,c+20|0,0)|0;do if((Zl(d,1,8,a)|0)>>>0>=8){if(en(d,19008,8)|0?en(d,18962,8)|0:0){d=-1;break}Kl(a)|0;if((Kl(a)|0)<<24>>24==2?(Kl(a)|0)<<24>>24!=0:0){_l(a,c,0)|0;xb(a,b,20);d=0}else d=-1}else d=-1;while(0);l=e;return d|0}function mc(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;v=l;l=l+1184|0;p=v+8|0;o=v;q=v+16|0;_l(g,h,0)|0;Zl(q,20,1,g)|0;h=q+20|0;Zl(h,8,1,g)|0;a[q+28>>0]=Kl(g)|0;a[q+29>>0]=Kl(g)|0;m=q+30|0;a[m>>0]=Kl(g)|0;n=q+31|0;a[n>>0]=Kl(g)|0;k=q+32|0;a[k>>0]=Kl(g)|0;j=q+33|0;a[j>>0]=Kl(g)|0;a[q+34>>0]=Kl(g)|0;Zl(q+35|0,13,1,g)|0;i=0;do{Zl(q+48+(i*36|0)|0,12,1,g)|0;a[q+48+(i*36|0)+12>>0]=Kl(g)|0;a[q+48+(i*36|0)+13>>0]=Kl(g)|0;b[q+48+(i*36|0)+14>>1]=Ml(g)|0;b[q+48+(i*36|0)+16>>1]=Ml(g)|0;b[q+48+(i*36|0)+18>>1]=Ml(g)|0;b[q+48+(i*36|0)+20>>1]=Ml(g)|0;a[q+48+(i*36|0)+22>>0]=Kl(g)|0;a[q+48+(i*36|0)+23>>0]=Kl(g)|0;b[q+48+(i*36|0)+24>>1]=Ml(g)|0;c[q+48+(i*36|0)+28>>2]=Vl(g)|0;b[q+48+(i*36|0)+32>>1]=Ml(g)|0;i=i+1|0}while((i|0)!=31);i=(fn(h,18962,8)|0)==0;u=d[j>>0]|0;s=f+128|0;c[s>>2]=u;r=f+136|0;c[f+132>>2]=O(c[r>>2]|0,u)|0;c[f+148>>2]=(d[k>>0]|0)>>>4;u=f+140|0;c[u>>2]=31;c[f+144>>2]=31;c[f+1264>>2]=8363;wb(f,q,20)|0;h=f+64|0;if(i)ao(h,64,18157,o);else{o=d[n>>0]|0;c[p>>2]=d[m>>0];c[p+4>>2]=o;ao(h,64,18170,p)}if((nb(f)|0)<0){f=-1;l=v;return f|0}a:do if((c[u>>2]|0)>0){k=f+180|0;j=f+176|0;i=0;while(1){if((ob(f,i,1)|0)<0){h=-1;break}p=b[q+48+(i*36|0)+16>>1]|0;h=c[k>>2]|0;c[h+(i*52|0)+32>>2]=p&65535;c[h+(i*52|0)+36>>2]=e[q+48+(i*36|0)+18>>1];o=b[q+48+(i*36|0)+20>>1]|0;o=o<<16>>16==-1?0:o&65535;c[h+(i*52|0)+40>>2]=o;c[h+(i*52|0)+44>>2]=o|0?2:0;h=c[j>>2]|0;o=c[h+(i*764|0)+756>>2]|0;c[o>>2]=d[q+48+(i*36|0)+22>>0];c[o+8>>2]=128;c[o+40>>2]=i;if(p<<16>>16)c[h+(i*764|0)+36>>2]=1;vb(h,i,q+48+(i*36|0)|0,12);p=q+48+(i*36|0)+24|0;o=(((e[p>>1]|0)*8363|0)>>>0)/8448|0;b[p>>1]=o;p=c[(c[j>>2]|0)+(i*764|0)+756>>2]|0;mi(o&65535,p+12|0,p+16|0);i=i+1|0;if((i|0)>=(c[u>>2]|0))break a}l=v;return h|0}while(0);Zl(f+952|0,1,128,g)|0;i=c[s>>2]|0;h=0;do{if((d[f+952+h>>0]|0)>=(i|0))break;h=h+1|0}while((h|0)<128);c[f+156>>2]=h;if((pb(f)|0)<0){f=-1;l=v;return f|0}b:do if((c[s>>2]|0)>0){q=f+172|0;p=f+168|0;o=0;while(1){if((tb(f,o,64)|0)<0){h=-1;break}h=c[r>>2]|0;c:do if((h|0)>0){n=0;while(1){m=c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+(((n|0)%(h|0)|0)<<2)>>2]<<2)>>2]|0;k=(n|0)/(h|0)|0;i=m+4+(k<<3)|0;h=Kl(g)|0;j=i;w=j;a[w>>0]=0;a[w+1>>0]=0;a[w+2>>0]=0;a[w+3>>0]=0;j=j+4|0;a[j>>0]=0;a[j+1>>0]=0;a[j+2>>0]=0;a[j+3>>0]=0;switch(h<<24>>24){case -3:case -4:case -5:break;case -1:{h=0;t=25;break}default:t=25}d:do if((t|0)==25){t=0;j=h&255;a[i>>0]=h<<24>>24==0?0:(j&15)+37+((j>>>4)*12|0)&255;h=Kl(g)|0;j=m+4+(k<<3)+2|0;a[j>>0]=h&7;a[m+4+(k<<3)+1>>0]=(h&255)>>>3;h=(Kl(g)|0)&255;i=(h>>>1&120)+(d[j>>0]|0)|0;a[j>>0]=(i&255)>>>0>64?0:(i&255)+1<<24>>24;j=m+4+(k<<3)+3|0;a[j>>0]=a[18997+(h&15)>>0]|0;h=Kl(g)|0;i=m+4+(k<<3)+4|0;a[i>>0]=h;switch(a[j>>0]|0){case 15:{h=(h&255)>>>4;break}case -1:{a[j>>0]=0;h=0;break}default:break d}a[i>>0]=h}while(0);n=n+1|0;h=c[r>>2]|0;if((n|0)>=(h<<6|0))break c}}while(0);o=o+1|0;if((o|0)>=(c[s>>2]|0))break b}l=v;return h|0}while(0);h=c[u>>2]|0;e:do if((h|0)>0){m=f+180|0;k=f+176|0;j=0;while(1){i=c[m>>2]|0;if((c[i+(j*52|0)+32>>2]|0)>1){if((Ub(f,g,0,i+(j*52|0)|0,0)|0)<0){h=-1;break}h=c[u>>2]|0}else c[(c[k>>2]|0)+(j*764|0)+36>>2]=0;j=j+1|0;if((j|0)>=(h|0))break e}l=v;return h|0}while(0);w=f+1280|0;c[w>>2]=c[w>>2]|293601889;c[f+1284>>2]=2;w=0;l=v;return w|0}function nc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=Pl(a)|0;if(d<<16>>16<26982)switch(d<<16>>16){case 19022:{e=2;break}default:d=-1}else switch(d<<16>>16){case 26982:{e=2;break}default:d=-1}if((e|0)==2){_l(a,238,1)|0;if((Kl(a)|0)<<24>>24==-1){_l(a,c+2|0,0)|0;xb(a,b,36);d=0}else d=-1}return d|0}function oc(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+544|0;j=w;t=w+35|0;n=w+4|0;r=w+32|0;_l(e,f,0)|0;Zl(t,2,1,e)|0;k=t+2|0;Zl(k,108,1,e)|0;i=t+110|0;a[i>>0]=Kl(e)|0;g=t+111|0;a[g>>0]=Kl(e)|0;a[t+112>>0]=Kl(e)|0;h=t+113|0;Zl(h,128,1,e)|0;Zl(t+241|0,128,1,e)|0;Zl(t+369|0,128,1,e)|0;v=b+136|0;c[v>>2]=8;i=d[i>>0]|0;u=b+140|0;c[u>>2]=i;g=a[g>>0]|0;f=g&255;q=b+128|0;c[q>>2]=f;c[b+132>>2]=f<<3;f=0;do{if((d[t+113+f>>0]|0)>(g&255))break;f=f+1|0}while((f|0)<128);c[b+156>>2]=f;ap(b+952|0,h|0,f|0)|0;c[b+148>>2]=6;c[b+152>>2]=76;c[b+144>>2]=i;s=b+1280|0;c[s>>2]=c[s>>2]|4096;wb(b,k,36)|0;h=(fn(t,18210,2)|0)!=0;Eb(b,h?18213:18197,j);h=Om(109)|0;c[b+1220>>2]=h;i=h;f=k;g=i+108|0;do{a[i>>0]=a[f>>0]|0;i=i+1|0;f=f+1|0}while((i|0)<(g|0));a[h+108>>0]=0;if((nb(b)|0)<0){b=-1;l=w;return b|0}a:do if((c[u>>2]|0)>0){h=n+16|0;i=n+20|0;j=n+24|0;m=b+180|0;k=b+176|0;g=0;while(1){if((ob(b,g,1)|0)<0){f=-1;break}Zl(n,13,1,e)|0;c[h>>2]=Vl(e)|0;c[i>>2]=Vl(e)|0;o=Vl(e)|0;c[j>>2]=o;p=c[h>>2]|0;f=c[m>>2]|0;c[f+(g*52|0)+32>>2]=p;c[f+(g*52|0)+36>>2]=c[i>>2];o=o>>>0>1048574?0:o;c[f+(g*52|0)+40>>2]=o;c[f+(g*52|0)+44>>2]=o|0?2:0;f=c[k>>2]|0;o=c[f+(g*764|0)+756>>2]|0;c[o>>2]=64;c[o+8>>2]=128;c[o+40>>2]=g;if((p|0)>0)c[f+(g*764|0)+36>>2]=1;vb(f,g,n,13);g=g+1|0;if((g|0)>=(c[u>>2]|0))break a}l=w;return f|0}while(0);if((pb(b)|0)<0){b=-1;l=w;return b|0}b:do if((c[q>>2]|0)>0){p=b+172|0;o=b+168|0;m=r+2|0;k=r+1|0;n=0;while(1){if((tb(b,n,64)|0)<0){f=-1;break}h=c[p>>2]|0;g=c[(c[o>>2]|0)+(n<<2)>>2]|0;j=c[h+(c[g+4>>2]<<2)>>2]|0;a[j+9>>0]=126;a[j+10>>0]=a[t+241+n>>0]|0;j=c[h+(c[g+8>>2]<<2)>>2]|0;f=t+369+n|0;a[j+4+((d[f>>0]|0)<<3)+5>>0]=13;a[j+4+((d[f>>0]|0)<<3)+6>>0]=0;f=0;while(1){i=c[h+(c[g+4+(((f|0)%8|0)<<2)>>2]<<2)>>2]|0;j=(f|0)/8|0;Zl(r,1,3,e)|0;g=a[r>>0]|0;h=g&255;if((h&254|0)!=254){a[i+4+(j<<3)>>0]=(h>>>2)+37;a[i+4+(j<<3)+1>>0]=((g<<4&48|1)&255)+((d[k>>0]|0)>>>4)}if(g<<24>>24!=-1)a[i+4+(j<<3)+2>>0]=a[k>>0]<<2&60|1;g=a[m>>0]|0;c:do if((g&255)<=95){h=a[18222+((g&255)>>>4)>>0]|0;a[i+4+(j<<3)+3>>0]=h;switch(h<<24>>24){case 122:case 120:case 121:{a[i+4+(j<<3)+4>>0]=g&15;break c}case 123:{a[i+4+(j<<3)+4>>0]=1;break c}case -90:{a[i+4+(j<<3)+4>>0]=(g<<4&255)+128;break c}case 126:{a[i+4+(j<<3)+4>>0]=g&15;a[i+4+(j<<3)+5>>0]=127;break c}default:break c}}while(0);f=f+1|0;if((f|0)==512)break;g=c[(c[o>>2]|0)+(n<<2)>>2]|0;h=c[p>>2]|0}n=n+1|0;if((n|0)>=(c[q>>2]|0))break b}l=w;return f|0}while(0);f=c[u>>2]|0;d:do if((f|0)>0){i=b+180|0;h=0;while(1){g=c[i>>2]|0;if((c[g+(h*52|0)+32>>2]|0)>=3){if((Ub(b,e,2,g+(h*52|0)|0,0)|0)<0){f=-1;break}f=c[u>>2]|0}h=h+1|0;if((h|0)>=(f|0))break d}l=w;return f|0}while(0);if((c[v>>2]|0)>0){f=0;do{c[b+184+(f*12|0)>>2]=((f|0)%2|0)*255;f=f+1|0}while((f|0)<(c[v>>2]|0))}c[s>>2]=c[s>>2]|256;b=0;l=w;return b|0}function pc(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)==1178686206){xb(a,b,40);a=0}else a=-1;return a|0}function qc(e,f,g){e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;C=l;l=l+944|0;m=C;z=C+60|0;w=C+160|0;A=C+8|0;B=C+936|0;_l(f,g,0)|0;Xl(f)|0;j=z+4|0;Zl(j,40,1,f)|0;Zl(z+44|0,3,1,f)|0;b[z+48>>1]=Ml(f)|0;k=z+50|0;a[k>>0]=Kl(f)|0;Zl(z+51|0,16,1,f)|0;_l(f,9,1)|0;i=z+76|0;a[i>>0]=Kl(f)|0;Zl(z+77|0,16,1,f)|0;Vl(f)|0;h=Ml(f)|0;b[z+98>>1]=h;_l(f,h&65535,1)|0;Zl(w,256,1,f)|0;a[w+256>>0]=Kl(f)|0;h=w+257|0;a[h>>0]=Kl(f)|0;a[w+258>>0]=Kl(f)|0;g=0;do{b[w+260+(g<<1)>>1]=Ml(f)|0;g=g+1|0}while((g|0)!=256);v=e+136|0;c[v>>2]=16;z=d[h>>0]|0;c[e+156>>2]=z;c[e+148>>2]=6;c[e+152>>2]=480/((d[i>>0]|0)>>>0)|0;ap(e+952|0,w|0,z|0)|0;i=0;a:while(1){h=i;while(1){if((h|0)>=256)break a;g=h+1|0;if(!(b[w+260+(h<<1)>>1]|0))h=g;else{i=g;continue a}}}u=e+128|0;c[u>>2]=i;c[e+132>>2]=i<<4;yo(e,j,40)|0;z=d[k>>0]|0;c[m>>2]=z>>>4;c[m+4>>2]=z&15;Eb(e,18247,m);if((pb(e)|0)<0){B=-1;l=C;return B|0}b:do if((c[u>>2]|0)>0){s=e+168|0;t=e+172|0;r=0;g=0;c:while(1){if((qb(e,r)|0)<0){g=-1;h=55;break}h=b[w+260+(r<<1)>>1]|0;d:do if(h<<16>>16){c[c[(c[s>>2]|0)+(r<<2)>>2]>>2]=((h&65535)+-2|0)/64|0;if((sb(e,r)|0)<0){g=-1;h=55;break c}h=Kl(f)|0;Kl(f)|0;j=c[(c[s>>2]|0)+(r<<2)>>2]|0;i=c[v>>2]|0;if((O(i,c[j>>2]|0)|0)>0){q=(h&255)+1&255;p=0;while(1){z=(p|0)%(i|0)|0;o=c[(c[t>>2]|0)+(c[j+4+(z<<2)>>2]<<2)>>2]|0;n=(p|0)/(i|0)|0;if((z|0)==0&(n|0)==(q|0))a[o+4+(q<<3)+5>>0]=13;h=Kl(f)|0;j=Kl(f)|0;k=Kl(f)|0;m=Kl(f)|0;i=o+4+(n<<3)|0;if(!(h<<24>>24))h=a[i>>0]|0;else{h=(h&255)+48&255;a[i>>0]=h}if((h|j)<<24>>24)a[o+4+(n<<3)+1>>0]=(j&255)+1;h=k&255;h=h<<4|h>>>4;if((h&255)<<24>>24)a[o+4+(n<<3)+2>>0]=h+240;j=m&255;z=a[18272+(j>>>4)>>0]|0;m=o+4+(n<<3)+3|0;a[m>>0]=z;i=j&15;k=i&255;h=o+4+(n<<3)+4|0;a[h>>0]=k;do switch(z<<24>>24){case -1:{a[h>>0]=0;a[m>>0]=0;break}case -7:{a[m>>0]=14;a[h>>0]=k|16;break}case -8:{a[m>>0]=14;a[h>>0]=k|32;break}case -5:{a[m>>0]=14;a[h>>0]=k|-112;break}case -6:{a[m>>0]=14;a[h>>0]=k|-48;break}case -2:{a[h>>0]=0;a[m>>0]=0;g=i;break}case 4:{a[h>>0]=(j<<4)+g;break}case 123:{a[h>>0]=(j<<4)+g;break}case -3:{a[m>>0]=14;a[h>>0]=k|-96;break}case -4:{a[m>>0]=14;a[h>>0]=k|-80;break}case 15:{a[h>>0]=480/(i>>>0)|0;break}default:{}}while(0);p=p+1|0;j=c[(c[s>>2]|0)+(r<<2)>>2]|0;i=c[v>>2]|0;if((p|0)>=(O(i,c[j>>2]|0)|0))break d}}}while(0);r=r+1|0;if((r|0)>=(c[u>>2]|0))break b}if((h|0)==55){l=C;return g|0}}while(0);z=e+140|0;c[z>>2]=-1;Zl(B,1,8,f)|0;g=0;do{if(d[B+((g|0)/8|0)>>0]&1<<(g&7)|0)c[z>>2]=g;g=g+1|0}while((g|0)!=64);y=(c[z>>2]|0)+1|0;c[z>>2]=y;c[e+144>>2]=y;if((nb(e)|0)<0){B=-1;l=C;return B|0}g=c[z>>2]|0;e:do if((g|0)>0){r=A+32|0;q=A+36|0;w=A+37|0;s=A+40|0;t=A+44|0;v=A+48|0;u=A+49|0;y=e+180|0;x=e+176|0;p=0;while(1){if(d[B+((p|0)/8|0)>>0]&1<<(p&7)){if((ob(e,p,1)|0)<0){g=-1;h=55;break}Zl(A,32,1,f)|0;c[r>>2]=Vl(f)|0;a[q>>0]=Kl(f)|0;a[w>>0]=Kl(f)|0;c[s>>2]=Vl(f)|0;c[t>>2]=Vl(f)|0;a[v>>0]=Kl(f)|0;n=Kl(f)|0;a[u>>0]=n;g=c[r>>2]&65535;c[r>>2]=g;h=c[s>>2]&65535;c[s>>2]=h;i=c[t>>2]&65535;c[t>>2]=i;o=c[y>>2]|0;j=o+(p*52|0)+32|0;c[j>>2]=g;m=o+(p*52|0)+36|0;c[m>>2]=h;k=o+(p*52|0)+40|0;c[k>>2]=i;o=o+(p*52|0)+44|0;c[o>>2]=0;if(g|0)c[(c[x>>2]|0)+(p*764|0)+36>>2]=1;if(!(a[v>>0]|0))g=0;else{c[o>>2]=1;c[j>>2]=g>>>1;c[m>>2]=h>>>1;c[k>>2]=i>>>1;g=1}c[o>>2]=(n<<24>>24?2:0)|g;o=c[x>>2]|0;n=c[o+(p*764|0)+756>>2]|0;c[n>>2]=255;c[n+40>>2]=p;vb(o,p,A,32);if((Ub(e,f,0,(c[y>>2]|0)+(p*52|0)|0,0)|0)<0){g=-1;h=55;break}g=c[z>>2]|0}p=p+1|0;if((p|0)>=(g|0))break e}if((h|0)==55){l=C;return g|0}}while(0);c[e+1268>>2]=255;B=0;l=C;return B|0}function rc(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;e=l;l=l+16|0;d=e;if(((Zl(d,1,4,b)|0)>>>0>=4?(en(d,18326,3)|0)==0:0)?(a[d+3>>0]|0)==16:0){xb(b,c,20);d=0}else d=-1;l=e;return d|0}function sc(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0;K=l;l=l+384|0;z=K;J=K+112|0;A=K+8|0;D=K+184|0;G=K+48|0;_l(g,h,0)|0;Zl(J,3,1,g)|0;y=J+3|0;a[y>>0]=Kl(g)|0;x=J+4|0;Zl(x,20,1,g)|0;F=J+24|0;b[F>>1]=Ml(g)|0;v=J+26|0;a[v>>0]=Kl(g)|0;H=J+27|0;a[H>>0]=Kl(g)|0;E=J+28|0;b[E>>1]=Ml(g)|0;I=J+30|0;a[I>>0]=Kl(g)|0;k=J+31|0;a[k>>0]=Kl(g)|0;B=J+32|0;a[B>>0]=Kl(g)|0;w=J+33|0;a[w>>0]=Kl(g)|0;Zl(J+34|0,32,1,g)|0;C=f+132|0;c[C>>2]=(e[F>>1]|0)+1;F=f+128|0;c[F>>2]=(d[v>>0]|0)+1;c[f+156>>2]=(d[H>>0]|0)+1;I=d[I>>0]|0;H=f+140|0;c[H>>2]=I;c[f+144>>2]=I;I=f+136|0;c[I>>2]=d[w>>0];c[f+148>>2]=6;c[f+152>>2]=125;yo(f,x,20)|0;y=d[y>>0]|0;c[z>>2]=y>>>4;c[z+4>>2]=y&15;Eb(f,18301,z);if((nb(f)|0)<0){J=-1;l=K;return J|0}a:do if((c[H>>2]|0)>0){s=A+24|0;t=A+28|0;u=A+32|0;o=A+36|0;x=A+37|0;m=A+38|0;z=f+180|0;y=f+176|0;q=0;while(1){if((ob(f,q,1)|0)<0){h=-1;break}Zl(A,22,1,g)|0;c[s>>2]=Vl(g)|0;c[t>>2]=Vl(g)|0;c[u>>2]=Vl(g)|0;a[o>>0]=Kl(g)|0;a[x>>0]=Kl(g)|0;a[m>>0]=Kl(g)|0;j=c[s>>2]|0;p=c[z>>2]|0;r=p+(q*52|0)+32|0;c[r>>2]=j;h=c[t>>2]|0;w=p+(q*52|0)+36|0;c[w>>2]=h;i=c[u>>2]|0;v=p+(q*52|0)+40|0;c[v>>2]=i;n=i|0?2:0;p=p+(q*52|0)+44|0;c[p>>2]=n;if(a[k>>0]&1){c[p>>2]=n|1;c[r>>2]=j>>1;c[w>>2]=h>>1;c[v>>2]=i>>1}w=c[y>>2]|0;v=c[w+(q*764|0)+756>>2]|0;c[v>>2]=d[x>>0];c[v+16>>2]=d[o>>0];c[v+8>>2]=128;c[v+40>>2]=q;vb(w,q,A,22);if((c[(c[z>>2]|0)+(q*52|0)+32>>2]|0)>0)c[(c[y>>2]|0)+(q*764|0)+36>>2]=1;q=q+1|0;if((q|0)>=(c[H>>2]|0))break a}l=K;return h|0}while(0);Zl(f+952|0,1,128,g)|0;if((pb(f)|0)<0){J=-1;l=K;return J|0}b:do if((c[C>>2]|0)>0){o=f+172|0;m=0;while(1){if((rb(f,m,d[B>>0]|0)|0)<0){h=-1;break}if(m|0){Zl(D,3,64,g)|0;h=c[(c[o>>2]|0)+(m<<2)>>2]|0;n=0;do{i=n*3|0;k=D+i|0;A=(d[k>>0]|0)>>>2;a[h+4+(n<<3)>>0]=A<<24>>24==0?0:A+37<<24>>24;A=D+(i+1)|0;a[h+4+(n<<3)+1>>0]=a[k>>0]<<4&48|(d[A>>0]|0)>>>4;A=a[A>>0]&15;k=h+4+(n<<3)+3|0;a[k>>0]=A;i=a[D+(i+2)>>0]|0;j=h+4+(n<<3)+4|0;a[j>>0]=i;if(A<<24>>24==14&(i&-16)<<24>>24==-128){a[k>>0]=8;a[j>>0]=(i&255)<<4}n=n+1|0}while((n|0)!=64)}m=m+1|0;if((m|0)>=(c[C>>2]|0))break b}l=K;return h|0}while(0);c:do if((c[F>>2]|0)>0){k=f+168|0;j=0;while(1){if((qb(f,j)|0)<0){h=-1;break}c[c[(c[k>>2]|0)+(j<<2)>>2]>>2]=64;h=0;do{b[G+(h<<1)>>1]=Ml(g)|0;h=h+1|0}while((h|0)!=32);if((c[I>>2]|0)>0){h=c[(c[k>>2]|0)+(j<<2)>>2]|0;i=0;do{c[h+4+(i<<2)>>2]=e[G+(i<<1)>>1];i=i+1|0}while((i|0)<(c[I>>2]|0))}j=j+1|0;if((j|0)>=(c[F>>2]|0))break c}l=K;return h|0}while(0);_l(g,e[E>>1]|0,1)|0;d:do if((c[H>>2]|0)>0){i=f+180|0;h=0;while(1){if((Ub(f,g,2,(c[i>>2]|0)+(h*52|0)|0,0)|0)<0){h=-1;break}h=h+1|0;if((h|0)>=(c[H>>2]|0))break d}l=K;return h|0}while(0);if((c[I>>2]|0)>0)h=0;else{J=0;l=K;return J|0}do{c[f+184+(h*12|0)>>2]=(d[J+34+h>>0]|0)<<4;h=h+1|0}while((h|0)<(c[I>>2]|0));h=0;l=K;return h|0}function tc(a,b,c){a=a|0;b=b|0;c=c|0;_l(a,c+44|0,0)|0;if((Xl(a)|0)!=1347702086){b=-1;return b|0}_l(a,c,0)|0;xb(a,b,28);b=0;return b|0}function uc(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0;S=l;l=l+1728|0;p=S;Q=S+704|0;R=S+96|0;L=S+8|0;_l(g,h,0)|0;Zl(R,28,1,g)|0;a[R+28>>0]=Kl(g)|0;r=R+29|0;a[r>>0]=Kl(g)|0;q=R+30|0;a[q>>0]=Kl(g)|0;a[R+31>>0]=Kl(g)|0;k=R+32|0;b[k>>1]=Ml(g)|0;j=R+34|0;b[j>>1]=Ml(g)|0;m=R+36|0;b[m>>1]=Ml(g)|0;n=R+38|0;b[n>>1]=Ml(g)|0;b[R+40>>1]=Ml(g)|0;b[R+42>>1]=Ml(g)|0;c[R+44>>2]=Xl(g)|0;Zl(R+48|0,16,1,g)|0;Zl(R+64|0,32,1,g)|0;o=R+96|0;Zl(o,256,1,g)|0;i=0;do{b[R+352+(i<<1)>>1]=Ml(g)|0;i=i+1|0}while((i|0)!=128);c[f+156>>2]=e[k>>1];J=e[j>>1]|0;K=f+140|0;c[K>>2]=J;N=e[m>>1]|0;M=f+128|0;c[M>>2]=N;I=e[n>>1]|0;P=f+136|0;c[P>>2]=I;c[f+132>>2]=O(I,N)|0;N=f+144|0;c[N>>2]=J;c[f+148>>2]=6;c[f+152>>2]=125;ap(f+952|0,o|0,256)|0;c[f+1264>>2]=8363;wb(f,R,28)|0;J=d[r>>0]|0;c[p>>2]=d[q>>0];c[p+4>>2]=J;Eb(f,18343,p);if((nb(f)|0)<0){R=-1;l=S;return R|0}a:do if((c[K>>2]|0)>0){I=f+176|0;J=f+180|0;s=L+1|0;H=L+13|0;u=L+14|0;G=L+16|0;F=L+20|0;A=L+24|0;B=L+28|0;C=L+32|0;v=L+36|0;y=L+40|0;x=L+44|0;w=L+48|0;E=L+49|0;t=L+50|0;D=L+80|0;z=0;while(1){i=c[I>>2]|0;j=c[J>>2]|0;a[L>>0]=Kl(g)|0;Zl(s,12,1,g)|0;a[H>>0]=Kl(g)|0;b[u>>1]=Ml(g)|0;b[G>>1]=Ml(g)|0;c[F>>2]=Vl(g)|0;c[A>>2]=Vl(g)|0;c[B>>2]=Vl(g)|0;c[C>>2]=Vl(g)|0;c[v>>2]=Vl(g)|0;c[y>>2]=Vl(g)|0;c[x>>2]=Vl(g)|0;a[w>>0]=Kl(g)|0;a[E>>0]=Kl(g)|0;Zl(t,28,1,g)|0;c[D>>2]=Xl(g)|0;if((a[L>>0]&3)==1){if((ob(f,z,1)|0)<0){i=-1;break}k=c[i+(z*764|0)+756>>2]|0;c[Q+(z<<2)>>2]=c[F>>2];m=c[A>>2]|0;p=j+(z*52|0)+32|0;c[p>>2]=m;n=c[B>>2]|0;r=j+(z*52|0)+36|0;c[r>>2]=n;o=c[C>>2]|0;q=j+(z*52|0)+40|0;c[q>>2]=o;if((c[(c[J>>2]|0)+(z*52|0)+32>>2]|0)>0)c[(c[I>>2]|0)+(z*764|0)+36>>2]=1;j=j+(z*52|0)+44|0;T=d[L>>0]|0;i=(T&8|0)==0?T>>>1&2:6;c[j>>2]=i;if(T&16|0){c[j>>2]=i|1;c[p>>2]=m>>1;c[r>>2]=n>>1;c[q>>2]=o>>1}c[k>>2]=d[H>>0];c[k+8>>2]=128;c[k+40>>2]=z;c[D>>2]=0;vb(c[I>>2]|0,z,t,28);mi(e[u>>1]|0,k+12|0,k+16|0)}z=z+1|0;if((z|0)>=(c[K>>2]|0))break a}l=S;return i|0}while(0);if((pb(f)|0)<0){T=-1;l=S;return T|0}i=c[M>>2]|0;b:do if((i|0)>0){s=f+172|0;r=f+168|0;q=0;while(1){j=R+352+(q<<1)|0;if(b[j>>1]|0){if((tb(f,q,64)|0)<0){i=-1;break}_l(g,(e[j>>1]<<4)+h|0,0)|0;p=0;do{i=Kl(g)|0;if(i<<24>>24)do{o=i&255;i=o&31;if((i|0)<(c[P>>2]|0)){n=c[(c[s>>2]|0)+(c[(c[(c[r>>2]|0)+(q<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0;if(o&32|0){i=Kl(g)|0;switch(i<<24>>24){case -1:{i=0;break}case -2:{i=-127;break}default:i=(i&255)+12&255}a[n+4+(p<<3)>>0]=i;a[n+4+(p<<3)+1>>0]=Kl(g)|0}c:do if(o&64|0){m=n+4+(p<<3)+3|0;a[m>>0]=Kl(g)|0;j=Kl(g)|0;k=n+4+(p<<3)+4|0;a[k>>0]=j;i=a[m>>0]|0;if((i&255)>23){a[k>>0]=0;a[m>>0]=0;break}switch(i<<24>>24){case 14:{i=j&255;if((i&240|0)!=128)break c;a[m>>0]=8;a[k>>0]=i<<4;break c}case 16:{a[m>>0]=16;break c}case 17:{a[m>>0]=27;break c}case 18:{a[m>>0]=-84;break c}case 19:{a[m>>0]=-100;break c}case 20:{a[m>>0]=-99;break c}case 21:{a[m>>0]=-97;break c}case 22:{a[m>>0]=-98;break c}case 23:{a[k>>0]=0;a[m>>0]=0;break c}default:break c}}while(0);if(o&128|0)a[n+4+(p<<3)+2>>0]=((Kl(g)|0)&255)+1}i=Kl(g)|0}while(i<<24>>24!=0);p=p+1|0}while((p|0)!=64);i=c[M>>2]|0}q=q+1|0;if((q|0)>=(i|0))break b}l=S;return i|0}while(0);i=c[N>>2]|0;d:do if((i|0)>0){k=f+176|0;m=f+180|0;j=0;while(1){if((c[(c[k>>2]|0)+(j*764|0)+36>>2]|0)!=0?(c[(c[m>>2]|0)+(j*52|0)+32>>2]|0)!=0:0){_l(g,(c[Q+(j<<2)>>2]|0)+h|0,0)|0;if((Ub(f,g,4,(c[m>>2]|0)+(j*52|0)|0,0)|0)<0){i=-1;break}i=c[N>>2]|0}j=j+1|0;if((j|0)>=(i|0))break d}l=S;return i|0}while(0);c[f+1276>>2]=1368;if((c[P>>2]|0)>0){i=0;do{c[f+184+(i*12|0)>>2]=d[R+64+i>>0]<<4;i=i+1|0}while((i|0)<(c[P>>2]|0))}T=f+1280|0;c[T>>2]=c[T>>2]|293601825;c[f+1284>>2]=2;T=0;l=S;return T|0}function vc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+16|0;c=d;if((Zl(c,1,8,a)|0)>>>0>=8?(fn(c,18398,8)|0)==0:0){xb(a,b,0);c=0}else c=-1;l=d;return c|0}function wc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0;e=l;l=l+304|0;d=e+8|0;_l(b,c,0)|0;_l(b,8,1)|0;c=Fb()|0;if(!c){a=-1;l=e;return a|0}cp(d|0,0,296)|0;f=Jb(c,18378,1)|0;f=Jb(c,20798,2)|0|f;f=f|(Jb(c,18383,3)|0);f=f|(Jb(c,18388,4)|0);f=f|(Jb(c,20788,5)|0);f=f|(Jb(c,21298,6)|0);f=f|(Jb(c,20173,7)|0);if(f|(Jb(c,18393,8)|0)|0){f=-1;l=e;return f|0}Eb(a,18368,e);f=Gb(c,a,b,d)|0;Mb(c);f=f>>31;l=e;return f|0}function xc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=a+136|0;c[f>>2]=0;b=(Pl(d)|0)<<16>>16!=0&1;e=c[f>>2]|0;while(1){c[a+184+(e*12|0)>>2]=0;e=(c[f>>2]|0)+1|0;c[f>>2]=e;if((b|0)<=0)break;else b=b+-1|0}b=(Pl(d)|0)<<16>>16!=0&1;e=c[f>>2]|0;while(1){c[a+184+(e*12|0)>>2]=255;e=(c[f>>2]|0)+1|0;c[f>>2]=e;if((b|0)<=0)break;else b=b+-1|0}b=(Pl(d)|0)<<16>>16!=0&1;e=c[f>>2]|0;while(1){c[a+184+(e*12|0)>>2]=255;e=(c[f>>2]|0)+1|0;c[f>>2]=e;if((b|0)<=0)break;else b=b+-1|0}b=(Pl(d)|0)<<16>>16!=0&1;e=c[f>>2]|0;while(1){c[a+184+(e*12|0)>>2]=0;e=(c[f>>2]|0)+1|0;c[f>>2]=e;if((b|0)<=0)break;else b=b+-1|0}return 0}function yc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;l=(b|0)/32|0;j=a+140|0;c[j>>2]=l;c[a+144>>2]=l;if((nb(a)|0)<0){e=-1;return e|0}k=a+176|0;if((c[j>>2]|0)<=0){e=0;return e|0}l=a+180|0;i=e+144|0;h=0;b=0;while(1){f=c[k>>2]|0;g=c[l>>2]|0;if((ob(a,h,1)|0)<0){b=-1;f=8;break}n=c[f+(h*764|0)+756>>2]|0;m=f+(h*764|0)|0;Zl(m,1,20,d)|0;pl(m)|0;m=g+(b*52|0)+32|0;c[m>>2]=(Xl(d)|0)&-2;p=g+(b*52|0)+36|0;c[p>>2]=(Pl(d)|0)&65535;o=Pl(d)|0;c[g+(b*52|0)+40>>2]=(c[p>>2]|0)+(o&65535);c[g+(b*52|0)+44>>2]=(o&65535)>2?2:0;c[n>>2]=(Pl(d)|0)&65535;c[e+(h<<2)>>2]=(Pl(d)|0)&65535;c[n+8>>2]=128;c[n+40>>2]=b;c[i+(b<<2)>>2]=h;if((c[m>>2]|0)>0){c[f+(h*764|0)+36>>2]=1;b=b+1|0}h=h+1|0;if((h|0)>=(c[j>>2]|0)){b=0;f=8;break}}if((f|0)==8)return b|0;return 0}function zc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;c[a+148>>2]=(Pl(d)|0)&65535;c[a+152>>2]=125;return 0}function Ac(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=(Pl(d)|0)&65535;c[a+128>>2]=b;c[a+132>>2]=O(c[a+136>>2]|0,b)|0;return 0}function Bc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;c[a+156>>2]=(Pl(d)|0)&65535;return 0}function Cc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;Zl(a+952|0,1,c[a+156>>2]|0,d)|0;return 0}function Dc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=f+288|0;f=c[p>>2]|0;if((f|0)>=(c[b+128>>2]|0)){e=0;return e|0}if((f|0)==0?(pb(b)|0)<0:0){e=-1;return e|0}m=Pl(e)|0;m=m&65535;if((tb(b,c[p>>2]|0,m)|0)<0){e=-1;return e|0}l=b+136|0;d=c[l>>2]|0;n=(O(d,m)|0)>0;f=c[p>>2]|0;if(n){n=b+172|0;k=b+168|0;j=0;do{h=c[(c[n>>2]|0)+(c[(c[(c[k>>2]|0)+(f<<2)>>2]|0)+4+(((j|0)%(d|0)|0)<<2)>>2]<<2)>>2]|0;g=(j|0)/(d|0)|0;f=h+4+(g<<3)|0;d=f;b=d;a[b>>0]=0;a[b+1>>0]=0;a[b+2>>0]=0;a[b+3>>0]=0;d=d+4|0;a[d>>0]=0;a[d+1>>0]=0;a[d+2>>0]=0;a[d+3>>0]=0;d=Kl(e)|0;b=Kl(e)|0;if(d<<24>>24){a[f>>0]=(d&255)+48;a[h+4+(g<<3)+1>>0]=(b&255)+1}i=h+4+(g<<3)+3|0;a[i>>0]=c[1640+(((Kl(e)|0)&255)<<2)>>2];f=Kl(e)|0;b=h+4+(g<<3)+4|0;a[b>>0]=f;d=a[i>>0]|0;a:do if((f&255)>64&d<<24>>24==12){do if((f&255)<81){a[i>>0]=10;d=10;f=(f&255)+192|0}else{if((f&255)<97){a[i>>0]=10;d=10;f=(f&255)<<4;break}if((f&255)<113){a[i>>0]=-82;d=-82;f=(f&255)+160|0;break}if((f&255)>=129)break a;a[i>>0]=-83;d=-83;f=(f&255)+144|0}while(0);f=f&255;a[b>>0]=f;o=19}else o=19;while(0);b:do if((o|0)==19){o=0;switch(d<<24>>24){case 0:{i=f&255;a[b>>0]=(((24-(i>>>4)|0)>>>0)%12|0)<<4|i&15;break b}case -1:{a[b>>0]=0;a[i>>0]=0;break b}default:break b}}while(0);j=j+1|0;d=c[l>>2]|0;i=(j|0)<(O(d,m)|0);f=c[p>>2]|0}while(i)}c[p>>2]=f+1;e=0;return e|0}function Ec(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;g=e+292|0;b=c[g>>2]|0;if((b|0)>=(c[a+140>>2]|0)){a=0;return a|0}f=c[e+144+(b<<2)>>2]|0;switch(c[e+(f<<2)>>2]|0){case 2:case 0:{b=8;break}default:b=0}if((Ub(a,d,b,(c[a+180>>2]|0)+((c[(c[(c[a+176>>2]|0)+(f*764|0)+756>>2]|0)+40>>2]|0)*52|0)|0,0)|0)<0){a=-1;return a|0}c[g>>2]=(c[g>>2]|0)+1;a=0;return a|0}function Fc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;e=l;l=l+16|0;d=e;_l(a,c+1062|0,0)|0;if(((Zl(d,1,9,a)|0)>>>0>=9?(en(d,18428,2)|0)==0:0)?(en(d+6|0,18431,3)|0)==0:0){_l(a,c,0)|0;xb(a,b,24);d=0}else d=-1;l=e;return d|0}function Gc(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;y=l;l=l+1088|0;i=y;v=y+16|0;x=y+4|0;_l(e,f,0)|0;Zl(v,24,1,e)|0;Zl(v+24|0,24,1,e)|0;f=0;do{Zl(v+48+(f*34|0)|0,23,1,e)|0;Zl(v+48+(f*34|0)+23|0,11,1,e)|0;f=f+1|0}while((f|0)!=26);f=v+932|0;a[f>>0]=Kl(e)|0;g=v+933|0;a[g>>0]=Kl(e)|0;h=v+934|0;Zl(h,128,1,e)|0;Zl(v+1062|0,9,1,e)|0;w=Kl(e)|0;u=v+1071|0;a[u>>0]=w;if((w&-2)<<24>>24!=16){b=-1;l=y;return b|0}w=b+136|0;c[w>>2]=9;c[b+152>>2]=125;c[b+148>>2]=6;s=d[f>>0]|0;c[b+156>>2]=s;c[b+128>>2]=(d[g>>0]|0)+1;t=b+140|0;c[t>>2]=26;c[b+144>>2]=26;ap(b+952|0,h|0,s|0)|0;Eb(b,18407,i);yo(b,v,24)|0;if((nb(b)|0)<0){b=-1;l=y;return b|0}a:do if((c[t>>2]|0)>0){r=b+176|0;s=b+180|0;f=x+1|0;h=x+2|0;i=x+3|0;j=x+4|0;k=x+5|0;m=x+6|0;n=x+7|0;o=x+8|0;p=x+9|0;g=x+10|0;q=0;while(1){if((ob(b,q,1)|0)<0){f=-1;g=16;break}vb(c[r>>2]|0,q,v+48+(q*34|0)|0,23);z=c[r>>2]|0;A=c[z+(q*764|0)+756>>2]|0;c[A>>2]=64;c[A+8>>2]=128;c[A+40>>2]=q;c[z+(q*764|0)+36>>2]=1;a[x>>0]=a[v+48+(q*34|0)+23>>0]|0;a[f>>0]=a[v+48+(q*34|0)+28>>0]|0;a[h>>0]=a[v+48+(q*34|0)+24>>0]|0;a[i>>0]=a[v+48+(q*34|0)+29>>0]|0;a[j>>0]=a[v+48+(q*34|0)+25>>0]|0;a[k>>0]=a[v+48+(q*34|0)+30>>0]|0;a[m>>0]=a[v+48+(q*34|0)+26>>0]|0;a[n>>0]=a[v+48+(q*34|0)+31>>0]|0;a[o>>0]=a[v+48+(q*34|0)+27>>0]|0;a[p>>0]=a[v+48+(q*34|0)+32>>0]|0;a[g>>0]=a[v+48+(q*34|0)+33>>0]|0;if((Ub(b,e,4096,(c[s>>2]|0)+(q*52|0)|0,x)|0)<0){f=-1;g=16;break}q=q+1|0;if((q|0)>=(c[t>>2]|0))break a}if((g|0)==16){l=y;return f|0}}while(0);if((a[u>>0]|0)==16){if((Hc(b,e)|0)<0){A=-1;l=y;return A|0}}else if((Ic(b,e)|0)<0){A=-1;l=y;return A|0}if((c[w>>2]|0)>0){f=0;do{c[b+184+(f*12|0)>>2]=128;c[b+184+(f*12|0)+8>>2]=1;f=f+1|0}while((f|0)<(c[w>>2]|0))}c[b+6556>>2]=7212;A=0;l=y;return A|0}function Hc(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;j=b+128|0;c[b+132>>2]=(c[j>>2]|0)*9;if((pb(b)|0)<0){l=-1;return l|0}if((c[j>>2]|0)<=0){l=0;return l|0}h=b+136|0;l=b+172|0;k=b+168|0;i=0;e=1;while(1){if((tb(b,i,64)|0)<0){e=-1;f=8;break}f=c[h>>2]|0;if((f|0)>0){g=0;do{n=c[(c[l>>2]|0)+(c[(c[(c[k>>2]|0)+(i<<2)>>2]|0)+4+(((g|0)%(f|0)|0)<<2)>>2]<<2)>>2]|0;m=(g|0)/(f|0)|0;Jc(Kl(d)|0,n+4+(m<<3)|0,d);m=n+4+(m<<3)+4|0;n=a[m>>0]|0;e=n<<24>>24==15?3:e;a[m>>0]=O(e,n&255)|0;g=g+1|0;f=c[h>>2]|0}while((g|0)<(f<<6|0))}i=i+1|0;if((i|0)>=(c[j>>2]|0)){e=0;f=8;break}}if((f|0)==8)return e|0;return 0}function Ic(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;i=b+128|0;e=c[i>>2]|0;m=Qm(4,e+1|0)|0;j=b+168|0;c[j>>2]=m;if(!m){b=-1;return b|0}k=b+132|0;a:do if((e|0)>0){h=0;while(1){if((qb(b,h)|0)<0){e=-1;break}e=(Ml(d)|0)&65535;c[(c[(c[j>>2]|0)+(h<<2)>>2]|0)+4>>2]=e;if((e|0)>(c[k>>2]|0))c[k>>2]=e;e=(Ml(d)|0)&65535;c[(c[(c[j>>2]|0)+(h<<2)>>2]|0)+8>>2]=e;if((e|0)>(c[k>>2]|0))c[k>>2]=e;e=(Ml(d)|0)&65535;c[(c[(c[j>>2]|0)+(h<<2)>>2]|0)+12>>2]=e;if((e|0)>(c[k>>2]|0))c[k>>2]=e;e=(Ml(d)|0)&65535;c[(c[(c[j>>2]|0)+(h<<2)>>2]|0)+16>>2]=e;if((e|0)>(c[k>>2]|0))c[k>>2]=e;e=(Ml(d)|0)&65535;c[(c[(c[j>>2]|0)+(h<<2)>>2]|0)+20>>2]=e;if((e|0)>(c[k>>2]|0))c[k>>2]=e;e=(Ml(d)|0)&65535;c[(c[(c[j>>2]|0)+(h<<2)>>2]|0)+24>>2]=e;if((e|0)>(c[k>>2]|0))c[k>>2]=e;e=(Ml(d)|0)&65535;c[(c[(c[j>>2]|0)+(h<<2)>>2]|0)+28>>2]=e;if((e|0)>(c[k>>2]|0))c[k>>2]=e;e=(Ml(d)|0)&65535;c[(c[(c[j>>2]|0)+(h<<2)>>2]|0)+32>>2]=e;if((e|0)>(c[k>>2]|0))c[k>>2]=e;f=(Ml(d)|0)&65535;g=c[(c[j>>2]|0)+(h<<2)>>2]|0;c[g+36>>2]=f;e=c[k>>2]|0;if((f|0)>(e|0)){c[k>>2]=f;e=f}c[g>>2]=64;h=h+1|0;if((h|0)>=(c[i>>2]|0))break a}return e|0}else e=c[k>>2]|0;while(0);c[k>>2]=e+1;e=Ml(d)|0;m=e&65535;k=Qm(4,c[k>>2]|0)|0;l=b+172|0;c[l>>2]=k;if(!k){b=-1;return b|0}if(!(e<<16>>16)){b=0;return b|0}else{k=0;e=1}while(1){j=(Ml(d)|0)&65535;if((rb(b,j,64)|0)<0){e=-1;f=16;break}else f=0;do{g=c[(c[l>>2]|0)+(j<<2)>>2]|0;h=Kl(d)|0;i=h&255;if(!(i&128)){Jc(h,g+4+(f<<3)|0,d);i=g+4+(f<<3)+4|0;h=a[i>>0]|0;e=h<<24>>24==15?3:e;a[i>>0]=O(e,h&255)|0}else f=f+-1+(i&127)|0;f=f+1|0}while((f|0)<64);k=k+1|0;if((k|0)>=(m|0)){e=0;f=16;break}}if((f|0)==16)return e|0;return 0}function Jc(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0;f=c+4|0;a[f>>0]=b;b=Kl(e)|0;g=c+1|0;a[g>>0]=(b&255)>>>4;switch(b&15){case 7:{if((d[f>>0]|0)>31){a[f>>0]=0;b=0}else b=15;break}case 6:{b=13;break}case 5:{b=11;break}case 8:{b=3;break}case 4:{b=12;break}case 9:case 3:{a[f>>0]=0;b=0;break}default:b=b&15}a[c+3>>0]=b;f=Kl(e)|0;e=f&255;a[g>>0]=e<<4&16|(d[g>>0]|0);g=(f&255)>>>4;a[c>>0]=g<<24>>24==0?0:(g+24&255)+((e>>>1&7)*12|0)&255;return}function Kc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+16|0;c=d;if((Zl(c,1,16,a)|0)>>>0>=16?(en(c,18467,16)|0)==0:0){xb(a,b,0);c=0}else c=-1;l=d;return c|0}function Lc(e,f,g){e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;y=l;l=l+96|0;t=y;k=y+72|0;v=y+8|0;_l(f,g,0)|0;_l(f,16,0)|0;s=Kl(f)|0;u=Kl(f)|0;w=e+136|0;c[w>>2]=9;c[e+152>>2]=125;u=u&255;j=u&31;c[e+148>>2]=j>>>0<3?6:j;j=e+144|0;c[j>>2]=0;s=s&255;c[t>>2]=s>>>4;c[t+4>>2]=s&15;Eb(e,18457,t);if(u&128|0)do{}while((Kl(f)|0)<<24>>24!=0);i=$l(f)|0;m=e+140|0;c[m>>2]=0;h=Kl(f)|0;if(h<<24>>24)do{c[m>>2]=h&255;Zl(k,1,11,f)|0;h=Kl(f)|0}while(h<<24>>24!=0);_l(f,i,0)|0;c[j>>2]=c[m>>2];if((nb(e)|0)<0){x=-1;l=y;return x|0}i=e+180|0;while(1){h=Kl(f)|0;if(!(h<<24>>24))break;Zl(k,1,11,f)|0;if((Ub(e,f,12288,(c[i>>2]|0)+(((h&255)+-1|0)*52|0)|0,k)|0)<0){h=-1;x=40;break}}if((x|0)==40){l=y;return h|0}a:do if((c[m>>2]|0)>0){i=e+176|0;h=0;while(1){if((ob(e,h,1)|0)<0){h=-1;break}u=c[i>>2]|0;t=c[u+(h*764|0)+756>>2]|0;c[t>>2]=64;c[t+8>>2]=128;c[t+12>>2]=-1;c[t+40>>2]=h;c[u+(h*764|0)+36>>2]=1;h=h+1|0;if((h|0)>=(c[m>>2]|0))break a}l=y;return h|0}while(0);u=Kl(f)|0;k=e+156|0;c[k>>2]=u&255;if(u<<24>>24){j=0;h=0;do{i=Kl(f)|0;if(i<<24>>24>-1){a[e+952+h>>0]=i;h=h+1|0}j=j+1|0}while((j|0)<(c[k>>2]|0))}u=e+128|0;c[u>>2]=0;h=0;do{t=Ml(f)|0;b[v+(h<<1)>>1]=t;if(t<<16>>16)c[u>>2]=(c[u>>2]|0)+1;h=h+1|0}while((h|0)!=32);c[e+132>>2]=O(c[w>>2]|0,c[u>>2]|0)|0;if((pb(e)|0)<0){x=-1;l=y;return x|0}b:do if((c[u>>2]|0)>0){t=e+172|0;s=e+168|0;r=0;while(1){if((tb(e,r,64)|0)<0){h=-1;break}h=b[v+(r<<1)>>1]|0;if(h<<16>>16){_l(f,(h&65535)+g|0,0)|0;do{p=(Kl(f)|0)&255;o=p&127;do{q=(Kl(f)|0)&255;n=c[(c[t>>2]|0)+(c[(c[(c[s>>2]|0)+(r<<2)>>2]|0)+4+((q&127)<<2)>>2]<<2)>>2]|0;i=(Kl(f)|0)&255;k=n+4+(o<<3)+1|0;a[k>>0]=i>>>3&16;h=i&15;j=h&255;m=n+4+(o<<3)|0;a[m>>0]=j;if((h|0)!=15){if(j<<24>>24){h=h+26+((i>>>4&7)*12|0)&255;x=32}}else{h=-127;x=32}if((x|0)==32){x=0;a[m>>0]=h}m=(Kl(f)|0)&255;a[k>>0]=d[k>>0]|m>>>4;m=m&15;h=n+4+(o<<3)+3|0;a[h>>0]=m;if(m<<24>>24){m=Kl(f)|0;a[n+4+(o<<3)+4>>0]=(m&255)<3&(a[h>>0]|0)==15?6:m}}while(!(q&128|0))}while(!(p&128|0))}r=r+1|0;if((r|0)>=(c[u>>2]|0))break b}l=y;return h|0}while(0);if((c[w>>2]|0)>0){h=0;do{c[e+184+(h*12|0)>>2]=128;c[e+184+(h*12|0)+8>>2]=1;h=h+1|0}while((h|0)<(c[w>>2]|0))}c[e+6556>>2]=7212;x=e+1280|0;c[x>>2]=c[x>>2]|4096;x=0;l=y;return x|0}function Mc(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;e=l;l=l+16|0;d=e;if(((Zl(d,1,15,b)|0)>>>0>=15?(en(d,18543,14)|0)==0:0)?((a[d+14>>0]|0)+-48&255)<=4:0){xb(b,c,32);d=0}else d=-1;l=e;return d|0}function Nc(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0;S=l;l=l+400|0;R=S;N=S+344|0;A=S+80|0;y=S+8|0;Q=S+76|0;_l(g,h,0)|0;Zl(N,15,1,g)|0;M=N+15|0;Zl(M,32,1,g)|0;P=N+47|0;a[P>>0]=Kl(g)|0;N=d[N+14>>0]|0;B=N+-48|0;yo(f,M,32)|0;a[M>>0]=0;c[R>>2]=c[1804+(N+-49<<2)>>2];c[R+4>>2]=B;Eb(f,18498,R);_l(g,(d[P>>0]|0)<<5,1)|0;P=(Kl(g)|0)&255;c[f+144>>2]=P;R=f+140|0;c[R>>2]=P;if((nb(f)|0)<0){f=-1;l=S;return f|0}a:do if((c[R>>2]|0)>0){j=y+32|0;r=y+44|0;s=y+48|0;u=y+52|0;t=y+56|0;v=y+60|0;k=y+61|0;p=y+62|0;n=(B|0)<4;m=y+64|0;x=f+180|0;w=f+176|0;q=0;while(1){if((ob(f,q,1)|0)<0){h=-1;break}Zl(y,32,1,g)|0;Zl(j,12,1,g)|0;c[r>>2]=Vl(g)|0;c[s>>2]=Vl(g)|0;c[u>>2]=Vl(g)|0;c[t>>2]=Vl(g)|0;a[v>>0]=Kl(g)|0;a[k>>0]=Kl(g)|0;b[p>>1]=Ml(g)|0;if(n){o=0;h=0}else{o=Ml(g)|0;h=b[p>>1]|0;b[m>>1]=h^o;b[p>>1]=o;o=1}b[m>>1]=h;P=(c[t>>2]|0)-(c[u>>2]|0)|0;i=c[x>>2]|0;c[i+(q*52|0)+32>>2]=P;c[i+(q*52|0)+36>>2]=c[r>>2];c[i+(q*52|0)+40>>2]=c[s>>2];if((P|0)>0)c[(c[w>>2]|0)+(q*764|0)+36>>2]=1;P=(d[k>>0]|0)+-4|0;switch(P>>>2|P<<30|0){case 0:case 4:{h=1;z=14;break}case 1:{h=2;z=14;break}case 2:{h=3;z=14;break}case 5:{h=10;z=14;break}case 6:{h=11;z=14;break}default:{}}if((z|0)==14){z=0;c[i+(q*52|0)+44>>2]=h}P=c[w>>2]|0;N=c[P+(q*764|0)+756>>2]|0;c[N>>2]=d[v>>0];c[N+8>>2]=128;c[N+40>>2]=q;vb(P,q,y,24);if(o){P=c[(c[w>>2]|0)+(q*764|0)+756>>2]|0;mi(e[m>>1]|0,P+12|0,P+16|0)}q=q+1|0;if((q|0)>=(c[R>>2]|0))break a}l=S;return h|0}while(0);Zl(A,256,1,g)|0;j=A+256|0;a[j>>0]=Kl(g)|0;k=Kl(g)|0;a[A+257>>0]=k;h=0;do{i=a[A+h>>0]|0;if(i<<24>>24==-1)break;a[f+952+h>>0]=i;h=h+1|0}while((h|0)<256);c[f+156>>2]=h;i=(d[j>>0]|0)+1|0;P=f+136|0;c[P>>2]=i;h=(k&255)+1|0;N=f+128|0;c[N>>2]=h;c[f+148>>2]=6;c[f+152>>2]=125;c[f+132>>2]=O(i,h)|0;h=(B|0)>2;i=0;do{j=i;i=i+1|0;if(h)k=((Kl(g)|0)&255)*17|0;else k=(((i|0)/2|0|0)%2|0)*255|0;c[f+184+(j*12|0)>>2]=k}while((i|0)<(c[P>>2]|0));if((pb(f)|0)<0){f=-1;l=S;return f|0}h=c[N>>2]|0;b:do if((h|0)>0){i=0;while(1){if((tb(f,i,64)|0)<0){h=-1;break}i=i+1|0;h=c[N>>2]|0;if((i|0)>=(h|0))break b}l=S;return h|0}while(0);i=c[P>>2]|0;if((i|0)>0){M=f+172|0;L=f+168|0;K=Q+1|0;J=Q+3|0;I=Q+2|0;H=0;k=0;j=0;do{if((h|0)>0){m=0;while(1){h=Kl(g)|0;if(h<<24>>24==-4){i=(Kl(g)|0)&255;h=Kl(g)|0}else i=1;Zl(Q,4,1,g)|0;D=((i|0)==0&1)+i|0;c:do if(!D)i=m;else{E=h<<24>>24==0;z=a[Q>>0]|0;G=a[K>>0]|0;F=(G&255)>>>4;A=G&15;B=a[J>>0]|0;C=a[I>>0]|0;s=(h&255)+36&255;y=C<<24>>24!=0;w=C&255;v=w<<4&255;w=w<<2&255;x=B<<24>>24!=0;u=B&255;t=u<<4&255;u=u<<2&255;i=m;r=0;while(1){m=c[(c[M>>2]|0)+(c[(c[(c[L>>2]|0)+(i>>6<<2)>>2]|0)+4+(H<<2)>>2]<<2)>>2]|0;n=i&63;h=m+4+(n<<3)|0;q=h;p=q;a[p>>0]=0;a[p+1>>0]=0;a[p+2>>0]=0;a[p+3>>0]=0;q=q+4|0;a[q>>0]=0;a[q+1>>0]=0;a[q+2>>0]=0;a[q+3>>0]=0;if(!E)a[h>>0]=s;a[m+4+(n<<3)+1>>0]=z;p=m+4+(n<<3)+3|0;a[p>>0]=F;q=m+4+(n<<3)+5|0;a[q>>0]=A;o=m+4+(n<<3)+4|0;a[o>>0]=B;h=m+4+(n<<3)+6|0;a[h>>0]=C;switch(F&15){case 0:{if((k|0)==0|x)k=0;else{a[p>>0]=3;k=k+-1|0}break}case 3:{k=32;break}case 6:case 5:{a[o>>0]=0;a[p>>0]=0;break}case 11:{a[p>>0]=8;a[o>>0]=t;break}case 9:{a[o>>0]=u;break}default:{}}switch(G&15){case 0:{if((j|0)==0|y)j=0;else{a[q>>0]=3;j=j+-1|0}break}case 3:{j=32;break}case 6:case 5:{a[h>>0]=0;a[q>>0]=0;break}case 11:{a[q>>0]=8;a[h>>0]=v;break}case 9:{a[h>>0]=w;break}default:{}}r=r+1|0;i=i+1|0;if((r|0)>=(D|0))break c}}while(0);h=c[N>>2]|0;if((i|0)<(h<<6|0))m=i;else break}i=c[P>>2]|0}H=H+1|0}while((H|0)<(i|0))}h=c[R>>2]|0;d:do if((h|0)>0){k=f+180|0;j=0;while(1){i=c[k>>2]|0;if(c[i+(j*52|0)+32>>2]|0){if((Ub(f,g,0,i+(j*52|0)|0,0)|0)<0){h=-1;break}h=c[R>>2]|0}j=j+1|0;if((j|0)>=(h|0))break d}l=S;return h|0}while(0);c[f+1268>>2]=256;f=0;l=S;return f|0}function Oc(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)!=1145914444){b=-1;return b|0}Kl(a)|0;if((Pl(a)|0)<<16>>16==18766){Xl(a)|0;xb(a,b,32);b=0;return b|0}else{xb(a,b,0);b=0;return b|0}return 0}function Pc(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0;D=l;l=l+80|0;i=D;h=D+64|0;C=D+8|0;_l(e,f,0)|0;f=C;g=f+52|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));Xl(e)|0;Zl(h,1,1,e)|0;j=Fb()|0;if(!j){b=-1;l=D;return b|0}Jb(j,18571,9)|0;Jb(j,18574,10)|0;Jb(j,18577,11)|0;Jb(j,18580,12)|0;Jb(j,18583,13)|0;Jb(j,18586,14)|0;if((d[h>>0]|0)<16){Jb(j,18592,18)|0;Jb(j,18595,19)|0}else{Jb(j,18589,15)|0;Jb(j,18592,16)|0;Jb(j,18595,17)|0}Pb(j);Qb(j,1);u=a[h>>0]|0;c[i>>2]=u>>>4&15;c[i+4>>2]=u&15;Eb(b,18598,i);c[b+1268>>2]=255;c[b+1264>>2]=8363;u=C+36|0;c[u>>2]=0;v=C+32|0;c[v>>2]=0;w=C+28|0;c[w>>2]=0;A=C+4|0;c[A>>2]=Qm(256,4)|0;c[C>>2]=Qm(256,4)|0;f=Om(1024)|0;B=C+8|0;c[B>>2]=f;g=Om(1024)|0;z=C+12|0;c[z>>2]=g;h=Om(1024)|0;y=C+16|0;c[y>>2]=h;x=C+20|0;c[x>>2]=Qm(256,4)|0;i=0;do{c[h+(i<<2)>>2]=-1;c[g+(i<<2)>>2]=-1;c[f+(i<<2)>>2]=-1;i=i+1|0}while((i|0)!=256);t=(Gb(j,b,e,C)|0)<0;Mb(j);if(!t){f=c[b+132>>2]|0;if((f|0)>0){g=c[b+172>>2]|0;o=b+140|0;h=c[C>>2]|0;n=0;do{i=c[g+(n<<2)>>2]|0;j=c[i>>2]|0;if((j|0)>0){e=c[o>>2]|0;k=(e|0)>0;q=0;do{a:do if(k){p=i+4+(q<<3)+1|0;m=a[p>>0]|0;s=m<<24>>24==0;m=m&255;r=0;while(1){t=r;r=r+1|0;if(!s?(m|0)==(c[h+(t<<2)>>2]|0):0)break;if((r|0)>=(e|0))break a}a[p>>0]=r}while(0);q=q+1|0}while((q|0)!=(j|0))}n=n+1|0}while((n|0)!=(f|0))}else o=b+140|0;if((c[o>>2]|0)>0){t=b+176|0;s=C+40|0;q=C+44|0;n=C+48|0;r=b+144|0;f=c[t>>2]|0;p=0;while(1){$c(p,f+(p*764|0)+44|0,c[s>>2]|0,c[B>>2]|0,c[w>>2]|0);$c(p,(c[t>>2]|0)+(p*764|0)+200|0,c[q>>2]|0,c[z>>2]|0,c[v>>2]|0);$c(p,(c[t>>2]|0)+(p*764|0)+356|0,c[n>>2]|0,c[y>>2]|0,c[u>>2]|0);f=c[t>>2]|0;if((c[f+(p*764|0)+36>>2]|0)>0){m=0;do{h=c[r>>2]|0;b:do if((h|0)>0){i=c[f+(p*764|0)+756>>2]|0;k=i+(m<<6)+40|0;j=c[k>>2]|0;e=c[A>>2]|0;g=0;while(1){if((j|0)==(c[e+(g<<2)>>2]|0))break;g=g+1|0;if((g|0)>=(h|0))break b}c[k>>2]=g;mi(c[(c[x>>2]|0)+(g<<2)>>2]|0,i+(m<<6)+12|0,i+(m<<6)+16|0);f=c[t>>2]|0}while(0);m=m+1|0}while((m|0)<(c[f+(p*764|0)+36>>2]|0))}p=p+1|0;if((p|0)>=(c[o>>2]|0)){f=0;break}}}else f=0}else f=-1;Pm(c[x>>2]|0);Pm(c[y>>2]|0);Pm(c[z>>2]|0);Pm(c[B>>2]|0);Pm(c[C>>2]|0);Pm(c[A>>2]|0);Pm(c[C+40>>2]|0);Pm(c[C+44>>2]|0);Pm(c[C+48>>2]|0);Pm(c[C+24>>2]|0);C=b+1280|0;c[C>>2]=c[C>>2]|704905248;c[b+1284>>2]=1;b=f;l=D;return b|0}function Qc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;Zl(a,1,32,d)|0;_l(d,20,1)|0;f=a+156|0;c[f>>2]=(Ml(d)|0)&65535;c[a+160>>2]=(Ml(d)|0)&65535;Kl(d)|0;c[a+148>>2]=(Kl(d)|0)&255;c[a+152>>2]=(Kl(d)|0)&255;e=0;do{b=(Kl(d)|0)&255;if(b&128|0)break;c[a+184+(e*12|0)>>2]=b<<1;e=e+1|0}while((e|0)<32);c[a+136>>2]=e;_l(d,31-e|0,1)|0;Zl(a+952|0,1,c[f>>2]|0,d)|0;return 0}function Rc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;n=((Ml(f)|0)&65535)+1|0;o=b+132|0;c[o>>2]=n;n=Qm(4,n)|0;p=b+172|0;c[p>>2]=n;if(!n){b=-1;return b|0}l=Qm(1,2052)|0;if(!l){b=-1;return b|0}a:do if((rb(b,0,256)|0)>=0){b:do if((c[o>>2]|0)>1){m=l+4|0;n=1;c:while(1){g=Ml(f)|0;cp(l|0,0,2052)|0;d:do if(!(g<<16>>16))g=0;else{h=g&65535;g=0;while(1){k=m+(g<<3)|0;j=Kl(f)|0;i=j&255;e=h+-1|0;switch(j&3){case 0:{g=(i>>>2)+g|0;break}case 1:{j=i>>>2;h=k+-8|0;i=0;while(1){r=h;t=r;t=d[t>>0]|d[t+1>>0]<<8|d[t+2>>0]<<16|d[t+3>>0]<<24;r=r+4|0;r=d[r>>0]|d[r+1>>0]<<8|d[r+2>>0]<<16|d[r+3>>0]<<24;q=k+(i<<3)|0;s=q;a[s>>0]=t;a[s+1>>0]=t>>8;a[s+2>>0]=t>>16;a[s+3>>0]=t>>24;q=q+4|0;a[q>>0]=r;a[q+1>>0]=r>>8;a[q+2>>0]=r>>16;a[q+3>>0]=r>>24;if((i|0)==(j|0))break;else i=i+1|0}g=g+j|0;break}case 2:{s=m+(i>>>2<<3)|0;q=s;q=d[q>>0]|d[q+1>>0]<<8|d[q+2>>0]<<16|d[q+3>>0]<<24;s=s+4|0;s=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;t=k;r=t;a[r>>0]=q;a[r+1>>0]=q>>8;a[r+2>>0]=q>>16;a[r+3>>0]=q>>24;t=t+4|0;a[t>>0]=s;a[t+1>>0]=s>>8;a[t+2>>0]=s>>16;a[t+3>>0]=s>>24;break}case 3:{if(i&4){e=Kl(f)|0;a[k>>0]=e<<24>>24==-1?-127:(e&255)+12&255;e=h+-2|0}if(i&8){a[m+(g<<3)+1>>0]=Kl(f)|0;e=e+-1|0}if(i&16){a[m+(g<<3)+2>>0]=Kl(f)|0;e=e+-1|0}if(i&32){t=Kl(f)|0;a[m+(g<<3)+3>>0]=t&15;a[m+(g<<3)+5>>0]=(t&255)>>>4;e=e+-1|0}if(i&64){a[m+(g<<3)+4>>0]=Kl(f)|0;e=e+-1|0}if(i&128){a[m+(g<<3)+6>>0]=Kl(f)|0;e=e+-1|0}break}default:break c}g=g+1|0;if(!e)break d;else h=e}}while(0);e=(g|0)<65?64:(g|0)<129?128:256;if((rb(b,n,e)|0)<0)break a;ap(c[(c[p>>2]|0)+(n<<2)>>2]|0,l|0,e<<3|4|0)|0;g=c[(c[p>>2]|0)+(n<<2)>>2]|0;c[g>>2]=e;dd(g+7|0,g+8|0);ed(g+9|0,g+10|0);g=1;do{t=c[(c[p>>2]|0)+(n<<2)>>2]|0;dd(t+4+(g<<3)+3|0,t+4+(g<<3)+4|0);ed(t+4+(g<<3)+5|0,t+4+(g<<3)+6|0);g=g+1|0}while((g|0)<(e|0));n=n+1|0;if((n|0)>=(c[o>>2]|0))break b}}while(0);Pm(l);t=0;return t|0}while(0);Pm(l);t=-1;return t|0}function Sc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;k=a+144|0;if((c[k>>2]|0)<=0){a=0;return a|0}l=a+180|0;i=e+24|0;g=0;a:while(1){b=c[l>>2]|0;f=b+(g*52|0)|0;h=b+(g*52|0)+32|0;b=c[h>>2]<<(c[b+(g*52|0)+44>>2]&1);j=Qm(1,b)|0;if(!j){b=-1;e=13;break}switch(c[(c[i>>2]|0)+(g<<2)>>2]|0){case 0:{Zl(j,1,b,d)|0;break}case 1:{b=Vl(d)|0;e=Om(b+4|0)|0;if(!e){e=12;break a}Zl(e,1,b,d)|0;ad(j,e,b,c[h>>2]|0);Pm(e);break}case 2:{b=Vl(d)|0;e=Om(b+4|0)|0;if(!e){e=12;break a}Zl(e,1,b,d)|0;bd(j,e,b,c[h>>2]|0);Pm(e);break}default:{}}if((Ub(a,0,16,f,j)|0)<0){e=12;break}Pm(j);g=g+1|0;if((g|0)>=(c[k>>2]|0)){b=0;e=13;break}}if((e|0)==12){Pm(j);a=-1;return a|0}else if((e|0)==13)return b|0;return 0}function Tc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0;d=Kl(e)|0;b=d&255;g=f+28|0;c[g>>2]=b;if(!(d<<24>>24))return 0;d=f+40|0;c[d>>2]=Qm(b,33)|0;b=0;do{h=Kl(e)|0;f=c[d>>2]|0;a[f+(b*33|0)>>0]=h;Zl(f+(b*33|0)+1|0,1,30,e)|0;f=Kl(e)|0;a[(c[d>>2]|0)+(b*33|0)+31>>0]=f;f=Kl(e)|0;a[(c[d>>2]|0)+(b*33|0)+32>>0]=f;b=b+1|0}while((b|0)<(c[g>>2]|0));return 0}function Uc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0;d=Kl(e)|0;b=d&255;g=f+32|0;c[g>>2]=b;if(!(d<<24>>24))return 0;d=f+44|0;c[d>>2]=Qm(b,33)|0;b=0;do{h=Kl(e)|0;f=c[d>>2]|0;a[f+(b*33|0)>>0]=h;Zl(f+(b*33|0)+1|0,1,30,e)|0;f=Kl(e)|0;a[(c[d>>2]|0)+(b*33|0)+31>>0]=f;f=Kl(e)|0;a[(c[d>>2]|0)+(b*33|0)+32>>0]=f;b=b+1|0}while((b|0)<(c[g>>2]|0));return 0}function Vc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0;d=Kl(e)|0;b=d&255;g=f+36|0;c[g>>2]=b;if(!(d<<24>>24))return 0;d=f+48|0;c[d>>2]=Qm(b,33)|0;b=0;do{h=Kl(e)|0;f=c[d>>2]|0;a[f+(b*33|0)>>0]=h;Zl(f+(b*33|0)+1|0,1,30,e)|0;f=Kl(e)|0;a[(c[d>>2]|0)+(b*33|0)+31>>0]=f;f=Kl(e)|0;a[(c[d>>2]|0)+(b*33|0)+32>>0]=f;b=b+1|0}while((b|0)<(c[g>>2]|0));return 0}function Wc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;y=l;l=l+48|0;r=y;u=b+140|0;c[u>>2]=(Kl(e)|0)&255;if((nb(b)|0)<0){f=-1;l=y;return f|0}x=b+176|0;if((c[u>>2]|0)<=0){f=0;l=y;return f|0}q=r+32|0;w=f+8|0;v=f+12|0;s=f+16|0;p=c[x>>2]|0;t=0;while(1){o=(Kl(e)|0)&255;c[(c[f>>2]|0)+(t<<2)>>2]=o;o=p+(t*764|0)+36|0;c[o>>2]=(Kl(e)|0)&255;Zl(r,1,32,e)|0;a[q>>0]=0;pl(r)|0;yo(p+(t*764|0)|0,r,32)|0;if((ob(b,t,c[o>>2]|0)|0)<0){d=-1;g=27;break}else d=0;do{a[p+(t*764|0)+512+(d<<1)>>0]=-1;d=d+1|0}while((d|0)!=121);d=c[x>>2]|0;if((c[d+(t*764|0)+36>>2]|0)>0){o=p+(t*764|0)+756|0;n=p+(t*764|0)+40|0;m=0;d=0;while(1){j=c[o>>2]|0;c[j+(m<<6)+40>>2]=(Kl(e)|0)&255;k=(Kl(e)|0)&255;g=k+12|0;i=j+(m<<6)|0;c[i>>2]=(Kl(e)|0)&255;if((d|0)<=(g|0)){h=m&255;while(1){if((d|0)<121)a[p+(t*764|0)+512+(d<<1)>>0]=h;if((d|0)<(g|0))d=d+1|0;else break}}d=(Kl(e)|0)&255;g=(m|0)==0;if(g)c[(c[w>>2]|0)+(t<<2)>>2]=d&128|0?d&63:-1;if(!(d&64))c[i>>2]=255;d=((Kl(e)|0)&255)<<1;c[(c[(c[x>>2]|0)+(t*764|0)+756>>2]|0)+(m<<6)+8>>2]=d;d=(Kl(e)|0)&255;if(g)c[(c[v>>2]|0)+(t<<2)>>2]=d&128|0?d&63:-1;if(!(d&64))c[j+(m<<6)+8>>2]=128;d=Ml(e)|0;if(g)c[n>>2]=d&65535;c[j+(m<<6)+28>>2]=(Kl(e)|0)&255;c[j+(m<<6)+24>>2]=((Kl(e)|0)&255)>>>1;c[j+(m<<6)+32>>2]=(Kl(e)|0)&255;c[j+(m<<6)+20>>2]=(Kl(e)|0)&255;Kl(e)|0;d=(Kl(e)|0)&255;if(g)c[(c[s>>2]|0)+(t<<2)>>2]=d&128|0?d&63:-1;m=m+1|0;d=c[x>>2]|0;if((m|0)>=(c[d+(t*764|0)+36>>2]|0))break;else d=k+13|0}}t=t+1|0;if((t|0)>=(c[u>>2]|0)){d=0;g=27;break}else p=d}if((g|0)==27){l=y;return d|0}return 0}function Xc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;e=Kl(d)|0;h=e&255;i=a+128|0;c[i>>2]=h;h=Qm(4,h)|0;j=a+168|0;c[j>>2]=h;if(!h){a=-1;return a|0}if(!(e<<24>>24)){a=0;return a|0}b=a+136|0;g=0;while(1){if((qb(a,g)|0)<0){e=-1;b=10;break}h=Kl(d)|0;f=h&255;e=((Kl(d)|0)&255)+1|0;c[c[(c[j>>2]|0)+(g<<2)>>2]>>2]=e;_l(d,16,1)|0;if(h<<24>>24){h=0;do{e=Ml(d)|0;if((h|0)<(c[b>>2]|0))c[(c[(c[j>>2]|0)+(g<<2)>>2]|0)+4+(h<<2)>>2]=e&65535;h=h+1|0}while((h|0)!=(f|0))}g=g+1|0;if((g|0)>=(c[i>>2]|0)){e=0;b=10;break}}if((b|0)==10)return e|0;return 0}function Yc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=l;l=l+64|0;q=s;g=Kl(e)|0;d=g&255;r=b+144|0;c[r>>2]=d;h=Qm(52,d)|0;p=b+180|0;c[p>>2]=h;if(!h){e=-1;l=s;return e|0}n=Qm(4,d)|0;o=f+24|0;c[o>>2]=n;if(!n){e=-1;l=s;return e|0}if(!(g<<24>>24)){e=0;l=s;return e|0}n=f+4|0;m=q+32|0;k=f+20|0;d=0;while(1){f=(Kl(e)|0)&255;c[(c[n>>2]|0)+(d<<2)>>2]=f;Zl(q,1,32,e)|0;a[m>>0]=0;pl(q)|0;yo(h+(d*52|0)|0,q,32)|0;_l(e,8,1)|0;f=Vl(e)|0;c[(c[k>>2]|0)+(d<<2)>>2]=f;f=h+(d*52|0)+32|0;c[f>>2]=Vl(e)|0;j=h+(d*52|0)+36|0;c[j>>2]=Vl(e)|0;g=Vl(e)|0;i=h+(d*52|0)+40|0;h=h+(d*52|0)+44|0;c[h>>2]=(g|0)>0?2:0;c[i>>2]=(c[j>>2]|0)+g;Kl(e)|0;g=(Kl(e)|0)&255;b=c[h>>2]|0;if(g&1){b=b|1;c[h>>2]=b;c[f>>2]=c[f>>2]>>1;c[j>>2]=c[j>>2]>>1;c[i>>2]=c[i>>2]>>1}c[h>>2]=b|g<<1&4;c[(c[o>>2]|0)+(d<<2)>>2]=g>>>2&3;d=d+1|0;if((d|0)>=(c[r>>2]|0)){d=0;break}h=c[p>>2]|0}l=s;return d|0}function Zc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;e=Kl(d)|0;g=e&255;h=a+128|0;c[h>>2]=g;g=Qm(4,g)|0;i=a+168|0;c[i>>2]=g;if(!g){a=-1;return a|0}if(!(e<<24>>24)){a=0;return a|0}b=a+136|0;f=0;while(1){if((qb(a,f)|0)<0){e=-1;b=10;break}c[c[(c[i>>2]|0)+(f<<2)>>2]>>2]=64;g=0;do{e=Ml(d)|0;if((g|0)<(c[b>>2]|0))c[(c[(c[i>>2]|0)+(f<<2)>>2]|0)+4+(g<<2)>>2]=e&65535;g=g+1|0}while((g|0)!=32);f=f+1|0;if((f|0)>=(c[h>>2]|0)){e=0;b=10;break}}if((b|0)==10)return e|0;return 0}function _c(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;v=l;l=l+64|0;t=v;s=(Kl(e)|0)&255;d=b+144|0;c[d>>2]=s;u=b+140|0;c[u>>2]=s;if((nb(b)|0)<0){f=-1;l=v;return f|0}s=Qm(4,c[d>>2]|0)|0;p=f+24|0;c[p>>2]=s;if(!s){f=-1;l=v;return f|0}s=b+180|0;if((c[u>>2]|0)<=0){f=0;l=v;return f|0}r=b+176|0;q=f+4|0;m=t+32|0;n=f+20|0;o=0;while(1){d=c[s>>2]|0;c[(c[r>>2]|0)+(o*764|0)+36>>2]=1;if((ob(b,o,1)|0)<0){d=-1;g=9;break}g=c[(c[r>>2]|0)+(o*764|0)+756>>2]|0;i=(Kl(e)|0)&255;c[(c[q>>2]|0)+(o<<2)>>2]=i;c[(c[f>>2]|0)+(o<<2)>>2]=i;c[g+40>>2]=i;Zl(t,1,32,e)|0;a[m>>0]=0;pl(t)|0;_l(e,8,1)|0;yo((c[r>>2]|0)+(o*764|0)|0,t,32)|0;i=(Ml(e)|0)&65535;c[(c[n>>2]|0)+(o<<2)>>2]=i;i=d+(o*52|0)+32|0;c[i>>2]=Vl(e)|0;k=d+(o*52|0)+36|0;c[k>>2]=Vl(e)|0;w=Vl(e)|0;j=d+(o*52|0)+40|0;h=d+(o*52|0)+44|0;c[h>>2]=(w|0)>0?2:0;c[j>>2]=(c[k>>2]|0)+w;c[g>>2]=(Kl(e)|0)&255;c[g+8>>2]=128;g=(Kl(e)|0)&255;d=c[h>>2]|0;if(g&1){d=d|1;c[h>>2]=d;c[i>>2]=c[i>>2]>>1;c[k>>2]=c[k>>2]>>1;c[j>>2]=c[j>>2]>>1}c[h>>2]=d|g<<1&4;c[(c[p>>2]|0)+(o<<2)>>2]=g>>>2&3;o=o+1|0;if((o|0)>=(c[u>>2]|0)){d=0;g=9;break}}if((g|0)==9){l=v;return d|0}return 0}function $c(e,f,g,h,i){e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0;e=h+(e<<2)|0;if((c[e>>2]|0)<=-1)return;c[f>>2]=1;l=f+4|0;c[l>>2]=16;if((i|0)<=0)return;h=c[e>>2]|0;k=0;while(1){if((h|0)==(d[g+(k*33|0)>>0]|0|0))break;e=k+1|0;if((e|0)<(i|0))k=e;else{j=10;break}}if((j|0)==10)return;e=d[g+(k*33|0)+31>>0]|0;c[f>>2]=e>>>3&6|1;c[f+12>>2]=e&15;e=d[g+(k*33|0)+32>>0]|0;c[f+20>>2]=e&15;c[f+24>>2]=e&240;e=0;i=-1;while(1){j=e<<1;h=a[g+(k*33|0)+1+j>>0]|0;if(!(h<<24>>24))break;h=(h&255)+i|0;b[f+28+(j<<1)>>1]=h;j=j|1;b[f+28+(j<<1)>>1]=d[g+(k*33|0)+1+j>>0]|0;e=e+1|0;if((e|0)<(c[l>>2]|0))i=h<<16>>16;else break}c[l>>2]=e;return}function ad(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0;n=l;l=l+32|0;k=n+16|0;m=n;j=n+8|0;c[k>>2]=d;c[m>>2]=e;cd(0,k,m,j)|0;if((f|0)>0){h=0;i=0}else{l=n;return}while(1){g=cd(1,k,m,j)|0;if(!(cd(1,k,m,j)|0)){a:do if((c[m>>2]|0)>-1){d=8;while(1){e=(d&255)+16&255;if(cd(1,k,m,j)|0)break a;if((c[m>>2]|0)>-1)d=e;else{d=e;break}}}else d=8;while(0);d=(cd(4,k,m,j)|0)+(d&255)|0}else d=cd(3,k,m,j)|0;h=(((g|0)==0?d:d^255)&255)+(h&255)|0;a[b>>0]=h;i=i+1|0;if((i|0)==(f|0))break;else b=b+1|0}l=n;return}function bd(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0;o=l;l=l+32|0;m=o+16|0;n=o;k=o+8|0;c[m>>2]=d;c[n>>2]=e;cd(0,m,n,k)|0;if((f|0)>0){i=0;j=0}else{l=o;return}while(1){g=cd(8,m,n,k)|0;h=cd(1,m,n,k)|0;if(!(cd(1,m,n,k)|0)){a:do if((c[n>>2]|0)>-1){d=8;while(1){e=(d&255)+16&255;if(cd(1,m,n,k)|0)break a;if((c[n>>2]|0)>-1)d=e;else{d=e;break}}}else d=8;while(0);d=(cd(4,m,n,k)|0)+(d&255)|0}else d=cd(3,m,n,k)|0;i=(((h|0)==0?d:d^255)&255)+(i&255)|0;a[b>>0]=g;a[b+1>>0]=i;j=j+1|0;if((j|0)==(f|0))break;else b=b+2|0}l=o;return}function cd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;g=a<<24>>24;if(!(a<<24>>24)){i=c[b>>2]|0;c[e>>2]=fj(i)|0;c[b>>2]=i+4;c[d>>2]=(c[d>>2]|0)+-4;c[e+4>>2]=32;d=0;return d|0}i=c[e>>2]|0;f=i&(1<>>g;c[e>>2]=i;h=e+4|0;a=(c[h>>2]|0)-g|0;c[h>>2]=a;if(a>>>0>=25){d=f;return d|0}if(!(c[d>>2]|0)){d=f;return d|0}g=c[b>>2]|0;c[b>>2]=g+1;c[e>>2]=i|(fj(g)|0)<>2]=a+8;c[d>>2]=(c[d>>2]|0)+-1;d=f;return d|0}function dd(b,c){b=b|0;c=c|0;var d=0,e=0;switch(a[b>>0]|0){case 0:{d=c;e=4;break}case 5:{d=b;e=4;break}case 6:{a[c>>0]=0;d=b;e=4;break}default:{}}if((e|0)==4)a[d>>0]=0;fd(b,c);return}function ed(b,c){b=b|0;c=c|0;switch(a[b>>0]|0){case 0:{a[c>>0]=0;break}case 1:{a[b>>0]=-96;break}case 2:{a[b>>0]=-95;break}case 3:{a[b>>0]=27;break}case 4:{a[b>>0]=7;break}case 5:{a[b>>0]=29;break}case 6:{a[c>>0]=0;a[b>>0]=0;break}default:{}}fd(b,c);return}function fd(b,c){b=b|0;c=c|0;switch(a[b>>0]|0){case 7:{a[b>>0]=-85;return}case 10:case 9:case 8:{a[c>>0]=0;a[b>>0]=0;return}case 15:{a[b>>0]=-93;return}case 14:switch((d[c>>0]|0)>>>4&15){case 8:case 3:case 0:{a[c>>0]=0;a[b>>0]=0;return}case 1:{a[b>>0]=25;a[c>>0]=d[c>>0]<<4;return}case 2:{a[b>>0]=25;a[c>>0]=a[c>>0]&15;return}default:return}default:return}}function gd(a,b,c){a=a|0;b=b|0;c=c|0;if((Xl(a)|0)==1229803597){xb(a,b,26);a=0}else a=-1;return a|0} -function il(a,b){a=a|0;b=b|0;var d=0;d=c[a+8112>>2]|0;b=b+1|0;a=c[d+4>>2]|0;if((a|0)==(b|0)){d=0;return d|0}if((a|0)>=0){a=c[d+8>>2]|0;if((a|0)==(b|0)){d=1;return d|0}if((a|0)>=0){a=c[d+12>>2]|0;if((a|0)==(b|0)){d=2;return d|0}if((a|0)>=0){a=c[d+16>>2]|0;if((a|0)==(b|0)){d=3;return d|0}if((a|0)>=0){a=c[d+20>>2]|0;if((a|0)==(b|0)){d=4;return d|0}if((a|0)>=0){a=c[d+24>>2]|0;if((a|0)==(b|0)){d=5;return d|0}if((a|0)>=0){a=c[d+28>>2]|0;if((a|0)==(b|0)){d=6;return d|0}if((a|0)>=0){a=c[d+32>>2]|0;if((a|0)==(b|0)){d=7;return d|0}if((a|0)>=0){a=c[d+36>>2]|0;if((a|0)==(b|0)){d=8;return d|0}if((a|0)<0)a=8;else{d=-1;return d|0}}else a=7}else a=6}else a=5}else a=4}else a=3}else a=2}else a=1}else a=0;c[d+4+(a<<2)>>2]=b;d=a;return d|0}function jl(a,b){a=a|0;b=b|0;mk(a,0,b);return}function kl(a,b,d){a=a|0;b=b|0;d=d|0;mk(c[a>>2]|0,0,b);mk(c[a>>2]|0,1,d);return}function ll(a){a=a|0;var b=0;a=(c[a+8112>>2]|0)+4|0;b=a+36|0;do{c[a>>2]=-1;a=a+4|0}while((a|0)<(b|0));return}function ml(a){a=a|0;Pm(a);return}function nl(){var a=0,b=0,d=0;a=Om(40)|0;if(!a){d=0;return d|0}b=a+4|0;d=b+36|0;do{c[b>>2]=-1;b=b+4|0}while((b|0)<(d|0));d=a;return d|0}function ol(a){a=a|0;var b=0;b=za(22459)|0;yo(a,b|0?b:22466,4096)|0;Lo(a)|0;return}function pl(b){b=b|0;var c=0,d=0;c=a[b>>0]|0;if(!(c<<24>>24))return b|0;else d=0;while(1){if(c<<24>>24<0|(In(c<<24>>24)|0)==0)a[b+d>>0]=32;d=d+1|0;if(d>>>0>=(Zn(b)|0)>>>0)break;c=a[b+d>>0]|0}if(!(a[b>>0]|0))return b|0;while(1){c=b+((Zn(b)|0)+-1)|0;if((a[c>>0]|0)!=32){c=9;break}a[c>>0]=0;if(!(a[b>>0]|0)){c=9;break}}if((c|0)==9)return b|0;return 0}function ql(a){a=a|0;var b=0,d=0,e=0;b=a+2800|0;d=a+1552|0;e=d+128|0;do{c[d>>2]=0;d=d+4|0}while((d|0)<(e|0));h[b>>3]=250.0;c[a+2816>>2]=8287;c[a+2820>>2]=64;c[a+2824>>2]=64;c[a+2828>>2]=0;c[a+2832>>2]=0;c[a+2836>>2]=0;c[a+2772>>2]=0;c[a+8116>>2]=0;c[a+1680>>2]=0;c[a+1684>>2]=0;c[a+1688>>2]=4;c[a+1692>>2]=0;c[a+1696>>2]=0;c[a+1700>>2]=6;c[a+1704>>2]=125;c[a+1708>>2]=0;c[a+1712>>2]=0;c[a+8108>>2]=7184;c[a+8104>>2]=0;h[a+2808>>3]=10.0;b=a+2844|0;d=0;do{e=d;d=d+1|0;c[a+1736+(e*12|0)>>2]=((O(c[b>>2]|0,((((d|0)/2|0|0)%2|0)*255|0)+-128|0)|0)/100|0)+128;c[a+1736+(e*12|0)+4>>2]=64;c[a+1736+(e*12|0)+8>>2]=0}while((d|0)!=64);return}function rl(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;c[a+1716>>2]=c[a+2824>>2];b=a+1712|0;if((c[b>>2]|0)>=(c[a+1708>>2]|0))c[b>>2]=0;b=a+1700|0;if(!(c[b>>2]|0))c[b>>2]=6;b=a+1704|0;if(!(c[b>>2]|0))c[b>>2]=125;k=a+1692|0;b=c[k>>2]|0;if((b|0)<=0){k=a+24|0;k=c[k>>2]|0;l=a+28|0;c[l>>2]=k;tl(a);return}i=(c[a+2832>>2]&16384|0)==0;j=a+2820|0;l=a+1728|0;d=c[l>>2]|0;f=0;do{if(i)c[d+(f*764|0)+32>>2]=c[j>>2];e=c[d+(f*764|0)+36>>2]|0;if((e|0)>0){h=d+(f*764|0)+756|0;g=0;do{if(i)c[(c[h>>2]|0)+(g<<6)+4>>2]=c[j>>2];g=g+1|0}while((g|0)!=(e|0))}f=f+1|0}while((f|0)!=(b|0));b=0;while(1){sl(d+(b*764|0)+44|0);sl((c[l>>2]|0)+(b*764|0)+356|0);sl((c[l>>2]|0)+(b*764|0)+200|0);b=b+1|0;if((b|0)>=(c[k>>2]|0))break;d=c[l>>2]|0}k=a+24|0;k=c[k>>2]|0;l=a+28|0;c[l>>2]=k;tl(a);return}function sl(a){a=a|0;var b=0;b=c[a+4>>2]|0;if(((b|0)>=1?(c[a+20>>2]|0)<(b|0):0)?(c[a+24>>2]|0)<(b|0):0)return;c[a>>2]=c[a>>2]&-5;return}function tl(a){a=a|0;var b=0;b=a+2776|0;a=a+28|0;if(!(en(b,7408,16)|0))c[a>>2]=c[a>>2]|2;if(!(en(b,7428,16)|0))c[a>>2]=c[a>>2]|4;if(!(en(b,7448,16)|0))c[a>>2]=c[a>>2]|1;if(en(b,7468,16)|0)return;c[a>>2]=c[a>>2]|1;return}function ul(a){a=a|0;var b=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;i=a+1552|0;k=a+1720|0;if(!(c[k>>2]|0)){l=-4;return l|0}if(!(c[a+1724>>2]|0)){l=-4;return l|0}l=a+1708|0;b=c[l>>2]|0;a:do if((b|0)>0){j=a+1680|0;f=c[j>>2]|0;e=0;while(1){if((d[a+2504+e>>0]|0|0)<(f|0))break;e=e+1|0;if((e|0)>=(b|0))break a}e=Qm(4,b)|0;g=a+8116|0;c[g>>2]=e;if(!e){l=-6;return l|0}else e=0;while(1){b=d[a+2504+e>>0]|0;if((b|0)<(f|0)?(c[(c[k>>2]|0)+(b<<2)>>2]|0)==0:0){if((qb(i,b)|0)<0){b=-6;e=18;break}f=c[j>>2]|0}if((b|0)<(f|0)?(h=c[(c[k>>2]|0)+(b<<2)>>2]|0,(h|0)!=0):0){b=c[h>>2]|0;b=(b|0)==0?1:b}else b=1;b=Qm(1,b)|0;c[(c[g>>2]|0)+(e<<2)>>2]=b;if(!(c[(c[g>>2]|0)+(e<<2)>>2]|0)){b=-6;e=18;break}e=e+1|0;if((e|0)>=(c[l>>2]|0)){b=0;e=18;break}}if((e|0)==18)return b|0}while(0);c[l>>2]=0;l=0;return l|0}function vl(a){a=a|0;var b=0,d=0,e=0,f=0,g=0;b=a+8140|0;if((c[b>>2]|0)>1)qi(a);c[b>>2]=0;om(a);e=a+1684|0;if((c[e>>2]|0)>0){f=a+1724|0;d=0;do{Pm(c[(c[f>>2]|0)+(d<<2)>>2]|0);d=d+1|0;b=c[e>>2]|0}while((d|0)<(b|0));if((b|0)>0)Pm(c[f>>2]|0)}e=a+1680|0;if((c[e>>2]|0)>0){f=a+1720|0;d=0;do{Pm(c[(c[f>>2]|0)+(d<<2)>>2]|0);d=d+1|0;b=c[e>>2]|0}while((d|0)<(b|0));if((b|0)>0)Pm(c[f>>2]|0)}e=a+1692|0;if((c[e>>2]|0)>0){f=a+1728|0;d=0;do{Pm(c[(c[f>>2]|0)+(d*764|0)+756>>2]|0);Pm(c[(c[f>>2]|0)+(d*764|0)+760>>2]|0);d=d+1|0;b=c[e>>2]|0}while((d|0)<(b|0));if((b|0)>0)Pm(c[f>>2]|0)}f=a+1696|0;b=c[f>>2]|0;if((b|0)>0){g=a+1732|0;e=0;do{d=c[(c[g>>2]|0)+(e*52|0)+48>>2]|0;if(d){Pm(d+-4|0);b=c[f>>2]|0}e=e+1|0}while((e|0)<(b|0));if((b|0)>0)Pm(c[g>>2]|0)}f=a+8116|0;b=c[f>>2]|0;if(!b){g=a+2772|0;g=c[g>>2]|0;Pm(g);g=a+2760|0;g=c[g>>2]|0;Pm(g);a=a+2764|0;a=c[a>>2]|0;Pm(a);return}e=a+1708|0;if((c[e>>2]|0)>0){d=0;do{Pm(c[b+(d<<2)>>2]|0);d=d+1|0;b=c[f>>2]|0}while((d|0)<(c[e>>2]|0))}Pm(b);g=a+2772|0;g=c[g>>2]|0;Pm(g);g=a+2760|0;g=c[g>>2]|0;Pm(g);a=a+2764|0;a=c[a>>2]|0;Pm(a);return}function wl(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;g=a+1552|0;ql(a);f=3500;e=0;while(1){_l(b,0,0)|0;d=Ja[c[(c[f>>2]|0)+4>>2]&255](b,0,0)|0;e=e+1|0;if(!d){h=4;break}if((e|0)==53){e=-1;break}else f=3500+(e<<2)|0}if((h|0)==4){_l(b,0,0)|0;e=Ja[c[(c[f>>2]|0)+8>>2]&255](g,b,0)|0;d=0}if(!(e|d))xl(b,a+2776|0);dm(b);if((d|0)<0){Pm(c[a+2764>>2]|0);Pm(c[a+2760>>2]|0);a=-3;return a|0}if((e|0)<0){vl(a);a=-4;return a|0}pl(g)|0;rl(a);d=ul(a)|0;if((d|0)<0){a=d;return a|0}Aj(a);c[a+8140>>2]=1;a=0;return a|0}function xl(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0;h=l;l=l+16560|0;f=h+168|0;g=h;e=h+88|0;if((fm(b,e)|0)<0){l=h;return}if((c[e+36>>2]|0)<1){e=d+16|0;do{a[d>>0]=0;d=d+1|0}while((d|0)<(e|0));l=h;return}_l(b,0,0)|0;lj(g);e=Zl(f,1,16384,b)|0;if((e|0)>0)do{mj(g,f,e);e=Zl(f,1,16384,b)|0}while((e|0)>0);oj(d,g);l=h;return}function yl(a,b,d){a=a|0;b=b|0;d=d|0;b=cm(b,(((d|0)==0)<<31>>31)+d|0)|0;if(!b){a=-6;return a|0}if((c[a+8140>>2]|0)>0)vl(a);c[a+2768>>2]=0;c[a+2764>>2]=0;c[a+2760>>2]=0;c[a+2792>>2]=0;a=wl(a,b)|0;return a|0}function zl(a){a=a|0;var b=0,e=0;if((Al(a)|0)<=0){a=-1;return a|0}b=c[a>>2]|0;e=a+4|0;a=c[e>>2]|0;c[e>>2]=a+1;a=d[b+a>>0]|0;return a|0}function Al(a){a=a|0;var b=0;b=c[a+8>>2]|0;if((b|0)<=-1){a=2147483647;return a|0}a=c[a+4>>2]|0;a=(a|0)>-1?b-a|0:0;return a|0}function Bl(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=O(d,b)|0;d=Al(e)|0;if((d|0)<1){b=0;return b|0}f=f>>>0>d>>>0?d:f;d=e+4|0;ap(a|0,(c[e>>2]|0)+(c[d>>2]|0)|0,f|0)|0;c[d>>2]=(c[d>>2]|0)+f;b=(f>>>0)/(b>>>0)|0;return b|0}function Cl(a,b,d){a=a|0;b=b|0;d=d|0;switch(d|0){case 2:{d=c[a+8>>2]|0;if((d|0)<0){b=-1;return b|0}c[a+4>>2]=d+b;b=0;return b|0}case 1:{if((c[a+8>>2]|0)>-1){if((Al(a)|0)<(b|0)){b=-1;return b|0}a=a+4|0;d=c[a>>2]|0;if((b|0)<(0-d|0)){b=-1;return b|0}}else{a=a+4|0;d=c[a>>2]|0}c[a>>2]=d+b;b=0;return b|0}default:{d=c[a+8>>2]|0;if((d|0)>-1?(b|0)<0|(d|0)<(b|0):0){b=-1;return b|0}c[a+4>>2]=b;b=0;return b|0}}return 0}function Dl(a){a=a|0;return a|0}function El(a){a=a|0;if((c[a+8>>2]|0)<1){a=0;return a|0}a=(Al(a)|0)<1&1;return a|0}function Fl(a,b){a=a|0;b=b|0;var d=0;d=Om(12)|0;if(!d){b=0;return b|0}c[d>>2]=a;c[d+4>>2]=0;c[d+8>>2]=b;b=d;return b|0}function Gl(a){a=a|0;Pm(a);return}function Hl(a,b){a=a|0;b=b|0;var d=0,e=0;d=b;e=d+76|0;do{c[d>>2]=0;d=d+4|0}while((d|0)<(e|0));c[b+36>>2]=c[a+8>>2];return}function Il(a){a=a|0;switch(c[a>>2]|0){case 0:{a=Wi(c[a+4>>2]|0)|0;break}case 1:{a=Jl(c[a+4>>2]|0)|0;break}default:a=0}return a|0}function Jl(a){a=a|0;return (zl(a)|0)&255|0}function Kl(a){a=a|0;switch(c[a>>2]|0){case 0:{a=Vi(c[a+4>>2]|0)|0;break}case 1:{a=Ll(c[a+4>>2]|0)|0;break}default:a=0}return a|0}function Ll(a){a=a|0;return (zl(a)|0)&255|0}function Ml(a){a=a|0;switch(c[a>>2]|0){case 0:{a=Xi(c[a+4>>2]|0)|0;break}case 1:{a=Nl(c[a+4>>2]|0)|0;break}default:a=0}return a|0}function Nl(b){b=b|0;var d=0,e=0,f=0;d=Ol(b)|0;e=b+4|0;f=c[e>>2]|0;if((d|0)>1){b=(c[b>>2]|0)+f|0;d=2;b=bj(a[b>>0]|0,a[b+1>>0]|0)|0}else b=-1;c[e>>2]=f+d;return b|0}function Ol(a){a=a|0;var b=0;b=c[a+8>>2]|0;if((b|0)<=-1){a=2147483647;return a|0}a=c[a+4>>2]|0;a=(a|0)>-1?b-a|0:0;return a|0}function Pl(a){a=a|0;switch(c[a>>2]|0){case 0:{a=Yi(c[a+4>>2]|0)|0;break}case 1:{a=Ql(c[a+4>>2]|0)|0;break}default:a=0}return a|0}function Ql(b){b=b|0;var d=0,e=0,f=0;d=Ol(b)|0;e=b+4|0;f=c[e>>2]|0;if((d|0)>1){b=(c[b>>2]|0)+f|0;d=2;b=cj(a[b>>0]|0,a[b+1>>0]|0)|0}else b=-1;c[e>>2]=f+d;return b|0}function Rl(a){a=a|0;switch(c[a>>2]|0){case 0:{a=Zi(c[a+4>>2]|0)|0;break}case 1:{a=Sl(c[a+4>>2]|0)|0;break}default:a=0}return a|0}function Sl(b){b=b|0;var d=0,e=0,f=0;f=Ol(b)|0;d=b+4|0;e=c[d>>2]|0;if((f|0)<=2){b=-1;f=e+f|0;c[d>>2]=f;return b|0}b=(c[b>>2]|0)+e|0;f=3;b=dj(a[b>>0]|0,a[b+1>>0]|0,a[b+2>>0]|0)|0;f=e+f|0;c[d>>2]=f;return b|0}function Tl(a){a=a|0;switch(c[a>>2]|0){case 0:{a=_i(c[a+4>>2]|0)|0;break}case 1:{a=Ul(c[a+4>>2]|0)|0;break}default:a=0}return a|0}function Ul(b){b=b|0;var d=0,e=0,f=0;f=Ol(b)|0;d=b+4|0;e=c[d>>2]|0;if((f|0)<=2){b=-1;f=e+f|0;c[d>>2]=f;return b|0}b=(c[b>>2]|0)+e|0;f=3;b=ej(a[b>>0]|0,a[b+1>>0]|0,a[b+2>>0]|0)|0;f=e+f|0;c[d>>2]=f;return b|0}function Vl(a){a=a|0;switch(c[a>>2]|0){case 0:{a=$i(c[a+4>>2]|0)|0;break}case 1:{a=Wl(c[a+4>>2]|0)|0;break}default:a=0}return a|0}function Wl(a){a=a|0;var b=0,d=0,e=0;b=Ol(a)|0;d=a+4|0;e=c[d>>2]|0;if((b|0)>3){b=4;a=fj((c[a>>2]|0)+e|0)|0}else a=-1;c[d>>2]=e+b;return a|0}function Xl(a){a=a|0;switch(c[a>>2]|0){case 0:{a=aj(c[a+4>>2]|0)|0;break}case 1:{a=Yl(c[a+4>>2]|0)|0;break}default:a=0}return a|0}function Yl(a){a=a|0;var b=0,d=0,e=0;b=Ol(a)|0;d=a+4|0;e=c[d>>2]|0;if((b|0)>3){b=4;a=gj((c[a>>2]|0)+e|0)|0}else a=-1;c[d>>2]=e+b;return a|0}function Zl(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;switch(c[e>>2]|0){case 0:{b=Go(a,b,d,c[e+4>>2]|0)|0;return b|0}case 1:{b=Bl(a,b,d,c[e+4>>2]|0)|0;return b|0}default:{b=0;return b|0}}return 0}function _l(a,b,d){a=a|0;b=b|0;d=d|0;switch(c[a>>2]|0){case 0:{d=ro(c[a+4>>2]|0,b,d)|0;return d|0}case 1:{d=Cl(c[a+4>>2]|0,b,d)|0;return d|0}default:{d=-1;return d|0}}return 0}function $l(a){a=a|0;switch(c[a>>2]|0){case 0:{a=Ho(c[a+4>>2]|0)|0;return a|0}case 1:{a=Dl(c[(c[a+4>>2]|0)+4>>2]|0)|0;return a|0}default:{a=-1;return a|0}}return 0}function am(a){a=a|0;switch(c[a>>2]|0){case 0:{a=qo(c[a+4>>2]|0)|0;break}case 1:{a=El(c[a+4>>2]|0)|0;break}default:a=-1}return a|0}function bm(a,b){a=a|0;b=b|0;var d=0;d=Om(8)|0;if(!d){a=0;return a|0}c[d>>2]=0;a=ho(a,b)|0;c[d+4>>2]=a;if(a|0){a=d;return a|0}Pm(d);a=0;return a|0}function cm(a,b){a=a|0;b=b|0;var d=0;d=Om(8)|0;if(!d){b=0;return b|0}c[d>>2]=1;c[d+4>>2]=Fl(a,b)|0;b=d;return b|0}function dm(a){a=a|0;switch(c[a>>2]|0){case 0:{no(c[a+4>>2]|0)|0;break}case 1:{Gl(c[a+4>>2]|0);break}default:{}}Pm(a);return}function em(a){a=a|0;var b=0;b=Om(8)|0;if(!b){a=0;return a|0}c[b>>2]=0;a=jo(a,21624)|0;c[b+4>>2]=a;if(a|0){a=b;return a|0}Pm(b);a=0;return a|0}function fm(a,b){a=a|0;b=b|0;switch(c[a>>2]|0){case 0:{b=Ln(Eo(c[a+4>>2]|0)|0,b)|0;return b|0}case 1:{Hl(c[a+4>>2]|0,b);b=0;return b|0}default:{b=-1;return b|0}}return 0}function gm(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=c[e+400>>2]|0;if((g|0)==0?c[e>>2]&67584|0:0)c[r+4>>2]=0;l=b+1728|0;h=c[l>>2]|0;k=e+44|0;i=c[k>>2]|0;p=r+4|0;n=c[p>>2]|0;g=c[h+(i*764|0)+760>>2]|0;j=d[g+12+n>>0]|0;o=a[g+76+n>>0]&127;if((j|0)<(c[h+(i*764|0)+36>>2]|0)?(m=c[(c[h+(i*764|0)+756>>2]|0)+(j<<6)+40>>2]|0,q=e+56|0,(m|0)!=(c[q>>2]|0)):0){c[q>>2]=m;_h(b,f,m);g=c[(c[l>>2]|0)+((c[k>>2]|0)*764|0)+760>>2]|0}if((n|0)<(c[g+8>>2]|0)){e=n+1|0;c[p>>2]=e;r=r+8|0;c[r>>2]=o;return}e=c[g+4>>2]|0;c[p>>2]=e;r=r+8|0;c[r>>2]=o;return}function hm(a){a=a|0;var b=0;b=Qm(1,140)|0;c[a+760>>2]=b;if(!b){a=-1;return a|0}c[b>>2]=68929562;a=0;return a|0}function im(a){a=a|0;var b=0;b=Qm(1,12)|0;c[a+400>>2]=b;if(!b){a=-1;return a|0}c[b>>2]=68929562;a=0;return a|0}function jm(b){b=b|0;var c=0;b=b+4|0;c=b;a[c>>0]=0;a[c+1>>0]=0;a[c+2>>0]=0;a[c+3>>0]=0;b=b+4|0;a[b>>0]=0;a[b+1>>0]=0;a[b+2>>0]=0;a[b+3>>0]=0;return}function km(a){a=a|0;Pm(a);return}function lm(a){a=a|0;var b=0;b=Qm(1,4)|0;c[a+6552>>2]=b;if(!b){a=-1;return a|0}c[b>>2]=68929562;a=0;return a|0}function mm(a){a=a|0;Pm(a);return}function nm(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0;if(d<<24>>24!=-78)return;g=b+180|0;f=b+164|0;d=22473+((e&255)<<4)|0;b=f+16|0;do{a[f>>0]=a[d>>0]|0;f=f+1|0;d=d+1|0}while((f|0)<(b|0));c[g>>2]=16;return}function om(a){a=a|0;var b=0,d=0;d=a+1552|0;a=c[a+8104>>2]|0;if(!a)return;b=c[a>>2]|0;if((b|0)<133303461){switch(b|0){case 68929562:break;default:return}mm(a);return}else{switch(b|0){case 133303461:break;default:return}Oj(d);return}}function pm(a,b){a=a|0;b=b|0;a:do if(a|0){a=c[a>>2]|0;if((a|0)<133303461){switch(a|0){case 68929562:break;default:break a}if((im(b)|0)<0)a=-1;else break;return a|0}else{switch(a|0){case 133303461:break;default:break a}if((Kj(b)|0)<0)a=-1;else break;return a|0}}while(0);b=0;return b|0}function qm(a,b){a=a|0;b=b|0;if(!a)return;a=c[a>>2]|0;if((a|0)<133303461){switch(a|0){case 68929562:break;default:return}km(c[b+400>>2]|0);return}else{switch(a|0){case 133303461:break;default:return}Mj(c[b+400>>2]|0);return}}function rm(a,b){a=a|0;b=b|0;if(!a)return;a=c[a>>2]|0;if((a|0)<133303461){switch(a|0){case 68929562:break;default:return}jm(c[b+400>>2]|0);return}else{switch(a|0){case 133303461:break;default:return}Lj(c[b+400>>2]|0);return}}function sm(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=c[b+44>>2]|0;if((f|0)>=(c[a+1692>>2]|0))return;f=c[(c[a+1728>>2]|0)+(f*764|0)+760>>2]|0;if(!f)return;f=c[f>>2]|0;if((f|0)<133303461){switch(f|0){case 68929562:break;default:return}gm(a,b,d,e);return}else{switch(f|0){case 133303461:break;default:return}Ij(a,b,d,e);return}}function tm(a,b){a=a|0;b=b|0;var d=0,e=0;d=c[b+44>>2]|0;e=c[b+80>>2]|0;if((d|0)>=(c[a+1692>>2]|0)){b=e;return b|0}d=c[(c[a+1728>>2]|0)+(d*764|0)+760>>2]|0;if(!d){b=e;return b|0}d=c[d>>2]|0;if((d|0)<133303461){switch(d|0){case 68929562:break;default:{b=e;return b|0}}b=(O(c[(c[b+400>>2]|0)+8>>2]|0,e)|0)/64|0;return b|0}else{switch(d|0){case 133303461:break;default:{b=e;return b|0}}b=(O(c[(c[b+400>>2]|0)+76>>2]|0,e)|0)/64|0;return b|0}return 0}function um(a){a=a|0;var b=0;b=c[a+400>>2]|0;if((b|0)!=0?(c[b>>2]|0)==133303461:0)a=Gj(a)|0;else a=0;return a|0}function vm(a,b){a=a|0;b=b|0;var d=0;d=c[b+400>>2]|0;if((d|0)!=0?(c[d>>2]|0)==133303461:0)a=Hj(a,b)|0;else a=0;return a|0}function wm(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=c[a+400>>2]|0;if(!e)return;e=c[e>>2]|0;if((e|0)<133303461){switch(e|0){case 68929562:break;default:return}nm(a,b,d);return}else{switch(e|0){case 133303461:break;default:return}Pj(a,b);return}}function xm(a,b){a=a|0;b=b|0;var d=0;d=c[a+1692>>2]|0;if((d|0)<=(b|0))if(((c[a+8124>>2]|0)+d|0)>(b|0)){b=b-d|0;d=a+8132|0}else{a=0;return a|0}else d=a+1728|0;a=(c[d>>2]|0)+(b*764|0)|0;return a|0}function ym(a,b){a=a|0;b=b|0;var d=0;d=c[a+1696>>2]|0;if((d|0)<=(b|0))if(((c[a+8128>>2]|0)+d|0)>(b|0)){b=b-d|0;d=a+8136|0}else{a=0;return a|0}else d=a+1732|0;a=(c[d>>2]|0)+(b*52|0)|0;return a|0}function zm(){qi(c[6314]|0);vl(c[6314]|0);Dj(c[6314]|0);return 0}function Am(){var a=0;Ii(c[6314]|0);a=c[6723]|0;c[6727]=a;c[6728]=a+64;return 26908}function Bm(){return c[(c[6314]|0)+4>>2]|0}function Cm(){Hi(c[6314]|0);return 0}function Dm(){return c[6330]|0}function Em(){return c[(c[6314]|0)+1708>>2]|0}function Fm(){Ii(c[6314]|0);return 0}function Gm(){return c[6315]|0}function Hm(){return c[6326]|0}function Im(){return c[6327]|0}function Jm(){c[6314]=Cj()|0;return 0}function Km(a,b,d){a=a|0;b=b|0;d=d|0;d=(d|0)>4e3?d:4e3;c[6315]=(d|0)<49170?d:49170;return yl(c[6314]|0,a,b)|0}function Lm(){return si(c[6314]|0)|0}function Mm(a){a=a|0;Fj(c[6314]|0,a);return}function Nm(){pi(c[6314]|0,c[6315]|0);return 0}function Om(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;x=l;l=l+16|0;o=x;do if(a>>>0<245){k=a>>>0<11?16:a+11&-8;a=k>>>3;n=c[6729]|0;d=n>>>a;if(d&3|0){e=(d&1^1)+a|0;f=26956+(e<<1<<2)|0;b=f+8|0;a=c[b>>2]|0;g=a+8|0;d=c[g>>2]|0;if((f|0)==(d|0))c[6729]=n&~(1<>2]=f;c[b>>2]=d}w=e<<3;c[a+4>>2]=w|3;w=a+w+4|0;c[w>>2]=c[w>>2]|1;w=g;l=x;return w|0}m=c[6731]|0;if(k>>>0>m>>>0){if(d|0){h=2<>>12&16;d=d>>>h;a=d>>>5&8;d=d>>>a;f=d>>>2&4;d=d>>>f;b=d>>>1&2;d=d>>>b;e=d>>>1&1;e=(a|h|f|b|e)+(d>>>e)|0;d=26956+(e<<1<<2)|0;b=d+8|0;f=c[b>>2]|0;h=f+8|0;a=c[h>>2]|0;if((d|0)==(a|0)){a=n&~(1<>2]=d;c[b>>2]=a;a=n}g=(e<<3)-k|0;c[f+4>>2]=k|3;f=f+k|0;c[f+4>>2]=g|1;c[f+g>>2]=g;if(m|0){e=c[6734]|0;b=m>>>3;d=26956+(b<<1<<2)|0;b=1<>2]|0}c[b>>2]=e;c[a+12>>2]=e;c[e+8>>2]=a;c[e+12>>2]=d}c[6731]=g;c[6734]=f;w=h;l=x;return w|0}i=c[6730]|0;if(i){d=(i&0-i)+-1|0;h=d>>>12&16;d=d>>>h;g=d>>>5&8;d=d>>>g;j=d>>>2&4;d=d>>>j;a=d>>>1&2;d=d>>>a;e=d>>>1&1;e=c[27220+((g|h|j|a|e)+(d>>>e)<<2)>>2]|0;d=(c[e+4>>2]&-8)-k|0;a=c[e+16+(((c[e+16>>2]|0)==0&1)<<2)>>2]|0;if(!a){j=d;h=e}else{do{h=(c[a+4>>2]&-8)-k|0;j=h>>>0>>0;d=j?h:d;e=j?a:e;a=c[a+16+(((c[a+16>>2]|0)==0&1)<<2)>>2]|0}while((a|0)!=0);j=d;h=e}g=h+k|0;if(h>>>0>>0){f=c[h+24>>2]|0;b=c[h+12>>2]|0;do if((b|0)==(h|0)){a=h+20|0;b=c[a>>2]|0;if(!b){a=h+16|0;b=c[a>>2]|0;if(!b){d=0;break}}while(1){e=b+20|0;d=c[e>>2]|0;if(d|0){b=d;a=e;continue}e=b+16|0;d=c[e>>2]|0;if(!d)break;else{b=d;a=e}}c[a>>2]=0;d=b}else{d=c[h+8>>2]|0;c[d+12>>2]=b;c[b+8>>2]=d;d=b}while(0);do if(f|0){b=c[h+28>>2]|0;a=27220+(b<<2)|0;if((h|0)==(c[a>>2]|0)){c[a>>2]=d;if(!d){c[6730]=i&~(1<>2]|0)!=(h|0)&1)<<2)>>2]=d;if(!d)break}c[d+24>>2]=f;b=c[h+16>>2]|0;if(b|0){c[d+16>>2]=b;c[b+24>>2]=d}b=c[h+20>>2]|0;if(b|0){c[d+20>>2]=b;c[b+24>>2]=d}}while(0);if(j>>>0<16){w=j+k|0;c[h+4>>2]=w|3;w=h+w+4|0;c[w>>2]=c[w>>2]|1}else{c[h+4>>2]=k|3;c[g+4>>2]=j|1;c[g+j>>2]=j;if(m|0){e=c[6734]|0;b=m>>>3;d=26956+(b<<1<<2)|0;b=1<>2]|0}c[b>>2]=e;c[a+12>>2]=e;c[e+8>>2]=a;c[e+12>>2]=d}c[6731]=j;c[6734]=g}w=h+8|0;l=x;return w|0}else n=k}else n=k}else n=k}else if(a>>>0<=4294967231){a=a+11|0;k=a&-8;e=c[6730]|0;if(e){d=0-k|0;a=a>>>8;if(a)if(k>>>0>16777215)j=31;else{n=(a+1048320|0)>>>16&8;v=a<>>16&4;v=v<>>16&2;j=14-(m|n|j)+(v<>>15)|0;j=k>>>(j+7|0)&1|j<<1}else j=0;a=c[27220+(j<<2)>>2]|0;a:do if(!a){f=0;a=0;v=57}else{f=0;h=k<<((j|0)==31?0:25-(j>>>1)|0);i=a;a=0;while(1){g=(c[i+4>>2]&-8)-k|0;if(g>>>0>>0)if(!g){d=0;f=i;a=i;v=61;break a}else{d=g;a=i}g=c[i+20>>2]|0;i=c[i+16+(h>>>31<<2)>>2]|0;f=(g|0)==0|(g|0)==(i|0)?f:g;g=(i|0)==0;if(g){v=57;break}else h=h<<((g^1)&1)}}while(0);if((v|0)==57){if((f|0)==0&(a|0)==0){a=2<>>12&16;a=a>>>j;i=a>>>5&8;a=a>>>i;m=a>>>2&4;a=a>>>m;n=a>>>1&2;a=a>>>n;f=a>>>1&1;f=c[27220+((i|j|m|n|f)+(a>>>f)<<2)>>2]|0;a=0}if(!f){i=d;j=a}else v=61}if((v|0)==61)while(1){v=0;m=(c[f+4>>2]&-8)-k|0;n=m>>>0>>0;d=n?m:d;a=n?f:a;f=c[f+16+(((c[f+16>>2]|0)==0&1)<<2)>>2]|0;if(!f){i=d;j=a;break}else v=61}if((j|0)!=0?i>>>0<((c[6731]|0)-k|0)>>>0:0){h=j+k|0;if(j>>>0>=h>>>0){w=0;l=x;return w|0}g=c[j+24>>2]|0;b=c[j+12>>2]|0;do if((b|0)==(j|0)){a=j+20|0;b=c[a>>2]|0;if(!b){a=j+16|0;b=c[a>>2]|0;if(!b){b=0;break}}while(1){f=b+20|0;d=c[f>>2]|0;if(d|0){b=d;a=f;continue}f=b+16|0;d=c[f>>2]|0;if(!d)break;else{b=d;a=f}}c[a>>2]=0}else{w=c[j+8>>2]|0;c[w+12>>2]=b;c[b+8>>2]=w}while(0);do if(g){a=c[j+28>>2]|0;d=27220+(a<<2)|0;if((j|0)==(c[d>>2]|0)){c[d>>2]=b;if(!b){e=e&~(1<>2]|0)!=(j|0)&1)<<2)>>2]=b;if(!b)break}c[b+24>>2]=g;a=c[j+16>>2]|0;if(a|0){c[b+16>>2]=a;c[a+24>>2]=b}a=c[j+20>>2]|0;if(a){c[b+20>>2]=a;c[a+24>>2]=b}}while(0);do if(i>>>0>=16){c[j+4>>2]=k|3;c[h+4>>2]=i|1;c[h+i>>2]=i;b=i>>>3;if(i>>>0<256){d=26956+(b<<1<<2)|0;a=c[6729]|0;b=1<>2]|0}c[b>>2]=h;c[a+12>>2]=h;c[h+8>>2]=a;c[h+12>>2]=d;break}b=i>>>8;if(b)if(i>>>0>16777215)b=31;else{v=(b+1048320|0)>>>16&8;w=b<>>16&4;w=w<>>16&2;b=14-(u|v|b)+(w<>>15)|0;b=i>>>(b+7|0)&1|b<<1}else b=0;d=27220+(b<<2)|0;c[h+28>>2]=b;a=h+16|0;c[a+4>>2]=0;c[a>>2]=0;a=1<>2]=h;c[h+24>>2]=d;c[h+12>>2]=h;c[h+8>>2]=h;break}a=i<<((b|0)==31?0:25-(b>>>1)|0);d=c[d>>2]|0;while(1){if((c[d+4>>2]&-8|0)==(i|0)){v=97;break}e=d+16+(a>>>31<<2)|0;b=c[e>>2]|0;if(!b){v=96;break}else{a=a<<1;d=b}}if((v|0)==96){c[e>>2]=h;c[h+24>>2]=d;c[h+12>>2]=h;c[h+8>>2]=h;break}else if((v|0)==97){v=d+8|0;w=c[v>>2]|0;c[w+12>>2]=h;c[v>>2]=h;c[h+8>>2]=w;c[h+12>>2]=d;c[h+24>>2]=0;break}}else{w=i+k|0;c[j+4>>2]=w|3;w=j+w+4|0;c[w>>2]=c[w>>2]|1}while(0);w=j+8|0;l=x;return w|0}else n=k}else n=k}else n=-1;while(0);d=c[6731]|0;if(d>>>0>=n>>>0){a=d-n|0;b=c[6734]|0;if(a>>>0>15){w=b+n|0;c[6734]=w;c[6731]=a;c[w+4>>2]=a|1;c[w+a>>2]=a;c[b+4>>2]=n|3}else{c[6731]=0;c[6734]=0;c[b+4>>2]=d|3;w=b+d+4|0;c[w>>2]=c[w>>2]|1}w=b+8|0;l=x;return w|0}h=c[6732]|0;if(h>>>0>n>>>0){u=h-n|0;c[6732]=u;w=c[6735]|0;v=w+n|0;c[6735]=v;c[v+4>>2]=u|1;c[w+4>>2]=n|3;w=w+8|0;l=x;return w|0}if(!(c[6847]|0)){c[6849]=4096;c[6848]=4096;c[6850]=-1;c[6851]=-1;c[6852]=0;c[6840]=0;a=o&-16^1431655768;c[o>>2]=a;c[6847]=a;a=4096}else a=c[6849]|0;i=n+48|0;j=n+47|0;g=a+j|0;e=0-a|0;k=g&e;if(k>>>0<=n>>>0){w=0;l=x;return w|0}a=c[6839]|0;if(a|0?(m=c[6837]|0,o=m+k|0,o>>>0<=m>>>0|o>>>0>a>>>0):0){w=0;l=x;return w|0}b:do if(!(c[6840]&4)){d=c[6735]|0;c:do if(d){f=27364;while(1){a=c[f>>2]|0;if(a>>>0<=d>>>0?(r=f+4|0,(a+(c[r>>2]|0)|0)>>>0>d>>>0):0)break;a=c[f+8>>2]|0;if(!a){v=118;break c}else f=a}b=g-h&e;if(b>>>0<2147483647){a=ep(b|0)|0;if((a|0)==((c[f>>2]|0)+(c[r>>2]|0)|0)){if((a|0)!=(-1|0)){h=a;g=b;v=135;break b}}else{e=a;v=126}}else b=0}else v=118;while(0);do if((v|0)==118){d=ep(0)|0;if((d|0)!=(-1|0)?(b=d,p=c[6848]|0,q=p+-1|0,b=((q&b|0)==0?0:(q+b&0-p)-b|0)+k|0,p=c[6837]|0,q=b+p|0,b>>>0>n>>>0&b>>>0<2147483647):0){r=c[6839]|0;if(r|0?q>>>0<=p>>>0|q>>>0>r>>>0:0){b=0;break}a=ep(b|0)|0;if((a|0)==(d|0)){h=d;g=b;v=135;break b}else{e=a;v=126}}else b=0}while(0);do if((v|0)==126){d=0-b|0;if(!(i>>>0>b>>>0&(b>>>0<2147483647&(e|0)!=(-1|0))))if((e|0)==(-1|0)){b=0;break}else{h=e;g=b;v=135;break b}a=c[6849]|0;a=j-b+a&0-a;if(a>>>0>=2147483647){h=e;g=b;v=135;break b}if((ep(a|0)|0)==(-1|0)){ep(d|0)|0;b=0;break}else{h=e;g=a+b|0;v=135;break b}}while(0);c[6840]=c[6840]|4;v=133}else{b=0;v=133}while(0);if(((v|0)==133?k>>>0<2147483647:0)?(s=ep(k|0)|0,r=ep(0)|0,u=r-s|0,t=u>>>0>(n+40|0)>>>0,!((s|0)==(-1|0)|t^1|s>>>0>>0&((s|0)!=(-1|0)&(r|0)!=(-1|0))^1)):0){h=s;g=t?u:b;v=135}if((v|0)==135){b=(c[6837]|0)+g|0;c[6837]=b;if(b>>>0>(c[6838]|0)>>>0)c[6838]=b;j=c[6735]|0;do if(j){f=27364;while(1){b=c[f>>2]|0;e=f+4|0;a=c[e>>2]|0;if((h|0)==(b+a|0)){v=145;break}d=c[f+8>>2]|0;if(!d)break;else f=d}if(((v|0)==145?(c[f+12>>2]&8|0)==0:0)?j>>>0>>0&j>>>0>=b>>>0:0){c[e>>2]=a+g;w=j+8|0;w=(w&7|0)==0?0:0-w&7;v=j+w|0;w=(c[6732]|0)+(g-w)|0;c[6735]=v;c[6732]=w;c[v+4>>2]=w|1;c[v+w+4>>2]=40;c[6736]=c[6851];break}if(h>>>0<(c[6733]|0)>>>0)c[6733]=h;d=h+g|0;a=27364;while(1){if((c[a>>2]|0)==(d|0)){v=153;break}b=c[a+8>>2]|0;if(!b)break;else a=b}if((v|0)==153?(c[a+12>>2]&8|0)==0:0){c[a>>2]=h;m=a+4|0;c[m>>2]=(c[m>>2]|0)+g;m=h+8|0;m=h+((m&7|0)==0?0:0-m&7)|0;b=d+8|0;b=d+((b&7|0)==0?0:0-b&7)|0;k=m+n|0;i=b-m-n|0;c[m+4>>2]=n|3;do if((b|0)!=(j|0)){if((b|0)==(c[6734]|0)){w=(c[6731]|0)+i|0;c[6731]=w;c[6734]=k;c[k+4>>2]=w|1;c[k+w>>2]=w;break}a=c[b+4>>2]|0;if((a&3|0)==1){h=a&-8;e=a>>>3;d:do if(a>>>0<256){a=c[b+8>>2]|0;d=c[b+12>>2]|0;if((d|0)==(a|0)){c[6729]=c[6729]&~(1<>2]=d;c[d+8>>2]=a;break}}else{g=c[b+24>>2]|0;a=c[b+12>>2]|0;do if((a|0)==(b|0)){e=b+16|0;d=e+4|0;a=c[d>>2]|0;if(!a){a=c[e>>2]|0;if(!a){a=0;break}else f=e}else f=d;while(1){e=a+20|0;d=c[e>>2]|0;if(d|0){a=d;f=e;continue}e=a+16|0;d=c[e>>2]|0;if(!d)break;else{a=d;f=e}}c[f>>2]=0}else{w=c[b+8>>2]|0;c[w+12>>2]=a;c[a+8>>2]=w}while(0);if(!g)break;d=c[b+28>>2]|0;e=27220+(d<<2)|0;do if((b|0)!=(c[e>>2]|0)){c[g+16+(((c[g+16>>2]|0)!=(b|0)&1)<<2)>>2]=a;if(!a)break d}else{c[e>>2]=a;if(a|0)break;c[6730]=c[6730]&~(1<>2]=g;e=b+16|0;d=c[e>>2]|0;if(d|0){c[a+16>>2]=d;c[d+24>>2]=a}d=c[e+4>>2]|0;if(!d)break;c[a+20>>2]=d;c[d+24>>2]=a}while(0);b=b+h|0;f=h+i|0}else f=i;b=b+4|0;c[b>>2]=c[b>>2]&-2;c[k+4>>2]=f|1;c[k+f>>2]=f;b=f>>>3;if(f>>>0<256){d=26956+(b<<1<<2)|0;a=c[6729]|0;b=1<>2]|0}c[b>>2]=k;c[a+12>>2]=k;c[k+8>>2]=a;c[k+12>>2]=d;break}b=f>>>8;do if(!b)a=0;else{if(f>>>0>16777215){a=31;break}v=(b+1048320|0)>>>16&8;w=b<>>16&4;w=w<>>16&2;a=14-(u|v|a)+(w<>>15)|0;a=f>>>(a+7|0)&1|a<<1}while(0);e=27220+(a<<2)|0;c[k+28>>2]=a;b=k+16|0;c[b+4>>2]=0;c[b>>2]=0;b=c[6730]|0;d=1<>2]=k;c[k+24>>2]=e;c[k+12>>2]=k;c[k+8>>2]=k;break}a=f<<((a|0)==31?0:25-(a>>>1)|0);d=c[e>>2]|0;while(1){if((c[d+4>>2]&-8|0)==(f|0)){v=194;break}e=d+16+(a>>>31<<2)|0;b=c[e>>2]|0;if(!b){v=193;break}else{a=a<<1;d=b}}if((v|0)==193){c[e>>2]=k;c[k+24>>2]=d;c[k+12>>2]=k;c[k+8>>2]=k;break}else if((v|0)==194){v=d+8|0;w=c[v>>2]|0;c[w+12>>2]=k;c[v>>2]=k;c[k+8>>2]=w;c[k+12>>2]=d;c[k+24>>2]=0;break}}else{w=(c[6732]|0)+i|0;c[6732]=w;c[6735]=k;c[k+4>>2]=w|1}while(0);w=m+8|0;l=x;return w|0}a=27364;while(1){b=c[a>>2]|0;if(b>>>0<=j>>>0?(w=b+(c[a+4>>2]|0)|0,w>>>0>j>>>0):0)break;a=c[a+8>>2]|0}f=w+-47|0;a=f+8|0;a=f+((a&7|0)==0?0:0-a&7)|0;f=j+16|0;a=a>>>0>>0?j:a;b=a+8|0;d=h+8|0;d=(d&7|0)==0?0:0-d&7;v=h+d|0;d=g+-40-d|0;c[6735]=v;c[6732]=d;c[v+4>>2]=d|1;c[v+d+4>>2]=40;c[6736]=c[6851];d=a+4|0;c[d>>2]=27;c[b>>2]=c[6841];c[b+4>>2]=c[6842];c[b+8>>2]=c[6843];c[b+12>>2]=c[6844];c[6841]=h;c[6842]=g;c[6844]=0;c[6843]=b;b=a+24|0;do{v=b;b=b+4|0;c[b>>2]=7}while((v+8|0)>>>0>>0);if((a|0)!=(j|0)){g=a-j|0;c[d>>2]=c[d>>2]&-2;c[j+4>>2]=g|1;c[a>>2]=g;b=g>>>3;if(g>>>0<256){d=26956+(b<<1<<2)|0;a=c[6729]|0;b=1<>2]|0}c[b>>2]=j;c[a+12>>2]=j;c[j+8>>2]=a;c[j+12>>2]=d;break}b=g>>>8;if(b)if(g>>>0>16777215)d=31;else{v=(b+1048320|0)>>>16&8;w=b<>>16&4;w=w<>>16&2;d=14-(u|v|d)+(w<>>15)|0;d=g>>>(d+7|0)&1|d<<1}else d=0;e=27220+(d<<2)|0;c[j+28>>2]=d;c[j+20>>2]=0;c[f>>2]=0;b=c[6730]|0;a=1<>2]=j;c[j+24>>2]=e;c[j+12>>2]=j;c[j+8>>2]=j;break}a=g<<((d|0)==31?0:25-(d>>>1)|0);d=c[e>>2]|0;while(1){if((c[d+4>>2]&-8|0)==(g|0)){v=216;break}e=d+16+(a>>>31<<2)|0;b=c[e>>2]|0;if(!b){v=215;break}else{a=a<<1;d=b}}if((v|0)==215){c[e>>2]=j;c[j+24>>2]=d;c[j+12>>2]=j;c[j+8>>2]=j;break}else if((v|0)==216){v=d+8|0;w=c[v>>2]|0;c[w+12>>2]=j;c[v>>2]=j;c[j+8>>2]=w;c[j+12>>2]=d;c[j+24>>2]=0;break}}}else{w=c[6733]|0;if((w|0)==0|h>>>0>>0)c[6733]=h;c[6841]=h;c[6842]=g;c[6844]=0;c[6738]=c[6847];c[6737]=-1;b=0;do{w=26956+(b<<1<<2)|0;c[w+12>>2]=w;c[w+8>>2]=w;b=b+1|0}while((b|0)!=32);w=h+8|0;w=(w&7|0)==0?0:0-w&7;v=h+w|0;w=g+-40-w|0;c[6735]=v;c[6732]=w;c[v+4>>2]=w|1;c[v+w+4>>2]=40;c[6736]=c[6851]}while(0);b=c[6732]|0;if(b>>>0>n>>>0){u=b-n|0;c[6732]=u;w=c[6735]|0;v=w+n|0;c[6735]=v;c[v+4>>2]=u|1;c[w+4>>2]=n|3;w=w+8|0;l=x;return w|0}}c[6869]=12;w=0;l=x;return w|0}function Pm(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;if(!a)return;d=a+-8|0;e=c[6733]|0;a=c[a+-4>>2]|0;b=a&-8;k=d+b|0;do if(!(a&1)){f=c[d>>2]|0;if(!(a&3))return;g=d+(0-f)|0;h=f+b|0;if(g>>>0>>0)return;if((g|0)==(c[6734]|0)){b=k+4|0;a=c[b>>2]|0;if((a&3|0)!=3){i=g;j=g;b=h;break}c[6731]=h;c[b>>2]=a&-2;c[g+4>>2]=h|1;c[g+h>>2]=h;return}d=f>>>3;if(f>>>0<256){a=c[g+8>>2]|0;b=c[g+12>>2]|0;if((b|0)==(a|0)){c[6729]=c[6729]&~(1<>2]=b;c[b+8>>2]=a;i=g;j=g;b=h;break}}f=c[g+24>>2]|0;a=c[g+12>>2]|0;do if((a|0)==(g|0)){d=g+16|0;b=d+4|0;a=c[b>>2]|0;if(!a){a=c[d>>2]|0;if(!a){d=0;break}else e=d}else e=b;while(1){d=a+20|0;b=c[d>>2]|0;if(b|0){a=b;e=d;continue}d=a+16|0;b=c[d>>2]|0;if(!b)break;else{a=b;e=d}}c[e>>2]=0;d=a}else{d=c[g+8>>2]|0;c[d+12>>2]=a;c[a+8>>2]=d;d=a}while(0);if(f){a=c[g+28>>2]|0;b=27220+(a<<2)|0;if((g|0)==(c[b>>2]|0)){c[b>>2]=d;if(!d){c[6730]=c[6730]&~(1<>2]|0)!=(g|0)&1)<<2)>>2]=d;if(!d){i=g;j=g;b=h;break}}c[d+24>>2]=f;b=g+16|0;a=c[b>>2]|0;if(a|0){c[d+16>>2]=a;c[a+24>>2]=d}a=c[b+4>>2]|0;if(a){c[d+20>>2]=a;c[a+24>>2]=d;i=g;j=g;b=h}else{i=g;j=g;b=h}}else{i=g;j=g;b=h}}else{i=d;j=d}while(0);if(i>>>0>=k>>>0)return;a=k+4|0;e=c[a>>2]|0;if(!(e&1))return;if(!(e&2)){a=c[6734]|0;if((k|0)==(c[6735]|0)){k=(c[6732]|0)+b|0;c[6732]=k;c[6735]=j;c[j+4>>2]=k|1;if((j|0)!=(a|0))return;c[6734]=0;c[6731]=0;return}if((k|0)==(a|0)){k=(c[6731]|0)+b|0;c[6731]=k;c[6734]=i;c[j+4>>2]=k|1;c[i+k>>2]=k;return}f=(e&-8)+b|0;d=e>>>3;do if(e>>>0<256){b=c[k+8>>2]|0;a=c[k+12>>2]|0;if((a|0)==(b|0)){c[6729]=c[6729]&~(1<>2]=a;c[a+8>>2]=b;break}}else{g=c[k+24>>2]|0;a=c[k+12>>2]|0;do if((a|0)==(k|0)){d=k+16|0;b=d+4|0;a=c[b>>2]|0;if(!a){a=c[d>>2]|0;if(!a){d=0;break}else e=d}else e=b;while(1){d=a+20|0;b=c[d>>2]|0;if(b|0){a=b;e=d;continue}d=a+16|0;b=c[d>>2]|0;if(!b)break;else{a=b;e=d}}c[e>>2]=0;d=a}else{d=c[k+8>>2]|0;c[d+12>>2]=a;c[a+8>>2]=d;d=a}while(0);if(g|0){a=c[k+28>>2]|0;b=27220+(a<<2)|0;if((k|0)==(c[b>>2]|0)){c[b>>2]=d;if(!d){c[6730]=c[6730]&~(1<>2]|0)!=(k|0)&1)<<2)>>2]=d;if(!d)break}c[d+24>>2]=g;b=k+16|0;a=c[b>>2]|0;if(a|0){c[d+16>>2]=a;c[a+24>>2]=d}a=c[b+4>>2]|0;if(a|0){c[d+20>>2]=a;c[a+24>>2]=d}}}while(0);c[j+4>>2]=f|1;c[i+f>>2]=f;if((j|0)==(c[6734]|0)){c[6731]=f;return}}else{c[a>>2]=e&-2;c[j+4>>2]=b|1;c[i+b>>2]=b;f=b}a=f>>>3;if(f>>>0<256){d=26956+(a<<1<<2)|0;b=c[6729]|0;a=1<>2]|0}c[a>>2]=j;c[b+12>>2]=j;c[j+8>>2]=b;c[j+12>>2]=d;return}a=f>>>8;if(a)if(f>>>0>16777215)b=31;else{i=(a+1048320|0)>>>16&8;k=a<>>16&4;k=k<>>16&2;b=14-(h|i|b)+(k<>>15)|0;b=f>>>(b+7|0)&1|b<<1}else b=0;e=27220+(b<<2)|0;c[j+28>>2]=b;c[j+20>>2]=0;c[j+16>>2]=0;a=c[6730]|0;d=1<>>1)|0);d=c[e>>2]|0;while(1){if((c[d+4>>2]&-8|0)==(f|0)){a=73;break}e=d+16+(b>>>31<<2)|0;a=c[e>>2]|0;if(!a){a=72;break}else{b=b<<1;d=a}}if((a|0)==72){c[e>>2]=j;c[j+24>>2]=d;c[j+12>>2]=j;c[j+8>>2]=j;break}else if((a|0)==73){i=d+8|0;k=c[i>>2]|0;c[k+12>>2]=j;c[i>>2]=j;c[j+8>>2]=k;c[j+12>>2]=d;c[j+24>>2]=0;break}}else{c[6730]=a|d;c[e>>2]=j;c[j+24>>2]=e;c[j+12>>2]=j;c[j+8>>2]=j}while(0);k=(c[6737]|0)+-1|0;c[6737]=k;if(!k)a=27372;else return;while(1){a=c[a>>2]|0;if(!a)break;else a=a+8|0}c[6737]=-1;return}function Qm(a,b){a=a|0;b=b|0;var d=0;if(a){d=O(b,a)|0;if((b|a)>>>0>65535)d=((d>>>0)/(a>>>0)|0|0)==(b|0)?d:-1}else d=0;b=Om(d)|0;if(!b)return b|0;if(!(c[b+-4>>2]&3))return b|0;cp(b|0,0,d|0)|0;return b|0}function Rm(a,b){a=a|0;b=b|0;var d=0,e=0;if(!a){a=Om(b)|0;return a|0}if(b>>>0>4294967231){c[6869]=12;a=0;return a|0}d=Sm(a+-8|0,b>>>0<11?16:b+11&-8)|0;if(d|0){a=d+8|0;return a|0}d=Om(b)|0;if(!d){a=0;return a|0}e=c[a+-4>>2]|0;e=(e&-8)-((e&3|0)==0?8:4)|0;ap(d|0,a|0,(e>>>0>>0?e:b)|0)|0;Pm(a);a=d;return a|0}function Sm(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;m=a+4|0;l=c[m>>2]|0;d=l&-8;i=a+d|0;if(!(l&3)){if(b>>>0<256){a=0;return a|0}if(d>>>0>=(b+4|0)>>>0?(d-b|0)>>>0<=c[6849]<<1>>>0:0)return a|0;a=0;return a|0}if(d>>>0>=b>>>0){d=d-b|0;if(d>>>0<=15)return a|0;k=a+b|0;c[m>>2]=l&1|b|2;c[k+4>>2]=d|3;b=k+d+4|0;c[b>>2]=c[b>>2]|1;Tm(k,d);return a|0}if((i|0)==(c[6735]|0)){k=(c[6732]|0)+d|0;e=k-b|0;d=a+b|0;if(k>>>0<=b>>>0){a=0;return a|0}c[m>>2]=l&1|b|2;c[d+4>>2]=e|1;c[6735]=d;c[6732]=e;return a|0}if((i|0)==(c[6734]|0)){f=(c[6731]|0)+d|0;if(f>>>0>>0){a=0;return a|0}d=f-b|0;e=l&1;if(d>>>0>15){l=a+b|0;k=l+d|0;c[m>>2]=e|b|2;c[l+4>>2]=d|1;c[k>>2]=d;e=k+4|0;c[e>>2]=c[e>>2]&-2;e=l}else{c[m>>2]=e|f|2;e=a+f+4|0;c[e>>2]=c[e>>2]|1;e=0;d=0}c[6731]=d;c[6734]=e;return a|0}e=c[i+4>>2]|0;if(e&2|0){a=0;return a|0}j=(e&-8)+d|0;if(j>>>0>>0){a=0;return a|0}k=j-b|0;f=e>>>3;do if(e>>>0<256){e=c[i+8>>2]|0;d=c[i+12>>2]|0;if((d|0)==(e|0)){c[6729]=c[6729]&~(1<>2]=d;c[d+8>>2]=e;break}}else{h=c[i+24>>2]|0;d=c[i+12>>2]|0;do if((d|0)==(i|0)){f=i+16|0;e=f+4|0;d=c[e>>2]|0;if(!d){d=c[f>>2]|0;if(!d){f=0;break}else g=f}else g=e;while(1){f=d+20|0;e=c[f>>2]|0;if(e|0){d=e;g=f;continue}f=d+16|0;e=c[f>>2]|0;if(!e)break;else{d=e;g=f}}c[g>>2]=0;f=d}else{f=c[i+8>>2]|0;c[f+12>>2]=d;c[d+8>>2]=f;f=d}while(0);if(h|0){d=c[i+28>>2]|0;e=27220+(d<<2)|0;if((i|0)==(c[e>>2]|0)){c[e>>2]=f;if(!f){c[6730]=c[6730]&~(1<>2]|0)!=(i|0)&1)<<2)>>2]=f;if(!f)break}c[f+24>>2]=h;e=i+16|0;d=c[e>>2]|0;if(d|0){c[f+16>>2]=d;c[d+24>>2]=f}d=c[e+4>>2]|0;if(d|0){c[f+20>>2]=d;c[d+24>>2]=f}}}while(0);d=l&1;if(k>>>0<16){c[m>>2]=j|d|2;b=a+j+4|0;c[b>>2]=c[b>>2]|1;return a|0}else{l=a+b|0;c[m>>2]=d|b|2;c[l+4>>2]=k|3;b=l+k+4|0;c[b>>2]=c[b>>2]|1;Tm(l,k);return a|0}return 0}function Tm(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0;j=a+b|0;d=c[a+4>>2]|0;do if(!(d&1)){e=c[a>>2]|0;if(!(d&3))return;g=a+(0-e)|0;h=e+b|0;if((g|0)==(c[6734]|0)){a=j+4|0;d=c[a>>2]|0;if((d&3|0)!=3){i=g;a=h;break}c[6731]=h;c[a>>2]=d&-2;c[g+4>>2]=h|1;c[g+h>>2]=h;return}b=e>>>3;if(e>>>0<256){d=c[g+8>>2]|0;a=c[g+12>>2]|0;if((a|0)==(d|0)){c[6729]=c[6729]&~(1<>2]=a;c[a+8>>2]=d;i=g;a=h;break}}f=c[g+24>>2]|0;d=c[g+12>>2]|0;do if((d|0)==(g|0)){b=g+16|0;a=b+4|0;d=c[a>>2]|0;if(!d){d=c[b>>2]|0;if(!d){b=0;break}else e=b}else e=a;while(1){b=d+20|0;a=c[b>>2]|0;if(a|0){d=a;e=b;continue}b=d+16|0;a=c[b>>2]|0;if(!a)break;else{d=a;e=b}}c[e>>2]=0;b=d}else{b=c[g+8>>2]|0;c[b+12>>2]=d;c[d+8>>2]=b;b=d}while(0);if(f){d=c[g+28>>2]|0;a=27220+(d<<2)|0;if((g|0)==(c[a>>2]|0)){c[a>>2]=b;if(!b){c[6730]=c[6730]&~(1<>2]|0)!=(g|0)&1)<<2)>>2]=b;if(!b){i=g;a=h;break}}c[b+24>>2]=f;a=g+16|0;d=c[a>>2]|0;if(d|0){c[b+16>>2]=d;c[d+24>>2]=b}d=c[a+4>>2]|0;if(d){c[b+20>>2]=d;c[d+24>>2]=b;i=g;a=h}else{i=g;a=h}}else{i=g;a=h}}else{i=a;a=b}while(0);d=j+4|0;e=c[d>>2]|0;if(!(e&2)){d=c[6734]|0;if((j|0)==(c[6735]|0)){j=(c[6732]|0)+a|0;c[6732]=j;c[6735]=i;c[i+4>>2]=j|1;if((i|0)!=(d|0))return;c[6734]=0;c[6731]=0;return}if((j|0)==(d|0)){j=(c[6731]|0)+a|0;c[6731]=j;c[6734]=i;c[i+4>>2]=j|1;c[i+j>>2]=j;return}f=(e&-8)+a|0;b=e>>>3;do if(e>>>0<256){a=c[j+8>>2]|0;d=c[j+12>>2]|0;if((d|0)==(a|0)){c[6729]=c[6729]&~(1<>2]=d;c[d+8>>2]=a;break}}else{g=c[j+24>>2]|0;d=c[j+12>>2]|0;do if((d|0)==(j|0)){b=j+16|0;a=b+4|0;d=c[a>>2]|0;if(!d){d=c[b>>2]|0;if(!d){b=0;break}else e=b}else e=a;while(1){b=d+20|0;a=c[b>>2]|0;if(a|0){d=a;e=b;continue}b=d+16|0;a=c[b>>2]|0;if(!a)break;else{d=a;e=b}}c[e>>2]=0;b=d}else{b=c[j+8>>2]|0;c[b+12>>2]=d;c[d+8>>2]=b;b=d}while(0);if(g|0){d=c[j+28>>2]|0;a=27220+(d<<2)|0;if((j|0)==(c[a>>2]|0)){c[a>>2]=b;if(!b){c[6730]=c[6730]&~(1<>2]|0)!=(j|0)&1)<<2)>>2]=b;if(!b)break}c[b+24>>2]=g;a=j+16|0;d=c[a>>2]|0;if(d|0){c[b+16>>2]=d;c[d+24>>2]=b}d=c[a+4>>2]|0;if(d|0){c[b+20>>2]=d;c[d+24>>2]=b}}}while(0);c[i+4>>2]=f|1;c[i+f>>2]=f;if((i|0)==(c[6734]|0)){c[6731]=f;return}}else{c[d>>2]=e&-2;c[i+4>>2]=a|1;c[i+a>>2]=a;f=a}d=f>>>3;if(f>>>0<256){b=26956+(d<<1<<2)|0;a=c[6729]|0;d=1<>2]|0}c[d>>2]=i;c[a+12>>2]=i;c[i+8>>2]=a;c[i+12>>2]=b;return}d=f>>>8;if(d)if(f>>>0>16777215)a=31;else{h=(d+1048320|0)>>>16&8;j=d<>>16&4;j=j<>>16&2;a=14-(g|h|a)+(j<>>15)|0;a=f>>>(a+7|0)&1|a<<1}else a=0;e=27220+(a<<2)|0;c[i+28>>2]=a;c[i+20>>2]=0;c[i+16>>2]=0;d=c[6730]|0;b=1<>2]=i;c[i+24>>2]=e;c[i+12>>2]=i;c[i+8>>2]=i;return}a=f<<((a|0)==31?0:25-(a>>>1)|0);b=c[e>>2]|0;while(1){if((c[b+4>>2]&-8|0)==(f|0)){d=69;break}e=b+16+(a>>>31<<2)|0;d=c[e>>2]|0;if(!d){d=68;break}else{a=a<<1;b=d}}if((d|0)==68){c[e>>2]=i;c[i+24>>2]=b;c[i+12>>2]=i;c[i+8>>2]=i;return}else if((d|0)==69){h=b+8|0;j=c[h>>2]|0;c[j+12>>2]=i;c[h>>2]=i;c[i+8>>2]=j;c[i+12>>2]=b;c[i+24>>2]=0;return}}function Um(a){a=a|0;var b=0,d=0;b=l;l=l+16|0;d=b;c[d>>2]=Ym(c[a+60>>2]|0)|0;a=Xm(ta(6,d|0)|0)|0;l=b;return a|0}function Vm(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0;n=l;l=l+48|0;i=n+16|0;f=n;e=n+32|0;j=a+28|0;g=c[j>>2]|0;c[e>>2]=g;k=a+20|0;g=(c[k>>2]|0)-g|0;c[e+4>>2]=g;c[e+8>>2]=b;c[e+12>>2]=d;g=g+d|0;h=a+60|0;c[f>>2]=c[h>>2];c[f+4>>2]=e;c[f+8>>2]=2;b=Xm(la(146,f|0)|0)|0;a:do if((g|0)!=(b|0)){f=2;while(1){if((b|0)<0)break;g=g-b|0;p=c[e+4>>2]|0;o=b>>>0>p>>>0;e=o?e+8|0:e;f=(o<<31>>31)+f|0;p=b-(o?p:0)|0;c[e>>2]=(c[e>>2]|0)+p;o=e+4|0;c[o>>2]=(c[o>>2]|0)-p;c[i>>2]=c[h>>2];c[i+4>>2]=e;c[i+8>>2]=f;b=Xm(la(146,i|0)|0)|0;if((g|0)==(b|0)){m=3;break a}}c[a+16>>2]=0;c[j>>2]=0;c[k>>2]=0;c[a>>2]=c[a>>2]|32;if((f|0)==2)d=0;else d=d-(c[e+4>>2]|0)|0}else m=3;while(0);if((m|0)==3){p=c[a+44>>2]|0;c[a+16>>2]=p+(c[a+48>>2]|0);c[j>>2]=p;c[k>>2]=p}l=n;return d|0}function Wm(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=l;l=l+32|0;g=f;e=f+20|0;c[g>>2]=c[a+60>>2];c[g+4>>2]=0;c[g+8>>2]=b;c[g+12>>2]=e;c[g+16>>2]=d;if((Xm(ja(140,g|0)|0)|0)<0){c[e>>2]=-1;a=-1}else a=c[e>>2]|0;l=f;return a|0}function Xm(a){a=a|0;if(a>>>0>4294963200){c[6869]=0-a;a=-1}return a|0}function Ym(a){a=a|0;return a|0}function Zm(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0;k=l;l=l+32|0;f=k;i=k+16|0;c[i>>2]=d;g=i+4|0;j=b+48|0;m=c[j>>2]|0;c[g>>2]=e-((m|0)!=0&1);h=b+44|0;c[i+8>>2]=c[h>>2];c[i+12>>2]=m;c[f>>2]=c[b+60>>2];c[f+4>>2]=i;c[f+8>>2]=2;f=Xm(ka(145,f|0)|0)|0;if((f|0)>=1){i=c[g>>2]|0;if(f>>>0>i>>>0){g=c[h>>2]|0;h=b+4|0;c[h>>2]=g;c[b+8>>2]=g+(f-i);if(!(c[j>>2]|0))f=e;else{c[h>>2]=g+1;a[d+(e+-1)>>0]=a[g>>0]|0;f=e}}}else c[b>>2]=c[b>>2]|f&48^16;l=k;return f|0}function _m(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0;g=l;l=l+32|0;f=g;c[b+36>>2]=146;if((c[b>>2]&64|0)==0?(c[f>>2]=c[b+60>>2],c[f+4>>2]=21523,c[f+8>>2]=g+16,sa(54,f|0)|0):0)a[b+75>>0]=-1;f=Vm(b,d,e)|0;l=g;return f|0}function $m(a){a=a|0;var b=0;b=(an(a)|0)==0;return (b?a:a|32)|0}function an(a){a=a|0;return (a+-65|0)>>>0<26|0}function bn(a){a=a|0;var b=0,e=0;e=l;l=l+16|0;b=e;if((cn(a)|0)==0?(Ja[c[a+32>>2]&255](a,b,1)|0)==1:0)b=d[b>>0]|0;else b=-1;l=e;return b|0}function cn(b){b=b|0;var d=0,e=0;e=b+74|0;d=a[e>>0]|0;a[e>>0]=d+255|d;e=b+20|0;d=b+28|0;if((c[e>>2]|0)>>>0>(c[d>>2]|0)>>>0)Ja[c[b+36>>2]&255](b,0,0)|0;c[b+16>>2]=0;c[d>>2]=0;c[e>>2]=0;d=c[b>>2]|0;if(!(d&4)){e=(c[b+44>>2]|0)+(c[b+48>>2]|0)|0;c[b+8>>2]=e;c[b+4>>2]=e;d=d<<27>>31}else{c[b>>2]=d|32;d=-1}return d|0}function dn(b,c){b=b|0;c=c|0;var d=0,e=0;d=a[b>>0]|0;e=a[c>>0]|0;if(!(d<<24>>24==0?1:d<<24>>24!=e<<24>>24))do{b=b+1|0;c=c+1|0;d=a[b>>0]|0;e=a[c>>0]|0}while(!(d<<24>>24==0?1:d<<24>>24!=e<<24>>24));return (d&255)-(e&255)|0}function en(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;a:do if(!d)b=0;else{while(1){e=a[b>>0]|0;f=a[c>>0]|0;if(e<<24>>24!=f<<24>>24)break;d=d+-1|0;if(!d){b=0;break a}else{b=b+1|0;c=c+1|0}}b=(e&255)-(f&255)|0}while(0);return b|0}function fn(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0;if(!d)e=0;else{h=a[b>>0]|0;f=h&255;g=a[c>>0]|0;e=g&255;a:do if(h<<24>>24)do{d=d+-1|0;if(!(h<<24>>24==g<<24>>24&((d|0)!=0&g<<24>>24!=0)))break a;b=b+1|0;c=c+1|0;h=a[b>>0]|0;f=h&255;g=a[c>>0]|0;e=g&255}while(h<<24>>24!=0);while(0);e=f-e|0}return e|0}function gn(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0;p=l;l=l+128|0;g=p+124|0;h=p;n=h;q=7760;r=n+124|0;do{c[n>>2]=c[q>>2];n=n+4|0;q=q+4|0}while((n|0)<(r|0));if((d+-1|0)>>>0>2147483646)if(!d){i=1;j=g;o=4}else c[6869]=75;else{i=d;j=b;o=4}if((o|0)==4?(r=-2-j|0,r=i>>>0>r>>>0?r:i,c[h+48>>2]=r,m=h+20|0,c[m>>2]=j,c[h+44>>2]=j,q=j+r|0,k=h+16|0,c[k>>2]=q,c[h+28>>2]=q,hn(h,e,f)|0,r|0):0){r=c[m>>2]|0;a[r+(((r|0)==(c[k>>2]|0))<<31>>31)>>0]=0}l=p;return}function hn(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0;r=l;l=l+224|0;n=r+120|0;q=r+80|0;p=r;o=r+136|0;f=q;g=f+40|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));c[n>>2]=c[e>>2];if((jn(0,d,n,p,q)|0)<0)e=-1;else{e=c[b>>2]|0;m=e&32;if((a[b+74>>0]|0)<1)c[b>>2]=e&-33;h=b+48|0;if(!(c[h>>2]|0)){g=b+44|0;f=c[g>>2]|0;c[g>>2]=o;i=b+28|0;c[i>>2]=o;k=b+20|0;c[k>>2]=o;c[h>>2]=80;j=b+16|0;c[j>>2]=o+80;e=jn(b,d,n,p,q)|0;if(f){Ja[c[b+36>>2]&255](b,0,0)|0;e=(c[k>>2]|0)==0?-1:e;c[g>>2]=f;c[h>>2]=0;c[j>>2]=0;c[i>>2]=0;c[k>>2]=0}}else e=jn(b,d,n,p,q)|0;q=c[b>>2]|0;c[b>>2]=q|m;e=(q&32|0)==0?e:-1}l=r;return e|0}function jn(d,e,f,g,i){d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;var j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;H=l;l=l+64|0;D=H+16|0;A=H;y=H+24|0;G=H+8|0;C=H+20|0;c[D>>2]=e;F=(d|0)!=0;x=y+40|0;E=x;y=y+39|0;B=G+4|0;q=e;e=0;j=0;n=0;a:while(1){do if((e|0)>-1)if((j|0)>(2147483647-e|0)){c[6869]=75;e=-1;break}else{e=j+e|0;break}while(0);j=a[q>>0]|0;if(!(j<<24>>24)){w=87;break}else k=q;b:while(1){switch(j<<24>>24){case 37:{j=k;w=9;break b}case 0:{j=k;break b}default:{}}v=k+1|0;c[D>>2]=v;j=a[v>>0]|0;k=v}c:do if((w|0)==9)while(1){w=0;if((a[j+1>>0]|0)!=37)break c;k=k+1|0;j=j+2|0;c[D>>2]=j;if((a[j>>0]|0)==37)w=9;else break}while(0);k=k-q|0;if(F)ln(d,q,k);if(k|0){q=j;j=k;continue}m=j+1|0;k=(a[m>>0]|0)+-48|0;if(k>>>0<10){v=(a[j+2>>0]|0)==36;s=v?k:-1;p=v?1:n;m=v?j+3|0:m}else{s=-1;p=n}c[D>>2]=m;j=a[m>>0]|0;k=(j<<24>>24)+-32|0;d:do if(k>>>0<32){n=0;while(1){k=1<>2]=m;j=a[m>>0]|0;k=(j<<24>>24)+-32|0;if(k>>>0>=32){o=n;break}}}else o=0;while(0);if(j<<24>>24==42){k=m+1|0;j=(a[k>>0]|0)+-48|0;if(j>>>0<10?(a[m+2>>0]|0)==36:0){c[i+(j<<2)>>2]=10;n=1;j=m+3|0;k=c[g+((a[k>>0]|0)+-48<<3)>>2]|0}else{if(p|0){e=-1;break}if(F){n=(c[f>>2]|0)+(4-1)&~(4-1);v=c[n>>2]|0;c[f>>2]=n+4;n=0;j=k;k=v}else{n=0;j=k;k=0}}c[D>>2]=j;u=(k|0)<0;m=j;r=u?o|8192:o;v=n;u=u?0-k|0:k}else{j=mn(D)|0;if((j|0)<0){e=-1;break}m=c[D>>2]|0;r=o;v=p;u=j}do if((a[m>>0]|0)==46){j=m+1|0;if((a[j>>0]|0)!=42){c[D>>2]=j;o=mn(D)|0;j=c[D>>2]|0;break}j=m+2|0;k=(a[j>>0]|0)+-48|0;if(k>>>0<10?(a[m+3>>0]|0)==36:0){c[i+(k<<2)>>2]=10;o=c[g+((a[j>>0]|0)+-48<<3)>>2]|0;j=m+4|0;c[D>>2]=j;break}if(v|0){e=-1;break a}if(F){t=(c[f>>2]|0)+(4-1)&~(4-1);k=c[t>>2]|0;c[f>>2]=t+4}else k=0;c[D>>2]=j;o=k}else{j=m;o=-1}while(0);p=0;while(1){if(((a[j>>0]|0)+-65|0)>>>0>57){e=-1;break a}t=j+1|0;c[D>>2]=t;k=a[(a[j>>0]|0)+-65+(22729+(p*58|0))>>0]|0;n=k&255;if((n+-1|0)>>>0<8){j=t;p=n}else break}if(!(k<<24>>24)){e=-1;break}m=(s|0)>-1;do if(k<<24>>24==19)if(m){e=-1;break a}else w=49;else{if(m){c[i+(s<<2)>>2]=n;n=g+(s<<3)|0;s=c[n+4>>2]|0;w=A;c[w>>2]=c[n>>2];c[w+4>>2]=s;w=49;break}if(!F){e=0;break a}nn(A,n,f)}while(0);if((w|0)==49?(w=0,!F):0){q=t;j=0;n=v;continue}n=a[j>>0]|0;n=(p|0)!=0&(n&15|0)==3?n&-33:n;k=r&-65537;s=(r&8192|0)==0?r:k;e:do switch(n|0){case 110:switch((p&255)<<24>>24){case 0:{c[c[A>>2]>>2]=e;q=t;j=0;n=v;continue a}case 1:{c[c[A>>2]>>2]=e;q=t;j=0;n=v;continue a}case 2:{q=c[A>>2]|0;c[q>>2]=e;c[q+4>>2]=((e|0)<0)<<31>>31;q=t;j=0;n=v;continue a}case 3:{b[c[A>>2]>>1]=e;q=t;j=0;n=v;continue a}case 4:{a[c[A>>2]>>0]=e;q=t;j=0;n=v;continue a}case 6:{c[c[A>>2]>>2]=e;q=t;j=0;n=v;continue a}case 7:{q=c[A>>2]|0;c[q>>2]=e;c[q+4>>2]=((e|0)<0)<<31>>31;q=t;j=0;n=v;continue a}default:{q=t;j=0;n=v;continue a}}case 112:{j=s|8;k=o>>>0>8?o:8;n=120;w=61;break}case 88:case 120:{j=s;k=o;w=61;break}case 111:{r=A;q=c[r>>2]|0;r=c[r+4>>2]|0;p=pn(q,r,x)|0;k=E-p|0;j=s;k=(s&8|0)==0|(o|0)>(k|0)?o:k+1|0;m=0;o=23193;w=67;break}case 105:case 100:{k=A;j=c[k>>2]|0;k=c[k+4>>2]|0;if((k|0)<0){j=Ro(0,0,j|0,k|0)|0;k=z;m=A;c[m>>2]=j;c[m+4>>2]=k;m=1;n=23193;w=66;break e}else{m=(s&2049|0)!=0&1;n=(s&2048|0)==0?((s&1|0)==0?23193:23195):23194;w=66;break e}}case 117:{k=A;j=c[k>>2]|0;k=c[k+4>>2]|0;m=0;n=23193;w=66;break}case 99:{a[y>>0]=c[A>>2];q=y;p=k;n=1;m=0;k=23193;j=x;break}case 109:{j=rn(c[6869]|0)|0;w=71;break}case 115:{j=c[A>>2]|0;j=j|0?j:23203;w=71;break}case 67:{c[G>>2]=c[A>>2];c[B>>2]=0;c[A>>2]=G;j=G;o=-1;w=75;break}case 83:{j=c[A>>2]|0;if(!o){tn(d,32,u,0,s);j=0;w=84}else w=75;break}case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:{q=t;j=vn(d,+h[A>>3],u,o,s,n)|0;n=v;continue a}default:{p=s;n=o;m=0;k=23193;j=x}}while(0);f:do if((w|0)==61){r=A;q=c[r>>2]|0;r=c[r+4>>2]|0;p=on(q,r,x,n&32)|0;o=(j&8|0)==0|(q|0)==0&(r|0)==0;m=o?0:2;o=o?23193:23193+(n>>4)|0;w=67}else if((w|0)==66){q=j;r=k;p=qn(j,k,x)|0;j=s;k=o;o=n;w=67}else if((w|0)==71){w=0;s=sn(j,0,o)|0;r=(s|0)==0;q=j;p=k;n=r?o:s-j|0;m=0;k=23193;j=r?j+o|0:s}else if((w|0)==75){w=0;m=0;k=0;p=j;while(1){n=c[p>>2]|0;if(!n)break;k=un(C,n)|0;if((k|0)<0|k>>>0>(o-m|0)>>>0)break;m=k+m|0;if(o>>>0>m>>>0)p=p+4|0;else break}if((k|0)<0){e=-1;break a}tn(d,32,u,m,s);if(!m){j=0;w=84}else{n=0;while(1){k=c[j>>2]|0;if(!k){j=m;w=84;break f}k=un(C,k)|0;n=k+n|0;if((n|0)>(m|0)){j=m;w=84;break f}ln(d,C,k);if(n>>>0>=m>>>0){j=m;w=84;break}else j=j+4|0}}}while(0);if((w|0)==67){w=0;n=(q|0)!=0|(r|0)!=0;s=(k|0)!=0|n;n=((n^1)&1)+(E-p)|0;q=s?p:x;p=(k|0)>-1?j&-65537:j;n=s?((k|0)>(n|0)?k:n):k;k=o;j=x}else if((w|0)==84){w=0;tn(d,32,u,j,s^8192);q=t;j=(u|0)>(j|0)?u:j;n=v;continue}s=j-q|0;r=(n|0)<(s|0)?s:n;n=r+m|0;j=(u|0)<(n|0)?n:u;tn(d,32,j,n,p);ln(d,k,m);tn(d,48,j,n,p^65536);tn(d,48,r,s,0);ln(d,q,s);tn(d,32,j,n,p^8192);q=t;n=v}g:do if((w|0)==87)if(!d)if(!n)e=0;else{e=1;while(1){j=c[i+(e<<2)>>2]|0;if(!j){j=0;break}nn(g+(e<<3)|0,j,f);e=e+1|0;if((e|0)>=10){e=1;break g}}while(1){e=e+1|0;if(j|0){e=-1;break g}if((e|0)>=10){e=1;break g}j=c[i+(e<<2)>>2]|0}}while(0);l=H;return e|0}function kn(){return 0}function ln(a,b,d){a=a|0;b=b|0;d=d|0;if(!(c[a>>2]&32))Fn(b,d,a)|0;return}function mn(b){b=b|0;var d=0,e=0,f=0;d=c[b>>2]|0;e=(a[d>>0]|0)+-48|0;if(e>>>0<10){f=d;d=0;do{d=e+(d*10|0)|0;f=f+1|0;c[b>>2]=f;e=(a[f>>0]|0)+-48|0}while(e>>>0<10)}else d=0;return d|0}function nn(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0.0;a:do if(b>>>0<=20)do switch(b|0){case 9:{e=(c[d>>2]|0)+(4-1)&~(4-1);b=c[e>>2]|0;c[d>>2]=e+4;c[a>>2]=b;break a}case 10:{e=(c[d>>2]|0)+(4-1)&~(4-1);b=c[e>>2]|0;c[d>>2]=e+4;e=a;c[e>>2]=b;c[e+4>>2]=((b|0)<0)<<31>>31;break a}case 11:{e=(c[d>>2]|0)+(4-1)&~(4-1);b=c[e>>2]|0;c[d>>2]=e+4;e=a;c[e>>2]=b;c[e+4>>2]=0;break a}case 12:{e=(c[d>>2]|0)+(8-1)&~(8-1);b=e;f=c[b>>2]|0;b=c[b+4>>2]|0;c[d>>2]=e+8;e=a;c[e>>2]=f;c[e+4>>2]=b;break a}case 13:{f=(c[d>>2]|0)+(4-1)&~(4-1);e=c[f>>2]|0;c[d>>2]=f+4;e=(e&65535)<<16>>16;f=a;c[f>>2]=e;c[f+4>>2]=((e|0)<0)<<31>>31;break a}case 14:{f=(c[d>>2]|0)+(4-1)&~(4-1);e=c[f>>2]|0;c[d>>2]=f+4;f=a;c[f>>2]=e&65535;c[f+4>>2]=0;break a}case 15:{f=(c[d>>2]|0)+(4-1)&~(4-1);e=c[f>>2]|0;c[d>>2]=f+4;e=(e&255)<<24>>24;f=a;c[f>>2]=e;c[f+4>>2]=((e|0)<0)<<31>>31;break a}case 16:{f=(c[d>>2]|0)+(4-1)&~(4-1);e=c[f>>2]|0;c[d>>2]=f+4;f=a;c[f>>2]=e&255;c[f+4>>2]=0;break a}case 17:{f=(c[d>>2]|0)+(8-1)&~(8-1);g=+h[f>>3];c[d>>2]=f+8;h[a>>3]=g;break a}case 18:{f=(c[d>>2]|0)+(8-1)&~(8-1);g=+h[f>>3];c[d>>2]=f+8;h[a>>3]=g;break a}default:break a}while(0);while(0);return}function on(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;if(!((b|0)==0&(c|0)==0))do{e=e+-1|0;a[e>>0]=d[23245+(b&15)>>0]|0|f;b=Zo(b|0,c|0,4)|0;c=z}while(!((b|0)==0&(c|0)==0));return e|0}function pn(b,c,d){b=b|0;c=c|0;d=d|0;if(!((b|0)==0&(c|0)==0))do{d=d+-1|0;a[d>>0]=b&7|48;b=Zo(b|0,c|0,3)|0;c=z}while(!((b|0)==0&(c|0)==0));return d|0}function qn(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;if(c>>>0>0|(c|0)==0&b>>>0>4294967295)while(1){e=Yo(b|0,c|0,10,0)|0;d=d+-1|0;a[d>>0]=e&255|48;e=b;b=Xo(b|0,c|0,10,0)|0;if(!(c>>>0>9|(c|0)==9&e>>>0>4294967295))break;else c=z}if(b)while(1){d=d+-1|0;a[d>>0]=(b>>>0)%10|0|48;if(b>>>0<10)break;else b=(b>>>0)/10|0}return d|0}function rn(a){a=a|0;return An(a,c[2018]|0)|0}function sn(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;h=d&255;f=(e|0)!=0;a:do if(f&(b&3|0)!=0){g=d&255;while(1){if((a[b>>0]|0)==g<<24>>24)break a;b=b+1|0;e=e+-1|0;f=(e|0)!=0;if(!(f&(b&3|0)!=0)){i=5;break}}}else i=5;while(0);b:do if((i|0)==5)if(f){g=d&255;if((a[b>>0]|0)!=g<<24>>24){f=O(h,16843009)|0;c:do if(e>>>0>3)while(1){h=c[b>>2]^f;if((h&-2139062144^-2139062144)&h+-16843009|0)break;b=b+4|0;e=e+-4|0;if(e>>>0<=3){i=11;break c}}else i=11;while(0);if((i|0)==11)if(!e){e=0;break}while(1){if((a[b>>0]|0)==g<<24>>24)break b;b=b+1|0;e=e+-1|0;if(!e){e=0;break}}}}else e=0;while(0);return (e|0?b:0)|0}function tn(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0;g=l;l=l+256|0;f=g;if((c|0)>(d|0)&(e&73728|0)==0){e=c-d|0;cp(f|0,b|0,(e>>>0<256?e:256)|0)|0;if(e>>>0>255){d=e;do{ln(a,f,256);d=d+-256|0}while(d>>>0>255);e=e&255}ln(a,f,e)}l=g;return}function un(a,b){a=a|0;b=b|0;if(!a)a=0;else a=zn(a,b)|0;return a|0}function vn(b,e,f,g,h,i){b=b|0;e=+e;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0.0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;H=l;l=l+560|0;m=H+8|0;u=H;G=H+524|0;F=G;n=H+512|0;c[u>>2]=0;E=n+12|0;wn(e)|0;if((z|0)<0){D=1;B=23210;e=-e}else{D=(h&2049|0)!=0&1;B=(h&2048|0)==0?((h&1|0)==0?23211:23216):23213}wn(e)|0;C=z&2146435072;do if(C>>>0<2146435072|(C|0)==2146435072&0<0){r=+xn(e,u)*2.0;j=r!=0.0;if(j)c[u>>2]=(c[u>>2]|0)+-1;w=i|32;if((w|0)==97){s=i&32;q=(s|0)==0?B:B+9|0;p=D|2;j=12-g|0;do if(!(g>>>0>11|(j|0)==0)){e=8.0;do{j=j+-1|0;e=e*16.0}while((j|0)!=0);if((a[q>>0]|0)==45){e=-(e+(-r-e));break}else{e=r+e-e;break}}else e=r;while(0);k=c[u>>2]|0;j=(k|0)<0?0-k|0:k;j=qn(j,((j|0)<0)<<31>>31,E)|0;if((j|0)==(E|0)){j=n+11|0;a[j>>0]=48}a[j+-1>>0]=(k>>31&2)+43;o=j+-2|0;a[o>>0]=i+15;m=(g|0)<1;n=(h&8|0)==0;k=G;while(1){D=~~e;j=k+1|0;a[k>>0]=d[23245+D>>0]|s;e=(e-+(D|0))*16.0;if((j-F|0)==1?!(n&(m&e==0.0)):0){a[j>>0]=46;j=k+2|0}if(!(e!=0.0))break;else k=j}D=j-F|0;F=E-o|0;E=(g|0)!=0&(D+-2|0)<(g|0)?g+2|0:D;j=F+p+E|0;tn(b,32,f,j,h);ln(b,q,p);tn(b,48,f,j,h^65536);ln(b,G,D);tn(b,48,E-D|0,0,0);ln(b,o,F);tn(b,32,f,j,h^8192);break}k=(g|0)<0?6:g;if(j){j=(c[u>>2]|0)+-28|0;c[u>>2]=j;e=r*268435456.0}else{j=c[u>>2]|0;e=r}C=(j|0)<0?m:m+288|0;m=C;do{y=~~e>>>0;c[m>>2]=y;m=m+4|0;e=(e-+(y>>>0))*1.0e9}while(e!=0.0);if((j|0)>0){n=C;o=m;while(1){p=(j|0)<29?j:29;j=o+-4|0;if(j>>>0>=n>>>0){m=0;do{x=_o(c[j>>2]|0,0,p|0)|0;x=Qo(x|0,z|0,m|0,0)|0;y=z;v=Yo(x|0,y|0,1e9,0)|0;c[j>>2]=v;m=Xo(x|0,y|0,1e9,0)|0;j=j+-4|0}while(j>>>0>=n>>>0);if(m){n=n+-4|0;c[n>>2]=m}}m=o;while(1){if(m>>>0<=n>>>0)break;j=m+-4|0;if(!(c[j>>2]|0))m=j;else break}j=(c[u>>2]|0)-p|0;c[u>>2]=j;if((j|0)>0)o=m;else break}}else n=C;if((j|0)<0){g=((k+25|0)/9|0)+1|0;t=(w|0)==102;do{s=0-j|0;s=(s|0)<9?s:9;if(n>>>0>>0){p=(1<>>s;q=0;j=n;do{y=c[j>>2]|0;c[j>>2]=(y>>>s)+q;q=O(y&p,o)|0;j=j+4|0}while(j>>>0>>0);j=(c[n>>2]|0)==0?n+4|0:n;if(!q){n=j;j=m}else{c[m>>2]=q;n=j;j=m+4|0}}else{n=(c[n>>2]|0)==0?n+4|0:n;j=m}m=t?C:n;m=(j-m>>2|0)>(g|0)?m+(g<<2)|0:j;j=(c[u>>2]|0)+s|0;c[u>>2]=j}while((j|0)<0);j=n;g=m}else{j=n;g=m}y=C;if(j>>>0>>0){m=(y-j>>2)*9|0;o=c[j>>2]|0;if(o>>>0>=10){n=10;do{n=n*10|0;m=m+1|0}while(o>>>0>=n>>>0)}}else m=0;t=(w|0)==103;v=(k|0)!=0;n=k-((w|0)!=102?m:0)+((v&t)<<31>>31)|0;if((n|0)<(((g-y>>2)*9|0)+-9|0)){o=n+9216|0;n=C+4+(((o|0)/9|0)+-1024<<2)|0;o=((o|0)%9|0)+1|0;if((o|0)<9){p=10;do{p=p*10|0;o=o+1|0}while((o|0)!=9)}else p=10;q=c[n>>2]|0;s=(q>>>0)%(p>>>0)|0;o=(n+4|0)==(g|0);if(!(o&(s|0)==0)){r=(((q>>>0)/(p>>>0)|0)&1|0)==0?9007199254740992.0:9007199254740994.0;x=(p|0)/2|0;e=s>>>0>>0?.5:o&(s|0)==(x|0)?1.0:1.5;if(D){x=(a[B>>0]|0)==45;r=x?-r:r;e=x?-e:e}o=q-s|0;c[n>>2]=o;if(r+e!=r){x=o+p|0;c[n>>2]=x;if(x>>>0>999999999){m=n;while(1){n=m+-4|0;c[m>>2]=0;if(n>>>0>>0){j=j+-4|0;c[j>>2]=0}x=(c[n>>2]|0)+1|0;c[n>>2]=x;if(x>>>0>999999999)m=n;else break}}m=(y-j>>2)*9|0;p=c[j>>2]|0;if(p>>>0>=10){o=10;do{o=o*10|0;m=m+1|0}while(p>>>0>=o>>>0)}}}w=n+4|0;x=j;j=g>>>0>w>>>0?w:g}else{x=j;j=g}w=j;while(1){if(w>>>0<=x>>>0){u=0;break}j=w+-4|0;if(!(c[j>>2]|0))w=j;else{u=1;break}}g=0-m|0;do if(t){j=((v^1)&1)+k|0;if((j|0)>(m|0)&(m|0)>-5){k=j+-1-m|0;o=i+-1|0}else{k=j+-1|0;o=i+-2|0}j=h&8;if(!j){if(u?(A=c[w+-4>>2]|0,(A|0)!=0):0)if(!((A>>>0)%10|0)){j=10;n=0;do{j=j*10|0;n=n+1|0}while(!((A>>>0)%(j>>>0)|0|0))}else n=0;else n=9;j=((w-y>>2)*9|0)+-9|0;if((o|32|0)==102){i=j-n|0;i=(i|0)>0?i:0;s=0;k=(k|0)<(i|0)?k:i;break}else{i=j+m-n|0;i=(i|0)>0?i:0;s=0;k=(k|0)<(i|0)?k:i;break}}else s=j}else{s=h&8;o=i}while(0);t=k|s;p=(t|0)!=0&1;q=(o|32|0)==102;if(q){v=0;j=(m|0)>0?m:0}else{j=(m|0)<0?g:m;j=qn(j,((j|0)<0)<<31>>31,E)|0;n=E;if((n-j|0)<2)do{j=j+-1|0;a[j>>0]=48}while((n-j|0)<2);a[j+-1>>0]=(m>>31&2)+43;j=j+-2|0;a[j>>0]=o;v=j;j=n-j|0}j=D+1+k+p+j|0;tn(b,32,f,j,h);ln(b,B,D);tn(b,48,f,j,h^65536);if(q){p=x>>>0>C>>>0?C:x;s=G+9|0;q=s;o=G+8|0;n=p;do{m=qn(c[n>>2]|0,0,s)|0;if((n|0)==(p|0)){if((m|0)==(s|0)){a[o>>0]=48;m=o}}else if(m>>>0>G>>>0){cp(G|0,48,m-F|0)|0;do m=m+-1|0;while(m>>>0>G>>>0)}ln(b,m,q-m|0);n=n+4|0}while(n>>>0<=C>>>0);if(t|0)ln(b,23261,1);if(n>>>0>>0&(k|0)>0)while(1){m=qn(c[n>>2]|0,0,s)|0;if(m>>>0>G>>>0){cp(G|0,48,m-F|0)|0;do m=m+-1|0;while(m>>>0>G>>>0)}ln(b,m,(k|0)<9?k:9);n=n+4|0;m=k+-9|0;if(!(n>>>0>>0&(k|0)>9)){k=m;break}else k=m}tn(b,48,k+9|0,9,0)}else{u=u?w:x+4|0;if((k|0)>-1){t=G+9|0;g=(s|0)==0;s=t;o=0-F|0;q=G+8|0;p=x;do{m=qn(c[p>>2]|0,0,t)|0;if((m|0)==(t|0)){a[q>>0]=48;m=q}do if((p|0)==(x|0)){n=m+1|0;ln(b,m,1);if(g&(k|0)<1){m=n;break}ln(b,23261,1);m=n}else{if(m>>>0<=G>>>0)break;cp(G|0,48,m+o|0)|0;do m=m+-1|0;while(m>>>0>G>>>0)}while(0);F=s-m|0;ln(b,m,(k|0)>(F|0)?F:k);k=k-F|0;p=p+4|0}while(p>>>0>>0&(k|0)>-1)}tn(b,48,k+18|0,18,0);ln(b,v,E-v|0)}tn(b,32,f,j,h^8192)}else{G=(i&32|0)!=0;j=D+3|0;tn(b,32,f,j,h&-65537);ln(b,B,D);ln(b,e!=e|0.0!=0.0?(G?23237:23241):G?23229:23233,3);tn(b,32,f,j,h^8192)}while(0);l=H;return ((j|0)<(f|0)?f:j)|0}function wn(a){a=+a;var b=0;h[j>>3]=a;b=c[j>>2]|0;z=c[j+4>>2]|0;return b|0}function xn(a,b){a=+a;b=b|0;return +(+yn(a,b))}function yn(a,b){a=+a;b=b|0;var d=0,e=0,f=0;h[j>>3]=a;d=c[j>>2]|0;e=c[j+4>>2]|0;f=Zo(d|0,e|0,52)|0;switch(f&2047){case 0:{if(a!=0.0){a=+yn(a*18446744073709551616.0,b);d=(c[b>>2]|0)+-64|0}else d=0;c[b>>2]=d;break}case 2047:break;default:{c[b>>2]=(f&2047)+-1022;c[j>>2]=d;c[j+4>>2]=e&-2146435073|1071644672;a=+h[j>>3]}}return +a}function zn(b,d){b=b|0;d=d|0;do if(b){if(d>>>0<128){a[b>>0]=d;b=1;break}if(!(c[c[2018]>>2]|0))if((d&-128|0)==57216){a[b>>0]=d;b=1;break}else{c[6869]=84;b=-1;break}if(d>>>0<2048){a[b>>0]=d>>>6|192;a[b+1>>0]=d&63|128;b=2;break}if(d>>>0<55296|(d&-8192|0)==57344){a[b>>0]=d>>>12|224;a[b+1>>0]=d>>>6&63|128;a[b+2>>0]=d&63|128;b=3;break}if((d+-65536|0)>>>0<1048576){a[b>>0]=d>>>18|240;a[b+1>>0]=d>>>12&63|128;a[b+2>>0]=d>>>6&63|128;a[b+3>>0]=d&63|128;b=4;break}else{c[6869]=84;b=-1;break}}else b=1;while(0);return b|0}function An(b,e){b=b|0;e=e|0;var f=0,g=0;f=0;while(1){if((d[23263+f>>0]|0)==(b|0)){g=2;break}f=f+1|0;if((f|0)==87){f=87;b=23351;g=5;break}}if((g|0)==2)if(!f)f=23351;else{b=23351;g=5}if((g|0)==5)while(1){do{g=b;b=b+1|0}while((a[g>>0]|0)!=0);f=f+-1|0;if(!f){f=b;break}else g=5}return Bn(f,c[e+20>>2]|0)|0}function Bn(a,b){a=a|0;b=b|0;return Cn(a,b)|0}function Cn(a,b){a=a|0;b=b|0;if(!b)b=0;else b=Dn(c[b>>2]|0,c[b+4>>2]|0,a)|0;return (b|0?b:a)|0}function Dn(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;o=(c[b>>2]|0)+1794895138|0;h=En(c[b+8>>2]|0,o)|0;f=En(c[b+12>>2]|0,o)|0;g=En(c[b+16>>2]|0,o)|0;a:do if((h>>>0>>2>>>0?(n=d-(h<<2)|0,f>>>0>>0&g>>>0>>0):0)?((g|f)&3|0)==0:0){n=f>>>2;m=g>>>2;l=0;while(1){k=h>>>1;j=l+k|0;i=j<<1;g=i+n|0;f=En(c[b+(g<<2)>>2]|0,o)|0;g=En(c[b+(g+1<<2)>>2]|0,o)|0;if(!(g>>>0>>0&f>>>0<(d-g|0)>>>0)){f=0;break a}if(a[b+(g+f)>>0]|0){f=0;break a}f=dn(e,b+g|0)|0;if(!f)break;f=(f|0)<0;if((h|0)==1){f=0;break a}else{l=f?l:j;h=f?k:h-k|0}}f=i+m|0;g=En(c[b+(f<<2)>>2]|0,o)|0;f=En(c[b+(f+1<<2)>>2]|0,o)|0;if(f>>>0>>0&g>>>0<(d-f|0)>>>0)f=(a[b+(f+g)>>0]|0)==0?b+f|0:0;else f=0}else f=0;while(0);return f|0}function En(a,b){a=a|0;b=b|0;var c=0;c=$o(a|0)|0;return ((b|0)==0?a:c)|0}function Fn(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;g=e+16|0;f=c[g>>2]|0;if(!f)if(!(Gn(e)|0)){f=c[g>>2]|0;h=5}else f=0;else h=5;a:do if((h|0)==5){j=e+20|0;i=c[j>>2]|0;g=i;if((f-i|0)>>>0>>0){f=Ja[c[e+36>>2]&255](e,b,d)|0;break}b:do if((a[e+75>>0]|0)>-1){i=d;while(1){if(!i){h=g;e=0;g=d;f=b;break b}f=i+-1|0;if((a[b+f>>0]|0)==10)break;else i=f}f=Ja[c[e+36>>2]&255](e,b,i)|0;if(f>>>0>>0)break a;h=c[j>>2]|0;e=i;g=d-i|0;f=b+i|0}else{h=g;e=0;g=d;f=b}while(0);ap(h|0,f|0,g|0)|0;c[j>>2]=(c[j>>2]|0)+g;f=e+g|0}while(0);return f|0}function Gn(b){b=b|0;var d=0,e=0;d=b+74|0;e=a[d>>0]|0;a[d>>0]=e+255|e;d=c[b>>2]|0;if(!(d&8)){c[b+8>>2]=0;c[b+4>>2]=0;d=c[b+44>>2]|0;c[b+28>>2]=d;c[b+20>>2]=d;c[b+16>>2]=d+(c[b+48>>2]|0);d=0}else{c[b>>2]=d|32;d=-1}return d|0}function Hn(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;e=a+20|0;f=c[e>>2]|0;a=(c[a+16>>2]|0)-f|0;a=a>>>0>d>>>0?d:a;ap(f|0,b|0,a|0)|0;c[e>>2]=(c[e>>2]|0)+a;return d|0}function In(a){a=a|0;return (a+-32|0)>>>0<95|0}function Jn(a){a=a|0;Kn(c[a>>2]|0);Pm(a);return}function Kn(a){a=a|0;var b=0,d=0;b=l;l=l+16|0;d=b;c[d>>2]=Ym(a)|0;a=ta(6,d|0)|0;Xm((a|0)==-4?0:a)|0;l=b;return}function Ln(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=l;l=l+48|0;f=g+40|0;e=g+8|0;d=g;c[d>>2]=a;c[d+4>>2]=b;d=na(197,d|0)|0;if((d|0)==-9?(c[e>>2]=a,c[e+4>>2]=1,(pa(221,e|0)|0)>=0):0){Mn(e,a);c[f>>2]=e;c[f+4>>2]=b;b=Xm(ma(195,f|0)|0)|0}else b=Xm(d)|0;l=g;return b|0}function Mn(b,c){b=b|0;c=c|0;var d=0,e=0,f=0;d=b;e=25155;f=d+15|0;do{a[d>>0]=a[e>>0]|0;d=d+1|0;e=e+1|0}while((d|0)<(f|0));if(!c){a[b+14>>0]=48;a[b+15>>0]=0}else{d=14;e=c;while(1){d=d+1|0;if(e>>>0<10)break;else e=(e>>>0)/10|0}a[b+d>>0]=0;while(1){d=d+-1|0;a[b+d>>0]=(c>>>0)%10|0|48;if(c>>>0<10)break;else c=(c>>>0)/10|0}}return}function Nn(a){a=a|0;var b=0,d=0,e=0;e=l;l=l+16|0;d=e+8|0;b=On(a,589824,e)|0;do if((b|0)>=0){a=Qm(1,2072)|0;if(!a){c[d>>2]=b;ta(6,d|0)|0;a=0;break}else{c[a>>2]=b;break}}else a=0;while(0);l=e;return a|0}function On(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;h=l;l=l+48|0;g=h+16|0;f=h;e=h+32|0;if(!(b&4194368))e=0;else{c[e>>2]=d;i=(c[e>>2]|0)+(4-1)&~(4-1);d=c[i>>2]|0;c[e>>2]=i+4;e=d}c[f>>2]=a;c[f+4>>2]=b|32768;c[f+8>>2]=e;e=ra(5,f|0)|0;if(!((b&524288|0)==0|(e|0)<0)){c[g>>2]=e;c[g+4>>2]=2;c[g+8>>2]=1;pa(221,g|0)|0}i=Xm(e)|0;l=h;return i|0}function Pn(a){a=a|0;var b=0,d=0,f=0,g=0,h=0,i=0;i=l;l=l+16|0;d=i;g=a+8|0;b=c[g>>2]|0;f=a+12|0;a:do if((b|0)<(c[f>>2]|0))h=6;else{c[d>>2]=c[a>>2];c[d+4>>2]=a+24;c[d+8>>2]=2048;b=oa(220,d|0)|0;if((b|0)>=1){c[f>>2]=b;c[g>>2]=0;b=0;h=6;break}switch(b|0){case 0:case -2:{b=0;break a}default:{}}c[6869]=0-b;b=0}while(0);if((h|0)==6){h=a+24+b|0;c[g>>2]=(e[h+8>>1]|0)+b;c[a+4>>2]=c[h+4>>2];b=h}l=i;return b|0}function Qn(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0;m=l;l=l+208|0;j=m+8|0;k=m;f=b<<2;i=k;c[i>>2]=1;c[i+4>>2]=0;a:do if(f|0){c[j+4>>2]=4;c[j>>2]=4;b=4;d=4;e=2;while(1){b=b+4+d|0;c[j+(e<<2)>>2]=b;if(b>>>0>>0){i=d;d=b;e=e+1|0;b=i}else break}g=a+f+-4|0;if(g>>>0>a>>>0){h=g;i=k+4|0;e=1;d=a;b=1;do{do if((e&3|0)!=3){f=b+-1|0;if((c[j+(f<<2)>>2]|0)>>>0<(h-d|0)>>>0)Rn(d,b,j);else Tn(d,e,c[i>>2]|0,b,0,j);if((b|0)==1){Un(k,1);b=0;break}else{Un(k,f);b=1;break}}else{Rn(d,b,j);Sn(k,2);b=b+2|0}while(0);e=c[k>>2]|1;c[k>>2]=e;d=d+4|0}while(d>>>0>>0);g=i;f=c[i>>2]|0}else{g=k+4|0;f=0;e=1;d=a;b=1}Tn(d,e,f,b,0,j);f=k+4|0;while(1){if((b|0)==1&(e|0)==1){if(!(c[f>>2]|0))break a}else if((b|0)>=2){Un(k,2);a=b+-2|0;c[k>>2]=c[k>>2]^7;Sn(k,1);Tn(d+(0-(c[j+(a<<2)>>2]|0))+-4|0,c[k>>2]|0,c[g>>2]|0,b+-1|0,1,j);Un(k,1);e=c[k>>2]|1;c[k>>2]=e;i=d+-4|0;Tn(i,e,c[g>>2]|0,a,1,j);d=i;b=a;continue}a=Vn(k)|0;Sn(k,a);e=c[k>>2]|0;d=d+-4|0;b=a+b|0}}while(0);l=m;return}function Rn(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;k=l;l=l+240|0;j=k;c[j>>2]=a;a:do if((b|0)>1){i=a;e=a;a=1;while(1){e=e+-4|0;g=b+-2|0;f=e+(0-(c[d+(g<<2)>>2]|0))|0;if((Fh(i,f)|0)>-1?(Fh(i,e)|0)>-1:0)break a;h=a+1|0;a=j+(a<<2)|0;if((Fh(f,e)|0)>-1){c[a>>2]=f;a=f;b=b+-1|0}else{c[a>>2]=e;a=e;b=g}if((b|0)<=1){a=h;break a}i=c[j>>2]|0;e=a;a=h}}else a=1;while(0);Xn(j,a);l=k;return}function Sn(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=a+4|0;if(b>>>0>31){d=c[f>>2]|0;c[a>>2]=d;c[f>>2]=0;e=0;b=b+-32|0}else{d=c[a>>2]|0;e=c[f>>2]|0}c[a>>2]=e<<32-b|d>>>b;c[f>>2]=e>>>b;return}function Tn(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0;n=l;l=l+240|0;k=n+232|0;m=n;c[k>>2]=b;j=k+4|0;c[j>>2]=d;c[m>>2]=a;a:do if((b|0)!=1|(d|0)!=0?(h=a+(0-(c[g+(e<<2)>>2]|0))|0,(Fh(h,a)|0)>=1):0){b=h;i=1;h=(f|0)==0;while(1){if(h&(e|0)>1){h=a+-4|0;if((Fh(h,b)|0)>-1){b=a;h=i;d=10;break a}if((Fh(h+(0-(c[g+(e+-2<<2)>>2]|0))|0,b)|0)>-1){b=a;h=i;d=10;break a}}d=i+1|0;c[m+(i<<2)>>2]=b;f=Vn(k)|0;Sn(k,f);e=f+e|0;if(!((c[k>>2]|0)!=1|(c[j>>2]|0)!=0)){h=d;d=10;break a}h=b+(0-(c[g+(e<<2)>>2]|0))|0;if((Fh(h,c[m>>2]|0)|0)<1){h=d;d=10;break}else{a=b;b=h;i=d;h=1}}}else d=9;while(0);if((d|0)==9?(f|0)==0:0){b=a;h=1;d=10}if((d|0)==10){Xn(m,h);Rn(b,e,g)}l=n;return}function Un(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=a+4|0;if(b>>>0>31){d=c[a>>2]|0;c[f>>2]=d;c[a>>2]=0;e=0;b=b+-32|0}else{d=c[f>>2]|0;e=c[a>>2]|0}c[f>>2]=e>>>(32-b|0)|d<>2]=e<>2]|0)+-1|0)|0;if(!b){a=Wn(c[a+4>>2]|0)|0;return ((a|0)==0?0:a+32|0)|0}else return b|0;return 0}function Wn(a){a=a|0;var b=0;if(a)if(!(a&1)){b=0;do{b=b+1|0;a=a>>>1}while(!(a&1|0))}else b=0;else b=32;return b|0}function Xn(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;i=l;l=l+256|0;f=i;a:do if((e|0)>=2){c[b+(e<<2)>>2]=f;h=c[b>>2]|0;c[f>>2]=d[h>>0]|d[h+1>>0]<<8|d[h+2>>0]<<16|d[h+3>>0]<<24;f=0;while(1){j=b+(f<<2)|0;f=f+1|0;g=b+(f<<2)|0;k=c[g>>2]|0;k=d[k>>0]|d[k+1>>0]<<8|d[k+2>>0]<<16|d[k+3>>0]<<24;a[h>>0]=k;a[h+1>>0]=k>>8;a[h+2>>0]=k>>16;a[h+3>>0]=k>>24;c[j>>2]=(c[j>>2]|0)+4;if((f|0)==(e|0))break a;h=c[g>>2]|0}}while(0);l=i;return}function Yn(b,c){b=b|0;c=c|0;var e=0,f=0,g=0;e=a[b>>0]|0;f=e&255;a:do if(e<<24>>24){g=b;do{b=a[c>>0]|0;if(!(b<<24>>24))break a;if(e<<24>>24!=b<<24>>24?(e=$m(f)|0,(e|0)!=($m(b&255)|0)):0)break a;g=g+1|0;c=c+1|0;e=a[g>>0]|0;f=e&255}while(e<<24>>24!=0)}while(0);g=$m(f)|0;return g-($m(d[c>>0]|0)|0)|0}function Zn(b){b=b|0;var d=0,e=0,f=0;f=b;a:do if(!(f&3)){d=b;e=4}else{d=f;while(1){if(!(a[b>>0]|0))break a;b=b+1|0;d=b;if(!(d&3)){d=b;e=4;break}}}while(0);if((e|0)==4){while(1){b=c[d>>2]|0;if(!((b&-2139062144^-2139062144)&b+-16843009))d=d+4|0;else break}if((b&255)<<24>>24)do d=d+1|0;while((a[d>>0]|0)!=0)}return d-f|0}function _n(b,c){b=b|0;c=c|0;b=$n(b,c)|0;return ((a[b>>0]|0)==(c&255)<<24>>24?b:0)|0}function $n(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;f=d&255;a:do if(!f)b=b+(Zn(b)|0)|0;else{if(b&3){e=d&255;do{g=a[b>>0]|0;if(g<<24>>24==0?1:g<<24>>24==e<<24>>24)break a;b=b+1|0}while((b&3|0)!=0)}f=O(f,16843009)|0;e=c[b>>2]|0;b:do if(!((e&-2139062144^-2139062144)&e+-16843009))do{g=e^f;if((g&-2139062144^-2139062144)&g+-16843009|0)break b;b=b+4|0;e=c[b>>2]|0}while(!((e&-2139062144^-2139062144)&e+-16843009|0));while(0);e=d&255;while(1){g=a[b>>0]|0;if(g<<24>>24==0?1:g<<24>>24==e<<24>>24)break;else b=b+1|0}}while(0);return b|0}function ao(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;f=l;l=l+16|0;g=f;c[g>>2]=e;gn(a,b,d,g);l=f;return}function bo(a){a=+a;var b=0,d=0,e=0,f=0,g=0.0,i=0.0,k=0.0,l=0.0,m=0.0;h[j>>3]=a;d=c[j>>2]|0;b=c[j+4>>2]|0;e=(b|0)<0;do if(e|b>>>0<1048576){if((d|0)==0&(b&2147483647|0)==0){a=-1.0/(a*a);break}if(e){a=(a-a)/0.0;break}else{h[j>>3]=a*18014398509481984.0;b=c[j+4>>2]|0;e=c[j>>2]|0;d=-1077;f=9;break}}else if(b>>>0<=2146435071)if((d|0)==0&0==0&(b|0)==1072693248)a=0.0;else{e=d;d=-1023;f=9}while(0);if((f|0)==9){f=b+614242|0;c[j>>2]=e;c[j+4>>2]=(f&1048575)+1072079006;k=+h[j>>3]+-1.0;i=k*(k*.5);l=k/(k+2.0);m=l*l;a=m*m;h[j>>3]=k-i;e=c[j+4>>2]|0;c[j>>2]=0;c[j+4>>2]=e;g=+h[j>>3];a=k-g-i+l*(i+(a*(a*(a*.15313837699209373+.22222198432149784)+.3999999999940942)+m*(a*(a*(a*.14798198605116586+.1818357216161805)+.2857142874366239)+.6666666666666735)));m=g*.4342944818781689;i=+(d+(f>>>20)|0);l=i*.30102999566361177;k=l+m;a=k+(m+(l-k)+(a*.4342944818781689+(i*3.694239077158931e-13+(g+a)*2.5082946711645275e-11)))}return +a}function co(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;b=O(c,b)|0;Fn(a,b,d)|0;return}function eo(a){a=a|0;var b=0;if(c[a+68>>2]|0){b=c[a+116>>2]|0;a=a+112|0;if(b|0)c[b+112>>2]=c[a>>2];a=c[a>>2]|0;c[((a|0)==0?8116:a+116|0)>>2]=b}return}function fo(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0;m=l;l=l+16|0;j=m;k=e&255;a[j>>0]=k;h=b+16|0;g=c[h>>2]|0;if(!g)if(!(Gn(b)|0)){g=c[h>>2]|0;i=4}else f=-1;else i=4;do if((i|0)==4){i=b+20|0;h=c[i>>2]|0;if(h>>>0>>0?(f=e&255,(f|0)!=(a[b+75>>0]|0)):0){c[i>>2]=h+1;a[h>>0]=k;break}if((Ja[c[b+36>>2]&255](b,j,1)|0)==1)f=d[j>>0]|0;else f=-1}while(0);l=m;return f|0}function go(a,b){a=a|0;b=b|0;var d=0,e=0;d=l;l=l+16|0;e=d;c[e>>2]=a;c[e+4>>2]=b;a=Xm(ma(195,e|0)|0)|0;l=d;return a|0}function ho(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;i=l;l=l+48|0;h=i+32|0;g=i+16|0;e=i;if(sn(25170,a[d>>0]|0,4)|0){f=io(d)|0;c[e>>2]=b;c[e+4>>2]=f|32768;c[e+8>>2]=438;e=Xm(ra(5,e|0)|0)|0;if((e|0)>=0){if(f&524288|0){c[g>>2]=e;c[g+4>>2]=2;c[g+8>>2]=1;pa(221,g|0)|0}b=jo(e,d)|0;if(!b){c[h>>2]=e;ta(6,h|0)|0;b=0}}else b=0}else{c[6869]=22;b=0}l=i;return b|0}function io(b){b=b|0;var c=0,d=0,e=0;d=(_n(b,43)|0)==0;c=a[b>>0]|0;d=d?c<<24>>24!=114&1:2;e=(_n(b,120)|0)==0;d=e?d:d|128;b=(_n(b,101)|0)==0;b=b?d:d|524288;b=c<<24>>24==114?b:b|64;b=c<<24>>24==119?b|512:b;return (c<<24>>24==97?b|1024:b)|0}function jo(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0;o=l;l=l+64|0;m=o+40|0;k=o+24|0;j=o+16|0;g=o;n=o+56|0;f=a[d>>0]|0;if(sn(25170,f<<24>>24,4)|0){e=Om(1156)|0;if(!e)e=0;else{h=e;i=h+124|0;do{c[h>>2]=0;h=h+4|0}while((h|0)<(i|0));if(!(_n(d,43)|0))c[e>>2]=f<<24>>24==114?8:4;if(_n(d,101)|0){c[g>>2]=b;c[g+4>>2]=2;c[g+8>>2]=1;pa(221,g|0)|0;f=a[d>>0]|0}if(f<<24>>24==97){c[j>>2]=b;c[j+4>>2]=3;f=pa(221,j|0)|0;if(!(f&1024)){c[k>>2]=b;c[k+4>>2]=4;c[k+8>>2]=f|1024;pa(221,k|0)|0}d=c[e>>2]|128;c[e>>2]=d}else d=c[e>>2]|0;c[e+60>>2]=b;c[e+44>>2]=e+132;c[e+48>>2]=1024;f=e+75|0;a[f>>0]=-1;if((d&8|0)==0?(c[m>>2]=b,c[m+4>>2]=21523,c[m+8>>2]=n,(sa(54,m|0)|0)==0):0)a[f>>0]=10;c[e+32>>2]=150;c[e+36>>2]=146;c[e+40>>2]=147;c[e+12>>2]=5;if(!(c[6854]|0))c[e+76>>2]=-1;ko(e)|0}}else{c[6869]=22;e=0}l=o;return e|0}function ko(a){a=a|0;var b=0;lo();b=c[6872]|0;c[a+56>>2]=b;if(b|0)c[b+52>>2]=a;c[6872]=a;mo();return a|0}function lo(){ga(27480);return}function mo(){ua(27480);return}function no(a){a=a|0;var b=0,d=0,e=0;eo(a);e=(c[a>>2]&1|0)!=0;if(!e){lo();d=c[a+52>>2]|0;b=a+56|0;if(d|0)c[d+56>>2]=c[b>>2];b=c[b>>2]|0;if(b|0)c[b+52>>2]=d;if((c[6872]|0)==(a|0))c[6872]=b;mo()}d=oo(a)|0;d=Ha[c[a+12>>2]&7](a)|0|d;b=c[a+92>>2]|0;if(b|0)Pm(b);if(!e)Pm(a);return d|0}function oo(a){a=a|0;var b=0;if(!a){if(!(c[1939]|0))a=0;else a=oo(c[1939]|0)|0;lo();b=c[6872]|0;if(b)do{if((c[b+20>>2]|0)>>>0>(c[b+28>>2]|0)>>>0)a=po(b)|0|a;b=c[b+56>>2]|0}while((b|0)!=0);mo()}else a=po(a)|0;return a|0}function po(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;h=a+20|0;g=a+28|0;if((c[h>>2]|0)>>>0>(c[g>>2]|0)>>>0?(Ja[c[a+36>>2]&255](a,0,0)|0,(c[h>>2]|0)==0):0)b=-1;else{f=a+4|0;b=c[f>>2]|0;e=a+8|0;d=c[e>>2]|0;if(b>>>0>>0)Ja[c[a+40>>2]&255](a,b-d|0,1)|0;c[a+16>>2]=0;c[g>>2]=0;c[h>>2]=0;c[e>>2]=0;c[f>>2]=0;b=0}return b|0}function qo(a){a=a|0;return (c[a>>2]|0)>>>4&1|0}function ro(a,b,c){a=a|0;b=b|0;c=c|0;return to(a,b,c)|0}function so(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;a=l;l=l+16|0;e=a;c[e>>2]=d;hn(7508,b,e)|0;l=a;return}function to(a,b,c){a=a|0;b=b|0;c=c|0;return uo(a,b,c)|0}function uo(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;if((d|0)==1)b=b-(c[a+8>>2]|0)+(c[a+4>>2]|0)|0;f=a+20|0;e=a+28|0;if((c[f>>2]|0)>>>0>(c[e>>2]|0)>>>0?(Ja[c[a+36>>2]&255](a,0,0)|0,(c[f>>2]|0)==0):0)b=-1;else{c[a+16>>2]=0;c[e>>2]=0;c[f>>2]=0;if((Ja[c[a+40>>2]&255](a,b,d)|0)<0)b=-1;else{c[a+8>>2]=0;c[a+4>>2]=0;c[a>>2]=c[a>>2]&-17;b=0}}return b|0}function vo(a,b){a=a|0;b=b|0;return wo(a,b,(Zn(a)|0)+1|0)|0}function wo(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;e=c&255;do{if(!d){c=0;break}d=d+-1|0;c=b+d|0}while((a[c>>0]|0)!=e<<24>>24);return c|0}function xo(a){a=a|0;var b=0,d=0;b=l;l=l+16|0;d=b;c[d>>2]=a;Xm(ia(10,d|0)|0)|0;l=b;return}function yo(a,b,c){a=a|0;b=b|0;c=c|0;zo(a,b,c);return a|0}function zo(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;g=d;a:do if(!((g^b)&3)){f=(e|0)!=0;if(f&(g&3|0)!=0)do{g=a[d>>0]|0;a[b>>0]=g;if(!(g<<24>>24))break a;e=e+-1|0;d=d+1|0;b=b+1|0;f=(e|0)!=0}while(f&(d&3|0)!=0);if(f){if(a[d>>0]|0){b:do if(e>>>0>3){f=d;while(1){d=c[f>>2]|0;if((d&-2139062144^-2139062144)&d+-16843009|0){d=f;break b}c[b>>2]=d;e=e+-4|0;d=f+4|0;b=b+4|0;if(e>>>0>3)f=d;else break}}while(0);h=11}}else e=0}else h=11;while(0);c:do if((h|0)==11)if(!e)e=0;else while(1){h=a[d>>0]|0;a[b>>0]=h;if(!(h<<24>>24))break c;e=e+-1|0;b=b+1|0;if(!e){e=0;break}else d=d+1|0}while(0);cp(b|0,0,e|0)|0;return}function Ao(){var a=0,b=0,d=0;b=25184;b=Wo(c[b>>2]|0,c[b+4>>2]|0,1284865837,1481765933)|0;b=Qo(b|0,z|0,1,0)|0;a=z;d=25184;c[d>>2]=b;c[d+4>>2]=a;a=Zo(b|0,a|0,33)|0;return a|0}function Bo(a){a=a|0;var b=0,e=0,f=0;do if((c[a+76>>2]|0)>=0?(kn()|0)!=0:0){e=a+4|0;b=c[e>>2]|0;if(b>>>0<(c[a+8>>2]|0)>>>0){c[e>>2]=b+1;b=d[b>>0]|0;break}else{b=bn(a)|0;break}}else f=3;while(0);do if((f|0)==3){e=a+4|0;b=c[e>>2]|0;if(b>>>0<(c[a+8>>2]|0)>>>0){c[e>>2]=b+1;b=d[b>>0]|0;break}else{b=bn(a)|0;break}}while(0);return b|0}function Co(a){a=a|0;return Do(a)|0}function Do(a){a=a|0;var b=0;if(!(c[a>>2]&128))b=1;else b=(c[a+20>>2]|0)>>>0>(c[a+28>>2]|0)>>>0?2:1;b=Ja[c[a+40>>2]&255](a,0,b)|0;if((b|0)>=0)b=b-(c[a+8>>2]|0)+(c[a+4>>2]|0)+(c[a+20>>2]|0)-(c[a+28>>2]|0)|0;return b|0}function Eo(a){a=a|0;return c[a+60>>2]|0}function Fo(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;g=b&255;h=b&255;do if((c[d+76>>2]|0)>=0?(kn()|0)!=0:0){if((h|0)!=(a[d+75>>0]|0)?(j=d+20|0,f=c[j>>2]|0,f>>>0<(c[d+16>>2]|0)>>>0):0){c[j>>2]=f+1;a[f>>0]=g;break}fo(d,b)|0}else k=3;while(0);do if((k|0)==3){if((h|0)!=(a[d+75>>0]|0)?(i=d+20|0,e=c[i>>2]|0,e>>>0<(c[d+16>>2]|0)>>>0):0){c[i>>2]=e+1;a[e>>0]=g;break}fo(d,b)|0}while(0);return}function Go(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0;j=O(e,d)|0;e=(d|0)==0?0:e;h=f+74|0;g=a[h>>0]|0;a[h>>0]=g+255|g;h=f+4|0;g=c[h>>2]|0;k=(c[f+8>>2]|0)-g|0;i=k>>>0>>0?k:j;if((k|0)>0){ap(b|0,g|0,i|0)|0;c[h>>2]=g+i;g=b+i|0;h=j-i|0}else{g=b;h=j}a:do if(h){i=f+32|0;while(1){if(cn(f)|0)break;b=Ja[c[i>>2]&255](f,g,h)|0;if((b+1|0)>>>0<2)break;h=h-b|0;if(!h)break a;else g=g+b|0}e=((j-h|0)>>>0)/(d>>>0)|0}while(0);return e|0}function Ho(a){a=a|0;return Co(a)|0}function Io(){var a=0;a=rn(c[6869]|0)|0;co(21628,24,1,7508);Fo(58,7508);Fo(32,7508);co(a,Zn(a)|0,1,7508);Fo(10,7508);return}function Jo(a,b){a=a|0;b=b|0;var d=0,e=0;d=l;l=l+16|0;e=d;c[e>>2]=b;hn(7632,a,e)|0;l=d;return}function Ko(b){b=b|0;var d=0,e=0,f=0;f=l;l=l+16|0;e=f;fa(0,e|0)|0;d=0;e=(c[e+4>>2]|0)*65537^(e>>>4)+b;while(1){a[b+d>>0]=(e&15)+65|e<<1&32;d=d+1|0;if((d|0)==6)break;else e=e>>>5}l=f;return b|0}function Lo(b){b=b|0;var c=0,d=0,e=0;d=b+(Zn(b)|0)|0;e=22471;while(1){c=a[e>>0]|0;if(!(c<<24>>24))break;a[d>>0]=c;d=d+1|0;e=e+1|0}a[d>>0]=0;return b|0}function Mo(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0;i=l;l=l+16|0;g=i;d=Zn(b)|0;a:do if(d>>>0>=6?(f=b+d+-6|0,(en(f,25174,6)|0)==0):0){e=100;do{Ko(f)|0;c[g>>2]=384;d=On(b,194,g)|0;if((d|0)>-1)break a;e=e+-1|0}while((e|0)!=0&(c[6869]|0)==17);a[f>>0]=a[25174]|0;a[f+1>>0]=a[25175]|0;a[f+2>>0]=a[25176]|0;a[f+3>>0]=a[25177]|0;a[f+4>>0]=a[25178]|0;a[f+5>>0]=a[25179]|0;d=-1}else h=3;while(0);if((h|0)==3){c[6869]=22;d=-1}l=i;return d|0}function No(a){a=a|0;return Mo(a)|0}function Oo(a){a=a|0;var b=0,d=0;b=l;l=l+16|0;d=b;c[d>>2]=a;a=Xm(qa(41,d|0)|0)|0;l=b;return a|0}function Po(){}function Qo(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;c=a+c>>>0;return (z=b+d+(c>>>0>>0|0)>>>0,c|0)|0}function Ro(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;d=b-d-(c>>>0>a>>>0|0)>>>0;return (z=d,a-c>>>0|0)|0}function So(b){b=b|0;var c=0;c=a[n+(b&255)>>0]|0;if((c|0)<8)return c|0;c=a[n+(b>>8&255)>>0]|0;if((c|0)<8)return c+8|0;c=a[n+(b>>16&255)>>0]|0;if((c|0)<8)return c+16|0;return (a[n+(b>>>24)>>0]|0)+24|0}function To(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;l=a;j=b;k=j;h=d;n=e;i=n;if(!k){g=(f|0)!=0;if(!i){if(g){c[f>>2]=(l>>>0)%(h>>>0);c[f+4>>2]=0}n=0;f=(l>>>0)/(h>>>0)>>>0;return (z=n,f)|0}else{if(!g){n=0;f=0;return (z=n,f)|0}c[f>>2]=a|0;c[f+4>>2]=b&0;n=0;f=0;return (z=n,f)|0}}g=(i|0)==0;do if(h){if(!g){g=(R(i|0)|0)-(R(k|0)|0)|0;if(g>>>0<=31){m=g+1|0;i=31-g|0;b=g-31>>31;h=m;a=l>>>(m>>>0)&b|k<>>(m>>>0)&b;g=0;i=l<>2]=a|0;c[f+4>>2]=j|b&0;n=0;f=0;return (z=n,f)|0}g=h-1|0;if(g&h|0){i=(R(h|0)|0)+33-(R(k|0)|0)|0;p=64-i|0;m=32-i|0;j=m>>31;o=i-32|0;b=o>>31;h=i;a=m-1>>31&k>>>(o>>>0)|(k<>>(i>>>0))&b;b=b&k>>>(i>>>0);g=l<>>(o>>>0))&j|l<>31;break}if(f|0){c[f>>2]=g&l;c[f+4>>2]=0}if((h|0)==1){o=j|b&0;p=a|0|0;return (z=o,p)|0}else{p=So(h|0)|0;o=k>>>(p>>>0)|0;p=k<<32-p|l>>>(p>>>0)|0;return (z=o,p)|0}}else{if(g){if(f|0){c[f>>2]=(k>>>0)%(h>>>0);c[f+4>>2]=0}o=0;p=(k>>>0)/(h>>>0)>>>0;return (z=o,p)|0}if(!l){if(f|0){c[f>>2]=0;c[f+4>>2]=(k>>>0)%(i>>>0)}o=0;p=(k>>>0)/(i>>>0)>>>0;return (z=o,p)|0}g=i-1|0;if(!(g&i)){if(f|0){c[f>>2]=a|0;c[f+4>>2]=g&k|b&0}o=0;p=k>>>((So(i|0)|0)>>>0);return (z=o,p)|0}g=(R(i|0)|0)-(R(k|0)|0)|0;if(g>>>0<=30){b=g+1|0;i=31-g|0;h=b;a=k<>>(b>>>0);b=k>>>(b>>>0);g=0;i=l<>2]=a|0;c[f+4>>2]=j|b&0;o=0;p=0;return (z=o,p)|0}while(0);if(!h){k=i;j=0;i=0}else{m=d|0|0;l=n|e&0;k=Qo(m|0,l|0,-1,-1)|0;d=z;j=i;i=0;do{e=j;j=g>>>31|j<<1;g=i|g<<1;e=a<<1|e>>>31|0;n=a>>>31|b<<1|0;Ro(k|0,d|0,e|0,n|0)|0;p=z;o=p>>31|((p|0)<0?-1:0)<<1;i=o&1;a=Ro(e|0,n|0,o&m|0,(((p|0)<0?-1:0)>>31|((p|0)<0?-1:0)<<1)&l|0)|0;b=z;h=h-1|0}while((h|0)!=0);k=j;j=0}h=0;if(f|0){c[f>>2]=a;c[f+4>>2]=b}o=(g|0)>>>31|(k|h)<<1|(h<<1|g>>>31)&0|j;p=(g<<1|0>>>31)&-2|i;return (z=o,p)|0}function Uo(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0;j=b>>31|((b|0)<0?-1:0)<<1;i=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;f=d>>31|((d|0)<0?-1:0)<<1;e=((d|0)<0?-1:0)>>31|((d|0)<0?-1:0)<<1;h=Ro(j^a|0,i^b|0,j|0,i|0)|0;g=z;a=f^j;b=e^i;return Ro((To(h,g,Ro(f^c|0,e^d|0,f|0,e|0)|0,z,0)|0)^a|0,z^b|0,a|0,b|0)|0}function Vo(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;f=a&65535;e=b&65535;c=O(e,f)|0;d=a>>>16;a=(c>>>16)+(O(e,d)|0)|0;e=b>>>16;b=O(e,f)|0;return (z=(a>>>16)+(O(e,d)|0)+(((a&65535)+b|0)>>>16)|0,a+b<<16|c&65535|0)|0}function Wo(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;e=a;f=c;c=Vo(e,f)|0;a=z;return (z=(O(b,f)|0)+(O(d,e)|0)+a|a&0,c|0|0)|0}function Xo(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return To(a,b,c,d,0)|0}function Yo(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;g=l;l=l+16|0;f=g|0;To(a,b,d,e,f)|0;l=g;return (z=c[f+4>>2]|0,c[f>>2]|0)|0}function Zo(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){z=b>>>c;return a>>>c|(b&(1<>>c-32|0}function _o(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){z=b<>>32-c;return a<>8&255)<<16|(a>>16&255)<<8|a>>>24|0}function ap(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;if((e|0)>=8192)return ya(b|0,d|0,e|0)|0;h=b|0;g=b+e|0;if((b&3)==(d&3)){while(b&3){if(!e)return h|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}e=g&-4|0;f=e-64|0;while((b|0)<=(f|0)){c[b>>2]=c[d>>2];c[b+4>>2]=c[d+4>>2];c[b+8>>2]=c[d+8>>2];c[b+12>>2]=c[d+12>>2];c[b+16>>2]=c[d+16>>2];c[b+20>>2]=c[d+20>>2];c[b+24>>2]=c[d+24>>2];c[b+28>>2]=c[d+28>>2];c[b+32>>2]=c[d+32>>2];c[b+36>>2]=c[d+36>>2];c[b+40>>2]=c[d+40>>2];c[b+44>>2]=c[d+44>>2];c[b+48>>2]=c[d+48>>2];c[b+52>>2]=c[d+52>>2];c[b+56>>2]=c[d+56>>2];c[b+60>>2]=c[d+60>>2];b=b+64|0;d=d+64|0}while((b|0)<(e|0)){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0}}else{e=g-4|0;while((b|0)<(e|0)){a[b>>0]=a[d>>0]|0;a[b+1>>0]=a[d+1>>0]|0;a[b+2>>0]=a[d+2>>0]|0;a[b+3>>0]=a[d+3>>0]|0;b=b+4|0;d=d+4|0}}while((b|0)<(g|0)){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0}return h|0}function bp(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;if((c|0)<(b|0)&(b|0)<(c+d|0)){e=b;c=c+d|0;b=b+d|0;while((d|0)>0){b=b-1|0;c=c-1|0;d=d-1|0;a[b>>0]=a[c>>0]|0}b=e}else ap(b,c,d)|0;return b|0}function cp(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;h=b+e|0;d=d&255;if((e|0)>=67){while(b&3){a[b>>0]=d;b=b+1|0}f=h&-4|0;g=f-64|0;i=d|d<<8|d<<16|d<<24;while((b|0)<=(g|0)){c[b>>2]=i;c[b+4>>2]=i;c[b+8>>2]=i;c[b+12>>2]=i;c[b+16>>2]=i;c[b+20>>2]=i;c[b+24>>2]=i;c[b+28>>2]=i;c[b+32>>2]=i;c[b+36>>2]=i;c[b+40>>2]=i;c[b+44>>2]=i;c[b+48>>2]=i;c[b+52>>2]=i;c[b+56>>2]=i;c[b+60>>2]=i;b=b+64|0}while((b|0)<(f|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}return h-e|0}function dp(a){a=+a;return a>=0.0?+A(a+.5):+N(a-.5)}function ep(a){a=a|0;var b=0,d=0;d=a+15&-16|0;b=c[i>>2]|0;a=b+d|0;if((d|0)>0&(a|0)<(b|0)|(a|0)<0){W()|0;ha(12);return -1}c[i>>2]=a;if((a|0)>(V()|0)?(U()|0)==0:0){c[i>>2]=b;ha(12);return -1}return b|0}function fp(a,b){a=a|0;b=b|0;return Ha[a&7](b|0)|0}function gp(a,b,c){a=a|0;b=b|0;c=c|0;return Ia[a&63](b|0,c|0)|0}function hp(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return Ja[a&255](b|0,c|0,d|0)|0}function ip(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;return Ka[a&127](b|0,c|0,d|0,e|0)|0}function jp(a,b,c){a=a|0;b=b|0;c=c|0;La[a&1](b|0,c|0)}function kp(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;Ma[a&3](b|0,c|0,d|0)}function lp(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;Na[a&1](b|0,c|0,d|0,e|0)}function mp(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;Oa[a&31](b|0,c|0,d|0,e|0,f|0,g|0)}function np(a){a=a|0;S(0);return 0}function op(a,b){a=a|0;b=b|0;S(1);return 0}function pp(a,b,c){a=a|0;b=b|0;c=c|0;S(2);return 0}function qp(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;S(3);return 0}function rp(a,b){a=a|0;b=b|0;S(4)}function sp(a,b,c){a=a|0;b=b|0;c=c|0;S(5)}function tp(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;S(6)}function up(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;S(7)} +function Zc(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0;L=l;l=l+176|0;q=L+8|0;J=L+160|0;p=L+96|0;D=L+16|0;cm(p,20,1,g)|0;i=p+20|0;cm(i,8,1,g)|0;n=p+28|0;b[n>>1]=Rl(g)|0;b[p+30>>1]=Rl(g)|0;r=p+32|0;b[r>>1]=Rl(g)|0;s=p+34|0;b[s>>1]=Rl(g)|0;t=p+36|0;b[t>>1]=Rl(g)|0;b[p+38>>1]=Rl(g)|0;b[p+40>>1]=Rl(g)|0;a[p+42>>0]=Pl(g)|0;o=p+43|0;a[o>>0]=Pl(g)|0;b[p+44>>1]=Rl(g)|0;b[p+46>>1]=Rl(g)|0;k=p+48|0;b[k>>1]=Rl(g)|0;j=p+50|0;b[j>>1]=Rl(g)|0;m=p+52|0;b[m>>1]=Rl(g)|0;b[p+54>>1]=Rl(g)|0;b[p+56>>1]=Rl(g)|0;b[p+58>>1]=Rl(g)|0;cm(p+60|0,4,1,g)|0;k=b[k>>1]|0;j=b[j>>1]|0;m=b[m>>1]|0;if((k&65535)>254|(j&65535)>256|(m&65535)>256){f=-1;l=L;return f|0}F=(on(i,33039,8)|0)==0;G=j&65535;K=f+140|0;c[K>>2]=G;j=k&65535;I=f+128|0;c[I>>2]=j;H=f+136|0;c[f+132>>2]=O(c[H>>2]|0,j)|0;j=f+156|0;c[j>>2]=m&65535;c[f+148>>2]=(d[o>>0]|0)>>>4;c[f+144>>2]=G;c[f+1264>>2]=8363;dm(g,(e[r>>1]<<4)+h|0,0)|0;dm(g,(((Rl(g)|0)&65535)<<4)+h|0,0)|0;G=Rl(g)|0;G=G<<16>>16==(b[n>>1]|0);Ho(f,p,20)|0;if(F)ob(f,33048,L);else{c[q>>2]=(G^1)&1;io(f+64|0,64,33061,q)}E=Xm(2,c[I>>2]|0)|0;if(!E){f=-1;l=L;return f|0}F=Xm(2,c[K>>2]|0)|0;if(F|0){dm(g,(e[r>>1]<<4)+h|0,0)|0;if((c[I>>2]|0)>0){i=0;do{b[E+(i<<1)>>1]=Rl(g)|0;i=i+1|0}while((i|0)<(c[I>>2]|0))}dm(g,(e[s>>1]<<4)+h|0,0)|0;if((c[K>>2]|0)>0){i=0;do{b[F+(i<<1)>>1]=Rl(g)|0;i=i+1|0}while((i|0)<(c[K>>2]|0))}dm(g,h+32+(e[t>>1]<<4)|0,0)|0;if((c[j>>2]|0)>0){i=0;do{a[f+952+i>>0]=Pl(g)|0;dm(g,4,1)|0;i=i+1|0}while((i|0)<(c[j>>2]|0))}a:do if((Za(f)|0)>=0){if((c[K>>2]|0)>0){i=D+1|0;w=D+14|0;t=D+16|0;u=D+20|0;v=D+24|0;A=D+28|0;y=D+29|0;x=D+30|0;o=D+31|0;n=D+32|0;z=D+34|0;j=D+36|0;r=D+40|0;q=D+42|0;s=D+44|0;k=D+48|0;m=D+76|0;C=f+180|0;B=f+176|0;p=0;do{if((_a(f,p,1)|0)<0)break a;dm(g,(e[F+(p<<1)>>1]<<4)+h|0,0)|0;a[D>>0]=Pl(g)|0;cm(i,13,1,g)|0;b[w>>1]=Rl(g)|0;c[t>>2]=_l(g)|0;c[u>>2]=_l(g)|0;c[v>>2]=_l(g)|0;a[A>>0]=Pl(g)|0;a[y>>0]=Pl(g)|0;a[x>>0]=Pl(g)|0;a[o>>0]=Pl(g)|0;b[n>>1]=Rl(g)|0;b[z>>1]=Rl(g)|0;cm(j,4,1,g)|0;b[r>>1]=Rl(g)|0;b[q>>1]=Rl(g)|0;c[s>>2]=_l(g)|0;cm(k,28,1,g)|0;cm(m,4,1,g)|0;M=c[C>>2]|0;c[M+(p*52|0)+32>>2]=c[t>>2];c[M+(p*52|0)+36>>2]=c[u>>2];P=c[v>>2]|0;N=(P|0)==65535;c[M+(p*52|0)+40>>2]=N?0:P;c[M+(p*52|0)+44>>2]=(P|0)>0&(N^1)?2:0;M=c[B>>2]|0;N=c[M+(p*764|0)+756>>2]|0;c[N>>2]=d[A>>0];c[N+8>>2]=128;c[N+40>>2]=p;c[M+(p*764|0)+36>>2]=1;fb(M,p,k,12);M=c[(c[B>>2]|0)+(p*764|0)+756>>2]|0;Gi(e[n>>1]|0,M+12|0,M+16|0);p=p+1|0}while((p|0)<(c[K>>2]|0))}if(($a(f)|0)>=0){if((c[I>>2]|0)>0){q=f+172|0;p=f+168|0;o=0;do{if((db(f,o,64)|0)<0)break a;i=b[E+(o<<1)>>1]|0;if(i<<16>>16){dm(g,((i&65535)<<4)+h|0,0)|0;if(G){dm(g,2,1)|0;n=0}else n=0;do{i=Pl(g)|0;if(i<<24>>24){j=i&255;while(1){i=j&31;if((i|0)<(c[H>>2]|0))m=(c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+(n<<3)|0;else m=J;if(j&32|0){P=Pl(g)|0;i=P&255;switch(P<<24>>24){case -1:{i=0;break}case -2:{i=-127;break}default:i=(i&15)+37+((i>>>4)*12|0)&255}a[m>>0]=i;a[m+1>>0]=Pl(g)|0}if(j&64|0)a[m+2>>0]=((Pl(g)|0)&255)+1;b:do if(j&128|0){i=Pl(g)|0;k=Pl(g)|0;if((i&255)>=11)break;P=a[33074+(i&255)>>0]|0;i=m+3|0;a[i>>0]=P;j=m+4|0;a[j>>0]=k;switch(P<<24>>24){case 15:{i=(k&255)>>>4;break}case -1:{a[i>>0]=0;i=0;break}default:break b}a[j>>0]=i}while(0);i=Pl(g)|0;if(!(i<<24>>24))break;else j=i&255}}n=n+1|0}while((n|0)!=64)}o=o+1|0}while((o|0)<(c[I>>2]|0))}Wm(F);Wm(E);c:do if((c[K>>2]|0)>0){j=f+180|0;i=0;while(1){if((Eb(f,g,0,(c[j>>2]|0)+(i*52|0)|0,0)|0)<0){i=-1;break}i=i+1|0;if((i|0)>=(c[K>>2]|0))break c}l=L;return i|0}while(0);P=f+1284|0;c[P>>2]=c[P>>2]|1224737377;c[f+1288>>2]=2;P=0;l=L;return P|0}}while(0);Wm(F)}Wm(E);P=-1;l=L;return P|0}function _c(a,b,c){a=a|0;b=b|0;c=c|0;do if(((am(a)|0)==1179603533?(am(a)|0,(am(a)|0)==1297040460):0)?(am(a)|0)==1447383635:0){am(a)|0;dm(a,10,1)|0;if((am(a)|0)==1229866575){am(a)|0;hb(a,b,32);a=0;break}else{hb(a,b,0);a=0;break}}else a=-1;while(0);return a|0}function $c(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;e=l;l=l+32|0;d=e;f=e+4|0;am(b)|0;am(b)|0;am(b)|0;am(b)|0;am(b)|0;cm(f,1,10,b)|0;c[d>>2]=f+4;ob(a,33112,d);d=pb()|0;if(!d){f=-1;l=e;return f|0}f=tb(d,34737,20)|0;f=tb(d,33127,21)|0|f;if(f|(tb(d,33132,22)|0)|0){f=-1;l=e;return f|0}Ab(d,2);f=(qb(d,a,b,0)|0)<0;wb(d);if(f){f=-1;l=e;return f|0}f=((c[a+144>>2]|0)<1)<<31>>31;l=e;return f|0}function ad(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;cm(a,1,32,d)|0;f=a+140|0;c[f>>2]=(Ul(d)|0)&65535;e=a+156|0;c[e>>2]=(Ul(d)|0)&65535;b=a+128|0;c[b>>2]=(Ul(d)|0)&65535;c[a+164>>2]=(Ul(d)|0)&65535;c[a+152>>2]=(Ul(d)|0)&65535;Ul(d)|0;Ul(d)|0;Ul(d)|0;Ul(d)|0;Ul(d)|0;Ul(d)|0;Ul(d)|0;Ul(d)|0;Ul(d)|0;Ul(d)|0;if((c[f>>2]|0)>255)return -1;if((c[e>>2]|0)>256)return -1;else return ((c[b>>2]|0)>255)<<31>>31|0;return 0}function bd(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return 0}function cd(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;dd(a,c);return 0}function dd(f,g){f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;r=l;l=l+1088|0;o=r;p=r+1084|0;cm(o,20,1,g)|0;h=0;do{cm(o+20+(h*30|0)|0,22,1,g)|0;b[o+20+(h*30|0)+22>>1]=Ul(g)|0;a[o+20+(h*30|0)+24>>0]=Pl(g)|0;a[o+20+(h*30|0)+25>>0]=Pl(g)|0;b[o+20+(h*30|0)+26>>1]=Ul(g)|0;b[o+20+(h*30|0)+28>>1]=Ul(g)|0;h=h+1|0}while((h|0)!=31);j=o+950|0;a[j>>0]=Pl(g)|0;h=o+951|0;a[h>>0]=Pl(g)|0;i=o+952|0;cm(i,128,1,g)|0;cm(o+1080|0,4,1,g)|0;m=f+140|0;c[m>>2]=31;q=f+144|0;c[q>>2]=31;c[f+136>>2]=4;c[f+156>>2]=d[j>>0];c[f+160>>2]=d[h>>0];h=f+952|0;j=h+128|0;do{b[h>>1]=b[i>>1]|0;h=h+2|0;i=i+2|0}while((h|0)<(j|0));n=f+128|0;h=c[n>>2]|0;j=0;do{i=d[f+952+j>>0]|0;if((i|0)>(h|0)){c[n>>2]=i;h=i}j=j+1|0}while((j|0)!=128);k=h+1|0;c[n>>2]=k;c[f+132>>2]=k<<2;if((Za(f)|0)<0){l=r;return}a:do if((c[m>>2]|0)>0){k=f+180|0;h=f+176|0;j=0;while(1){if((_a(f,j,1)|0)<0)break;s=b[o+20+(j*30|0)+22>>1]|0;i=c[k>>2]|0;c[i+(j*52|0)+32>>2]=(s&65535)<<1;u=e[o+20+(j*30|0)+26>>1]<<1;c[i+(j*52|0)+36>>2]=u;t=b[o+20+(j*30|0)+28>>1]|0;c[i+(j*52|0)+40>>2]=((t&65535)<<1)+u;c[i+(j*52|0)+44>>2]=(t&65535)>1?2:0;i=c[h>>2]|0;if(s<<16>>16)c[i+(j*764|0)+36>>2]=1;u=c[i+(j*764|0)+756>>2]|0;c[u+16>>2]=d[o+20+(j*30|0)+24>>0]<<28>>24;c[u>>2]=a[o+20+(j*30|0)+25>>0];c[u+8>>2]=128;c[u+40>>2]=j;c[i+(j*764|0)+40>>2]=4095;fb(i,j,o+20+(j*30|0)|0,22);j=j+1|0;if((j|0)>=(c[m>>2]|0))break a}l=r;return}while(0);if(($a(f)|0)<0){l=r;return}b:do if((c[n>>2]|0)>0){k=f+172|0;j=f+168|0;h=0;while(1){if((db(f,h,64)|0)<0)break;else i=0;do{u=(c[(c[k>>2]|0)+(c[(c[(c[j>>2]|0)+(h<<2)>>2]|0)+4+(((i|0)%4|0)<<2)>>2]<<2)>>2]|0)+4+(((i|0)/4|0)<<3)|0;cm(p,1,4,g)|0;lb(u,p);i=i+1|0}while((i|0)!=256);h=h+1|0;if((h|0)>=(c[n>>2]|0))break b}l=r;return}while(0);c[f+1292>>2]=1;h=c[q>>2]|0;if((h|0)<=0){l=r;return}k=f+180|0;j=0;while(1){i=c[k>>2]|0;if(c[i+(j*52|0)+32>>2]|0){if((Eb(f,g,0,i+(j*52|0)|0,0)|0)<0){h=26;break}h=c[q>>2]|0}j=j+1|0;if((j|0)>=(h|0)){h=26;break}}if((h|0)==26){l=r;return}}function ed(a,b,c){a=a|0;b=b|0;c=c|0;dm(a,60,1)|0;c=am(a)|0;dm(a,60,1)|0;if((c|0)!=1397706311&(am(a)|0)!=1397706311){b=-1;return b|0}hb(a,b,0);b=0;return b|0}function fd(a,b,c){a=a|0;b=b|0;c=c|0;if((gd(a,b,15)|0)>=0){c=0;return c|0}c=gd(a,b,31)|0;return c|0}function gd(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;y=l;l=l+1232|0;p=y+8|0;o=y;k=y+136|0;n=y+1092|0;w=y+1088|0;r=y+12|0;q=y+156|0;m=(h|0)>0;i=am(g)|0;if(m){j=0;do{c[r+(j<<2)>>2]=i;j=j+1|0;i=am(g)|0}while((j|0)!=(h|0))}c[k>>2]=i;x=Ul(g)|0;i=k+4|0;b[i>>1]=x;if((x&65535)<178){f=-1;l=y;return f|0}cm(k+6|0,14,1,g)|0;if((c[k>>2]|0)!=1397706311){f=-1;l=y;return f|0}v=f+136|0;c[v>>2]=4;x=f+140|0;c[x>>2]=h;c[f+144>>2]=h;c[f+152>>2]=1776930/((e[i>>1]|0)>>>0)|0;if(m){i=0;do{cm(q+(i*30|0)|0,22,1,g)|0;b[q+(i*30|0)+22>>1]=Ul(g)|0;a[q+(i*30|0)+24>>0]=Pl(g)|0;a[q+(i*30|0)+25>>0]=Pl(g)|0;b[q+(i*30|0)+26>>1]=Ul(g)|0;b[q+(i*30|0)+28>>1]=Ul(g)|0;i=i+1|0}while((i|0)<(c[x>>2]|0))}a[n>>0]=Pl(g)|0;a[n+1>>0]=Pl(g)|0;i=n+2|0;if((cm(i,1,128,g)|0)!=128){f=-1;l=y;return f|0}j=a[n>>0]|0;m=j&255;c[f+156>>2]=m;if(j<<24>>24<0){f=-1;l=y;return f|0}ep(f+952|0,i|0,m|0)|0;u=f+128|0;c[u>>2]=0;if(!(j<<24>>24))i=0;else{i=0;k=0;do{j=d[f+952+k>>0]|0;if((j|0)>(i|0)){c[u>>2]=j;i=j}k=k+1|0}while((k|0)!=(m|0))}t=i+1|0;c[u>>2]=t;c[f+132>>2]=O(c[v>>2]|0,t)|0;if((c[x>>2]|0)==15)ob(f,33154,o);else ob(f,33166,p);if((Za(f)|0)<0){f=-1;l=y;return f|0}a:do if((c[x>>2]|0)>0){j=f+176|0;k=f+180|0;i=0;while(1){if((_a(f,i,1)|0)<0){i=-1;break}t=c[j>>2]|0;p=c[k>>2]|0;s=c[t+(i*764|0)+756>>2]|0;c[p+(i*52|0)+32>>2]=c[r+(i<<2)>>2];n=e[q+(i*30|0)+26>>1]|0;c[p+(i*52|0)+36>>2]=n;o=b[q+(i*30|0)+28>>1]|0;c[p+(i*52|0)+40>>2]=((o&65535)<<1)+n;c[p+(i*52|0)+44>>2]=(o&65535)>1?2:0;c[t+(i*764|0)+36>>2]=1;c[s>>2]=d[q+(i*30|0)+25>>0];c[s+16>>2]=(d[q+(i*30|0)+24>>0]|0)<<28>>24;c[s+8>>2]=128;c[s+40>>2]=i;fb(t,i,q+(i*30|0)|0,22);i=i+1|0;if((i|0)>=(c[x>>2]|0))break a}l=y;return i|0}while(0);if(($a(f)|0)<0){f=-1;l=y;return f|0}b:do if((c[u>>2]|0)>0){t=f+172|0;s=f+168|0;o=w+1|0;p=w+2|0;q=w+3|0;r=0;while(1){if((db(f,r,64)|0)<0){i=-1;break}i=c[v>>2]|0;c:do if((i|0)>0){n=0;while(1){h=c[(c[t>>2]|0)+(c[(c[(c[s>>2]|0)+(r<<2)>>2]|0)+4+(((n|0)%(i|0)|0)<<2)>>2]<<2)>>2]|0;k=(n|0)/(i|0)|0;cm(w,1,4,g)|0;i=a[w>>0]|0;a[h+4+(k<<3)>>0]=Ei((i&15)<<8|(d[o>>0]|0))|0;j=a[p>>0]|0;a[h+4+(k<<3)+1>>0]=(j&255)>>>4|i&-16&255;i=a[q>>0]|0;m=h+4+(k<<3)+4|0;a[m>>0]=i;d:do switch(j&15){case 1:{a[h+4+(k<<3)+3>>0]=0;break}case 2:{j=i&255;if(j&240|0){a[h+4+(k<<3)+3>>0]=2;a[m>>0]=(i&255)>>>4;break d}if(!(j&15))break d;a[h+4+(k<<3)+3>>0]=1;a[m>>0]=i&15;break}case 5:{a[h+4+(k<<3)+3>>0]=-74;break}case 6:{a[h+4+(k<<3)+3>>0]=-73;break}case 7:{a[h+4+(k<<3)+3>>0]=-72;break}case 8:{a[h+4+(k<<3)+3>>0]=-71;break}default:{a[m>>0]=0;a[h+4+(k<<3)+3>>0]=0}}while(0);n=n+1|0;i=c[v>>2]|0;if((n|0)>=(i<<6|0))break c}}while(0);r=r+1|0;if((r|0)>=(c[u>>2]|0))break b}l=y;return i|0}while(0);i=f+1284|0;c[i>>2]=c[i>>2]|128;c[f+1292>>2]=1;i=c[x>>2]|0;if((i|0)<=0){f=0;l=y;return f|0}m=f+180|0;k=0;while(1){j=c[m>>2]|0;if((c[j+(k*52|0)+32>>2]|0)>=3){if((Eb(f,g,0,j+(k*52|0)|0,0)|0)<0){i=-1;j=45;break}i=c[x>>2]|0}k=k+1|0;if((k|0)>=(i|0)){i=0;j=45;break}}if((j|0)==45){l=y;return i|0}return 0}function hd(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;f=l;l=l+16|0;e=f;dm(b,d+1080|0,0)|0;a:do if((cm(e,1,4,b)|0)>>>0<4)e=-1;else{if(nn(e,33432,3)|0?nn(e,33436,3)|0:0){e=-1;break}switch(a[e+3>>0]|0){case 77:case 56:case 52:break;default:{e=-1;break a}}dm(b,d,0)|0;hb(b,c,20);e=0}while(0);l=f;return e|0}function id(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;y=l;l=l+2176|0;t=y+32|0;o=y+24|0;j=y+16|0;i=y+8|0;h=y;w=y+40|0;x=y+2168|0;n=y+1144|0;p=y+1128|0;m=f+1208|0;k=f+1212|0;v=c[k>>2]|0;c[h>>2]=c[m>>2];c[h+4>>2]=v;io(n,1024,33190,h);h=hm(n,35139)|0;if(!h){h=c[k>>2]|0;c[i>>2]=c[m>>2];c[i+4>>2]=h;io(n,1024,33198,i);h=hm(n,35139)|0;if(!h){h=c[k>>2]|0;c[j>>2]=c[m>>2];c[j+4>>2]=h;io(n,1024,33206,j);h=hm(n,35139)|0;if(!h){i=c[k>>2]|0;c[o>>2]=c[m>>2];c[o+4>>2]=i;io(n,1024,33214,o);i=hm(n,35139)|0;if(!i){v=0;i=0;h=0;p=33178;j=10}else{h=1;j=6}}else j=4}else j=4}else j=4;if((j|0)==4){i=h;h=(h|0)!=0;j=6}if((j|0)==6)if((cm(p,1,16,i)|0)==16)if(nn(p,33222,16)|0)if(!(nn(p,33239,16)|0)){v=1;p=33308;j=10}else{p=(nn(p,33256,16)|0)==0;v=p&1;p=p?33273:33178;j=10}else{v=1;p=33292;j=10}a:do if((j|0)==10){cm(w,20,1,g)|0;j=0;do{cm(w+20+(j*30|0)|0,22,1,g)|0;b[w+20+(j*30|0)+22>>1]=Ul(g)|0;a[w+20+(j*30|0)+24>>0]=Pl(g)|0;a[w+20+(j*30|0)+25>>0]=Pl(g)|0;b[w+20+(j*30|0)+26>>1]=Ul(g)|0;b[w+20+(j*30|0)+28>>1]=Ul(g)|0;j=j+1|0}while((j|0)!=31);m=w+950|0;a[m>>0]=Pl(g)|0;j=w+951|0;a[j>>0]=Pl(g)|0;k=w+952|0;cm(k,128,1,g)|0;o=w+1080|0;cm(o,4,1,g)|0;s=f+136|0;n=(a[w+1083>>0]|0)==52?4:8;c[s>>2]=n;q=f+140|0;c[q>>2]=31;u=f+144|0;c[u>>2]=31;c[f+156>>2]=d[m>>0];c[f+160>>2]=d[j>>0];j=f+952|0;m=j+128|0;do{b[j>>1]=b[k>>1]|0;j=j+2|0;k=k+2|0}while((j|0)<(m|0));r=f+128|0;m=0;do{k=f+952+m|0;j=a[k>>0]|0;if((n|0)>4){j=(j&255)>>>1;a[k>>0]=j}k=j&255;j=c[r>>2]|0;if((k|0)>(j|0)){c[r>>2]=k;j=k}m=m+1|0;n=c[s>>2]|0}while((m|0)!=128);m=j+1|0;c[r>>2]=m;c[f+132>>2]=O(m,n)|0;Ho(f,w,20)|0;c[t>>2]=p;c[t+4>>2]=o;ob(f,33324,t);if((Za(f)|0)>=0){if((c[q>>2]|0)>0){n=f+176|0;o=f+180|0;m=0;do{j=c[n>>2]|0;k=c[o>>2]|0;if((_a(f,m,1)|0)<0)break a;p=c[j+(m*764|0)+756>>2]|0;t=b[w+20+(m*30|0)+22>>1]|0;c[k+(m*52|0)+32>>2]=(t&65535)<<1;A=e[w+20+(m*30|0)+26>>1]<<1;c[k+(m*52|0)+36>>2]=A;z=b[w+20+(m*30|0)+28>>1]|0;c[k+(m*52|0)+40>>2]=((z&65535)<<1)+A;c[k+(m*52|0)+44>>2]=(z&65535)>1?2:0;c[p+16>>2]=d[w+20+(m*30|0)+24>>0]<<28>>24;c[p>>2]=a[w+20+(m*30|0)+25>>0];c[p+8>>2]=128;c[p+40>>2]=m;c[j+(m*764|0)+40>>2]=4095;if(t<<16>>16)c[j+(m*764|0)+36>>2]=1;fb(c[n>>2]|0,m,w+20+(m*30|0)|0,22);m=m+1|0}while((m|0)<(c[q>>2]|0))}if(($a(f)|0)>=0){if((c[r>>2]|0)>0){q=f+172|0;p=f+168|0;o=0;do{if((db(f,o,64)|0)<0)break a;else j=0;do{A=(c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+(((j|0)%4|0)<<2)>>2]<<2)>>2]|0)+4+(((j|0)/4|0)<<3)|0;cm(x,1,4,g)|0;jb(A,x);j=j+1|0}while((j|0)!=256);if((c[s>>2]|0)>4){n=0;do{j=c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+(((n|0)%4|0)+4<<2)>>2]<<2)>>2]|0;k=(n|0)/4|0;cm(x,1,4,g)|0;jb(j+4+(k<<3)|0,x);m=j+4+(k<<3)+3|0;if((a[m>>0]|0)==14){a[j+4+(k<<3)+4>>0]=0;a[m>>0]=0}n=n+1|0}while((n|0)!=256)}o=o+1|0}while((o|0)<(c[r>>2]|0))}if((c[u>>2]|0)>0){n=f+180|0;m=(v|0)==0;k=0;do{j=c[n>>2]|0;if(!(c[j+(k*52|0)+32>>2]|0)){if((!m?jd(i,k)|0:0)?(kd(f,i,k)|0)<0:0)break a}else if((Eb(f,g,512,j+(k*52|0)|0,0)|0)<0)break a;k=k+1|0}while((k|0)<(c[u>>2]|0))}if(!h){A=0;l=y;return A|0}lm(i);A=0;l=y;return A|0}}}while(0);if(!h){A=-1;l=y;return A|0}lm(i);A=-1;l=y;return A|0}function jd(a,b){a=a|0;b=b|0;var c=0,d=0;c=l;l=l+16|0;d=c;dm(a,(b*120|0)+144|0,0)|0;cm(d,1,2,a)|0;if(nn(d,33429,2)|0){d=0;l=c;return d|0}dm(a,24,1)|0;d=Ul(a)|0;d=(d&65535)<4&(gm(a)|0)==0&1;l=c;return d|0}function kd(d,e,f){d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;A=l;l=l+1024|0;g=A;i=c[d+176>>2]|0;j=c[d+180>>2]|0;k=j+(f*52|0)|0;dm(e,(f*120|0)+150|0,0)|0;v=Ul(e)|0;w=Ul(e)|0;x=Ul(e)|0;m=Ul(e)|0;n=Ul(e)|0;o=Ul(e)|0;p=Ul(e)|0;q=Ul(e)|0;Ul(e)|0;r=Ul(e)|0;h=Ul(e)|0;z=0-((Ul(e)|0)&65535)|0;y=z&65535;s=Ul(e)|0;t=Ul(e)|0;u=Ul(e)|0;if(gm(e)|0){z=-1;l=A;return z|0}if(h<<16>>16<3){c[j+(f*52|0)+32>>2]=32;c[j+(f*52|0)+36>>2]=0;c[j+(f*52|0)+40>>2]=32;g=33333+(h<<16>>16<<5)|0}else{c[j+(f*52|0)+32>>2]=1024;c[j+(f*52|0)+36>>2]=0;c[j+(f*52|0)+40>>2]=1024;h=0;do{a[g+h>>0]=Jo()|0;h=h+1|0}while((h|0)!=1024)}c[j+(f*52|0)+44>>2]=2;j=c[i+(f*764|0)+756>>2]|0;c[j>>2]=64;c[i+(f*764|0)+36>>2]=1;c[j+12>>2]=O(u<<16>>16,-12)|0;c[j+20>>2]=0;c[j+24>>2]=s<<16>>16<<2;c[j+28>>2]=t<<16>>16;c[i+(f*764|0)+48>>2]=6;c[i+(f*764|0)+44>>2]=1;b[i+(f*764|0)+72>>1]=0;t=v<<16>>16;b[i+(f*764|0)+74>>1]=(t|0)/4|0;u=w<<16>>16;s=w<<16>>16>v<<16>>16;v=s?256-t|0:t;x=((s?u-t|0:t-u|0)<<8|0)/(O((v|0)==0?1:v,x<<16>>16==0?1:x<<16>>16)|0)|0;b[i+(f*764|0)+76>>1]=x;b[i+(f*764|0)+78>>1]=(u|0)/4|0;v=m<<16>>16;w=m<<16>>16>w<<16>>16;t=w?256-u|0:u;t=x+(((w?v-u|0:u-v|0)<<8|0)/(O((t|0)==0?1:t,n<<16>>16==0?1:n<<16>>16)|0)|0)|0;b[i+(f*764|0)+80>>1]=t;b[i+(f*764|0)+82>>1]=(v|0)/4|0;w=o<<16>>16;u=o<<16>>16>m<<16>>16;x=u?256-v|0:v;x=(t&65535)+(((u?w-v|0:v-w|0)<<8|0)/(O((x|0)==0?1:x,p<<16>>16==0?1:p<<16>>16)|0)|0)|0;b[i+(f*764|0)+84>>1]=x;w=((w|0)/4|0)&65535;b[i+(f*764|0)+86>>1]=w;x=x+(q&65535)|0;b[i+(f*764|0)+88>>1]=x;b[i+(f*764|0)+90>>1]=w;b[i+(f*764|0)+92>>1]=(256/((r<<16>>16==0?1:r<<16>>16)|0)|0)+x;b[i+(f*764|0)+94>>1]=0;if(y<<16>>16){c[i+(f*764|0)+360>>2]=2;c[i+(f*764|0)+356>>2]=1;b[i+(f*764|0)+384>>1]=0;b[i+(f*764|0)+386>>1]=0;z=z<<16;y=z>>16;b[i+(f*764|0)+388>>1]=1024/(((z|0)>-65536?y:0-y|0)|0)|0;b[i+(f*764|0)+390>>1]=(z>>31&-512|256)*10}z=((Eb(d,0,16,k,g)|0)!=0)<<31>>31;l=A;return z|0}function ld(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+608|0;u=w;s=w+600|0;v=mm(c[f+4>>2]|0)|0;if((v|0)<600){g=-1;l=w;return g|0}dm(f,h,0)|0;cm(u,1,20,f)|0;if((ib(u,20)|0)<0){g=-1;l=w;return g|0}else i=0;do{cm(u+20+(i*30|0)|0,1,22,f)|0;b[u+20+(i*30|0)+22>>1]=Ul(f)|0;a[u+20+(i*30|0)+24>>0]=Pl(f)|0;a[u+20+(i*30|0)+25>>0]=Pl(f)|0;b[u+20+(i*30|0)+26>>1]=Ul(f)|0;b[u+20+(i*30|0)+28>>1]=Ul(f)|0;i=i+1|0}while((i|0)!=15);k=u+470|0;a[k>>0]=Pl(f)|0;a[u+471>>0]=Pl(f)|0;cm(u+472|0,1,128,f)|0;j=0;r=0;do{q=a[u+472+j>>0]|0;i=q&255;if(q<<24>>24<0){t=-1;m=30;break}r=(i|0)>(r|0)?i:r;j=j+1|0}while((j|0)<128);if((m|0)==30){l=w;return t|0}if((r|0)>126|(a[k>>0]|0)<1){g=-1;l=w;return g|0}else{m=0;q=0}while(1){if((ib(u+20+(m*30|0)|0,22)|0)<0){t=-1;m=30;break}if((a[u+20+(m*30|0)+25>>0]|0)>64){t=-1;m=30;break}if((a[u+20+(m*30|0)+24>>0]|0)>15){t=-1;m=30;break}i=b[u+20+(m*30|0)+22>>1]|0;k=i&65535;if((i&65535)>32768){t=-1;m=30;break}if((e[u+20+(m*30|0)+28>>1]|0)>32768){t=-1;m=30;break}j=b[u+20+(m*30|0)+26>>1]|0;n=(j&65535)>>>1;if(n>>>0>k>>>0){t=-1;m=30;break}p=i<<16>>16!=0;if(!((p|j<<16>>16==0)^p&(n|0)==(k|0))){t=-1;m=30;break}q=(k<<1)+q|0;m=m+1|0;if((m|0)>=15){m=16;break}}if((m|0)==16){if((q|0)<8){g=-1;l=w;return g|0}m=s+2|0;n=s+1|0;o=0;i=0;a:while(1){p=i;k=0;do{cm(s,1,4,f)|0;i=a[s>>0]|0;j=(d[m>>0]|0)>>>4|i&-16&255;if(j>>>0>15){t=-1;m=30;break a}p=(j|0)>(p|0)?j:p;i=d[n>>0]|(i&15)<<8;b:do switch(i&4095){case 162:case 0:break;default:{j=0;while(1){if((i|0)==(c[1880+(j<<2)>>2]|0))break b;j=j+1|0;if((j|0)==36){t=-1;m=30;break a}}}}while(0);k=k+1|0}while((k|0)<256);if((o|0)<(r|0)){o=o+1|0;i=p}else{m=25;break}}if((m|0)==25){k=(r<<10)+1624|0;if((v|0)<(q+k|0)){if((p|0)>0){j=0;i=0;do{i=(e[u+20+(j*30|0)+22>>1]<<1)+i|0;j=j+1|0}while((j|0)!=(p|0))}else i=0;if((v|0)<(i+k|0)){g=-1;l=w;return g|0}}dm(f,h,0)|0;hb(f,g,20);g=0;l=w;return g|0}else if((m|0)==30){l=w;return t|0}}else if((m|0)==30){l=w;return t|0}return 0}function md(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;A=l;l=l+624|0;s=A;r=A+616|0;z=A+8|0;u=A+608|0;x=f+136|0;c[x>>2]=4;y=f+140|0;c[y>>2]=15;c[f+144>>2]=15;cm(z,1,20,g)|0;i=0;do{cm(z+20+(i*30|0)|0,1,22,g)|0;b[z+20+(i*30|0)+22>>1]=Ul(g)|0;a[z+20+(i*30|0)+24>>0]=Pl(g)|0;a[z+20+(i*30|0)+25>>0]=Pl(g)|0;b[z+20+(i*30|0)+26>>1]=Ul(g)|0;b[z+20+(i*30|0)+28>>1]=Ul(g)|0;i=i+1|0}while((i|0)!=15);w=z+470|0;a[w>>0]=Pl(g)|0;m=z+471|0;a[m>>0]=Pl(g)|0;j=z+472|0;cm(j,1,128,g)|0;v=f+156|0;c[v>>2]=d[w>>0];m=a[m>>0]|0;w=f+160|0;c[w>>2]=m&255;i=f+952|0;k=i+128|0;do{b[i>>1]=b[j>>1]|0;i=i+2|0;j=j+2|0}while((i|0)<(k|0));t=f+128|0;i=c[t>>2]|0;k=0;while(1){j=d[f+952+k>>0]|0;if((j|0)>(i|0))c[t>>2]=j;else j=i;k=k+1|0;if((k|0)==128)break;else i=j}i=(m&255)>63&1;c[t>>2]=j+1;j=c[y>>2]|0;if((j|0)>0){k=0;do{i=(a[z+20+(k*30|0)+24>>0]|0)==0?i:0;if(!(((e[z+20+(k*30|0)+22>>1]|0)<=4999?(e[z+20+(k*30|0)+26>>1]|0)<=9999:0)?(e[z+20+(k*30|0)+28>>1]|0)<=4999:0))i=0;k=k+1|0}while((k|0)!=(j|0))}if((Za(f)|0)<0){z=-1;l=A;return z|0}a:do if((c[y>>2]|0)>0){n=f+176|0;o=f+180|0;m=0;while(1){j=c[n>>2]|0;k=c[o>>2]|0;if((_a(f,m,1)|0)<0){i=-1;break}p=c[j+(m*764|0)+756>>2]|0;q=k+(m*52|0)+32|0;c[q>>2]=(e[z+20+(m*30|0)+22>>1]<<1)-(e[z+20+(m*30|0)+26>>1]|0);c[k+(m*52|0)+36>>2]=0;B=b[z+20+(m*30|0)+28>>1]|0;c[k+(m*52|0)+40>>2]=(B&65535)<<1;c[k+(m*52|0)+44>>2]=(B&65535)>1?2:0;c[p+16>>2]=d[z+20+(m*30|0)+24>>0]<<28>>24;c[p>>2]=a[z+20+(m*30|0)+25>>0];c[p+8>>2]=128;c[p+40>>2]=m;Ho(j+(m*764|0)|0,z+20+(m*30|0)|0,22)|0;if((c[q>>2]|0)>0)c[j+(m*764|0)+36>>2]=1;m=m+1|0;if((m|0)>=(c[y>>2]|0))break a}l=A;return i|0}while(0);c[f+132>>2]=O(c[t>>2]|0,c[x>>2]|0)|0;Ho(f,z,20)|0;q=em(g)|0;j=c[t>>2]|0;if((j|0)>0){p=r+3|0;o=r+4|0;k=c[x>>2]|0;m=j;j=0;n=0;do{if((k|0)>0){m=0;do{cm(u,1,4,g)|0;lb(r,u);B=a[p>>0]|0;k=a[o>>0]|0;j=(B<<24>>24==0?k<<24>>24!=0&1:1<<(B&255))|j;i=(B&255)<3?i:0;switch(B<<24>>24){case 1:{i=k<<24>>24==0?0:i;break}case 2:{B=k&255;i=(B&15|0)==0|(B&240|0)==0?i:0;break}default:{}}m=m+1|0;k=c[x>>2]|0}while((m|0)<(k<<6|0));m=c[t>>2]|0}n=n+1|0}while((n|0)<(m|0))}else j=0;o=(i|0)!=0&(j&-7|0)==0;if(o)i=33508;else i=(j&-53256|0)==0?33492:(j&-63496|0)==0?33453:33476;c[s>>2]=i;io(f+64|0,64,34920,s);if((dm(g,q+h|0,0)|0)<0){B=-1;l=A;return B|0}if(($a(f)|0)<0){B=-1;l=A;return B|0}i=c[t>>2]|0;b:do if((i|0)>0){n=f+172|0;m=f+168|0;k=0;while(1){if((db(f,k,64)|0)<0){i=-1;break}i=c[x>>2]|0;if((i|0)>0){j=0;do{B=(c[(c[n>>2]|0)+(c[(c[(c[m>>2]|0)+(k<<2)>>2]|0)+4+(((j|0)%(i|0)|0)<<2)>>2]<<2)>>2]|0)+4+(((j|0)/(i|0)|0)<<3)|0;cm(u,1,4,g)|0;lb(B,u);j=j+1|0;i=c[x>>2]|0}while((j|0)<(i<<6|0))}k=k+1|0;i=c[t>>2]|0;if((k|0)>=(i|0)){u=i;break b}}l=A;return i|0}else u=i;while(0);i=f+1284|0;c[i>>2]=c[i>>2]|268435456;c[f+1292>>2]=1;i=c[w>>2]|0;if(o){c[f+152>>2]=i;c[w>>2]=0;if((u|0)>0){k=c[x>>2]|0;o=(k|0)>0;t=f+172|0;s=f+168|0;h=k<<6;q=0;do{c:do if(o){m=c[t>>2]|0;n=c[(c[s>>2]|0)+(q<<2)>>2]|0;r=0;while(1){i=c[m+(c[n+4+(((r|0)%(k|0)|0)<<2)>>2]<<2)>>2]|0;j=(r|0)/(k|0)|0;p=i+4+(j<<3)+3|0;d:do switch(a[p>>0]|0){case 1:{a[p>>0]=0;break}case 2:{j=i+4+(j<<3)+4|0;i=a[j>>0]|0;if((i&255)<16){a[p>>0]=1;break d}if(!(i&15))a[j>>0]=(i&255)>>>4;break}default:{}}while(0);r=r+1|0;if((r|0)>=(h|0))break c}}while(0);q=q+1|0}while((q|0)!=(u|0))}}else if((i|0)>=(c[v>>2]|0))c[w>>2]=0;i=c[y>>2]|0;if((i|0)<=0){B=0;l=A;return B|0}k=f+180|0;j=0;while(1){if(c[(c[k>>2]|0)+(j*52|0)+32>>2]|0){dm(g,e[z+20+(j*30|0)+26>>1]|0,1)|0;if((Eb(f,g,0,(c[k>>2]|0)+(j*52|0)|0,0)|0)<0){i=-1;j=60;break}i=c[y>>2]|0}j=j+1|0;if((j|0)>=(i|0)){i=0;j=60;break}}if((j|0)==60){l=A;return i|0}return 0}function nd(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1179603533){b=-1;return b|0}am(a)|0;if((am(a)|0)!=1162694468){b=-1;return b|0}if((am(a)|0)==1162692931){am(a)|0;Ul(a)|0;hb(a,b,20);b=0;return b|0}else{hb(a,b,0);b=0;return b|0}return 0}function od(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;am(b)|0;am(b)|0;am(b)|0;c=pb()|0;if(!c){a=-1;return a|0}d=tb(c,33546,23)|0;d=tb(c,35016,24)|0|d;if(d|(tb(c,33551,25)|0)|0){d=-1;return d|0}d=qb(c,a,b,0)|0;wb(c);d=d>>31;return d|0}function pd(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0;m=l;l=l+272|0;j=m;k=m+8|0;i=(Ul(e)|0)&65535;cm(b,1,20,e)|0;dm(e,20,1)|0;c[b+152>>2]=(Pl(e)|0)&255;g=(Pl(e)|0)&255;h=b+140|0;c[h>>2]=g;c[b+144>>2]=g;c[b+1292>>2]=1;c[j>>2]=i;io(b+64|0,64,33556,j);if((Za(b)|0)<0){b=-1;l=m;return b|0}a:do if((c[h>>2]|0)>0){i=b+176|0;j=b+180|0;g=0;while(1){f=c[i>>2]|0;d=c[j>>2]|0;if((_a(b,g,1)|0)<0){f=-1;break}n=c[f+(g*764|0)+756>>2]|0;Pl(e)|0;c[n>>2]=(Pl(e)|0)&255;c[d+(g*52|0)+32>>2]=((Ul(e)|0)&65535)<<1;cm(f+(g*764|0)|0,1,20,e)|0;c[d+(g*52|0)+44>>2]=(Pl(e)|0)<<1&2;c[n+16>>2]=(Nl(e)|0)<<24>>24<<4;o=((Ul(e)|0)&65535)<<1;c[d+(g*52|0)+36>>2]=o;c[d+(g*52|0)+40>>2]=(((Ul(e)|0)&65535)<<1)+o;am(e)|0;c[f+(g*764|0)+36>>2]=1;c[n+8>>2]=128;c[n+40>>2]=g;g=g+1|0;if((g|0)>=(c[h>>2]|0))break a}l=m;return f|0}while(0);Pl(e)|0;o=(Pl(e)|0)&255;d=b+128|0;c[d>>2]=o;c[b+132>>2]=O(c[b+136>>2]|0,o)|0;if(($a(b)|0)<0){o=-1;l=m;return o|0}gp(k|0,0,256)|0;b:do if((c[d>>2]|0)>0){f=0;while(1){a[k+((Pl(e)|0)&255)>>0]=f;if((db(b,f,((Pl(e)|0)&255)+1|0)|0)<0){f=-1;break}dm(e,20,1)|0;am(e)|0;f=f+1|0;if((f|0)>=(c[d>>2]|0))break b}l=m;return f|0}while(0);o=Pl(e)|0;d=b+156|0;c[d>>2]=o&255;if(!(o<<24>>24)){o=0;l=m;return o|0}else f=0;do{a[b+952+f>>0]=a[k+((Pl(e)|0)&255)>>0]|0;f=f+1|0}while((f|0)<(c[d>>2]|0));f=0;l=m;return f|0}function qd(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;l=b+128|0;f=c[l>>2]|0;if((f|0)<=0)return 0;m=b+168|0;k=b+136|0;j=b+172|0;d=c[m>>2]|0;i=0;do{if((c[c[d+(i<<2)>>2]>>2]|0)>0){f=c[k>>2]|0;h=0;do{if((f|0)>0){b=0;while(1){f=c[(c[j>>2]|0)+(c[(c[d+(i<<2)>>2]|0)+4+(b<<2)>>2]<<2)>>2]|0;a[f+4+(h<<3)+1>>0]=Pl(e)|0;g=(Pl(e)|0)&255;d=g+1|0;a[f+4+(h<<3)>>0]=(d&255|0)==0?d:g+49|0;g=f+4+(h<<3)+3|0;a[g>>0]=(Pl(e)|0)&15;d=Pl(e)|0;f=f+4+(h<<3)+4|0;a[f>>0]=d;switch(a[g>>0]|0){case 4:{d=d&255;d=d<<1&14|d&240;n=9;break}case 9:{f=g;d=18;n=9;break}case 11:{f=g;d=17;n=9;break}default:{}}if((n|0)==9){n=0;a[f>>0]=d}b=b+1|0;f=c[k>>2]|0;if((b|0)>=(f|0))break;d=c[m>>2]|0}d=c[m>>2]|0}h=h+1|0}while((h|0)<(c[c[d+(i<<2)>>2]>>2]|0));f=c[l>>2]|0}i=i+1|0}while((i|0)<(f|0));return 0}function rd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=a+180|0;b=a+144|0;if((c[b>>2]|0)>0)e=0;else{a=0;return a|0}while(1){if((Eb(a,d,0,(c[f>>2]|0)+(e*52|0)|0,0)|0)<0){e=-1;b=4;break}e=e+1|0;if((e|0)>=(c[b>>2]|0)){e=0;b=4;break}}if((b|0)==4)return e|0;return 0}function sd(a,b,c){a=a|0;b=b|0;c=c|0;dm(a,c+60|0,0)|0;if((am(a)|0)!=1229795632){b=-1;return b|0}dm(a,c,0)|0;hb(a,b,32);b=0;return b|0}function td(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0;na=l;l=l+1296|0;q=na;w=na+1288|0;s=na+456|0;la=na+72|0;ma=na+8|0;cm(s,32,1,g)|0;j=s+32|0;b[j>>1]=Rl(g)|0;o=s+34|0;b[o>>1]=Rl(g)|0;k=s+36|0;b[k>>1]=Rl(g)|0;n=s+38|0;b[n>>1]=Rl(g)|0;cm(s+40|0,8,1,g)|0;p=s+48|0;a[p>>0]=Pl(g)|0;m=s+49|0;a[m>>0]=Pl(g)|0;a[s+50>>0]=Pl(g)|0;a[s+51>>0]=Pl(g)|0;cm(s+52|0,8,1,g)|0;i=s+60|0;c[i>>2]=am(g)|0;if((e[j>>1]|0)>256|(e[o>>1]|0)>256|(e[k>>1]|0)>255){pa=-1;l=na;return pa|0}else h=0;do{cm(s+64+(h<<4)|0,12,1,g)|0;a[s+64+(h<<4)+12>>0]=Pl(g)|0;a[s+64+(h<<4)+13>>0]=Pl(g)|0;a[s+64+(h<<4)+14>>0]=Pl(g)|0;a[s+64+(h<<4)+15>>0]=Pl(g)|0;h=h+1|0}while((h|0)!=32);r=s+576|0;cm(r,256,1,g)|0;if((c[i>>2]|0)!=1229795632){pa=-1;l=na;return pa|0}gb(f,s,32)|0;t=f+156|0;c[t>>2]=e[j>>1];ka=f+140|0;c[ka>>2]=e[k>>1];ja=f+144|0;c[ja>>2]=1024;v=f+128|0;c[v>>2]=e[o>>1];if(b[n>>1]&1)c[f+1292>>2]=2;c[f+148>>2]=d[p>>0];c[f+152>>2]=d[m>>0];ob(f,33600,q);u=f+136|0;c[u>>2]=0;h=0;do{i=h;h=h+1|0;if(a[s+64+(i<<4)+12>>0]|0){c[u>>2]=h;c[f+184+(i*12|0)>>2]=d[s+64+(i<<4)+13>>0]}}while((h|0)!=32);c[f+132>>2]=O(c[u>>2]|0,c[v>>2]|0)|0;h=c[t>>2]|0;ep(f+952|0,r|0,h|0)|0;if((h|0)>0){j=0;do{i=f+952+j|0;if((a[i>>0]|0)==-1){a[i>>0]=-2;h=c[t>>2]|0}j=j+1|0}while((j|0)<(h|0))}ia=f+1264|0;c[ia>>2]=8363;if(($a(f)|0)<0){pa=-1;l=na;return pa|0}a:do if((c[v>>2]|0)>0){s=f+172|0;r=f+168|0;q=0;b:while(1){h=Rl(g)|0;ha=Rl(g)|0;p=ha&65535;if((ha&65535)>256){h=-1;i=70;break}i=h&65535;if((db(f,q,p)|0)<0){h=-1;i=70;break}c:do if((h&65535)>4){j=i+-5|0;h=i+-4|0;o=0;while(1){n=(o|0)<(p|0);k=j;while(1){ha=Pl(g)|0;m=ha&255;if(!(ha<<24>>24))break;if(!n){h=-1;i=70;break b}i=m&31;if((i|0)<(c[u>>2]|0))j=(c[(c[s>>2]|0)+(c[(c[(c[r>>2]|0)+(q<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+(o<<3)|0;else j=w;if(!(m&32))h=k;else{ha=Pl(g)|0;i=ha&255;switch(ha<<24>>24){case -96:case -1:{i=-127;break}default:i=(i&15)+13+((i>>>4)*12|0)&255}a[j>>0]=i;a[j+1>>0]=Pl(g)|0;h=h+-3|0}if(m&128){ga=j+3|0;a[ga>>0]=Pl(g)|0;ha=j+4|0;a[ha>>0]=Pl(g)|0;ud(ga,ha);h=h+-2|0}if(m&64){ga=j+5|0;a[ga>>0]=Pl(g)|0;ha=j+6|0;a[ha>>0]=Pl(g)|0;ud(ga,ha);h=h+-2|0}if((h|0)>0)k=h+-1|0;else break c}if((k|0)>0){j=k+-1|0;h=k;o=o+1|0}else break}}while(0);q=q+1|0;if((q|0)>=(c[v>>2]|0))break a}if((i|0)==70){l=na;return h|0}}while(0);if((Za(f)|0)<0){pa=-1;l=na;return pa|0}d:do if((c[ka>>2]|0)>0){ga=f+176|0;D=la+31|0;v=la+32|0;w=la+152|0;G=la+376|0;$=la+378|0;W=la+380|0;_=la+352|0;ea=la+353|0;U=la+354|0;Q=la+355|0;J=la+356|0;ha=f+180|0;x=ma+13|0;M=ma+16|0;V=ma+20|0;R=ma+24|0;ba=ma+28|0;fa=ma+32|0;aa=ma+33|0;y=ma+34|0;K=ma+48|0;z=ma+49|0;F=ma+54|0;E=ma+56|0;X=ma+60|0;A=la+357|0;Y=la+360|0;ca=la+361|0;S=la+362|0;N=la+363|0;H=la+364|0;B=la+365|0;Z=la+368|0;da=la+369|0;T=la+370|0;P=la+371|0;I=la+372|0;C=la+373|0;L=0;h=0;e:while(1){m=c[ga>>2]|0;cm(la,32,1,g)|0;a[D>>0]=0;cm(v,120,1,g)|0;cm(w,8,1,g)|0;i=0;do{b[la+160+(i<<1)>>1]=Rl(g)|0;i=i+1|0}while((i|0)!=32);i=0;do{b[la+224+(i<<1)>>1]=Rl(g)|0;i=i+1|0}while((i|0)!=32);i=0;do{b[la+288+(i<<1)>>1]=Rl(g)|0;i=i+1|0}while((i|0)!=32);a[_>>0]=Pl(g)|0;a[ea>>0]=Pl(g)|0;a[U>>0]=Pl(g)|0;a[Q>>0]=Pl(g)|0;a[J>>0]=Pl(g)|0;cm(A,3,1,g)|0;a[Y>>0]=Pl(g)|0;a[ca>>0]=Pl(g)|0;a[S>>0]=Pl(g)|0;a[N>>0]=Pl(g)|0;a[H>>0]=Pl(g)|0;cm(B,3,1,g)|0;a[Z>>0]=Pl(g)|0;a[da>>0]=Pl(g)|0;a[T>>0]=Pl(g)|0;a[P>>0]=Pl(g)|0;a[I>>0]=Pl(g)|0;cm(C,3,1,g)|0;b[G>>1]=Rl(g)|0;b[$>>1]=Rl(g)|0;j=am(g)|0;c[W>>2]=j;i=b[$>>1]|0;k=i&65535;if((i&65535)>255){h=-1;i=70;break}if((j|0)!=1229533488){h=-2;i=70;break}c[m+(L*764|0)+36>>2]=k;if(i<<16>>16?(_a(f,L,k)|0)<0:0){h=-1;i=70;break}Ho(m+(L*764|0)|0,la,24)|0;i=0;do{a[m+(L*764|0)+512+(i+12<<1)>>0]=a[la+32+i>>0]|0;i=i+1|0}while((i|0)!=108);i=a[_>>0]|0;j=m+(L*764|0)+48|0;c[j>>2]=i&255;c[m+(L*764|0)+56>>2]=d[ea>>0];c[m+(L*764|0)+64>>2]=d[U>>0];c[m+(L*764|0)+68>>2]=d[Q>>0];c[m+(L*764|0)+44>>2]=a[J>>0]&7;if((i&255)>15){h=-1;i=70;break}if(i<<24>>24){i=0;do{u=i<<1;b[m+(L*764|0)+72+(u<<1)>>1]=b[la+160+(u<<1)>>1]|0;u=u|1;b[m+(L*764|0)+72+(u<<1)>>1]=b[la+160+(u<<1)>>1]|0;i=i+1|0}while((i|0)<(c[j>>2]|0))}f:do if(b[$>>1]|0){u=m+(L*764|0)+756|0;t=0;g:while(1){j=c[u>>2]|0;i=c[ha>>2]|0;cm(ma,13,1,g)|0;cm(x,3,1,g)|0;c[M>>2]=_l(g)|0;c[V>>2]=_l(g)|0;c[R>>2]=_l(g)|0;c[ba>>2]=_l(g)|0;a[fa>>0]=Pl(g)|0;a[aa>>0]=Pl(g)|0;cm(y,14,1,g)|0;a[K>>0]=Pl(g)|0;cm(z,5,1,g)|0;b[F>>1]=Rl(g)|0;c[E>>2]=_l(g)|0;c[X>>2]=am(g)|0;k=c[M>>2]|0;do if(k>>>0>1048576)i=1;else{m=c[V>>2]|0;if(m>>>0>1048576){i=1;break}n=c[R>>2]|0;if(n>>>0>1048576){i=1;break}s=j+(t<<6)+40|0;c[s>>2]=h;c[j+(t<<6)>>2]=d[fa>>0];c[j+(t<<6)+8>>2]=d[aa>>0];p=i+(h*52|0)+32|0;c[p>>2]=k;r=i+(h*52|0)+36|0;c[r>>2]=m;q=i+(h*52|0)+40|0;c[q>>2]=n;qa=a[K>>0]|0;o=qa<<1&2;i=i+(h*52|0)+44|0;c[i>>2]=o;if(qa&4){c[i>>2]=o|1;c[p>>2]=k>>>1;c[r>>2]=m>>>1;c[q>>2]=n>>>1}Gi(c[ba>>2]|0,j+(t<<6)+12|0,j+(t<<6)+16|0);if((c[p>>2]|0)<1){i=52;break}i=(Eb(f,g,0,(c[ha>>2]|0)+((c[s>>2]|0)*52|0)|0,0)|0)>>>31}while(0);switch(i&63){case 52:case 0:break;default:break g}t=t+1|0;h=h+1|0;if((t|0)>=(e[$>>1]|0))break f}if(i){h=-1;i=70;break e}}while(0);L=L+1|0;if((L|0)>=(c[ka>>2]|0)){oa=h;pa=ha;break d}}if((i|0)==70){l=na;return h|0}}else{oa=0;pa=f+180|0}while(0);c[ja>>2]=oa;qa=Ym(c[pa>>2]|0,oa*52|0)|0;c[pa>>2]=qa;if(!qa){qa=-1;l=na;return qa|0}pa=f+7592|0;qa=Ym(c[pa>>2]|0,c[ja>>2]<<3)|0;c[pa>>2]=qa;if(!qa){qa=-1;l=na;return qa|0}c[ia>>2]=8363;qa=f+1284|0;c[qa>>2]=c[qa>>2]|1761673761;c[f+1288>>2]=2;qa=0;l=na;return qa|0}function ud(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0;e=a[c>>0]|0;f=e&15;g=f&255;h=a[33622+(d[b>>0]|0)>>0]|0;a[b>>0]=h;switch(h<<24>>24){case -2:{a[b>>0]=1;h=a[c>>0]|0;e=h&255;if((h&255)<48){a[c>>0]=e>>>2&15|224;return}else{a[c>>0]=e>>>4|240;return}}case -3:{a[b>>0]=2;h=a[c>>0]|0;e=h&255;if((h&255)<48){a[c>>0]=e>>>2&15|224;return}else{a[c>>0]=e>>>4|240;return}}case 14:switch((e&255)>>>4&15){case 15:case 14:case 9:case 7:case 6:case 4:case 2:case 1:{a[b>>0]=0;a[c>>0]=0;return}case 3:{a[c>>0]=g|48;return}case 5:{a[c>>0]=g|64;return}case 8:{a[c>>0]=g|112;return}case 10:{a[c>>0]=g|96;return}case 11:{a[c>>0]=g|224;return}case 12:{if(f<<24>>24)return;a[c>>0]=0;a[b>>0]=0;return}default:return}case -1:{a[c>>0]=0;a[b>>0]=0;return}default:return}}function vd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+32|0;c=d;if((cm(c,1,20,a)|0)>>>0>=20?(nn(c,33691,19)|0)==0:0){dm(a,156,1)|0;dm(a,384,1)|0;dm(a,64,1)|0;hb(a,b,32);c=0}else c=-1;l=d;return c|0}function wd(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=l;l=l+1648|0;m=v;n=v+4|0;t=v+1640|0;s=v+1576|0;cm(n,20,1,e)|0;j=n+20|0;cm(j,4,1,e)|0;a[n+24>>0]=Pl(e)|0;i=n+25|0;a[i>>0]=Pl(e)|0;u=n+26|0;a[u>>0]=Pl(e)|0;cm(n+27|0,19,1,e)|0;g=n+46|0;a[g>>0]=Pl(e)|0;r=Pl(e)|0;k=n+47|0;a[k>>0]=r;if(r<<24>>24<0){b=-1;l=v;return b|0}cm(n+48|0,128,1,e)|0;f=0;do{c[n+176+(f<<2)>>2]=am(e)|0;f=f+1|0}while((f|0)!=31);f=0;do{c[n+300+(f<<2)>>2]=am(e)|0;f=f+1|0}while((f|0)!=31);f=0;do{c[n+424+(f<<2)>>2]=am(e)|0;f=f+1|0}while((f|0)!=31);f=0;do{a[n+548+f>>0]=Pl(e)|0;f=f+1|0}while((f|0)!=31);f=0;do{a[n+579+f>>0]=Nl(e)|0;f=f+1|0}while((f|0)!=31);h=n+610|0;cm(h,32,1,e)|0;f=0;do{cm(n+642+(f*30|0)|0,30,1,e)|0;f=f+1|0}while((f|0)!=31);r=b+140|0;c[r>>2]=31;c[b+144>>2]=31;g=(d[g>>0]|0)+1|0;q=b+128|0;c[q>>2]=g;o=d[i>>0]|0;p=b+136|0;c[p>>2]=o;c[b+132>>2]=O(o,g)|0;g=b+156|0;c[g>>2]=(d[k>>0]|0)+1;c[b+1292>>2]=1;gb(b,h,32)|0;c[m>>2]=j;ob(b,33671,m);if((c[g>>2]|0)>0){f=0;do{a[b+952+f>>0]=a[n+48+f>>0]|0;f=f+1|0}while((f|0)<(c[g>>2]|0))}if((Za(b)|0)<0){b=-1;l=v;return b|0}a:do if((c[r>>2]|0)>0){i=b+180|0;h=b+176|0;g=0;while(1){if((_a(b,g,1)|0)<0){f=-1;break}o=c[n+176+(g<<2)>>2]|0;f=c[i>>2]|0;c[f+(g*52|0)+32>>2]=o;m=n+300+(g<<2)|0;c[f+(g*52|0)+36>>2]=c[m>>2];m=(c[n+424+(g<<2)>>2]|0)+(c[m>>2]|0)|0;c[f+(g*52|0)+40>>2]=m;c[f+(g*52|0)+44>>2]=(m|0)>0?2:0;f=c[h>>2]|0;m=c[f+(g*764|0)+756>>2]|0;c[m>>2]=d[n+548+g>>0];c[m+16>>2]=a[n+579+g>>0];c[m+8>>2]=128;c[m+40>>2]=g;if((o|0)>0)c[f+(g*764|0)+36>>2]=1;fb(f,g,n+642+(g*30|0)|0,30);g=g+1|0;if((g|0)>=(c[r>>2]|0))break a}l=v;return f|0}while(0);if(($a(b)|0)<0){b=-1;l=v;return b|0}b:do if((c[q>>2]|0)>0){o=b+172|0;n=b+168|0;m=0;while(1){if((db(b,m,64)|0)<0){f=-1;break}if(!(a[u>>0]|0)){f=c[p>>2]|0;g=s;h=g+64|0;do{a[g>>0]=255;g=g+1|0}while((g|0)<(h|0));k=0}else{Ul(e)|0;cm(s,1,64,e)|0;f=c[p>>2]|0;k=0}do{if((f|0)>0){j=s+k|0;h=0;i=128;while(1){if(d[j>>0]&i){cm(t,4,1,e)|0;f=c[(c[o>>2]|0)+(c[(c[(c[n>>2]|0)+(m<<2)>>2]|0)+4+(h<<2)>>2]<<2)>>2]|0;lb(f+4+(k<<3)|0,t);g=f+4+(k<<3)+3|0;c:do switch(a[g>>0]|0){case 8:{a[f+4+(k<<3)+4>>0]=0;a[g>>0]=0;break}case 14:{f=f+4+(k<<3)+4|0;switch((d[f>>0]|0)>>>4&15){case 9:case 8:case 3:case 0:{a[f>>0]=0;f=g;break}case 4:{a[g>>0]=12;break}default:break c}a[f>>0]=0;break}default:{}}while(0);f=c[p>>2]|0}h=h+1|0;if((h|0)>=(f|0))break;else i=i>>1}}k=k+1|0}while((k|0)!=64);m=m+1|0;if((m|0)>=(c[q>>2]|0))break b}l=v;return f|0}while(0);g=b+180|0;if((c[r>>2]|0)>0)f=0;else{b=0;l=v;return b|0}while(1){if((Eb(b,e,0,(c[g>>2]|0)+(f*52|0)|0,0)|0)<0){f=-1;g=42;break}f=f+1|0;if((f|0)>=(c[r>>2]|0)){f=0;g=42;break}}if((g|0)==42){l=v;return f|0}return 0}function xd(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;if(((((am(a)|0)==1182101099?(Pl(a)|0,d=Pl(a)|0,f=Pl(a)|0,Pl(a)|0,(d&255)>=20):0)?!(f<<24>>24<0|(f&14)>9):0)?(e=_l(a)|0,(e|0)>=1024):0)?(mm(c[a+4>>2]|0)|0)==(e|0):0){hb(a,b,0);e=0}else e=-1;return e|0}function yd(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+2736|0;n=w+16|0;m=w+8|0;k=w;u=w+20|0;t=w+2728|0;cm(u,4,1,e)|0;cm(u+4|0,4,1,e)|0;c[u+8>>2]=_l(e)|0;j=u+12|0;cm(j,4,1,e)|0;a[u+16>>0]=Pl(e)|0;i=u+17|0;cm(i,256,1,e)|0;cm(u+273|0,128,1,e)|0;f=0;while(1){if((d[u+273+f>>0]|0)>63){f=-1;o=63;break}f=f+1|0;if((f|0)>=128){f=0;break}}if((o|0)==63){l=w;return f|0}do{cm(u+404+(f*36|0)|0,19,1,e)|0;c[u+404+(f*36|0)+20>>2]=_l(e)|0;c[u+404+(f*36|0)+24>>2]=_l(e)|0;a[u+404+(f*36|0)+28>>0]=Pl(e)|0;a[u+404+(f*36|0)+29>>0]=Pl(e)|0;a[u+404+(f*36|0)+30>>0]=Pl(e)|0;a[u+404+(f*36|0)+31>>0]=Pl(e)|0;a[u+404+(f*36|0)+32>>0]=Pl(e)|0;f=f+1|0}while((f|0)!=64);v=b+140|0;c[v>>2]=64;c[b+144>>2]=64;s=b+128|0;g=c[s>>2]|0;f=0;do{r=a[u+17+f>>0]|0;h=r&255;if(r<<24>>24==-1)break;if((h|0)>(g|0)){c[s>>2]=h;g=h}f=f+1|0}while((f|0)<256);c[s>>2]=g+1;c[b+156>>2]=f;ep(b+952|0,i|0,f|0)|0;c[b+148>>2]=4;g=b+152|0;c[g>>2]=125;r=b+136|0;c[r>>2]=0;a:do if((a[j>>0]|0)==70)switch(a[u+13>>0]|0){case 50:{p=a[u+7>>0]|0;q=(p&255)>>>1&63;c[g>>2]=(p<<24>>24<0?0-q|0:q)+125;ob(b,33723,k);break a}case 107:case 118:{ob(b,33711,m);break a}default:{o=14;break a}}else o=14;while(0);if((o|0)==14){c[r>>2]=8;ob(b,33739,n)}f=c[r>>2]|0;if(!f){f=a[u+14>>0]|0;if((f+-48&255)>9)f=8;else{q=a[u+15>>0]|0;f=(q+-48&255)>9?8:((f&255)*10|0)+-528+(q&255)|0}c[r>>2]=f}c[g>>2]=(c[g>>2]<<2|0)/5|0;c[b+132>>2]=O(c[s>>2]|0,f)|0;c[b+1292>>2]=2;if((Za(b)|0)<0){b=-1;l=w;return b|0}b:do if((c[v>>2]|0)>0){i=b+180|0;h=b+176|0;g=0;while(1){if((_a(b,g,1)|0)<0){f=-1;break}q=c[u+404+(g*36|0)+24>>2]|0;f=c[i>>2]|0;c[f+(g*52|0)+32>>2]=q;p=c[u+404+(g*36|0)+20>>2]|0;c[f+(g*52|0)+36>>2]=(p|0)==-1?0:p;c[f+(g*52|0)+40>>2]=q;c[f+(g*52|0)+44>>2]=(p|0)!=-1?2:0;f=c[h>>2]|0;p=c[f+(g*764|0)+756>>2]|0;c[p>>2]=d[u+404+(g*36|0)+28>>0];c[p+8>>2]=d[u+404+(g*36|0)+29>>0];c[p+40>>2]=g;if((q|0)>0)c[f+(g*764|0)+36>>2]=1;fb(f,g,u+404+(g*36|0)|0,19);g=g+1|0;if((g|0)>=(c[v>>2]|0))break b}l=w;return f|0}while(0);if(($a(b)|0)<0){b=-1;l=w;return b|0}c:do if((c[s>>2]|0)>0){q=b+172|0;p=b+168|0;m=t+1|0;n=t+2|0;o=0;while(1){if((db(b,o,64)|0)<0){f=-1;break}h=c[q>>2]|0;g=c[(c[p>>2]|0)+(o<<2)>>2]|0;a[(c[h+(c[g+8>>2]<<2)>>2]|0)+4+(d[u+273+o>>0]<<3)+5>>0]=13;f=c[r>>2]|0;d:do if((f|0)>0){i=0;while(1){k=c[h+(c[g+4+(((i|0)%(f|0)|0)<<2)>>2]<<2)>>2]|0;j=(i|0)/(f|0)|0;cm(t,1,3,e)|0;f=a[t>>0]|0;g=(f&255)>>>2;h=a[m>>0]|0;if((g+-61|0)>>>0>=3){a[k+4+(j<<3)>>0]=g+37;g=(h&255)>>>4;f=f<<4&48;a[k+4+(j<<3)+1>>0]=g+1+f;a[k+4+(j<<3)+2>>0]=a[u+404+((f|g)*36|0)+28>>0]|0}e:do switch(h&15){case 0:{a[k+4+(j<<3)+3>>0]=121;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 1:{a[k+4+(j<<3)+3>>0]=120;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 2:{a[k+4+(j<<3)+3>>0]=122;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 3:{a[k+4+(j<<3)+3>>0]=123;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 6:{a[k+4+(j<<3)+3>>0]=124;a[k+4+(j<<3)+4>>0]=d[n>>0]<<1;break}case 7:{a[k+4+(j<<3)+3>>0]=125;a[k+4+(j<<3)+4>>0]=d[n>>0]<<1;break}case 11:{a[k+4+(j<<3)+3>>0]=0;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 13:{a[k+4+(j<<3)+3>>0]=12;a[k+4+(j<<3)+4>>0]=a[n>>0]|0;break}case 14:{f=a[n>>0]|0;g=f&255;if((f+-10&255)<3){a[k+4+(j<<3)+3>>0]=127;break e}switch((f&255)>>>4&15){case 1:{a[k+4+(j<<3)+3>>0]=14;f=g&15|192;break}case 2:{a[k+4+(j<<3)+3>>0]=14;f=g&15|208;break}case 13:{a[k+4+(j<<3)+3>>0]=14;f=g&15|144;break}case 14:{a[k+4+(j<<3)+3>>0]=8;f=g<<4&240|8;break}case 15:{a[k+4+(j<<3)+3>>0]=15;f=g&15;break}default:break e}a[k+4+(j<<3)+4>>0]=f;break}default:{}}while(0);i=i+1|0;f=c[r>>2]|0;if((i|0)>=(f<<6|0))break d;g=c[(c[p>>2]|0)+(o<<2)>>2]|0;h=c[q>>2]|0}}while(0);o=o+1|0;if((o|0)>=(c[s>>2]|0))break c}l=w;return f|0}while(0);f=c[v>>2]|0;f:do if((f|0)>0){i=b+180|0;h=0;while(1){g=c[i>>2]|0;if((c[g+(h*52|0)+32>>2]|0)>=3){if((Eb(b,e,0,g+(h*52|0)|0,0)|0)<0){f=-1;break}f=c[v>>2]|0}h=h+1|0;if((h|0)>=(f|0))break f}l=w;return f|0}while(0);if((c[r>>2]|0)>0){f=0;do{c[b+184+(f*12|0)>>2]=128;f=f+1|0}while((f|0)<(c[r>>2]|0))}c[b+1268>>2]=255;c[b+1284>>2]=64;b=0;l=w;return b|0}function zd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;dm(a,c+1464|0,0)|0;d=am(a)|0;if((d|0)<1297370624)switch(d|0){case 1230254384:{e=2;break}default:d=-1}else switch(d|0){case 1297370624:{e=2;break}default:d=-1}if((e|0)==2){dm(a,c,0)|0;hb(a,b,28);d=0}return d|0}function Ad(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;t=l;l=l+1488|0;o=t+8|0;n=t;q=t+12|0;s=t+1480|0;cm(q,20,1,g)|0;h=0;do{cm(q+20+(h*30|0)|0,22,1,g)|0;b[q+20+(h*30|0)+22>>1]=Ul(g)|0;a[q+20+(h*30|0)+24>>0]=Pl(g)|0;a[q+20+(h*30|0)+25>>0]=Pl(g)|0;b[q+20+(h*30|0)+26>>1]=Ul(g)|0;b[q+20+(h*30|0)+28>>1]=Ul(g)|0;h=h+1|0}while((h|0)!=31);m=q+950|0;a[m>>0]=Pl(g)|0;p=q+951|0;a[p>>0]=Pl(g)|0;cm(q+952|0,512,1,g)|0;k=am(g)|0;c[q+1464>>2]=k;h=a[m>>0]|0;if((h&255)>128){f=-1;l=t;return f|0}a:do if(h<<24>>24){j=a[p>>0]|0;h=h&255;i=0;while(1){if((d[q+952+(i<<2)>>0]|0)>=(j&255)){h=-1;i=40;break}if((d[q+952+(i<<2)+1>>0]|0)>=(j&255)){h=-1;i=40;break}if((d[q+952+(i<<2)+2>>0]|0)>=(j&255)){h=-1;i=40;break}if((d[q+952+(i<<2)+3>>0]|0)>=(j&255)){h=-1;i=40;break}i=i+1|0;if((i|0)>=(h|0))break a}if((i|0)==40){l=t;return h|0}}while(0);b:do if((k|0)<1297370624)switch(k|0){case 1230254384:{ob(f,33786,n);break b}default:{f=-1;l=t;return f|0}}else switch(k|0){case 1297370624:{ob(f,33798,o);break b}default:{f=-1;l=t;return f|0}}while(0);r=f+140|0;c[r>>2]=31;c[f+144>>2]=31;o=d[m>>0]|0;n=f+128|0;c[n>>2]=o;c[f+156>>2]=o;o=f+132|0;c[o>>2]=d[p>>0];Ho(f,q,20)|0;if((Za(f)|0)<0){f=-1;l=t;return f|0}c:do if((c[r>>2]|0)>0){j=f+176|0;k=f+180|0;i=0;while(1){if((_a(f,i,1)|0)<0){h=-1;break}h=c[j>>2]|0;m=c[k>>2]|0;p=b[q+20+(i*30|0)+22>>1]|0;c[m+(i*52|0)+32>>2]=(p&65535)<<1;v=e[q+20+(i*30|0)+26>>1]<<1;c[m+(i*52|0)+36>>2]=v;u=b[q+20+(i*30|0)+28>>1]|0;c[m+(i*52|0)+40>>2]=((u&65535)<<1)+v;c[m+(i*52|0)+44>>2]=(u&65535)>1?2:0;m=c[h+(i*764|0)+756>>2]|0;c[m>>2]=d[q+20+(i*30|0)+25>>0];c[m+8>>2]=128;c[m+40>>2]=i;if(p<<16>>16)c[h+(i*764|0)+36>>2]=1;i=i+1|0;if((i|0)>=(c[r>>2]|0))break c}l=t;return h|0}while(0);if(($a(f)|0)<0){v=-1;l=t;return v|0}d:do if((c[n>>2]|0)>0){m=f+168|0;i=f+136|0;j=0;while(1){if((ab(f,j)|0)<0){h=-1;break}h=c[(c[m>>2]|0)+(j<<2)>>2]|0;c[h>>2]=64;if((c[i>>2]|0)>0){k=0;do{c[h+4+(k<<2)>>2]=d[q+952+(j<<2)+k>>0];k=k+1|0}while((k|0)<(c[i>>2]|0))}a[f+952+j>>0]=j;j=j+1|0;if((j|0)>=(c[n>>2]|0))break d}l=t;return h|0}while(0);e:do if((c[o>>2]|0)>0){m=f+172|0;k=0;while(1){if((bb(f,k,64)|0)<0){h=-1;break}h=c[(c[m>>2]|0)+(k<<2)>>2]|0;if((c[h>>2]|0)>0){j=0;do{cm(s,1,4,g)|0;lb(h+4+(j<<3)|0,s);i=h+4+(j<<3)+3|0;if((a[i>>0]|0)==15?(v=d[h+4+(j<<3)+4>>0]|0,!((v&240|0)==0|(v&15|0)==0)):0)a[i>>0]=-94;j=j+1|0;h=c[(c[m>>2]|0)+(k<<2)>>2]|0}while((j|0)<(c[h>>2]|0))}k=k+1|0;if((k|0)>=(c[o>>2]|0))break e}l=t;return h|0}while(0);c[f+1292>>2]=1;h=c[r>>2]|0;if((h|0)<=0){v=0;l=t;return v|0}k=f+180|0;j=0;while(1){i=c[k>>2]|0;if((c[i+(j*52|0)+32>>2]|0)>=5){if((Eb(f,g,0,i+(j*52|0)|0,0)|0)<0){h=-1;i=40;break}h=c[r>>2]|0}j=j+1|0;if((j|0)>=(h|0)){h=0;i=40;break}}if((i|0)==40){l=t;return h|0}return 0}function Bd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+16|0;c=d;if((cm(c,1,14,a)|0)>>>0>=14?(nn(c,33855,14)|0)==0:0){hb(a,b,30);c=0}else c=-1;l=d;return c|0}function Cd(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0;_=l;l=l+352|0;Z=_;u=_+208|0;X=_+56|0;D=_+16|0;r=_+320|0;cm(u,14,1,g)|0;p=u+14|0;cm(p,30,1,g)|0;cm(u+44|0,20,1,g)|0;Pl(g)|0;q=u+65|0;cm(q,20,1,g)|0;s=u+86|0;b[s>>1]=Rl(g)|0;m=u+88|0;b[m>>1]=Rl(g)|0;j=u+90|0;b[j>>1]=Rl(g)|0;b[u+92>>1]=Rl(g)|0;b[u+94>>1]=Rl(g)|0;k=u+96|0;b[k>>1]=Rl(g)|0;c[u+100>>2]=_l(g)|0;n=u+104|0;b[n>>1]=Rl(g)|0;o=u+106|0;b[o>>1]=Rl(g)|0;i=u+108|0;b[i>>1]=Rl(g)|0;u=u+110|0;b[u>>1]=Rl(g)|0;if((e[k>>1]|0)>64|(e[n>>1]|0)>256|(e[o>>1]|0)>256){Z=-1;l=_;return Z|0}if((e[s>>1]|0)<256){b[u>>1]=b[i>>1]|0;b[i>>1]=0;dm(g,-2,1)|0}i=b[i>>1]|0;if((i&65535)>256){Z=-1;l=_;return Z|0}c[f+148>>2]=e[m>>1];c[f+152>>2]=e[j>>1];S=e[k>>1]|0;y=f+136|0;c[y>>2]=S;R=e[n>>1]|0;x=f+128|0;c[x>>2]=R;k=e[o>>1]|0;c[f+144>>2]=k;T=f+140|0;c[T>>2]=k;k=f+156|0;c[k>>2]=i&65535;c[f+132>>2]=O(R,S)|0;S=f+1284|0;c[S>>2]=c[S>>2]|16384;Ho(f,p,30)|0;Ho(r,q,20)|0;a[r+20>>0]=0;i=r+19|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;U=88;break}case 0:{U=88;break}default:{}}a:do if((U|0)==88){i=r+18|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+17|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+16|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+15|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+14|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+13|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+12|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+11|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+10|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+9|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+8|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+7|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+6|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+5|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+4|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+3|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+2|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}i=r+1|0;switch(a[i>>0]|0){case 32:{a[i>>0]=0;break}case 0:break;default:break a}if((a[r>>0]|0)==32)a[r>>0]=0}while(0);R=e[s>>1]|0;c[Z>>2]=r;c[Z+4>>2]=R>>>8;c[Z+8>>2]=R&255;io(f+64|0,64,33815,Z);if(!(b[s>>1]|0)){dm(g,h+240|0,0)|0;cm(f+952|0,1,256,g)|0;dm(g,(e[u>>1]|0)+h|0,0)|0;i=0;do{if((a[f+952+i>>0]|0)==-1)break;i=i+1|0}while((i|0)<256);c[k>>2]=i}else{if((c[y>>2]|0)>0){j=0;b:do{i=Pl(g)|0;c:do if((i&255)>63){switch(i<<24>>24){case 64:{i=63;break c}case 66:break;default:{Y=-1;U=86;break b}}i=f+184+(j*12|0)+8|0;c[i>>2]=c[i>>2]|16;i=31}while(0);c[f+184+(j*12|0)>>2]=(i&255)<<2;j=j+1|0;t=c[y>>2]|0}while((j|0)<(t|0));if((U|0)==86){l=_;return Y|0}if((t|0)>0){i=0;do{c[f+184+(i*12|0)+4>>2]=(Pl(g)|0)&255;i=i+1|0}while((i|0)<(c[y>>2]|0))}}cm(f+952|0,1,c[k>>2]|0,g)|0;dm(g,(e[u>>1]|0)+-109+(O(c[y>>2]|0,-2)|0)-(c[k>>2]|0)|0,1)|0}c[f+1264>>2]=8363;if(($a(f)|0)<0){Z=-1;l=_;return Z|0}d:do if((c[x>>2]|0)>0){t=D+30|0;u=D+32|0;s=D+36|0;v=f+168|0;w=f+172|0;r=0;i=0;e:while(1){if((ab(f,r)|0)<0){Y=-1;U=86;break}j=am(g)|0;if((j|0)>=1280311296){switch(j|0){case 1280311296:break;default:{Y=-1;U=86;break e}}cm(D,30,1,g)|0;b[t>>1]=Rl(g)|0;c[u>>2]=_l(g)|0;c[s>>2]=_l(g)|0;j=b[t>>1]|0;if((j&65535)>256){Y=-1;U=86;break}c[c[(c[v>>2]|0)+(r<<2)>>2]>>2]=j&65535;cb(f,r)|0;h=em(g)|0;if((r|0)>=(c[x>>2]|0)){Y=-1;U=86;break}o=c[y>>2]|0;q=0;k=0;m=0;f:while(1){if((q|0)>=(o|0)){Y=-1;U=86;break e}j=c[(c[v>>2]|0)+(r<<2)>>2]|0;if((k|0)>=(c[j>>2]|0)){Y=-1;U=86;break e}j=(c[(c[w>>2]|0)+(c[j+4+(q<<2)>>2]<<2)>>2]|0)+4+(k<<3)|0;g:do if(!(m<<24>>24)){i=Pl(g)|0;if((r|0)>=(c[x>>2]|0)){Y=-1;U=86;break e}h:while(1){m=c[y>>2]|0;if((q|0)>=(m|0)){Y=-1;U=86;break e}j=c[(c[v>>2]|0)+(r<<2)>>2]|0;if((k|0)>=(c[j>>2]|0)){Y=-1;U=86;break e}n=c[(c[w>>2]|0)+(c[j+4+(q<<2)>>2]<<2)>>2]|0;o=n+4+(k<<3)|0;j=i&255;switch(i<<24>>24){case -64:break f;case -128:{o=q;i=-128;p=0;break g}case -31:{U=36;break h}case -96:{A=m;C=q;E=-96;break h}case -32:{U=38;break h}default:{}}if((i+63&255)<31){U=40;break}if((i+95&255)<31){U=43;break}if((i+127&255)<31){U=46;break}if((i&255)>=254){if(i<<24>>24==-2){z=-127;U=54}}else{z=j+37&255;U=54}if((U|0)==54){U=0;a[o>>0]=z}B=Pl(g)|0;if((B&255)<=100){U=57;break}if((r|0)<(c[x>>2]|0)){k=k+1|0;i=B}else{Y=-1;U=86;break e}}if((U|0)==36){U=0;E=Pl(g)|0;A=c[y>>2]|0;C=(E&255)+q|0}else if((U|0)==38){U=0;i=Pl(g)|0;o=q;k=(i&255)+k|0;p=0;break}else if((U|0)==40){U=0;if((Dd(i,o,g)|0)<0){Y=-1;U=86;break e}Ed(o);o=q;p=0;break}else if((U|0)==43){U=0;j=Pl(g)|0;if((Dd(i,o,g)|0)<0){Y=-1;U=86;break e}Ed(o);o=q;p=j;break}else if((U|0)==46){U=0;j=Pl(g)|0;if((Dd(i,o,g)|0)<0){Y=-1;U=86;break e}Ed(o);if(!(j<<24>>24)){o=q;p=0;break}while(1){k=k+1|0;if((k|0)>=(e[t>>1]|0)){Y=-1;U=86;break e}Q=o;N=Q;N=d[N>>0]|d[N+1>>0]<<8|d[N+2>>0]<<16|d[N+3>>0]<<24;Q=Q+4|0;Q=d[Q>>0]|d[Q+1>>0]<<8|d[Q+2>>0]<<16|d[Q+3>>0]<<24;R=(c[(c[w>>2]|0)+(c[(c[(c[v>>2]|0)+(r<<2)>>2]|0)+4+(q<<2)>>2]<<2)>>2]|0)+4+(k<<3)|0;P=R;a[P>>0]=N;a[P+1>>0]=N>>8;a[P+2>>0]=N>>16;a[P+3>>0]=N>>24;R=R+4|0;a[R>>0]=Q;a[R+1>>0]=Q>>8;a[R+2>>0]=Q>>16;a[R+3>>0]=Q>>24;j=j+-1<<24>>24;if(!(j<<24>>24)){o=q;p=0;break g}}}else if((U|0)==57){U=0;m=n+4+(k<<3)+1|0;a[m>>0]=(B&255)+1;i=Pl(g)|0;if(i<<24>>24!=-1)a[n+4+(k<<3)+2>>0]=i;i=Pl(g)|0;j=n+4+(k<<3)+3|0;if(i<<24>>24!=-1)a[j>>0]=(i&255)+191;i=Pl(g)|0;a[n+4+(k<<3)+4>>0]=i;if((d[j>>0]|0)>24){Y=-1;U=86;break e}Ed(o);R=a[o>>0]|0;if(!((R&255)<120|R<<24>>24==-127)){Y=-1;U=86;break e}if((d[m>>0]|0)>100){Y=-1;U=86;break e}if((d[n+4+(k<<3)+2>>0]|0)>65){Y=-1;U=86;break e}else{o=q;p=0;break}}o=C+1|0;o=(o|0)<(A|0)?o:C;k=-1;i=E;p=0}else{if((Dd(i,j,g)|0)<0){Y=-1;U=86;break e}Ed(j);o=q;p=m+-1<<24>>24}while(0);m=k+1|0;n=(m|0)<(c[c[(c[v>>2]|0)+(r<<2)>>2]>>2]|0);k=((n^1)&1)+o|0;j=c[y>>2]|0;if((r|0)<(c[x>>2]|0)){o=j;q=(k|0)<(j|0)?k:0;k=n?m:0;m=n?p:0}else{Y=-1;U=86;break e}}R=(em(g)|0)-h|0;if((R|0)==(c[u>>2]|0))i=-64;else{Y=-1;U=86;break}}else switch(j|0){case 555819297:break;default:{Y=-1;U=86;break e}}r=r+1|0;if((r|0)>=(c[x>>2]|0))break d}if((U|0)==86){l=_;return Y|0}}while(0);if((Za(f)|0)<0){Z=-1;l=_;return Z|0}i:do if((c[T>>2]|0)>0){Q=f+176|0;R=f+180|0;w=Z+1|0;x=Z+2|0;y=Z+3|0;p=X+2|0;q=X+32|0;h=X+52|0;G=X+72|0;I=X+76|0;K=X+80|0;J=X+84|0;z=X+88|0;P=X+92|0;D=X+93|0;N=X+94|0;M=X+95|0;E=X+96|0;A=X+97|0;F=X+98|0;B=X+100|0;C=X+104|0;L=X+108|0;r=X+109|0;s=X+120|0;H=0;while(1){n=c[Q>>2]|0;t=c[R>>2]|0;v=t+(H*52|0)|0;if((_a(f,H,1)|0)<0)break;u=c[n+(H*764|0)+756>>2]|0;cm(Z,1,4,g)|0;k=a[Z>>0]|0;m=a[w>>0]|0;if(k<<24>>24==63){i=a[x>>0]|0;j=a[y>>0]|0;if(m<<24>>24==63&i<<24>>24==63&j<<24>>24==63)U=82;else{V=i;W=j;U=75}}else{V=a[x>>0]|0;W=a[y>>0]|0;U=75}if((U|0)==75){U=0;if(!(k<<24>>24==76&m<<24>>24==68&V<<24>>24==83&W<<24>>24==83))break;b[X>>1]=Rl(g)|0;cm(p,30,1,g)|0;cm(q,20,1,g)|0;cm(h,20,1,g)|0;a[G>>0]=Pl(g)|0;c[I>>2]=_l(g)|0;c[K>>2]=_l(g)|0;c[J>>2]=_l(g)|0;c[z>>2]=_l(g)|0;a[P>>0]=Pl(g)|0;a[D>>0]=Pl(g)|0;a[N>>0]=Pl(g)|0;a[M>>0]=Pl(g)|0;a[E>>0]=Pl(g)|0;a[A>>0]=Pl(g)|0;b[F>>1]=Rl(g)|0;b[B>>1]=Rl(g)|0;c[C>>2]=_l(g)|0;a[L>>0]=Pl(g)|0;cm(r,11,1,g)|0;cm(s,25,1,g)|0;o=c[I>>2]|0;c[n+(H*764|0)+36>>2]=(o|0)!=0&1;c[n+(H*764|0)+32>>2]=64;k=t+(H*52|0)+32|0;c[k>>2]=o;i=c[K>>2]|0;n=t+(H*52|0)+36|0;c[n>>2]=i;j=c[J>>2]|0;m=t+(H*52|0)+40|0;c[m>>2]=j;if(a[D>>0]&1){c[t+(H*52|0)+44>>2]=1;c[k>>2]=o>>1;c[n>>2]=i>>1;c[m>>2]=j>>1}if(j|0)c[t+(H*52|0)+44>>2]=2;a[E>>0]=64;c[u>>2]=d[P>>0];c[u+4>>2]=64;c[u+8>>2]=d[N>>0];c[u+40>>2]=H;fb(c[Q>>2]|0,H,p,31);Gi(c[z>>2]|0,u+12|0,u+16|0);dm(g,(e[F>>1]|0)+-144|0,1)|0;if(c[k>>2]|0){if((Eb(f,g,0,v,0)|0)<0){Y=-1;U=86;break}}else U=82}if((U|0)==82)U=0;H=H+1|0;if((H|0)>=(c[T>>2]|0))break i}if((U|0)==86){l=_;return Y|0}Z=-1;l=_;return Z|0}while(0);c[S>>2]=c[S>>2]|1224737313;c[f+1288>>2]=2;Z=0;l=_;return Z|0}function Dd(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0;f=c;g=f;a[g>>0]=0;a[g+1>>0]=0;a[g+2>>0]=0;a[g+3>>0]=0;f=f+4|0;a[f>>0]=0;a[f+1>>0]=0;a[f+2>>0]=0;a[f+3>>0]=0;b=b&255;if(b&1|0){g=Pl(e)|0;a[c>>0]=g<<24>>24==-2?-127:(g&255)+37&255}if(b&2|0)a[c+1>>0]=((Pl(e)|0)&255)+1;if(b&4|0)a[c+2>>0]=Pl(e)|0;if(b&8|0)a[c+3>>0]=((Pl(e)|0)&255)+191;if(b&16|0)a[c+4>>0]=Pl(e)|0;g=a[c>>0]|0;if(!((g&255)<108|g<<24>>24==-127))return -1;if((d[c+1>>0]|0)>100)return -1;if((d[c+2>>0]|0)>64)return -1;else return ((d[c+3>>0]|0)>26)<<31>>31|0;return 0}function Ed(b){b=b|0;var c=0,e=0,f=0,g=0,h=0;g=b+4|0;c=a[g>>0]|0;e=c&15;f=e&255;b=b+3|0;h=a[33830+(d[b>>0]|0)>>0]|0;a[b>>0]=h;switch(h<<24>>24){case 14:switch((c&255)>>>4&15){case 3:{a[g>>0]=f|48;return}case 4:{a[g>>0]=(e<<24>>24==3&1)+f|64;return}case 5:{a[g>>0]=f|80;return}case 6:{a[g>>0]=f|96;return}case 7:{a[g>>0]=(e<<24>>24==3&1)+f|112;return}case 12:{a[g>>0]=f|192;return}case 13:{a[g>>0]=f|208;return}case 14:{a[g>>0]=f|224;return}default:{a[g>>0]=0;a[b>>0]=0;return}}case -1:{a[g>>0]=0;a[b>>0]=0;return}default:return}}function Fd(c,f,g){c=c|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0;r=l;l=l+1088|0;q=r;cm(q,20,1,c)|0;k=0;p=0;while(1){h=q+20+(k*30|0)|0;if((cm(h,1,20,c)|0)>>>0<20){h=-1;i=15;break}b[q+20+(k*30|0)+20>>1]=Ul(c)|0;i=q+20+(k*30|0)+22|0;b[i>>1]=Ul(c)|0;a[q+20+(k*30|0)+24>>0]=Pl(c)|0;o=q+20+(k*30|0)+25|0;a[o>>0]=Pl(c)|0;m=q+20+(k*30|0)+26|0;b[m>>1]=Ul(c)|0;j=Ul(c)|0;b[q+20+(k*30|0)+28>>1]=j;i=b[i>>1]|0;n=(i&65535)<<1;p=n+p|0;if((ib(h,20)|0)<0){h=-1;i=15;break}if((d[o>>0]|0)>64|(i&65535)>32768){h=-1;i=15;break}if((e[m>>1]|0)>(i&65535)){h=-1;i=15;break}if(i<<16>>16!=0&(j&65535)>>>0>n>>>0){h=-1;i=15;break}k=k+1|0;if((k|0)>=31){i=8;break}}if((i|0)==8){if((p|0)<8){f=-1;l=r;return f|0}h=q+950|0;a[h>>0]=Pl(c)|0;p=q+951|0;a[p>>0]=Pl(c)|0;cm(q+952|0,128,1,c)|0;cm(q+1080|0,4,1,c)|0;if((d[p>>0]|0)>1){f=-1;l=r;return f|0}h=a[h>>0]|0;if(h<<24>>24<1|(a[q+1083>>0]|0)!=60){f=-1;l=r;return f|0}h=h&255;i=0;j=0;do{p=d[q+952+i>>0]|0;j=(p|0)>(j|0)?p:j;i=i+1|0}while((i|0)<(h|0));if((j|0)>126){f=-1;l=r;return f|0}dm(c,g,0)|0;hb(c,f,20);f=0;l=r;return f|0}else if((i|0)==15){l=r;return h|0}return 0}function Gd(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+1104|0;n=w;o=w+4|0;u=w+1088|0;m=f+136|0;c[m>>2]=4;p=f+140|0;c[p>>2]=31;v=f+144|0;c[v>>2]=31;cm(o,20,1,g)|0;h=0;do{cm(o+20+(h*30|0)|0,20,1,g)|0;b[o+20+(h*30|0)+20>>1]=Ul(g)|0;b[o+20+(h*30|0)+22>>1]=Ul(g)|0;a[o+20+(h*30|0)+24>>0]=Pl(g)|0;a[o+20+(h*30|0)+25>>0]=Pl(g)|0;b[o+20+(h*30|0)+26>>1]=Ul(g)|0;b[o+20+(h*30|0)+28>>1]=Ul(g)|0;h=h+1|0}while((h|0)!=31);t=Pl(g)|0;h=o+950|0;a[h>>0]=t;if((t&255)>128){f=-1;l=w;return f|0}a[o+951>>0]=Pl(g)|0;t=o+952|0;cm(t,128,1,g)|0;cm(o+1080|0,4,1,g)|0;s=a[h>>0]|0;k=s&255;c[f+156>>2]=k;ep(f+952|0,t|0,k|0)|0;t=f+128|0;h=c[t>>2]|0;if(s<<24>>24){j=0;do{i=d[f+952+j>>0]|0;if((i|0)>(h|0)){c[t>>2]=i;h=i}j=j+1|0}while((j|0)!=(k|0))}s=h+1|0;c[t>>2]=s;c[f+132>>2]=O(c[m>>2]|0,s)|0;Ho(f,o,20)|0;ob(f,33870,n);if((Za(f)|0)<0){f=-1;l=w;return f|0}a:do if((c[p>>2]|0)>0){j=f+176|0;k=f+180|0;i=0;while(1){if((_a(f,i,1)|0)<0){h=-1;break}h=c[j>>2]|0;r=c[h+(i*764|0)+756>>2]|0;q=c[k>>2]|0;s=b[o+20+(i*30|0)+22>>1]|0;c[q+(i*52|0)+32>>2]=(s&65535)<<1;m=e[o+20+(i*30|0)+26>>1]<<1;c[q+(i*52|0)+36>>2]=m;n=b[o+20+(i*30|0)+28>>1]|0;c[q+(i*52|0)+40>>2]=((n&65535)<<1)+m;c[q+(i*52|0)+44>>2]=(n&65535)>1?2:0;c[r+16>>2]=0;c[r>>2]=d[o+20+(i*30|0)+25>>0];c[r+8>>2]=128;c[r+40>>2]=i;if(s<<16>>16)c[h+(i*764|0)+36>>2]=1;fb(h,i,o+20+(i*30|0)|0,20);i=i+1|0;if((i|0)>=(c[p>>2]|0))break a}l=w;return h|0}while(0);if(($a(f)|0)<0){f=-1;l=w;return f|0}b:do if((c[t>>2]|0)>0){s=f+172|0;r=f+168|0;n=u+1|0;o=u+2|0;p=0;while(1){if((db(f,p,64)|0)<0){h=-1;break}else q=0;do{i=c[(c[s>>2]|0)+(c[(c[(c[r>>2]|0)+(p<<2)>>2]|0)+4+((q&3)<<2)>>2]<<2)>>2]|0;j=q>>2;m=i+4+(j<<3)|0;cm(u,1,3,g)|0;k=a[u>>0]|0;h=k&63;a[m>>0]=h;switch(k&63){case 63:case 0:{h=0;break}default:h=h+33<<24>>24}a[m>>0]=h;h=d[n>>0]|0;a[i+4+(j<<3)+1>>0]=(k&64)>>>2|h>>>4;k=i+4+(j<<3)+3|0;a[k>>0]=h&15;h=i+4+(j<<3)+4|0;a[h>>0]=a[o>>0]|0;kb(m);if((a[k>>0]|0)==13){m=a[h>>0]|0;a[h>>0]=(((m&255)/10|0)&255)<<4|((m&255)%10|0)&255}q=q+1|0}while((q|0)!=256);p=p+1|0;if((p|0)>=(c[t>>2]|0))break b}l=w;return h|0}while(0);c[f+1292>>2]=1;h=c[v>>2]|0;if((h|0)<=0){f=0;l=w;return f|0}k=f+180|0;j=0;while(1){i=c[k>>2]|0;if(c[i+(j*52|0)+32>>2]|0){if((Eb(f,g,0,i+(j*52|0)|0,0)|0)<0){h=-1;i=31;break}h=c[v>>2]|0}j=j+1|0;if((j|0)>=(h|0)){h=0;i=31;break}}if((i|0)==31){l=w;return h|0}return 0}function Hd(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1347636512){b=-1;return b|0}Pl(a)|0;Pl(a)|0;Pl(a)|0;if((Pl(a)|0)<<24>>24){b=-1;return b|0}if((am(a)|0)!=1179208773){b=-1;return b|0}am(a)|0;dm(a,_l(a)|0,1)|0;if((am(a)|0)==1414091852){hb(a,b,_l(a)|0);b=0;return b|0}else{hb(a,b,0);b=0;return b|0}return 0}function Id(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0;p=l;l=l+32|0;n=p+4|0;am(d)|0;c[n>>2]=0;a[b>>0]=0;dm(d,8,1)|0;c[b+140>>2]=0;c[b+144>>2]=0;c[n+4>>2]=0;c[n+8>>2]=0;g=em(d)|0;f=pb()|0;if(!f){b=-1;l=p;return b|0}m=tb(f,33910,26)|0;m=tb(f,33915,27)|0|m;m=m|(tb(f,34742,28)|0);m=m|(tb(f,33920,29)|0);if(m|(tb(f,33925,30)|0)|0){b=-1;l=p;return b|0}Ab(f,1);m=(qb(f,b,d,n)|0)<0;wb(f);if(m){b=-1;l=p;return b|0}j=b+128|0;f=c[j>>2]|0;c[b+132>>2]=O(c[b+136>>2]|0,f)|0;f=Vm(f<<3)|0;k=n+12|0;c[k>>2]=f;if(!f){b=-1;l=p;return b|0}i=Vm(2040)|0;m=n+16|0;c[m>>2]=i;if(i){ob(b,c[n>>2]|0?33930:33942,p);c[b+1264>>2]=8363;if(((((Za(b)|0)>=0?($a(b)|0)>=0:0)?(dm(d,g+e|0,0)|0,o=b+156|0,c[o>>2]=0,h=pb()|0,h|0):0)?(i=tb(h,34742,31)|0,i=tb(h,33920,32)|0|i,(i|(tb(h,33925,33)|0)|0)==0):0)?(Ab(h,1),i=(qb(h,b,d,n)|0)<0,wb(h),!i):0){a:do if((c[o>>2]|0)>0){g=c[j>>2]|0;i=0;do{b:do if((g|0)>0){d=(c[m>>2]|0)+(i<<3)|0;h=c[k>>2]|0;e=c[n>>2]|0?8:4;f=0;while(1){if(!(nn(d,h+(f<<3)|0,e)|0))break;f=f+1|0;if((f|0)>=(g|0))break b}a[b+952+i>>0]=f;g=c[j>>2]|0}else f=0;while(0);i=i+1|0;if((f|0)==(g|0))break a}while((i|0)<(c[o>>2]|0))}while(0);Wm(c[m>>2]|0);Wm(c[k>>2]|0);b=0;l=p;return b|0}Wm(c[m>>2]|0);f=c[k>>2]|0}Wm(f);b=-1;l=p;return b|0}function Jd(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;d=l;l=l+48|0;e=d;cm(e,1,40,c)|0;Ho(a,e,(b|0)<32?b:32)|0;l=d;return 0}function Kd(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return 0}function Ld(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;dm(d,10,1)|0;c[a+136>>2]=(Pl(d)|0)&255;return 0}function Md(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;e=a+140|0;b=(c[e>>2]|0)+1|0;c[e>>2]=b;c[a+144>>2]=b;return 0}function Nd(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0;g=l;l=l+32|0;d=g;b=b+128|0;c[b>>2]=(c[b>>2]|0)+1;cm(d,1,20,e)|0;if(!(a[d+9>>0]|0)){l=g;return 0}if(a[d+13>>0]|0){l=g;return 0}c[f>>2]=1;l=g;return 0}function Od(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0;h=l;l=l+32|0;cm(h,1,9,c)|0;Rl(c)|0;a:do if((b|0)>11){f=b+-11|0;while(1){b=am(c)|0;e=_l(c)|0;if(!e){b=-1;break a}f=f-e|0;b:do if((b|0)<1347436878){switch(b|0){case 1330662472:break;default:{g=7;break b}}if((Sd(a,f,c,d)|0)<0){b=-1;break a}}else{switch(b|0){case 1347436878:break;default:{g=7;break b}}Td(a,f,c)}while(0);if((g|0)==7){g=0;dm(c,e,1)|0}if((f|0)<=0){b=0;break}}}else b=0;while(0);l=h;return b|0}function Pd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;f=Pl(d)|0;dm(d,8,1)|0;dm(d,c[e>>2]|0?8:4,1)|0;l=e+8|0;i=c[l>>2]|0;if((_a(a,i,1)|0)<0){a=-1;return a|0}b=c[a+176>>2]|0;j=c[b+(i*764|0)+756>>2]|0;k=c[a+180>>2]|0;cm(b+(i*764|0)|0,1,31,d)|0;dm(d,8,1)|0;Pl(d)|0;Pl(d)|0;g=k+(i*52|0)+32|0;c[g>>2]=_l(d)|0;c[k+(i*52|0)+36>>2]=_l(d)|0;h=k+(i*52|0)+40|0;c[h>>2]=_l(d)|0;c[k+(i*52|0)+44>>2]=f<<24>>24<0?2:0;Rl(d)|0;if((c[h>>2]|0)<0)c[h>>2]=0;if((c[g>>2]|0)>0)c[b+(i*764|0)+36>>2]=1;if(!(c[e>>2]|0))b=0;else b=((Nl(d)|0)&255)<<28>>24;c[j>>2]=(((Pl(d)|0)&255)>>>1)+1&255;_l(d)|0;c[j+8>>2]=128;c[j+40>>2]=i;e=j+16|0;Gi((Rl(d)|0)&65535,j+12|0,e);c[e>>2]=(c[e>>2]|0)+b;dm(d,16,1)|0;if((Eb(a,d,4,k+(i*52|0)|0,0)|0)<0){a=-1;return a|0}c[l>>2]=(c[l>>2]|0)+1;a=0;return a|0}function Qd(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;s=l;l=l+16|0;q=s;p=f+4|0;m=c[p>>2]|0;_l(e)|0;cm((c[f+12>>2]|0)+(m<<3)|0,1,c[f>>2]|0?8:4,e)|0;o=(Rl(e)|0)&65535;if(gm(e)|0){t=-1;l=s;return t|0}if((db(b,m,o)|0)<0){t=-1;l=s;return t|0}n=b+136|0;r=b+172|0;k=b+168|0;j=0;do{d=Rl(e)|0;if(gm(e)|0){d=-1;t=56;break}a:do if((d&65535)>2){d=(d&65535)+-2|0;do{g=Pl(e)|0;if((d|0)==1)break a;b=(Pl(e)|0)&255;if((b|0)<(c[n>>2]|0))i=(c[(c[r>>2]|0)+(c[(c[(c[k>>2]|0)+(m<<2)>>2]|0)+4+(b<<2)>>2]<<2)>>2]|0)+4+(j<<3)|0;else i=q;g=g&255;if(!(g&128))d=d+-2|0;else{b=Pl(e)|0;b=b&255;if(!(c[f>>2]|0))b=(b&15)+13+((b>>>4)*12|0)|0;else b=b+36|0;a[i>>0]=b;d=d+-3|0}if(g&64){a[i+1>>0]=((Pl(e)|0)&255)+1;d=d+-1|0}if(g&32){a[i+2>>0]=(((Pl(e)|0)&255)>>>1)+1<<24>>24;d=d+-1|0}if(g&16){g=Pl(e)|0;b=Pl(e)|0;h=d+-2|0;do switch(g<<24>>24){case 1:{b=(b&255)>>>1&15|-96;g=14;d=h;break}case 2:{b=((b&255)>>>1&255)<<4&255;g=10;d=h;break}case 3:{b=(b&255)>>>1&15|-80;g=14;d=h;break}case 4:{b=(b&255)>>>1;g=10;d=h;break}case 11:{b=Rd(b,c[f>>2]|0)|0|16;g=1;d=h;break}case 12:{b=Rd(b,c[f>>2]|0)|0;g=1;d=h;break}case 13:{b=Rd(b,c[f>>2]|0)|0|32;g=2;d=h;break}case 14:{b=Rd(b,c[f>>2]|0)|0;g=2;d=h;break}case 15:{b=(b&255)>>>2;g=3;d=h;break}case 16:{b=0;g=5;d=h;break}case 17:{b=b&15|48;g=14;d=h;break}case 18:{b=(b&255)>>>4;g=5;d=h;break}case 21:{g=c[f>>2]|0?4:-84;d=h;break}case 22:{b=b&15|64;g=14;d=h;break}case 23:{b=(b&255)>>>4;g=6;d=h;break}case 24:{b=b&15;g=6;d=h;break}case 31:{g=7;d=h;break}case 32:{b=b&15|112;g=14;d=h;break}case 41:{b=Pl(e)|0;Pl(e)|0;g=9;d=d+-4|0;break}case 42:{b=b&15|-112;g=14;d=h;break}case 43:{b=b&15|-64;g=14;d=h;break}case 44:{b=b&15|-48;g=14;d=h;break}case 51:{Pl(e)|0;b=(b&255)>>>1;g=11;d=d+-3|0;break}case 52:{g=13;d=h;break}case 53:{b=b&15|96;g=14;d=h;break}case 54:{b=b&15|-32;g=14;d=h;break}case 61:{g=15;d=h;break}case 62:{g=15;d=h;break}case 71:{g=-76;d=h;break}case 72:{b=b&15|80;g=14;d=h;break}case 73:{b=(b&255)<<4&255;g=8;d=h;break}default:{b=0;g=0;d=h}}while(0);a[i+3>>0]=g;a[i+4>>0]=b}}while((d|0)>0)}while(0);j=j+1|0}while((j|0)<(o|0));if((t|0)==56){l=s;return d|0}c[p>>2]=(c[p>>2]|0)+1;t=0;l=s;return t|0}function Rd(a,b){a=a|0;b=b|0;do if(!b)if((a&255)<4){a=a|-16;break}else{a=(a&255)>>>2;break}while(0);return a|0}function Sd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=Rl(d)|0;m=r&65535;if(!(r<<16>>16!=0&(b|0)>0)){r=0;return r|0}p=e+16|0;o=a+156|0;q=a+160|0;r=a+148|0;l=a+152|0;k=2147483647;n=0;a:while(1){j=b+-1|0;b:do switch((Pl(d)|0)<<24>>24){case 0:{b=0;f=19;break a}case 1:{cm((c[p>>2]|0)+(c[o>>2]<<3)|0,1,c[e>>2]|0?8:4,d)|0;b=j-(c[e>>2]|0?8:4)|0;c[o>>2]=(c[o>>2]|0)+1;f=(k|0)==2147483647?n:k;break}case 4:{f=(Rl(d)|0)&65535;b=b+-3|0;if((f|0)<(k|0))f=k;else{c[q>>2]=f-k;f=k}break}case 7:{c[r>>2]=(Pl(d)|0)&255;f=k;b=b+-2|0;break}case 8:{c[l>>2]=(Pl(d)|0)&255;f=k;b=b+-2|0;break}case 12:{Rl(d)|0;Rl(d)|0;Rl(d)|0;f=k;b=b+-7|0;break}case 13:{f=Pl(d)|0;h=Pl(d)|0;i=Pl(d)|0;if((f&255)>63){f=k;b=j}else{g=f&255;f=a+184+(g*12|0)|0;b=b+-4|0;switch(i<<24>>24){case 0:{c[f>>2]=(h^-128)&255;f=k;break b}case 2:{c[f>>2]=128;f=a+184+(g*12|0)+8|0;c[f>>2]=c[f>>2]|16;f=k;break b}case 4:{c[f>>2]=128;f=k;break b}default:{f=k;break b}}}break}case 14:{f=Pl(d)|0;g=Pl(d)|0;if((f&255)>63){f=k;b=j}else{c[a+184+((f&255)*12|0)+4>>2]=((g&255)>>>2)+1;f=k;b=b+-3|0}break}default:{f=18;break a}}while(0);n=n+1|0;if(!((n|0)<(m|0)&(b|0)>0)){b=0;f=19;break}else k=f}if((f|0)==18){r=-1;return r|0}else if((f|0)==19)return b|0;return 0}function Td(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;if((b|0)>0)g=0;else return;do{e=a+184+(g*12|0)|0;h=Pl(d)|0;f=b;b=b+-2|0;switch(h<<24>>24){case 0:{c[e>>2]=((Pl(d)|0)^-128)&255;break}case 2:{c[e>>2]=128;h=a+184+(g*12|0)+8|0;c[h>>2]=c[h>>2]|16;break}case 4:{c[e>>2]=128;break}default:{}}g=g+1|0}while((g|0)<64&(f|0)>2);return}function Ud(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;e=l;l=l+16|0;d=e;f=(cm(d,1,3,b)|0)>>>0>2;if(((f&(a[d>>0]|0)==65?(a[d+1>>0]|0)==77:0)?(a[d+2>>0]|0)==70:0)?((Pl(b)|0)+-10&255)<=4:0){hb(b,c,32);d=0}else d=-1;l=e;return d|0}function Vd(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+1040|0;s=t;n=t+8|0;cm(n,1,3,e)|0;k=Pl(e)|0;f=k&255;cm(n,1,32,e)|0;Ho(b,n,32)|0;c[s>>2]=((k&255)/10|0)&255;c[s+4>>2]=((k&255)%10|0)&255;ob(b,33994,s);s=b+140|0;c[s>>2]=(Pl(e)|0)&255;j=b+156|0;c[j>>2]=(Pl(e)|0)&255;r=b+132|0;c[r>>2]=(Rl(e)|0)&65535;h=Pl(e)|0;q=b+136|0;c[q>>2]=h&255;g=c[s>>2]|0;if(!g){b=-1;l=t;return b|0}i=c[j>>2]|0;if(!i){b=-1;l=t;return b|0}if((h+-1&255)>63|(c[r>>2]|0)==0){b=-1;l=t;return b|0}c[b+144>>2]=g;p=b+128|0;c[p>>2]=i;do if(k<<24>>24!=10){if((k&255)>12){cm(n,1,32,e)|0;c[b+184>>2]=(a[n+31>>0]<<1)+128;c[b+152>>2]=(Pl(e)|0)&255;c[b+148>>2]=(Pl(e)|0)&255;break}if((k&255)>10)cm(n,1,16,e)|0}else cm(n,1,16,e)|0;while(0);c[b+1264>>2]=8363;if((c[j>>2]|0)>0){g=0;do{a[b+952+g>>0]=g;g=g+1|0}while((g|0)<(c[j>>2]|0))}g=c[p>>2]|0;m=Xm(4,g)|0;o=b+168|0;c[o>>2]=m;if(!m){b=-1;l=t;return b|0}a:do if((g|0)>0){g=(k&255)>13;h=0;while(1){if((ab(b,h)|0)<0){g=-1;h=109;break}if(g){m=Rl(e)|0;c[c[(c[o>>2]|0)+(h<<2)>>2]>>2]=m&65535;if((m&65535)>256){g=-1;h=109;break}}else c[c[(c[o>>2]|0)+(h<<2)>>2]>>2]=64;if((c[q>>2]|0)>0){i=0;do{m=(Rl(e)|0)&65535;c[(c[(c[o>>2]|0)+(h<<2)>>2]|0)+4+(i<<2)>>2]=m;i=i+1|0}while((i|0)<(c[q>>2]|0))}h=h+1|0;if((h|0)>=(c[p>>2]|0))break a}if((h|0)==109){l=t;return g|0}}while(0);if((Za(b)|0)<0){b=-1;l=t;return b|0}if((k&255)<11){i=em(e)|0;if((i|0)<0){b=-1;l=t;return b|0}b:do if((c[s>>2]|0)>0){h=0;do{if(((Pl(e)|0)&255)>=2){f=9;break b}dm(e,45,1)|0;if((_l(e)|0)>>>0>1048576){f=9;break b}g=_l(e)|0;if(g>>>0>1048576){f=9;break b}if(!((Rl(e)|0)<<16>>16)){f=9;break b}if(((Pl(e)|0)&255)>64){f=9;break b}if((_l(e)|0)>>>0>g>>>0){f=9;break b}h=h+1|0;if((_l(e)|0)>>>0>g>>>0){f=9;break b}}while((h|0)<(c[s>>2]|0))}while(0);dm(e,i,0)|0}c:do if((c[s>>2]|0)>0){k=b+176|0;m=b+180|0;i=(f|0)<10;j=0;while(1){if((_a(b,j,1)|0)<0){g=-1;break}Pl(e)|0;cm(n,1,32,e)|0;fb(c[k>>2]|0,j,n,32);cm(n,1,13,e)|0;_l(e)|0;g=c[k>>2]|0;c[g+(j*764|0)+36>>2]=1;g=c[g+(j*764|0)+756>>2]|0;c[g+40>>2]=j;c[g+8>>2]=128;g=_l(e)|0;c[(c[m>>2]|0)+(j*52|0)+32>>2]=g;g=(Rl(e)|0)&65535;h=c[(c[k>>2]|0)+(j*764|0)+756>>2]|0;Gi(g,h+12|0,h+16|0);h=(Pl(e)|0)&255;c[c[(c[k>>2]|0)+(j*764|0)+756>>2]>>2]=h;if(i){g=(Rl(e)|0)&65535;h=c[m>>2]|0;c[h+(j*52|0)+36>>2]=g;c[h+(j*52|0)+40>>2]=c[h+(j*52|0)+32>>2];f=0}else{g=_l(e)|0;c[(c[m>>2]|0)+(j*52|0)+36>>2]=g;g=_l(e)|0;h=c[m>>2]|0;c[h+(j*52|0)+40>>2]=g;f=c[h+(j*52|0)+36>>2]|0}c[h+(j*52|0)+44>>2]=(g|0)>(f|0)?2:0;j=j+1|0;if((j|0)>=(c[s>>2]|0))break c}l=t;return g|0}while(0);f=c[r>>2]|0;m=Xm(4,f)|0;if(!m){b=-1;l=t;return b|0}if((f|0)>0){g=0;f=0;do{n=(Rl(e)|0)&65535;c[m+(g<<2)>>2]=n;f=(n|0)>(f|0)?n:f;g=g+1|0}while((g|0)<(c[r>>2]|0))}else f=0;g=c[p>>2]|0;if((g|0)>0){h=c[q>>2]|0;k=0;do{if((h|0)>0){i=c[(c[o>>2]|0)+(k<<2)>>2]|0;j=0;do{h=i+4+(j<<2)|0;g=c[h>>2]|0;if((g|0)>=1?(g|0)<=(c[r>>2]|0):0)g=g+-1|0;else g=0;c[h>>2]=c[m+(g<<2)>>2];j=j+1|0;h=c[q>>2]|0}while((j|0)<(h|0));g=c[p>>2]|0}k=k+1|0}while((k|0)<(g|0))}c[r>>2]=f;Wm(m);q=(c[r>>2]|0)+1|0;c[r>>2]=q;q=Xm(4,q)|0;p=b+172|0;c[p>>2]=q;if(!q){b=-1;l=t;return b|0}if((bb(b,0,64)|0)<0){b=-1;l=t;return b|0}d:do if((c[r>>2]|0)>1){n=1;e:while(1){if((bb(b,n,64)|0)<0){g=-1;h=109;break}k=Wl(e)|0;f:do if((k|0)>0){o=0;do{g=Pl(e)|0;h=Pl(e)|0;i=Pl(e)|0;m=g&255;if((h&g)<<24>>24==-1&i<<24>>24==-1)break f;j=c[(c[p>>2]|0)+(n<<2)>>2]|0;if((m|0)>=(c[j>>2]|0)){g=-1;h=109;break e}f=j+4+(m<<3)|0;g:do if((h&255)<127){if(h<<24>>24)a[f>>0]=(h&255)+1;a[j+4+(m<<3)+2>>0]=i}else{h:do switch(h<<24>>24){case 127:{if(!(g<<24>>24)){g=-1;h=109;break e}m=j+4+(m+-1<<3)|0;i=m;i=d[i>>0]|d[i+1>>0]<<8|d[i+2>>0]<<16|d[i+3>>0]<<24;m=m+4|0;m=d[m>>0]|d[m+1>>0]<<8|d[m+2>>0]<<16|d[m+3>>0]<<24;q=f;j=q;a[j>>0]=i;a[j+1>>0]=i>>8;a[j+2>>0]=i>>16;a[j+3>>0]=i>>24;q=q+4|0;a[q>>0]=m;a[q+1>>0]=m>>8;a[q+2>>0]=m>>16;a[q+3>>0]=m>>24;break g}case -128:{a[j+4+(m<<3)+1>>0]=(i&255)+1;break g}case -127:{g=i;f=15;break}case -126:{f=i&255;if(i<<24>>24>0){g=f<<4&255;f=10;break h}else{g=0-f&15;f=10;break h}}case -125:{a[j+4+(m<<3)+2>>0]=i;g=0;f=0;break}case -124:{if(i<<24>>24>-1){g=i;f=2;break h}if(i<<24>>24==-128){g=0;f=1;break h}g=0-(i&255)&255;f=1;break}case -105:{g=(i<<24>>24<<1)+128&255;f=8;break}case -122:{g=i;f=3;break}case -121:{g=i;f=7;break}case -120:{g=i;f=0;break}case -119:{g=i;f=4;break}case -118:{f=i&255;if(i<<24>>24>0){g=f<<4&255;f=5;break h}else{g=0-f&15;f=5;break h}}case -117:{f=i&255;if(i<<24>>24>0){g=f<<4&255;f=6;break h}else{g=0-f&15;f=6;break h}}case -116:{g=i;f=13;break}case -115:{g=i;f=11;break}case -106:{g=-32;f=i<<24>>24>0?2:1;break}case -113:{g=i&15|-112;f=14;break}case -112:{g=i;f=9;break}case -111:{f=i&15;if(i<<24>>24>0){g=(f|160)&255;f=14;break h}else{g=(f|176)&255;f=14;break h}}case -110:{g=-16;f=i<<24>>24>0?2:1;break}case -109:{g=i&15|-48;f=14;break}case -108:{g=i&15|-64;f=14;break}case -107:{g=(i&255)>33?i:33;f=15;break}default:{g=0;f=0}}while(0);a[j+4+(m<<3)+3>>0]=f;a[j+4+(m<<3)+4>>0]=g}while(0);o=o+1|0}while((o|0)<(k|0))}while(0);n=n+1|0;if((n|0)>=(c[r>>2]|0))break d}if((h|0)==109){l=t;return g|0}}while(0);i:do if((c[s>>2]|0)>0){g=b+180|0;f=0;while(1){if((Eb(b,e,2,(c[g>>2]|0)+(f*52|0)|0,0)|0)<0){g=-1;break}f=f+1|0;if((f|0)>=(c[s>>2]|0))break i}l=t;return g|0}while(0);b=b+1284|0;c[b>>2]=c[b>>2]|32;b=0;l=t;return b|0}function Wd(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1347636734){b=-1;return b|0}hb(a,b,60);b=0;return b|0}function Xd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;t=l;l=l+1296|0;g=t;m=t+264|0;s=t+8|0;am(d)|0;cm(m,1,60,d)|0;Ho(b,m,60)|0;r=Pl(d)|0;f=(Pl(d)|0)&255;Pl(d)|0;if(r&1){e=-1;l=t;return e|0}c[g>>2]=f>>>4;c[g+4>>2]=f&15;ob(b,34027,g);c[b+148>>2]=(Pl(d)|0)&255;c[b+152>>2]=(Pl(d)|0)&255;Pl(d)|0;Rl(d)|0;g=b+156|0;c[g>>2]=(Rl(d)|0)&65535;q=b+128|0;c[q>>2]=(Rl(d)|0)&65535;r=b+140|0;c[r>>2]=(Rl(d)|0)&65535;Rl(d)|0;o=Rl(d)|0;j=o&65535;p=b+136|0;c[p>>2]=j;n=c[r>>2]|0;c[b+144>>2]=n;k=c[q>>2]|0;c[b+132>>2]=O(k,j)|0;if((c[g>>2]|0)>256|(k|0)>256|(n|0)>255|(o&65535)>64){e=-1;l=t;return e|0}n=_l(d)|0;o=_l(d)|0;k=_l(d)|0;f=_l(d)|0;c[b+1264>>2]=8363;dm(d,n+e|0,0)|0;cm(b+952|0,1,c[g>>2]|0,d)|0;dm(d,o+e|0,0)|0;cm(m,1,16,d)|0;if((Za(b)|0)<0){e=-1;l=t;return e|0}dm(d,f+e|0,0)|0;a:do if((c[r>>2]|0)>0){g=m+24|0;i=b+176|0;j=b+180|0;h=0;while(1){if((_a(b,h,1)|0)<0){f=-1;break}cm(m,1,13,d)|0;cm(m,1,24,d)|0;a[g>>0]=0;Ho((c[i>>2]|0)+(h*764|0)|0,m,24)|0;c[s+(h<<2)>>2]=_l(d)|0;_l(d)|0;Rl(d)|0;u=Pl(d)|0;n=_l(d)|0;c[(c[j>>2]|0)+(h*52|0)+32>>2]=n;n=_l(d)|0;c[(c[j>>2]|0)+(h*52|0)+36>>2]=n;n=_l(d)|0;c[(c[j>>2]|0)+(h*52|0)+40>>2]=n;n=((Pl(d)|0)&255)<<28>>24;o=(Pl(d)|0)&255;c[c[(c[i>>2]|0)+(h*764|0)+756>>2]>>2]=o;o=Rl(d)|0;f=c[(c[i>>2]|0)+(h*764|0)+756>>2]|0;c[f+8>>2]=128;c[f+40>>2]=h;u=u&255;c[(c[j>>2]|0)+(h*52|0)+44>>2]=u>>>6&2|u>>>3&4;Gi(o&65535,f+12|0,f+16|0);f=c[i>>2]|0;o=(c[f+(h*764|0)+756>>2]|0)+16|0;c[o>>2]=(c[o>>2]|0)+n;if((c[(c[j>>2]|0)+(h*52|0)+32>>2]|0)>0)c[f+(h*764|0)+36>>2]=1;h=h+1|0;if((h|0)>=(c[r>>2]|0))break a}l=t;return f|0}while(0);if(($a(b)|0)<0){u=-1;l=t;return u|0}dm(d,k+e|0,0)|0;b:do if((c[q>>2]|0)>0){o=b+172|0;n=b+168|0;m=0;c:while(1){f=((Rl(d)|0)&65535)+-4|0;g=Pl(d)|0;k=g&255;if((g&255)>64){f=-1;g=35;break}if(((Pl(d)|0)&255)>32){f=-1;g=35;break}if((db(b,m,k)|0)<0){f=-1;g=35;break}if(g<<24>>24){j=0;do{d:do if((f|0)>0){h=f;while(1){u=Pl(d)|0;f=h+-1|0;i=u&255;if(!(u<<24>>24))break d;g=i&15;if((g|0)>=(c[p>>2]|0)){f=-1;g=35;break c}g=c[(c[o>>2]|0)+(c[(c[(c[n>>2]|0)+(m<<2)>>2]|0)+4+(g<<2)>>2]<<2)>>2]|0;if(i&128){a[g+4+(j<<3)>>0]=((Pl(d)|0)&255)+37;a[g+4+(j<<3)+1>>0]=Pl(d)|0;f=h+-3|0}if(i&64){a[g+4+(j<<3)+2>>0]=((Pl(d)|0)&255)+1;f=f+-1|0}if(i&32){a[g+4+(j<<3)+3>>0]=Pl(d)|0;a[g+4+(j<<3)+4>>0]=Pl(d)|0;f=f+-2|0}if((f|0)>0)h=f;else break}}while(0);j=j+1|0}while((j|0)<(k|0))}if((f|0)>0)dm(d,f,1)|0;m=m+1|0;if((m|0)>=(c[q>>2]|0))break b}if((g|0)==35){l=t;return f|0}}while(0);if((c[r>>2]|0)<=0){u=0;l=t;return u|0}h=b+180|0;g=b+176|0;f=0;while(1){dm(d,(c[s+(f<<2)>>2]|0)+e|0,0)|0;if((Eb(b,d,1,(c[h>>2]|0)+((c[(c[(c[g>>2]|0)+(f*764|0)+756>>2]|0)+40>>2]|0)*52|0)|0,0)|0)<0){f=-1;g=35;break}f=f+1|0;if((f|0)>=(c[r>>2]|0)){f=0;g=35;break}}if((g|0)==35){l=t;return f|0}return 0}function Yd(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)==1398032717?((Ul(a)|0)&65535)<=16:0){hb(a,b,0);a=0}else a=-1;return a|0}function Zd(d,f,g){d=d|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;v=l;l=l+416|0;o=v;s=v+8|0;c[s>>2]=am(f)|0;t=s+4|0;c[t>>2]=am(f)|0;am(f)|0;am(f)|0;n=s+16|0;b[n>>1]=Ul(f)|0;i=s+18|0;b[i>>1]=Ul(f)|0;m=s+20|0;b[m>>1]=Ul(f)|0;cm(s+22|0,128,1,f)|0;if((e[n>>1]|0)>31|(e[i>>1]|0)>128|(e[m>>1]|0)>64){d=-1;l=v;return d|0}else h=0;do{u=(am(f)|0)+12|0;c[s+152+(h<<2)>>2]=u;h=h+1|0;if(u>>>0>1048576){j=-1;k=26;break}}while((h|0)<64);if((k|0)==26){l=v;return j|0}c[d+136>>2]=4;q=b[i>>1]|0;i=d+156|0;c[i>>2]=q&65535;p=e[m>>1]|0;r=d+128|0;c[r>>2]=p;n=e[n>>1]|0;c[d+140>>2]=n;u=d+144|0;c[u>>2]=n;c[d+132>>2]=p<<2;if(q<<16>>16){h=0;do{a[d+952+h>>0]=a[s+22+h>>0]|0;h=h+1|0}while((h|0)<(c[i>>2]|0))}ob(d,34057,o);if(($a(d)|0)<0){d=-1;l=v;return d|0}a:do if((c[r>>2]|0)>0){m=g+8|0;q=d+172|0;p=d+168|0;n=0;while(1){if((db(d,n,64)|0)<0){j=-1;break}dm(f,m+(c[s+152+(n<<2)>>2]|0)|0,0)|0;o=0;do{h=0;do{i=c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(n<<2)>>2]|0)+4+(o<<2)>>2]<<2)>>2]|0;j=i+4+(h<<3)|0;k=(Pl(f)|0)&255;if(!(k&128)){x=Pl(f)|0;w=Pl(f)|0;x=x&255;y=x&63;a[j>>0]=(y|0)==0?0:y+47&255;a[i+4+(h<<3)+1>>0]=k&31;a[i+4+(h<<3)+3>>0]=x>>>4&12|k>>>5;a[i+4+(h<<3)+4>>0]=w;kb(j)}else h=(k&127)+h|0;h=h+1|0}while((h|0)<64);o=o+1|0}while((o|0)!=4);n=n+1|0;if((n|0)>=(c[r>>2]|0))break a}l=v;return j|0}while(0);if((Za(d)|0)<0){y=-1;l=v;return y|0}dm(f,(c[t>>2]|0)+g+(c[u>>2]<<2)|0,0)|0;b:do if((c[u>>2]|0)>0){q=d+180|0;p=d+176|0;o=0;while(1){k=Ul(f)|0;m=Pl(f)|0;n=Pl(f)|0;h=Ul(f)|0;i=Ul(f)|0;if((_a(d,o,1)|0)<0){j=-1;k=26;break}j=c[q>>2]|0;c[j+(o*52|0)+32>>2]=(k&65535)<<1;h=(h&65535)<<1;c[j+(o*52|0)+36>>2]=h;c[j+(o*52|0)+40>>2]=((i&65535)<<1)+h;c[j+(o*52|0)+44>>2]=(i&65535)>1?2:0;h=c[p>>2]|0;y=c[h+(o*764|0)+756>>2]|0;c[y+16>>2]=(m&255)<<28>>24;c[y>>2]=n&255;c[y+8>>2]=128;c[y+40>>2]=o;c[h+(o*764|0)+40>>2]=4095;if(k<<16>>16?(c[h+(o*764|0)+36>>2]=1,(Eb(d,f,0,j+(o*52|0)|0,0)|0)<0):0){j=-1;k=26;break}o=o+1|0;if((o|0)>=(c[u>>2]|0))break b}if((k|0)==26){l=v;return j|0}}while(0);c[d+1292>>2]=1;y=0;l=v;return y|0}function _d(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0;h=b+3|0;do switch(a[h>>0]|0){case 4:{a[h>>0]=-110;return}case 8:{a[b+4>>0]=0;a[h>>0]=0;return}case 9:{e=b+4|0;if(((a[e>>0]|0)+-1&255)<20)e=15;else{a[e>>0]=0;e=0}a[h>>0]=e;return}case 13:{a[h>>0]=10;return}case 14:{a[b+4>>0]=0;a[h>>0]=0;return}case 15:{g=b+4|0;f=a[g>>0]|0;e=f&255;if(!(f<<24>>24)){a[h>>0]=13;return}if((f&255)<241){a[h>>0]=-85;if(c)e=$d(e)|0;a[g>>0]=e;return}switch(f<<24>>24){case -15:{a[h>>0]=14;a[g>>0]=-109;return}case -14:{a[h>>0]=14;a[g>>0]=-45;return}case -13:{a[h>>0]=14;a[g>>0]=-110;return}case -2:case -3:case -5:case -6:case -7:case -8:{a[g>>0]=0;a[h>>0]=0;return}case -1:{a[g>>0]=0;a[h>>0]=0;a[b>>0]=-126;return}default:{a[g>>0]=0;a[h>>0]=0;return}}}case 17:{a[h>>0]=-81;return}case 18:{a[h>>0]=-80;return}case 20:{a[h>>0]=4;return}case 21:{a[h>>0]=-90;h=b+4|0;a[h>>0]=(d[h>>0]<<4)+128;return}case 22:{a[h>>0]=14;f=b+4|0;e=a[f>>0]|0;if((e&255)>15){a[f>>0]=15;e=15}a[f>>0]=e|96;return}case 24:{a[h>>0]=14;f=b+4|0;e=a[f>>0]|0;if((e&255)>15){a[f>>0]=15;e=15}a[f>>0]=e|-64;return}case 25:{a[h>>0]=9;return}case 26:{a[h>>0]=-83;return}case 27:{a[h>>0]=-82;return}case 29:{a[h>>0]=13;return}case 30:{a[h>>0]=-77;return}case 31:{f=b+4|0;e=d[f>>0]|0;if(e&240|0){a[h>>0]=14;a[f>>0]=e>>>4|208;return}e=e&15;if(!e)return;a[h>>0]=14;a[f>>0]=e|144;return}case 46:{f=b+4|0;g=a[f>>0]|0;e=g<<24>>24<<3;b=e+128|0;if((g+-17&255)<=222)return;a[h>>0]=8;a[f>>0]=(b|0)==256?e+127|0:b;return}case 12:case 11:case 10:case 7:case 6:case 5:case 3:case 2:case 1:case 0:return;default:{a[b+4>>0]=0;a[h>>0]=0;return}}while(0)}function $d(a){a=a|0;if((a|0)<=0)return a|0;a=c[2160+(((a|0)<10?a:10)+-1<<2)>>2]|0;return a|0}function ae(a,b,d){a=a|0;b=b|0;d=d|0;var f=0,g=0,h=0,i=0;g=c[a+7584>>2]|0;f=e[d+14>>1]|0;a=Xm(1,f)|0;h=g+4|0;c[(c[h>>2]|0)+(b<<2)>>2]=a;a=c[(c[h>>2]|0)+(b<<2)>>2]|0;if(!a){d=-1;return d|0}ep(a|0,d+22|0,f|0)|0;f=e[d+16>>1]|0;i=Xm(1,f)|0;a=g+8|0;c[(c[a>>2]|0)+(b<<2)>>2]=i;a=c[(c[a>>2]|0)+(b<<2)>>2]|0;if(!a){Wm(c[(c[h>>2]|0)+(b<<2)>>2]|0);i=-1;return i|0}else{ep(a|0,d+150|0,f|0)|0;i=0;return i|0}return 0}function be(f,g,h,i,j,k,l){f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0;o=c[g+176>>2]|0;m=em(f)|0;if((c[g+144>>2]|0)<=(i|0)){q=-1;return q|0}a[j+6>>0]=Pl(f)|0;dm(f,3,1)|0;b[j+10>>1]=Ul(f)|0;b[j+12>>1]=Ul(f)|0;r=j+14|0;b[r>>1]=Ul(f)|0;n=j+16|0;b[n>>1]=Ul(f)|0;p=j+18|0;a[p>>0]=Pl(f)|0;q=j+19|0;a[q>>0]=Pl(f)|0;b[j+20>>1]=Ul(f)|0;cm(j+22|0,1,128,f)|0;cm(j+150|0,1,128,f)|0;if((e[r>>1]|0)>128){r=-1;return r|0}if((e[n>>1]|0)>128){r=-1;return r|0}dm(f,m+-6+(am(f)|0)|0,0)|0;m=am(f)|0;Ul(f)|0;if(wk(o+(h*764|0)|0)|0){r=-1;return r|0}c[o+(h*764|0)+36>>2]=1;if((_a(g,h,1)|0)<0){r=-1;return r|0}r=c[o+(h*764|0)+760>>2]|0;c[r+4>>2]=d[p>>0];c[r+8>>2]=d[q>>0];r=c[o+(h*764|0)+756>>2]|0;c[r+8>>2]=128;c[r>>2]=d[l+6>>0];c[r+12>>2]=(a[l+7>>0]|0)+36;c[r+40>>2]=i;c[r+16>>2]=a[k+3>>0];r=c[g+180>>2]|0;c[r+(i*52|0)+32>>2]=m;p=e[l>>1]<<1;c[r+(i*52|0)+36>>2]=p;q=b[l+2>>1]|0;c[r+(i*52|0)+40>>2]=((q&65535)<<1)+p;c[r+(i*52|0)+44>>2]=(q&65535)>1?2:0;r=(Eb(g,f,0,r+(i*52|0)|0,0)|0)>>31;return r|0}function ce(f,g,h,i,j,k,l){f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;r=g+176|0;s=c[r>>2]|0;w=em(f)|0;a[j+6>>0]=Pl(f)|0;dm(f,3,1)|0;b[j+10>>1]=Ul(f)|0;b[j+12>>1]=Ul(f)|0;o=j+14|0;b[o>>1]=Ul(f)|0;q=j+16|0;b[q>>1]=Ul(f)|0;n=j+18|0;a[n>>0]=Pl(f)|0;p=j+19|0;a[p>>0]=Pl(f)|0;x=j+20|0;b[x>>1]=Ul(f)|0;cm(j+22|0,1,128,f)|0;cm(j+150|0,1,128,f)|0;m=0;do{c[j+280+(m<<2)>>2]=am(f)|0;m=m+1|0}while((m|0)!=64);if((e[o>>1]|0)>128){x=-1;return x|0}if((e[q>>1]|0)>128){x=-1;return x|0}if((e[x>>1]|0)>64){x=-1;return x|0}if(wk((c[r>>2]|0)+(h*764|0)|0)|0){x=-1;return x|0}v=e[x>>1]|0;c[(c[r>>2]|0)+(h*764|0)+36>>2]=v;if((_a(g,h,v)|0)<0){x=-1;return x|0}u=c[s+(h*764|0)+760>>2]|0;c[u+4>>2]=d[n>>0];c[u+8>>2]=d[p>>0];u=s+(h*764|0)+756|0;t=g+144|0;if(!(b[x>>1]|0)){x=0;return x|0}v=g+180|0;s=s+(h*764|0)+36|0;r=l+7|0;q=k+3|0;p=w+-6|0;o=0;while(1){m=c[u>>2]|0;n=c[v>>2]|0;if((o|0)>=(c[s>>2]|0)){m=-1;n=14;break}if((i|0)>=(c[t>>2]|0)){m=-1;n=14;break}c[m+(o<<6)+8>>2]=128;c[m+(o<<6)>>2]=64;c[m+(o<<6)+12>>2]=(a[r>>0]|0)+12;c[m+(o<<6)+40>>2]=i;c[m+(o<<6)+16>>2]=a[q>>0];dm(f,p+(c[j+280+(o<<2)>>2]|0)|0,0)|0;c[n+(i*52|0)+32>>2]=((Ul(f)|0)&65535)<<1;c[n+(i*52|0)+36>>2]=0;c[n+(i*52|0)+40>>2]=c[(c[v>>2]|0)+(i*52|0)+32>>2];c[n+(i*52|0)+44>>2]=2;if((Eb(g,f,0,n+(i*52|0)|0,0)|0)<0){m=-1;n=14;break}o=o+1|0;if((o|0)>=(e[x>>1]|0)){m=0;n=14;break}else i=i+1|0}if((n|0)==14)return m|0;return 0}function de(f,g,h,i,j,k,l,m,n){f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;var o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=c[g+176>>2]|0;if((c[g+144>>2]|0)<=(i|0)){n=-1;return n|0}if(wk(v+(h*764|0)|0)|0){n=-1;return n|0}c[(c[v+(h*764|0)+760>>2]|0)+12>>2]=d[l>>0];c[v+(h*764|0)+40>>2]=d[l+1>>0]<<4^4095;c[v+(h*764|0)+36>>2]=1;if((_a(g,h,1)|0)<0){n=-1;return n|0}o=c[v+(h*764|0)+756>>2]|0;c[o>>2]=d[m+6>>0];c[o+8>>2]=128;q=a[m+7>>0]|0;r=o+12|0;c[r>>2]=q+36;if(((n|0)>1?(e[k+10>>1]|0)>4:0)?(p=a[l+4>>0]|0,p<<24>>24):0)c[r>>2]=q+11+(p&255);c[o+40>>2]=i;c[o+16>>2]=a[l+3>>0]<<4;k=c[g+180>>2]|0;r=c[j>>2]|0;t=k+(i*52|0)+32|0;c[t>>2]=r;s=e[m>>1]|0;p=s<<1;u=k+(i*52|0)+36|0;c[u>>2]=p;o=b[m+2>>1]|0;p=((o&65535)<<1)+p|0;l=k+(i*52|0)+40|0;c[l>>2]=p;q=k+(i*52|0)+44|0;o=(o&65535)>1?2:0;c[q>>2]=o;if(b[j+4>>1]&16){c[q>>2]=o|1;c[t>>2]=r>>1;c[u>>2]=s;c[l>>2]=p>>>1}if((n|0)<3){a[v+(h*764|0)+513>>0]=12;a[v+(h*764|0)+515>>0]=12;a[v+(h*764|0)+517>>0]=12;a[v+(h*764|0)+519>>0]=12;a[v+(h*764|0)+521>>0]=12;a[v+(h*764|0)+523>>0]=12;a[v+(h*764|0)+525>>0]=12;a[v+(h*764|0)+527>>0]=12;a[v+(h*764|0)+529>>0]=12;a[v+(h*764|0)+531>>0]=12;a[v+(h*764|0)+533>>0]=12;a[v+(h*764|0)+535>>0]=12;a[v+(h*764|0)+537>>0]=0;a[v+(h*764|0)+539>>0]=0;a[v+(h*764|0)+541>>0]=0;a[v+(h*764|0)+543>>0]=0;a[v+(h*764|0)+545>>0]=0;a[v+(h*764|0)+547>>0]=0;a[v+(h*764|0)+549>>0]=0;a[v+(h*764|0)+551>>0]=0;a[v+(h*764|0)+553>>0]=0;a[v+(h*764|0)+555>>0]=0;a[v+(h*764|0)+557>>0]=0;a[v+(h*764|0)+559>>0]=0;a[v+(h*764|0)+561>>0]=0;a[v+(h*764|0)+563>>0]=0;a[v+(h*764|0)+565>>0]=0;a[v+(h*764|0)+567>>0]=0;a[v+(h*764|0)+569>>0]=0;a[v+(h*764|0)+571>>0]=0;a[v+(h*764|0)+573>>0]=0;a[v+(h*764|0)+575>>0]=0;a[v+(h*764|0)+577>>0]=0;a[v+(h*764|0)+579>>0]=0;a[v+(h*764|0)+581>>0]=0;a[v+(h*764|0)+583>>0]=0;a[v+(h*764|0)+585>>0]=0;a[v+(h*764|0)+587>>0]=0;a[v+(h*764|0)+589>>0]=0;a[v+(h*764|0)+591>>0]=0;a[v+(h*764|0)+593>>0]=0;a[v+(h*764|0)+595>>0]=0;a[v+(h*764|0)+597>>0]=0;a[v+(h*764|0)+599>>0]=0;a[v+(h*764|0)+601>>0]=0;a[v+(h*764|0)+603>>0]=0;a[v+(h*764|0)+605>>0]=0;a[v+(h*764|0)+607>>0]=0;a[v+(h*764|0)+609>>0]=-12;a[v+(h*764|0)+611>>0]=-12;a[v+(h*764|0)+613>>0]=-12;a[v+(h*764|0)+615>>0]=-12;a[v+(h*764|0)+617>>0]=-12;a[v+(h*764|0)+619>>0]=-12;a[v+(h*764|0)+621>>0]=-12;a[v+(h*764|0)+623>>0]=-12;a[v+(h*764|0)+625>>0]=-12;a[v+(h*764|0)+627>>0]=-12;a[v+(h*764|0)+629>>0]=-12;a[v+(h*764|0)+631>>0]=-12;a[v+(h*764|0)+633>>0]=-24;a[v+(h*764|0)+635>>0]=-24;a[v+(h*764|0)+637>>0]=-24;a[v+(h*764|0)+639>>0]=-24;a[v+(h*764|0)+641>>0]=-24;a[v+(h*764|0)+643>>0]=-24;a[v+(h*764|0)+645>>0]=-24;a[v+(h*764|0)+647>>0]=-24;a[v+(h*764|0)+649>>0]=-24;a[v+(h*764|0)+651>>0]=-24;a[v+(h*764|0)+653>>0]=-24;a[v+(h*764|0)+655>>0]=-24;a[v+(h*764|0)+657>>0]=-36;a[v+(h*764|0)+659>>0]=-36;a[v+(h*764|0)+661>>0]=-36;a[v+(h*764|0)+663>>0]=-36;a[v+(h*764|0)+665>>0]=-36;a[v+(h*764|0)+667>>0]=-36;a[v+(h*764|0)+669>>0]=-36;a[v+(h*764|0)+671>>0]=-36;a[v+(h*764|0)+673>>0]=-36;a[v+(h*764|0)+675>>0]=-36;a[v+(h*764|0)+677>>0]=-36;a[v+(h*764|0)+679>>0]=-36;a[v+(h*764|0)+681>>0]=-48;a[v+(h*764|0)+683>>0]=-48;a[v+(h*764|0)+685>>0]=-48;a[v+(h*764|0)+687>>0]=-48;a[v+(h*764|0)+689>>0]=-48;a[v+(h*764|0)+691>>0]=-48;a[v+(h*764|0)+693>>0]=-48;a[v+(h*764|0)+695>>0]=-48;a[v+(h*764|0)+697>>0]=-48;a[v+(h*764|0)+699>>0]=-48;a[v+(h*764|0)+701>>0]=-48;a[v+(h*764|0)+703>>0]=-48;a[v+(h*764|0)+705>>0]=-60;a[v+(h*764|0)+707>>0]=-60;a[v+(h*764|0)+709>>0]=-60;a[v+(h*764|0)+711>>0]=-60;a[v+(h*764|0)+713>>0]=-60;a[v+(h*764|0)+715>>0]=-60;a[v+(h*764|0)+717>>0]=-60;a[v+(h*764|0)+719>>0]=-60;a[v+(h*764|0)+721>>0]=-60;a[v+(h*764|0)+723>>0]=-60;a[v+(h*764|0)+725>>0]=-60;a[v+(h*764|0)+727>>0]=-60}n=(Eb(g,f,64,k+(i*52|0)|0,0)|0)>>31;return n|0}function ee(f,g,h,i,j,k,l,m){f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;w=c[g+176>>2]|0;x=k+-2|0;if(x>>>0>5){y=-1;return y|0}if((k+i|0)>(c[g+144>>2]|0)){y=-1;return y|0}if(wk(w+(h*764|0)|0)|0){y=-1;return y|0}c[(c[w+(h*764|0)+760>>2]|0)+12>>2]=d[l>>0];c[w+(h*764|0)+40>>2]=d[l+1>>0]<<4^4095;c[w+(h*764|0)+36>>2]=k;if((_a(g,h,k)|0)<0){y=-1;return y|0}s=m+2|0;n=b[s>>1]|0;u=w+(h*764|0)+756|0;v=m+6|0;t=m+7|0;q=l+3|0;r=g+180|0;p=n;l=0;m=e[m>>1]|0;n=n&65535;o=((c[j>>2]|0)>>>0)/(((1<>>0)|0;while(1){j=n<<1;m=m<<1;n=c[u>>2]|0;c[n+(l<<6)>>2]=d[v>>0];c[n+(l<<6)+8>>2]=128;c[n+(l<<6)+12>>2]=(a[t>>0]|0)+24;c[n+(l<<6)+40>>2]=i;c[n+(l<<6)+16>>2]=a[q>>0]<<4;n=c[r>>2]|0;c[n+(i*52|0)+32>>2]=o;c[n+(i*52|0)+36>>2]=m;c[n+(i*52|0)+40>>2]=j+m;c[n+(i*52|0)+44>>2]=(p&65535)>1?2:0;if((Eb(g,f,64,n+(i*52|0)|0,0)|0)<0){l=-1;y=10;break}l=l+1|0;if((l|0)>=(k|0)){l=0;break}p=b[s>>1]|0;n=j;o=o<<1;i=i+1|0}if((y|0)==10)return l|0;do{u=a[34066+(x*9|0)+l>>0]|0;y=l*12|0;v=a[34120+(x*9|0)+l>>0]|0;a[w+(h*764|0)+512+(y<<1)>>0]=u;a[w+(h*764|0)+512+(y<<1)+1>>0]=v;t=y|1;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y|2;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y|3;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+4|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+5|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+6|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+7|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+8|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+9|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;t=y+10|0;a[w+(h*764|0)+512+(t<<1)>>0]=u;a[w+(h*764|0)+512+(t<<1)+1>>0]=v;y=y+11|0;a[w+(h*764|0)+512+(y<<1)>>0]=u;a[w+(h*764|0)+512+(y<<1)+1>>0]=v;l=l+1|0}while((l|0)!=9);l=0;return l|0}function fe(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;if(b|0){c[a+152>>2]=$d(d)|0;return}c[a+152>>2]=d;if(!e)return;h[a+1256>>3]=40.0/+(f|0);return}function ge(b,d){b=b|0;d=d|0;var e=0,f=0;am(b)|0;Ul(b)|0;if((Ul(b)|0)<<16>>16!=1)return;f=am(b)|0;a:do if((f|0)<2147483647){switch(f|0){case 0:break;default:break a}return}else{switch(f|0){case 2147483647:break;default:break a}return}while(0);e=Vm(f+1|0)|0;d=d+1220|0;c[d>>2]=e;if(!e)return;cm(e,1,f,b)|0;a[(c[d>>2]|0)+f>>0]=0;return}function he(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0;e=l;l=l+16|0;d=e;if((cm(d,1,4,a)|0)>>>0<4){b=-1;l=e;return b|0}if(nn(d,34241,4)|0?nn(d,34246,4)|0:0){b=-1;l=e;return b|0}dm(a,28,1)|0;d=am(a)|0;if(!d){hb(a,b,0);b=0;l=e;return b|0}else{dm(a,c+44+d|0,0)|0;f=am(a)|0;d=am(a)|0;dm(a,f+c|0,0)|0;hb(a,b,d);b=0;l=e;return b|0}return 0}function ie(f,g,i){f=f|0;g=g|0;i=i|0;var j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0;V=l;l=l+1504|0;y=V;K=V+656|0;U=V+708|0;S=V+648|0;T=V+112|0;Q=V+88|0;R=V+4|0;cm(K,4,1,g)|0;z=a[K+3>>0]|0;P=(z<<24>>24)+-48|0;c[K+4>>2]=am(g)|0;L=am(g)|0;Ul(g)|0;Ul(g)|0;x=am(g)|0;am(g)|0;I=am(g)|0;am(g)|0;r=am(g)|0;am(g)|0;b[K+40>>1]=Ul(g)|0;b[K+42>>1]=Ul(g)|0;b[K+44>>1]=Ul(g)|0;b[K+46>>1]=Ul(g)|0;b[K+48>>1]=Ul(g)|0;a[K+50>>0]=Pl(g)|0;a[K+51>>0]=Pl(g)|0;if(dm(g,L+i|0,0)|0){U=-1;l=V;return U|0}k=Ul(g)|0;j=0;do{b[U+(j<<3)>>1]=k;b[U+(j<<3)+2>>1]=Ul(g)|0;a[U+(j<<3)+4>>0]=Pl(g)|0;a[U+(j<<3)+5>>0]=Pl(g)|0;a[U+(j<<3)+6>>0]=Pl(g)|0;a[U+(j<<3)+7>>0]=Nl(g)|0;j=j+1|0;k=Ul(g)|0}while((j|0)!=63);p=U+504|0;b[p>>1]=k;L=Ul(g)|0;q=U+506|0;b[q>>1]=L;if((L&65535)>256|(e[p>>1]|0)>255){U=-1;l=V;return U|0}else j=0;do{a[U+508+j>>0]=Pl(g)|0;j=j+1|0}while((j|0)!=256);k=U+764|0;b[k>>1]=Ul(g)|0;H=U+766|0;a[H>>0]=Pl(g)|0;j=U+767|0;a[j>>0]=Pl(g)|0;m=U+768|0;a[m>>0]=Pl(g)|0;n=U+769|0;a[n>>0]=Pl(g)|0;a[U+770>>0]=Pl(g)|0;a[U+771>>0]=Pl(g)|0;a[U+772>>0]=Pl(g)|0;a[U+773>>0]=Pl(g)|0;a[U+774>>0]=Pl(g)|0;a[U+775>>0]=Pl(g)|0;a[U+776>>0]=Pl(g)|0;a[U+777>>0]=Pl(g)|0;a[U+778>>0]=Pl(g)|0;a[U+779>>0]=Pl(g)|0;a[U+780>>0]=Pl(g)|0;a[U+781>>0]=Pl(g)|0;a[U+782>>0]=Pl(g)|0;a[U+783>>0]=Pl(g)|0;a[U+784>>0]=Pl(g)|0;a[U+785>>0]=Pl(g)|0;a[U+786>>0]=Pl(g)|0;L=Pl(g)|0;o=U+787|0;a[o>>0]=L;if((L&255)>63){U=-1;l=V;return U|0}c[f+1264>>2]=8363;G=d[j>>0]|0;F=f+1284|0;c[F>>2]=(G&32|0?0:192)|c[F>>2];G=G&64;F=d[m>>0]|0;h[f+1256>>3]=2.64;fe(f,G,e[k>>1]|0,F&32,(F&31)+1|0);c[f+148>>2]=d[n>>0];F=f+128|0;c[F>>2]=e[p>>1];J=a[o>>0]|0;K=f+140|0;c[K>>2]=J&255;n=e[q>>1]|0;c[f+156>>2]=n;c[f+160>>2]=0;L=f+136|0;c[L>>2]=0;ep(f+952|0,U+508|0,n|0)|0;a[f>>0]=0;n=f+144|0;c[n>>2]=0;a:do if(J<<24>>24){k=I+i|0;m=0;while(1){if(dm(g,k+(m<<2)|0,0)|0){j=-1;N=102;break}j=am(g)|0;if(j|0){if(dm(g,j+i|0,0)|0){j=-1;N=102;break}am(g)|0;j=Ul(g)|0;if(j<<16>>16==-1){dm(g,14,1)|0;j=Ul(g)|0;if((j&65535)>256){j=-1;N=102;break}else j=j&65535}else if((j+-1&65535)<6)j=c[2224+((j<<16>>16)+-1<<2)>>2]|0;else j=1;c[n>>2]=(c[n>>2]|0)+j}m=m+1|0;if((m|0)>=(c[K>>2]|0))break a}if((N|0)==102){l=V;return j|0}}while(0);j=R+8|0;b[j>>1]=0;k=R+10|0;b[k>>1]=0;p=R+24|0;b[p>>1]=0;q=R+26|0;b[q>>1]=0;J=(r|0)!=0;if(J){if(dm(g,r+i|0,0)|0){U=-1;l=V;return U|0}am(g)|0;u=am(g)|0;r=Ul(g)|0;b[j>>1]=r;s=Ul(g)|0;b[k>>1]=s;m=am(g)|0;n=am(g)|0;c[R+16>>2]=n;t=am(g)|0;o=Ul(g)|0;b[p>>1]=o;p=Ul(g)|0;b[q>>1]=p;if((m|u|0)<0){U=-1;l=V;return U|0}if((t|0)<0|n>>>0>65536){U=-1;l=V;return U|0}am(g)|0;am(g)|0;am(g)|0;am(g)|0;E=am(g)|0;j=am(g)|0;c[R+48>>2]=j;dm(g,E+i|0,0)|0;if(j|0){k=0;do{a[f+k>>0]=Pl(g)|0;E=k;k=k+1|0}while(!((E|0)>62|k>>>0>=j>>>0))}if(!((m|0)==0|(n|0)==0)?(E=Vm(n+1|0)|0,v=f+1220|0,c[v>>2]=E,(E|0)!=0):0){dm(g,m+i|0,0)|0;cm(c[v>>2]|0,1,n,g)|0;a[(c[v>>2]|0)+n>>0]=0;E=r;D=u;C=t}else{E=r;D=u;C=t}}else{o=0;p=0;E=0;s=0;D=0;C=0}j=c[F>>2]|0;b:do if((j|0)>0){k=x+i|0;m=z<<24>>24>48;n=0;while(1){if(dm(g,k+(n<<2)|0,0)|0){j=-1;N=102;break}j=am(g)|0;if(j|0){if(dm(g,j+i|0,0)|0){j=-1;N=102;break}if(m){j=Ul(g)|0;Ul(g)|0}else{j=(Pl(g)|0)&255;Pl(g)|0}j=j&65535;if((j|0)>(c[L>>2]|0))c[L>>2]=j}n=n+1|0;j=c[F>>2]|0;if((n|0)>=(j|0)){w=j;break b}}if((N|0)==102){l=V;return j|0}}else w=j;while(0);j=c[L>>2]|0;if((j|0)>64){U=-1;l=V;return U|0}c[f+132>>2]=O(j,w)|0;ob(f,(P|0)==0?((j|0)>4?34191:34209):34223,y);if(($a(f)|0)<0){U=-1;l=V;return U|0}c:do if((c[F>>2]|0)>0){B=x+i|0;x=z<<24>>24>48;z=f+168|0;A=f+172|0;y=0;d:while(1){if(dm(g,B+(y<<2)|0,0)|0){j=-1;N=102;break}j=am(g)|0;e:do if(j|0){if(dm(g,j+i|0,0)|0){j=-1;N=102;break d}if(x){k=Ul(g)|0;j=Ul(g)|0;am(g)|0}else{k=(Pl(g)|0)&255;j=(Pl(g)|0)&255}if((db(f,y,(j&65535)+1|0)|0)<0){j=-1;N=102;break d}m=c[z>>2]|0;j=(c[c[m+(y<<2)>>2]>>2]|0)>0;if(!x){if(!j)break;u=k&65535;t=k<<16>>16==0;j=m;r=0;while(1){if(!t){q=0;do{v=Pl(g)|0;n=Pl(g)|0;m=Pl(g)|0;j=c[(c[A>>2]|0)+(c[(c[(c[z>>2]|0)+(y<<2)>>2]|0)+4+(q<<2)>>2]<<2)>>2]|0;k=j+4+(r<<3)|0;v=v&255;w=v&63;w=(w|0)==0?0:w+12&255;w=(w&255)>120?0:w;a[k>>0]=w;n=n&255;v=n>>>4|v>>>3&16|v>>>1&32;a[j+4+(r<<3)+1>>0]=v;if((v|0)!=0&w<<24>>24==0)a[j+4+(r<<3)+5>>0]=-79;a[j+4+(r<<3)+3>>0]=n&15;a[j+4+(r<<3)+4>>0]=m;_d(k,G);q=q+1|0}while((q|0)!=(u|0));j=c[z>>2]|0}r=r+1|0;if((r|0)>=(c[c[j+(y<<2)>>2]>>2]|0))break e}}if(j){w=k&65535;v=k<<16>>16==0;j=m;u=0;do{if(!v){t=0;do{j=Pl(g)|0;n=Pl(g)|0;q=Pl(g)|0;r=Pl(g)|0;k=c[(c[A>>2]|0)+(c[(c[(c[z>>2]|0)+(y<<2)>>2]|0)+4+(t<<2)>>2]<<2)>>2]|0;m=k+4+(u<<3)|0;j=j&127;a[m>>0]=j;if(!(j<<24>>24))j=0;else{j=(j+12&255)+(d[H>>0]|0)&255;j=(j&255)>120?0:j;a[m>>0]=j}n=n&63;a[k+4+(u<<3)+1>>0]=n;if(n<<24>>24!=0&j<<24>>24==0)a[k+4+(u<<3)+5>>0]=-79;a[k+4+(u<<3)+3>>0]=q;a[k+4+(u<<3)+4>>0]=r;_d(m,G);t=t+1|0}while((t|0)!=(w|0));j=c[z>>2]|0}u=u+1|0}while((u|0)<(c[c[j+(y<<2)>>2]>>2]|0))}}while(0);y=y+1|0;if((y|0)>=(c[F>>2]|0))break c}if((N|0)==102){l=V;return j|0}}while(0);if(Ak(f)|0){U=-1;l=V;return U|0}if((Za(f)|0)<0){U=-1;l=V;return U|0}f:do if((c[K>>2]|0)>0){t=I+i|0;y=S+4|0;A=f+176|0;v=Q+3|0;u=Q+1|0;x=Q+2|0;z=T+20|0;w=0;j=0;g:while(1){if(dm(g,t+(w<<2)|0,0)|0){j=-1;N=102;break}k=am(g)|0;h:do if(k){r=k+i|0;if((dm(g,r,0)|0)<0){j=-1;N=102;break g}c[S>>2]=am(g)|0;n=Ul(g)|0;b[y>>1]=n;q=em(g)|0;if((q|0)<0){j=-1;N=102;break g}do if(J){if((w|0)<(o&65535|0)){m=(O(p&65535,w)|0)+C|0;if((m|0)<0){j=-1;N=102;break g}k=c[A>>2]|0;if((dm(g,m,0)|0)<0){j=-1;N=102;break g}cm(k+(w*764|0)|0,40,1,g)|0}a[v>>0]=0;if((w|0)>=(E&65535|0))break;k=(O(s&65535,w)|0)+D|0;if((k|0)<0){j=-1;N=102;break g}if((dm(g,k,0)|0)<0){j=-1;N=102;break g}a[Q>>0]=Pl(g)|0;a[u>>0]=Pl(g)|0;a[x>>0]=Pl(g)|0;M=Pl(g)|0;N=88}else{M=0;N=88}while(0);if((N|0)==88){N=0;a[v>>0]=M}dm(g,q,0)|0;switch(n<<16>>16){case -2:{if((be(g,f,w,j,T,Q,U+(w<<3)|0)|0)<0){j=-1;N=102;break g}if(!(ae(f,w,T)|0)){j=j+1|0;break h}else{j=-1;N=102;break g}}case -1:{k=ce(g,f,w,j,T,Q,U+(w<<3)|0)|0;if((k|0)>0)break h;if((k|0)<0){j=-1;N=102;break g}j=(e[z>>1]|0)+j|0;if(!(ae(f,w,T)|0))break h;else{j=-1;N=102;break g}}default:{if((n+-1&65535)<6){k=c[2224+((n<<16>>16)+-1<<2)>>2]|0;dm(g,r+6|0,0)|0;if((ee(g,f,w,j,S,k,Q,U+(w<<3)|0)|0)<0){j=-1;N=102;break g}else{j=k+j|0;break h}}if(n<<16>>16){j=-1;N=102;break g}dm(g,r+6|0,0)|0;if((de(g,f,w,j,S,R,Q,U+(w<<3)|0,P)|0)<0){j=-1;N=102;break g}else{j=j+1|0;break h}}}}while(0);w=w+1|0;if((w|0)>=(c[K>>2]|0))break f}if((N|0)==102){l=V;return j|0}}while(0);if((c[L>>2]|0)>0){j=f+1300|0;k=0;do{c[f+184+(k*12|0)+4>>2]=d[U+770+k>>0];T=k;k=k+1|0;c[f+184+(T*12|0)>>2]=((O(c[j>>2]|0,((((k|0)/2|0|0)%2|0)*255|0)+-128|0)|0)/100|0)+128}while((k|0)<(c[L>>2]|0))}c[f+1288>>2]=4;U=0;l=V;return U|0}function je(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0;e=l;l=l+16|0;d=e;if((cm(d,1,4,a)|0)>>>0<4){b=-1;l=e;return b|0}if(nn(d,34301,4)|0?nn(d,34306,4)|0:0){b=-1;l=e;return b|0}dm(a,28,1)|0;d=am(a)|0;if(!d){hb(a,b,0);b=0;l=e;return b|0}else{dm(a,c+44+d|0,0)|0;f=am(a)|0;d=am(a)|0;dm(a,f+c|0,0)|0;hb(a,b,d);b=0;l=e;return b|0}return 0}function ke(f,g,i){f=f|0;g=g|0;i=i|0;var j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0;V=l;l=l+1504|0;y=V+8|0;x=V;k=V+1452|0;S=V+664|0;R=V+656|0;T=V+120|0;P=V+96|0;Q=V+12|0;cm(k,4,1,g)|0;j=a[k+3>>0]|0;c[k+4>>2]=am(g)|0;m=am(g)|0;Ul(g)|0;Ul(g)|0;w=am(g)|0;am(g)|0;I=am(g)|0;am(g)|0;s=am(g)|0;am(g)|0;b[k+40>>1]=Ul(g)|0;b[k+42>>1]=Ul(g)|0;b[k+44>>1]=Ul(g)|0;b[k+46>>1]=Ul(g)|0;b[k+48>>1]=Ul(g)|0;a[k+50>>0]=Pl(g)|0;a[k+51>>0]=Pl(g)|0;dm(g,m+i|0,0)|0;m=Ul(g)|0;k=0;do{b[S+(k<<3)>>1]=m;b[S+(k<<3)+2>>1]=Ul(g)|0;a[S+(k<<3)+4>>0]=Pl(g)|0;a[S+(k<<3)+5>>0]=Pl(g)|0;a[S+(k<<3)+6>>0]=Pl(g)|0;a[S+(k<<3)+7>>0]=Nl(g)|0;k=k+1|0;m=Ul(g)|0}while((k|0)!=63);v=j<<24>>24;M=v+-48|0;r=S+504|0;b[r>>1]=m;b[S+506>>1]=Ul(g)|0;j=am(g)|0;am(g)|0;N=am(g)|0;b[S+520>>1]=Ul(g)|0;b[S+522>>1]=Ul(g)|0;U=am(g)|0;c[S+528>>2]=am(g)|0;b[S+532>>1]=Ul(g)|0;b[S+534>>1]=Ul(g)|0;a[S+536>>0]=Pl(g)|0;a[S+537>>0]=Pl(g)|0;b[S+538>>1]=Ul(g)|0;a[S+540>>0]=Pl(g)|0;dm(g,223,1)|0;n=S+764|0;b[n>>1]=Ul(g)|0;H=S+766|0;a[H>>0]=Pl(g)|0;m=S+767|0;a[m>>0]=Pl(g)|0;o=S+768|0;a[o>>0]=Pl(g)|0;p=S+769|0;a[p>>0]=Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;Pl(g)|0;a[S+786>>0]=Pl(g)|0;L=Pl(g)|0;q=S+787|0;a[q>>0]=L;if((L&255)>63){f=-1;l=V;return f|0}dm(g,j+i|0,0)|0;dm(g,(am(g)|0)+i|0,0)|0;dm(g,32,1)|0;am(g)|0;am(g)|0;j=Ul(g)|0;k=f+156|0;c[k>>2]=j&65535;if((j&65535)>255){f=-1;l=V;return f|0}if(j<<16>>16){j=0;do{a[f+952+j>>0]=Ul(g)|0;j=j+1|0}while((j|0)<(c[k>>2]|0))}c[f+1264>>2]=8363;F=d[m>>0]|0;C=f+1284|0;c[C>>2]=(F&32|0?0:192)|c[C>>2];F=F&64;C=d[o>>0]|0;h[f+1256>>3]=2.64;fe(f,F,e[n>>1]|0,C&32,(C&31)+1|0);c[f+148>>2]=d[p>>0];C=f+128|0;c[C>>2]=e[r>>1];J=a[q>>0]|0;K=f+140|0;c[K>>2]=J&255;c[f+160>>2]=0;L=f+136|0;c[L>>2]=0;a[f>>0]=0;n=f+144|0;c[n>>2]=0;if(J<<24>>24){k=I+i|0;m=0;do{dm(g,k+(m<<2)|0,0)|0;j=am(g)|0;if(j|0){dm(g,j+i|0,0)|0;am(g)|0;if((Ul(g)|0)<<16>>16==-1){dm(g,14,1)|0;j=(Ul(g)|0)&65535}else j=1;c[n>>2]=(c[n>>2]|0)+j}m=m+1|0}while((m|0)<(c[K>>2]|0))}j=Q+8|0;b[j>>1]=0;k=Q+10|0;b[k>>1]=0;m=Q+24|0;b[m>>1]=0;n=Q+26|0;b[n>>1]=0;J=(s|0)!=0;if(J){dm(g,s+i|0,0)|0;am(g)|0;t=am(g)|0;q=Ul(g)|0;b[j>>1]=q;r=Ul(g)|0;b[k>>1]=r;am(g)|0;am(g)|0;s=am(g)|0;o=Ul(g)|0;b[m>>1]=o;p=Ul(g)|0;b[n>>1]=p;if((s|t|0)<0){f=-1;l=V;return f|0}am(g)|0;am(g)|0;am(g)|0;am(g)|0;j=am(g)|0;k=am(g)|0;c[Q+48>>2]=k;am(g)|0;m=am(g)|0;if(gm(g)|0){f=-1;l=V;return f|0}dm(g,j+i|0,0)|0;if(k|0){j=0;do{a[f+j>>0]=Pl(g)|0;G=j;j=j+1|0}while(!((G|0)>62|j>>>0>=k>>>0))}if(!m){G=q;E=r;D=t}else{dm(g,m+i|0,0)|0;ge(g,f);G=q;E=r;D=t}}else{o=0;p=0;G=0;E=0;D=0;s=0}j=c[C>>2]|0;if((j|0)>0){k=w+i|0;m=0;do{dm(g,k+(m<<2)|0,0)|0;j=am(g)|0;if(j|0?(dm(g,j+i|0,0)|0,u=Ul(g)|0,Ul(g)|0,u=u&65535,(u|0)>(c[L>>2]|0)):0)c[L>>2]=u;m=m+1|0;j=c[C>>2]|0}while((m|0)<(j|0))}k=c[L>>2]|0;if((k+-1|0)>>>0>63){f=-1;l=V;return f|0}c[f+132>>2]=O(k,j)|0;j=(M|0)==2;if(j)ob(f,34259,x);else{c[y>>2]=v;ob(f,34275,y)}if(($a(f)|0)<0){f=-1;l=V;return f|0}a:do if((c[C>>2]|0)>0){z=w+i|0;A=f+168|0;B=f+172|0;y=j?12:244;x=0;while(1){dm(g,z+(x<<2)|0,0)|0;j=am(g)|0;if(j|0){dm(g,j+i|0,0)|0;j=Ul(g)|0;w=Ul(g)|0;am(g)|0;if((db(f,x,(w&65535)+1|0)|0)<0){j=-1;break}k=c[A>>2]|0;if((c[c[k+(x<<2)>>2]>>2]|0)>0){w=j&65535;v=j<<16>>16==0;u=0;do{if(!v){t=0;do{j=Pl(g)|0;n=Pl(g)|0;q=Pl(g)|0;r=Pl(g)|0;k=c[(c[B>>2]|0)+(c[(c[(c[A>>2]|0)+(x<<2)>>2]|0)+4+(t<<2)>>2]<<2)>>2]|0;m=k+4+(u<<3)|0;j=j&127;a[m>>0]=j;if(!(j<<24>>24))j=0;else{j=(j&255)+y+(d[H>>0]|0)&255;j=(j&255)>120?0:j;a[m>>0]=j}n=n&63;a[k+4+(u<<3)+1>>0]=n;if(n<<24>>24!=0&j<<24>>24==0)a[k+4+(u<<3)+5>>0]=-79;a[k+4+(u<<3)+3>>0]=q;a[k+4+(u<<3)+4>>0]=r;_d(m,F);t=t+1|0}while((t|0)!=(w|0));k=c[A>>2]|0}u=u+1|0}while((u|0)<(c[c[k+(x<<2)>>2]>>2]|0))}}x=x+1|0;if((x|0)>=(c[C>>2]|0))break a}l=V;return j|0}while(0);if(Ak(f)|0){f=-1;l=V;return f|0}if((Za(f)|0)<0){f=-1;l=V;return f|0}b:do if((c[K>>2]|0)>0){t=I+i|0;A=R+4|0;C=f+176|0;u=P+1|0;z=P+2|0;w=P+3|0;v=P+4|0;y=P+5|0;B=T+20|0;x=0;j=0;c:while(1){dm(g,t+(x<<2)|0,0)|0;k=am(g)|0;d:do if(k){r=k+i|0;dm(g,r,0)|0;c[R>>2]=am(g)|0;q=Ul(g)|0;b[A>>1]=q;n=em(g)|0;if((n|0)<0){j=-1;k=85;break c}do if(J){if((x|0)<(o&65535|0)){m=(O(p&65535,x)|0)+s|0;if((m|0)<0){j=-1;k=85;break c}k=c[C>>2]|0;if((dm(g,m,0)|0)<0){j=-1;k=85;break c}cm(k+(x*764|0)|0,40,1,g)|0};c[P>>2]=0;c[P+4>>2]=0;c[P+8>>2]=0;c[P+12>>2]=0;c[P+16>>2]=0;if((x|0)>=(G&65535|0))break;k=(O(E&65535,x)|0)+D|0;if((k|0)<0){j=-1;k=85;break c}if((dm(g,k,0)|0)<0){j=-1;k=85;break c}a[P>>0]=Pl(g)|0;a[u>>0]=Pl(g)|0;a[z>>0]=Pl(g)|0;a[w>>0]=Pl(g)|0;if((E&65535)<=4)break;a[v>>0]=Pl(g)|0;a[y>>0]=Pl(g)|0}else{c[P>>2]=0;c[P+4>>2]=0;c[P+8>>2]=0;c[P+12>>2]=0;c[P+16>>2]=0}while(0);dm(g,n,0)|0;k=q<<16>>16;switch(q<<16>>16){case -2:{if((be(g,f,x,j,T,P,S+(x<<3)|0)|0)<0){j=-1;k=85;break c}if(!(ae(f,x,T)|0)){j=j+1|0;break d}else{j=-1;k=85;break c}}case -1:{k=ce(g,f,x,j,T,P,S+(x<<3)|0)|0;if((k|0)>0)break d;if((k|0)<0){j=-1;k=85;break c}j=(e[B>>1]|0)+j|0;if(!(ae(f,x,T)|0))break d;else{j=-1;k=85;break c}}default:{if((q+-1&65535)<6){k=c[2224+(k+-1<<2)>>2]|0;dm(g,r+6|0,0)|0;if((ee(g,f,x,j,R,k,P,S+(x<<3)|0)|0)<0){j=-1;k=85;break c}else{j=k+j|0;break d}}if(k&-49|0){c[(c[C>>2]|0)+(x*764|0)+36>>2]=0;break d}if(k&-17|0){j=-1;k=85;break c}dm(g,r+6|0,0)|0;if((de(g,f,x,j,R,Q,P,S+(x<<3)|0,M)|0)<0){j=-1;k=85;break c}else{j=j+1|0;break d}}}}while(0);x=x+1|0;if((x|0)>=(c[K>>2]|0))break b}if((k|0)==85){l=V;return j|0}}while(0);dm(g,N+i|0,0)|0;j=c[L>>2]|0;if((j|0)>0){k=0;do{c[f+184+(k*12|0)+4>>2]=(Pl(g)|0)&255;k=k+1|0;j=c[L>>2]|0}while((k|0)<(j|0))}if(!U){if((j|0)>0){j=0;do{c[f+184+(j*12|0)>>2]=128;j=j+1|0}while((j|0)<(c[L>>2]|0))}}else{dm(g,U+i|0,0)|0;if((c[L>>2]|0)>0){j=0;do{i=(Nl(g)|0)<<24>>24<<3;c[f+184+(j*12|0)>>2]=((i|0)<127?i:127)+128;j=j+1|0}while((j|0)<(c[L>>2]|0))}}c[f+1288>>2]=4;f=0;l=V;return f|0}function le(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+16|0;c=d;if(((cm(c,1,4,a)|0)>>>0>=4?(nn(c,34324,4)|0)==0:0)?(Pl(a)|0)<<24>>24==32:0){hb(a,b,32);c=0}else c=-1;l=d;return c|0}function me(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,ab=0,bb=0,cb=0,hb=0,ib=0,jb=0,kb=0;jb=l;l=l+608|0;o=jb;bb=jb+500|0;u=jb+368|0;cb=jb+12|0;n=jb+575|0;i=jb+542|0;if((ne(g,bb,34324)|0)<0){ib=-1;l=jb;return ib|0}x=b[bb+38>>1]|0;m=x&65535;cm(n,1,20,g)|0;a[n+20>>0]=0;cm(i,1,32,g)|0;a[i+32>>0]=0;p=u+52|0;b[p>>1]=Rl(g)|0;w=u+54|0;a[w>>0]=Pl(g)|0;q=u+55|0;a[q>>0]=Pl(g)|0;k=u+56|0;b[k>>1]=Rl(g)|0;j=u+58|0;b[j>>1]=Rl(g)|0;r=u+60|0;a[r>>0]=Pl(g)|0;s=u+61|0;a[s>>0]=Pl(g)|0;cm(u+62|0,32,1,g)|0;t=u+96|0;c[t>>2]=_l(g)|0;i=b[k>>1]|0;if((d[w>>0]|0)>32?1:((b[j>>1]|i)&65535)>255){ib=-1;l=jb;return ib|0}ab=(x&65535)>273;if(ab){dm(g,32,1)|0;i=b[k>>1]|0}a:do if(i<<16>>16){i=0;while(1){Ya=Rl(g)|0;a[f+952+i>>0]=Ya;i=i+1|0;if((Ya&255)>=(e[j>>1]|0)){i=-1;break}if((i|0)>=(e[k>>1]|0))break a}l=jb;return i|0}while(0);Ya=bb+5|0;Ho(f,Ya,20)|0;c[o>>2]=n;c[o+4>>2]=m>>>8;c[o+8>>2]=m&255;io(f+64|0,64,34329,o);c[f+156>>2]=e[k>>1];Xa=e[j>>1]|0;v=f+128|0;c[v>>2]=Xa;Wa=a[w>>0]|0;Va=Wa&255;j=f+136|0;c[j>>2]=Va;c[f+132>>2]=O(Va,Xa)|0;Xa=f+140|0;c[Xa>>2]=d[q>>0];c[f+148>>2]=d[r>>0];c[f+152>>2]=d[s>>0];c[f+1264>>2]=8363;c[f+1292>>2]=b[p>>1]<<1&2;if(Wa<<24>>24){i=0;do{c[f+184+(i*12|0)>>2]=d[u+62+i>>0];i=i+1|0}while((i|0)<(c[j>>2]|0))}if(($a(f)|0)<0){ib=-1;l=jb;return ib|0}Wa=bb+40|0;i=(e[Wa>>1]|0)+42+(c[t>>2]|0)|0;Va=(c[v>>2]|0)>0;dm(g,i+h|0,0)|0;b:do if(Va){u=f+172|0;t=f+168|0;s=0;c:while(1){if((ne(g,bb,34344)|0)<0){i=-1;j=72;break}Rl(g)|0;p=Pl(g)|0;j=Rl(g)|0;k=_l(g)|0;q=p&255;if((p&255)>(d[w>>0]|0)){i=-1;j=72;break}r=j&65535;if((j&65535)>256){i=-1;j=72;break}i=i+42+k+(e[Wa>>1]|0)|0;if((db(f,s,r)|0)<0){i=-1;j=72;break}if(j<<16>>16){o=0;do{j=Pl(g)|0;if(j<<24>>24){n=j&255;j=0;while(1){if((j|0)>=(q|0)){i=-1;j=72;break c}if(!(n&1)){k=(c[u>>2]|0)+(c[(c[(c[t>>2]|0)+(s<<2)>>2]|0)+4+(j<<2)>>2]<<2)|0;m=j}else{Va=Pl(g)|0;j=Va&255;if((Va&255)>=(p&255)){i=-1;j=72;break c}k=(c[u>>2]|0)+(c[(c[(c[t>>2]|0)+(s<<2)>>2]|0)+4+(j<<2)>>2]<<2)|0;m=j}j=c[k>>2]|0;if(n&2|0){Va=(Pl(g)|0)&255;a[j+4+(o<<3)>>0]=(Va+1&255|0)==255?-127:Va+13&255}if(n&4|0)a[j+4+(o<<3)+1>>0]=Pl(g)|0;if(n&8|0)a[j+4+(o<<3)+3>>0]=Pl(g)|0;if(n&16|0)a[j+4+(o<<3)+4>>0]=Pl(g)|0;if(n&32|0)a[j+4+(o<<3)+5>>0]=Pl(g)|0;if(n&64|0)a[j+4+(o<<3)+6>>0]=Pl(g)|0;j=Pl(g)|0;if(!(j<<24>>24))break;else{n=j&255;j=m+1|0}}}o=o+1|0}while((o|0)<(r|0))}s=s+1|0;Va=(s|0)<(c[v>>2]|0);dm(g,i+h|0,0)|0;if(!Va)break b}if((j|0)==72){l=jb;return i|0}}while(0);Va=f+144|0;c[Va>>2]=1024;if((Za(f)|0)<0){ib=-1;l=jb;return ib|0}d:do if((c[Xa>>2]|0)>0){Ua=f+176|0;Ea=cb+2|0;Da=cb+4|0;La=cb+124|0;Na=cb+224|0;Ja=cb+225|0;Ha=cb+226|0;Fa=cb+228|0;Ma=cb+232|0;Oa=cb+332|0;Ka=cb+333|0;Ia=cb+334|0;Ga=cb+336|0;Qa=cb+340|0;Sa=cb+341|0;Pa=cb+342|0;Ra=cb+343|0;Ta=cb+344|0;x=(x&65535)>271;D=cb+346|0;B=cb+347|0;E=cb+348|0;C=cb+349|0;F=cb+350|0;A=cb+351|0;z=cb+352|0;G=cb+353|0;ea=f+180|0;H=cb+128|0;fa=cb+132|0;I=cb+136|0;ga=cb+140|0;L=cb+144|0;ja=cb+148|0;M=cb+152|0;ka=cb+156|0;N=cb+160|0;la=cb+164|0;P=cb+168|0;ma=cb+172|0;Q=cb+176|0;na=cb+180|0;R=cb+184|0;oa=cb+188|0;S=cb+192|0;pa=cb+196|0;T=cb+200|0;qa=cb+204|0;J=cb+208|0;ha=cb+212|0;K=cb+216|0;ia=cb+220|0;U=cb+236|0;ra=cb+240|0;V=cb+244|0;sa=cb+248|0;Y=cb+252|0;va=cb+256|0;Z=cb+260|0;wa=cb+264|0;_=cb+268|0;xa=cb+272|0;$=cb+276|0;ya=cb+280|0;aa=cb+284|0;za=cb+288|0;ba=cb+292|0;Aa=cb+296|0;ca=cb+300|0;Ba=cb+304|0;da=cb+308|0;Ca=cb+312|0;W=cb+316|0;ta=cb+320|0;X=cb+324|0;ua=cb+328|0;y=0;i=0;e:while(1){n=c[Ua>>2]|0;if((ne(g,bb,34349)|0)<0){i=-1;j=72;break}fb(c[Ua>>2]|0,y,Ya,32);do if(!(b[Wa>>1]|0))a[cb>>0]=0;else{a[cb>>0]=Pl(g)|0;b[Ea>>1]=Rl(g)|0;if((cm(Da,1,120,g)|0)!=120){i=-1;j=72;break e}h=Pl(g)|0;a[La>>0]=h;if((h&255)>11){i=-1;j=72;break e}c[H>>2]=_l(g)|0;c[fa>>2]=_l(g)|0;c[I>>2]=_l(g)|0;c[ga>>2]=_l(g)|0;c[L>>2]=_l(g)|0;c[ja>>2]=_l(g)|0;c[M>>2]=_l(g)|0;c[ka>>2]=_l(g)|0;c[N>>2]=_l(g)|0;c[la>>2]=_l(g)|0;c[P>>2]=_l(g)|0;c[ma>>2]=_l(g)|0;c[Q>>2]=_l(g)|0;c[na>>2]=_l(g)|0;c[R>>2]=_l(g)|0;c[oa>>2]=_l(g)|0;c[S>>2]=_l(g)|0;c[pa>>2]=_l(g)|0;c[T>>2]=_l(g)|0;c[qa>>2]=_l(g)|0;c[J>>2]=_l(g)|0;c[ha>>2]=_l(g)|0;c[K>>2]=_l(g)|0;c[ia>>2]=_l(g)|0;a[Na>>0]=Pl(g)|0;a[Ja>>0]=Pl(g)|0;a[Ha>>0]=Pl(g)|0;b[Fa>>1]=Rl(g)|0;h=Pl(g)|0;a[Ma>>0]=h;if((h&255)>11){i=-1;j=72;break e}c[U>>2]=_l(g)|0;c[ra>>2]=_l(g)|0;c[V>>2]=_l(g)|0;c[sa>>2]=_l(g)|0;c[Y>>2]=_l(g)|0;c[va>>2]=_l(g)|0;c[Z>>2]=_l(g)|0;c[wa>>2]=_l(g)|0;c[_>>2]=_l(g)|0;c[xa>>2]=_l(g)|0;c[$>>2]=_l(g)|0;c[ya>>2]=_l(g)|0;c[aa>>2]=_l(g)|0;c[za>>2]=_l(g)|0;c[ba>>2]=_l(g)|0;c[Aa>>2]=_l(g)|0;c[ca>>2]=_l(g)|0;c[Ba>>2]=_l(g)|0;c[da>>2]=_l(g)|0;c[Ca>>2]=_l(g)|0;c[W>>2]=_l(g)|0;c[ta>>2]=_l(g)|0;c[X>>2]=_l(g)|0;c[ua>>2]=_l(g)|0;a[Oa>>0]=Pl(g)|0;a[Ka>>0]=Pl(g)|0;a[Ia>>0]=Pl(g)|0;b[Ga>>1]=Rl(g)|0;a[Qa>>0]=Pl(g)|0;a[Sa>>0]=Pl(g)|0;a[Pa>>0]=Pl(g)|0;a[Ra>>0]=Pl(g)|0;b[Ta>>1]=Rl(g)|0;if(x){a[D>>0]=Pl(g)|0;a[B>>0]=Pl(g)|0;a[E>>0]=Pl(g)|0;a[C>>0]=Pl(g)|0}if(ab){a[F>>0]=Pl(g)|0;a[A>>0]=Pl(g)|0;a[z>>0]=Pl(g)|0;a[G>>0]=Pl(g)|0}w=a[cb>>0]|0;h=n+(y*764|0)+36|0;w=((w&255)<16?w:16)&255;c[h>>2]=w;if((_a(f,y,w)|0)<0){i=-1;j=72;break e}else j=0;do{a[n+(y*764|0)+512+(j<<1)>>0]=a[cb+4+j>>0]|0;j=j+1|0}while((j|0)!=120);c[n+(y*764|0)+40>>2]=e[Ta>>1];w=a[La>>0]|0;k=n+(y*764|0)+48|0;c[k>>2]=w&255;c[n+(y*764|0)+56>>2]=d[Na>>0];c[n+(y*764|0)+64>>2]=d[Ja>>0];c[n+(y*764|0)+68>>2]=d[Ha>>0];c[n+(y*764|0)+44>>2]=e[Fa>>1];j=d[Ma>>0]|0;m=n+(y*764|0)+204|0;c[m>>2]=j;c[n+(y*764|0)+212>>2]=d[Oa>>0];c[n+(y*764|0)+220>>2]=d[Ka>>0];c[n+(y*764|0)+224>>2]=d[Ia>>0];c[n+(y*764|0)+200>>2]=e[Ga>>1];if(w<<24>>24){j=0;do{w=j<<1;b[n+(y*764|0)+72+(w<<1)>>1]=c[cb+128+(j<<3)>>2];b[n+(y*764|0)+72+((w|1)<<1)>>1]=(c[cb+128+(j<<3)+4>>2]|0)/2|0;j=j+1|0}while((j|0)<(c[k>>2]|0));j=c[m>>2]|0}if((j|0)>0){j=0;do{w=j<<1;b[n+(y*764|0)+228+(w<<1)>>1]=c[cb+236+(j<<3)>>2];b[n+(y*764|0)+228+((w|1)<<1)>>1]=((c[cb+236+(j<<3)+4>>2]|0)/2|0)+32;j=j+1|0}while((j|0)<(c[m>>2]|0))}if((c[h>>2]|0)<=0)break;w=n+(y*764|0)+756|0;v=0;do{j=c[w>>2]|0;if((ne(g,bb,34354)|0)<0){i=-1;j=72;break e}q=Rl(g)|0;p=Pl(g)|0;o=Pl(g)|0;r=_l(g)|0;u=_l(g)|0;s=_l(g)|0;t=_l(g)|0;kb=_l(g)|0;m=Pl(g)|0;k=Pl(g)|0;n=j+(v<<6)+12|0;Gi(kb,n,j+(v<<6)+16|0);c[n>>2]=48-(m&255)+(c[n>>2]|0);c[j+(v<<6)>>2]=(O(o&255,p&255)|0)>>>6;c[j+(v<<6)+8>>2]=(k<<24>>24<<1)+128;c[j+(v<<6)+20>>2]=a[Qa>>0];c[j+(v<<6)+24>>2]=a[Pa>>0]<<2;c[j+(v<<6)+28>>2]=a[Ra>>0];c[j+(v<<6)+32>>2]=a[Sa>>0];c[j+(v<<6)+40>>2]=i;k=c[Va>>2]|0;j=c[ea>>2]|0;if((i|0)>=(k|0)){j=eb(j,Va,(k*3|0)/2|0)|0;c[ea>>2]=j;if(!j){i=-1;j=72;break e}}p=j+(i*52|0)|0;gb(p,Ya,31)|0;m=j+(i*52|0)+32|0;c[m>>2]=r;o=j+(i*52|0)+36|0;c[o>>2]=s;n=j+(i*52|0)+40|0;c[n>>2]=t;k=j+(i*52|0)+44|0;c[k>>2]=0;if(!(q&2))j=0;else{c[k>>2]=1;c[m>>2]=r>>1;c[o>>2]=s>>1;c[n>>2]=t>>1;j=1}c[k>>2]=((u&255|0)==2?4:0)|(u&3|0?2:0)|j;if((Eb(f,g,1,p,0)|0)<0){i=-1;j=72;break e}v=v+1|0;i=i+1|0}while((v|0)<(c[h>>2]|0))}while(0);y=y+1|0;if((y|0)>=(c[Xa>>2]|0)){hb=i;ib=ea;break d}}if((j|0)==72){l=jb;return i|0}}else{hb=0;ib=f+180|0}while(0);kb=eb(c[ib>>2]|0,Va,hb)|0;c[ib>>2]=kb;if(!kb){kb=-1;l=jb;return kb|0}kb=f+1284|0;c[kb>>2]=c[kb>>2]|33554464;c[f+1288>>2]=1;kb=0;l=jb;return kb|0}function ne(c,d,e){c=c|0;d=d|0;e=e|0;cm(d,4,1,c)|0;if(nn(e,d,4)|0){e=-1;return e|0}e=Pl(c)|0;a[d+4>>0]=e;if(e<<24>>24!=32){e=-1;return e|0}if((cm(d+5|0,1,32,c)|0)!=32){e=-1;return e|0}a[d+37>>0]=Pl(c)|0;b[d+38>>1]=Rl(c)|0;b[d+40>>1]=Rl(c)|0;e=0;return e|0}function oe(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1143886894){b=-1;return b|0}am(a)|0;Ul(a)|0;Ul(a)|0;Ul(a)|0;Ul(a)|0;Ul(a)|0;am(a)|0;hb(a,b,32);b=0;return b|0}function pe(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=l;l=l+32|0;e=f;c[e>>2]=0;c[e+4>>2]=0;c[e+8>>2]=0;c[e+12>>2]=0;c[e+16>>2]=0;d=pb()|0;if(!d){a=-1;l=f;return a|0}c[a+1264>>2]=8363;g=tb(d,34375,34)|0;g=tb(d,34380,35)|0|g;g=g|(tb(d,35016,36)|0);g=g|(tb(d,35021,37)|0);g=g|(tb(d,34385,38)|0);if(g|(tb(d,34390,39)|0)|0){g=-1;l=f;return g|0}g=qb(d,a,b,e)|0;wb(d);if((g|0)<0){g=-1;l=f;return g|0}if(!(c[a+168>>2]|0)){g=0;l=f;return g|0}d=c[e+12>>2]|0;e=a+128|0;if((d|0)>=(c[e>>2]|0)){g=0;l=f;return g|0}while(1){if((db(a,d,64)|0)<0){d=-1;e=8;break}d=d+1|0;if((d|0)>=(c[e>>2]|0)){d=0;e=8;break}}if((e|0)==8){l=f;return d|0}return 0}function qe(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=l;l=l+16|0;Ul(d)|0;Ul(d)|0;Ul(d)|0;c[a+148>>2]=(Ul(d)|0)&65535;e=Ul(d)|0;if(e<<16>>16)c[a+152>>2]=e&65535;am(d)|0;cm(a,32,1,d)|0;ob(a,34395,b);l=b;return 0}function re(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0;g=b+128|0;if(c[g>>2]|0){b=-1;return b|0}d=b+156|0;c[d>>2]=(Ul(e)|0)&65535;f=Ul(e)|0;c[b+160>>2]=f&65535;if((f&65535)>255|(c[d>>2]|0)>256){b=-1;return b|0}am(e)|0;f=0;d=0;do{h=Pl(e)|0;a[b+952+f>>0]=h;h=h&255;d=(h|0)>(d|0)?h:d;f=f+1|0}while((f|0)!=128);c[g>>2]=d+1;h=0;return h|0}function se(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=a+136|0;c[b>>2]=(Ul(d)|0)&65535;c[e+8>>2]=(Ul(d)|0)&65535;c[a+132>>2]=O(c[a+128>>2]|0,c[b>>2]|0)|0;return 0}function te(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0;j=l;l=l+32|0;g=j;i=(Ul(d)|0)&65535;c[a+144>>2]=i;f=a+140|0;c[f>>2]=i;if((Za(a)|0)<0){a=-1;l=j;return a|0}if((c[f>>2]|0)<=0){a=0;l=j;return a|0}i=a+180|0;h=a+176|0;b=0;while(1){if((_a(a,b,1)|0)<0){e=-1;b=8;break}am(d)|0;e=am(d)|0;c[(c[i>>2]|0)+(b*52|0)+32>>2]=e;c[(c[h>>2]|0)+(b*764|0)+36>>2]=(e|0)!=0&1;e=(Nl(d)|0)<<24>>24;k=(Pl(d)|0)&255;m=c[(c[h>>2]|0)+(b*764|0)+756>>2]|0;c[m>>2]=k;c[m+8>>2]=128;m=am(d)|0;c[(c[i>>2]|0)+(b*52|0)+36>>2]=m;m=am(d)|0;k=c[i>>2]|0;c[k+(b*52|0)+40>>2]=m+-1+(c[k+(b*52|0)+36>>2]|0);c[k+(b*52|0)+44>>2]=(m|0)>2?2:0;cm(g,22,1,d)|0;fb(c[h>>2]|0,b,g,22);if(((Ul(d)|0)&255)>8){m=c[i>>2]|0;k=m+(b*52|0)+44|0;c[k>>2]=c[k>>2]|1;k=m+(b*52|0)+32|0;c[k>>2]=c[k>>2]>>1;k=m+(b*52|0)+36|0;c[k>>2]=c[k>>2]>>1;m=m+(b*52|0)+40|0;c[m>>2]=c[m>>2]>>1}am(d)|0;k=am(d)|0;m=c[(c[h>>2]|0)+(b*764|0)+756>>2]|0;Gi(k,m+12|0,m+16|0);m=c[(c[h>>2]|0)+(b*764|0)+756>>2]|0;k=m+16|0;c[k>>2]=(c[k>>2]|0)+e;c[m+40>>2]=b;b=b+1|0;if((b|0)>=(c[f>>2]|0)){e=0;b=8;break}}if((b|0)==8){l=j;return e|0}return 0}function ue(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if((c[f>>2]|0)==0?(c[f>>2]=1,c[f+12>>2]=0,($a(b)|0)<0):0){e=-1;return e|0}am(e)|0;n=(Ul(e)|0)&65535;g=Ul(e)|0;o=g&65535;if((g&65535)>256?1:(n|0)>=(c[b+128>>2]|0)){e=-1;return e|0}f=f+12|0;d=c[f>>2]|0;if((n|0)<(d|0)){e=-1;return e|0}while(1){if((db(b,d,o)|0)<0){d=-1;h=14;break}if((d|0)<(n|0))d=d+1|0;else break}if((h|0)==14)return d|0;c[f>>2]=n+1;if(!(g<<16>>16)){e=0;return e|0}l=b+136|0;m=b+172|0;k=b+168|0;d=c[l>>2]|0;j=0;do{if((d|0)>0){i=0;do{d=c[(c[m>>2]|0)+(c[(c[(c[k>>2]|0)+(n<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0;f=Pl(e)|0;g=Pl(e)|0;h=Pl(e)|0;b=Pl(e)|0;if(f<<24>>24){f=f+-1&255;a[d+4+(j<<3)>>0]=(f&15)+12+((f>>>4)*12|0)}a[d+4+(j<<3)+2>>0]=(g&255)>>>2;h=h&255;a[d+4+(j<<3)+1>>0]=(g&255)<<4&48|h>>>4;a[d+4+(j<<3)+3>>0]=h&15;a[d+4+(j<<3)+4>>0]=b;i=i+1|0;d=c[l>>2]|0}while((i|0)<(d|0))}j=j+1|0}while((j|0)!=(o|0));d=0;return d|0}function ve(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=e+4|0;if(!(c[f>>2]|0)){c[f>>2]=1;f=e+16|0;c[f>>2]=0}else f=e+16|0;if((b|0)>2){e=c[f>>2]|0;if((e|0)>=(c[a+140>>2]|0)){a=-1;return a|0}if((Eb(a,d,64,(c[a+180>>2]|0)+((c[(c[(c[a+176>>2]|0)+(e*764|0)+756>>2]|0)+40>>2]|0)*52|0)|0,0)|0)<=-1){a=-1;return a|0}}c[f>>2]=(c[f>>2]|0)+1;a=0;return a|0}function we(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0;dm(a,c,1)|0;if((am(a)|0)!=1313800192){f=-1;return f|0}e=Pl(a)|0;d=e&255;if(e<<24>>24==20)e=0;else{f=-1;return f|0}do{e=e+1|0;if(!((Pl(a)|0)<<24>>24)){d=-1;f=8;break}}while((e|0)<(d|0));if((f|0)==8)return d|0;dm(a,9,1)|0;if(!((Pl(a)|0)<<24>>24)){f=-1;return f|0}Pl(a)|0;if(((Pl(a)|0)+-1&255)>15){f=-1;return f|0}dm(a,c+5|0,0)|0;hb(a,b,d);f=0;return f|0}function xe(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+16|0;am(d)|0;ob(b,34433,t);s=Pl(d)|0;f=s&255;if(s<<24>>24){g=0;do{e=Pl(d)|0;if((g|0)<64)a[b+g>>0]=e;g=g+1|0}while((g|0)!=(f|0))}Rl(d)|0;Rl(d)|0;Rl(d)|0;Rl(d)|0;Pl(d)|0;r=b+128|0;c[r>>2]=(Pl(d)|0)&255;Pl(d)|0;s=(Pl(d)|0)&255;q=b+136|0;c[q>>2]=s;c[b+132>>2]=O(c[r>>2]|0,s)|0;Pl(d)|0;Rl(d)|0;Rl(d)|0;Pl(d)|0;c[b+144>>2]=63;s=b+140|0;c[s>>2]=63;e=0;do{f=Pl(d)|0;if(f<<24>>24==-1)break;a[b+952+e>>0]=f;e=e+1|0}while((e|0)<256);dm(d,255-e|0,1)|0;c[b+156>>2]=e;c[b+1264>>2]=8363;if((Za(b)|0)<0){b=-1;l=t;return b|0}a:do if((c[s>>2]|0)>0){j=b+176|0;k=b+180|0;i=0;while(1){if((_a(b,i,1)|0)<0){e=-1;m=49;break}e=Pl(d)|0;h=e&255;if(gm(d)|0){e=-1;m=49;break}if(e<<24>>24){f=0;g=0;do{e=Pl(d)|0;f=e<<24>>24==32?f:1;if((g|0)<32)a[(c[j>>2]|0)+(i*764|0)+g>>0]=e;g=g+1|0}while((g|0)!=(h|0));if(!f)m=18}else m=18;if((m|0)==18){m=0;a[(c[j>>2]|0)+(i*764|0)>>0]=0}_l(d)|0;_l(d)|0;g=(Pl(d)|0)&255;c[c[(c[j>>2]|0)+(i*764|0)+756>>2]>>2]=g;g=(Rl(d)|0)&65535;f=(Rl(d)|0)&65535;c[(c[k>>2]|0)+(i*52|0)+32>>2]=f;f=(Rl(d)|0)&65535;c[(c[k>>2]|0)+(i*52|0)+36>>2]=f;f=(Rl(d)|0)&65535;c[(c[k>>2]|0)+(i*52|0)+40>>2]=f;_l(d)|0;Rl(d)|0;f=c[k>>2]|0;e=c[j>>2]|0;if((c[f+(i*52|0)+32>>2]|0)>0)c[e+(i*764|0)+36>>2]=1;c[f+(i*52|0)+44>>2]=(c[f+(i*52|0)+40>>2]|0)>0?2:0;o=c[e+(i*764|0)+756>>2]|0;p=o+16|0;c[p>>2]=0;c[o+8>>2]=128;c[o+40>>2]=i;Gi(g,o+12|0,p);i=i+1|0;if((i|0)>=(c[s>>2]|0))break a}if((m|0)==49){l=t;return e|0}}while(0);if(($a(b)|0)<0){b=-1;l=t;return b|0}b:do if((c[r>>2]|0)>0){o=b+168|0;p=b+172|0;n=0;while(1){if((db(b,n,64)|0)<0){e=-1;break}e=c[o>>2]|0;if((c[c[e+(n<<2)>>2]>>2]|0)>0){f=c[q>>2]|0;m=0;do{if((f|0)>0){g=0;while(1){e=c[(c[p>>2]|0)+(c[(c[e+(n<<2)>>2]|0)+4+(g<<2)>>2]<<2)>>2]|0;h=_l(d)|0;f=h&63;i=h>>>6&127;j=h>>>13&127;k=h>>>20&15;if((f|0)!=63)a[e+4+(m<<3)>>0]=f+36;if((i|0)!=127)a[e+4+(m<<3)+1>>0]=i+1;if((j|0)!=127)a[e+4+(m<<3)+2>>0]=j;if((k|0)!=15){a[e+4+(m<<3)+3>>0]=a[34448+k>>0]|0;a[e+4+(m<<3)+4>>0]=h>>>24}g=g+1|0;f=c[q>>2]|0;if((g|0)>=(f|0))break;e=c[o>>2]|0}e=c[o>>2]|0}m=m+1|0}while((m|0)<(c[c[e+(n<<2)>>2]>>2]|0))}n=n+1|0;if((n|0)>=(c[r>>2]|0))break b}l=t;return e|0}while(0);e=c[s>>2]|0;c:do if((e|0)>0){h=b+180|0;g=0;while(1){f=c[h>>2]|0;if(c[f+(g*52|0)+32>>2]|0){if((Eb(b,d,2,f+(g*52|0)|0,0)|0)<0){e=-1;break}e=c[s>>2]|0}g=g+1|0;if((g|0)>=(e|0))break c}l=t;return e|0}while(0);d=b+1284|0;c[d>>2]=c[d>>2]|1224737313;c[b+1288>>2]=2;b=0;l=t;return b|0}function ye(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;if((am(a)|0)!=1297437528){e=-1;return e|0}_l(a)|0;a:do if(!(fm(a)|0)){while(1){c=am(a)|0;d=_l(a)|0;if(d>>>0>1048576){c=-1;e=8;break}if((c|0)==1296974157)break;dm(a,d,1)|0;if(fm(a)|0)break a}if((e|0)==8)return c|0;hb(a,b,32);e=0;return e|0}while(0);hb(a,b,0);e=0;return e|0}function ze(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;f=l;l=l+112|0;e=f;am(b)|0;am(b)|0;c[e>>2]=0;c[e+4>>2]=0;c[e+8>>2]=0;c[e+12>>2]=0;c[e+16>>2]=0;d=pb()|0;if(!d){a=-1;l=f;return a|0}tb(d,34482,40)|0;tb(d,34487,41)|0;tb(d,34492,42)|0;tb(d,34497,43)|0;tb(d,34502,44)|0;tb(d,34507,45)|0;tb(d,34512,46)|0;tb(d,34517,47)|0;tb(d,34522,48)|0;tb(d,35016,49)|0;tb(d,34527,50)|0;Ab(d,1);b=(qb(d,a,b,e)|0)<0;wb(d);if(b){a=-1;l=f;return a|0}d=a+136|0;if((c[d>>2]|0)<=0){a=0;l=f;return a|0}e=a+1300|0;b=0;do{c[a+184+(b*12|0)>>2]=((O(c[e>>2]|0,((((b+3|0)/2|0|0)%2|0)*255|0)+-128|0)|0)/100|0)+128;b=b+1|0}while((b|0)<(c[d>>2]|0));d=0;l=f;return d|0}function Ae(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=(Pl(d)|0)&255;c[e>>2]=((b>>>4)*10|0)+(b&15);b=(Pl(d)|0)&255;c[e>>2]=((b&15)*100|0)+(c[e>>2]|0)+((b>>>4)*1e3|0);b=(Pl(d)|0)&255;c[e+4>>2]=((b>>>4)*10|0)+(b&15);b=(Pl(d)|0)&255;c[e+8>>2]=((b>>>4)*10|0)+(b&15);return 0}function Be(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=_l(d)|0;c[a+136>>2]=b;return ((b+-1|0)>>>0>7)<<31>>31|0}function Ce(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0;h=f+28|0;if((cm(h,1,8,e)|0)!=8){b=-1;return b|0}g=b+136|0;f=c[g>>2]|0;if((f|0)>0)e=0;else{b=0;return b|0}do{d=a[h+e>>0]|0;if((d+-1&255)<7){c[b+184+(e*12|0)>>2]=((d&255)*42|0)+-40;f=c[g>>2]|0}e=e+1|0}while((e|0)<(f|0));f=0;return f|0}function De(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return ((cm(a,1,32,c)|0)!=32)<<31>>31|0}function Ee(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return 0}function Fe(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=_l(d)|0;c[a+156>>2]=b;return ((b|0)>255)<<31>>31|0}function Ge(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=_l(d)|0;c[a+128>>2]=b;return ((b|0)>64)<<31>>31|0}function He(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return ((cm(d+36|0,1,64,c)|0)!=64)<<31>>31|0}function Ie(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;b=l;l=l+16|0;cm(a+952|0,1,128,c)|0;ob(a,34463,b);l=b;return 0} +function Ga(a){a=a|0;var b=0;b=l;l=l+a|0;l=l+15&-16;return b|0}function Ha(){return l|0}function Ia(a){a=a|0;l=a}function Ja(a,b){a=a|0;b=b|0;l=a;m=b}function Ka(a,b){a=a|0;b=b|0;if(!o){o=a;p=b}}function La(a){a=a|0;z=a}function Ma(){return z|0}function Na(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;g=d+4|0;if((a|0)==-1){c[g>>2]=0;c[d>>2]=0;return}if(!(c[g>>2]|0))if((a|0)==144){c[g>>2]=1;return}else{Ea[b&1](a,e);c[d>>2]=a;return}if(a){if((a|0)>1){f=1;do{Ea[b&1](c[d>>2]|0,e);f=f+1|0}while((f|0)!=(a|0))}}else Ea[b&1](144,e);c[g>>2]=0;return}function Oa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+16|0;r=t;s=e+786480|0;c[s>>2]=31;c[e+786448>>2]=0;q=e+786484|0;c[q>>2]=8192;n=Xm(1,d)|0;if(!n){s=0;l=t;return s|0}p=e+786464|0;c[p>>2]=a;o=e+786468|0;c[o>>2]=a+b;c[e+786472>>2]=n;c[e+786476>>2]=n+d;c[e+786440>>2]=0;c[e+786436>>2]=0;c[e+786444>>2]=0;Na(-1,0,e+786456|0,p);j=e+786452|0;c[j>>2]=0;Pa(e);c[r>>2]=0;if(c[s>>2]&32|0)c[p>>2]=(c[p>>2]|0)+1;if((c[q>>2]|0)>8192){s=0;l=t;return s|0}c[e+1065016>>2]=0;k=e+524288|0;a:do if(Qa(r,9,e)|0){a=9;g=1;d=0;i=0;while(1){f=c[s>>2]|0;b=c[r>>2]|0;if((f&1|0)!=0&(b|0)==257)break a;if(!g)h=0;else{d=b;h=(c[j>>2]|0)!=0&1}if((b|0)==256)if(!(c[j>>2]|0)){c[k>>2]=(f>>>3&1)+255;Ra(a,e);if(!(Qa(r,9,e)|0))break a;b=c[r>>2]|0;a=9;g=13}else{b=256;g=15}else g=13;if((g|0)==13)if(!(c[j>>2]|0))if((b|0)>(c[k>>2]|0))g=17;else g=16;else g=15;if((g|0)==15)if((c[e+262144+(b<<2)>>2]|0)==-1)g=17;else g=16;if((g|0)==16){Sa(b,e);f=b;d=Ta(b,e)|0}else if((g|0)==17){Sa(i,e);Ua(d,e);f=b}if((!(h|0?1:(c[k>>2]|0)==((c[q>>2]|0)+-1|0))?(Va(i,d,e),m=c[k>>2]|0,(m|0)!=((c[q>>2]|0)+-1|0)):0)?(m|0)==((1<>2]&2|0){s=n;l=t;return s|0}if((c[p>>2]|0)==(c[o>>2]|0)){s=n;l=t;return s|0}Wm(n);s=0;l=t;return s|0}function Pa(a){a=a|0;var b=0;b=0;do{c[a+262144+(b<<2)>>2]=-1;c[a+(b<<2)>>2]=-1;c[a+524292+(b<<2)>>2]=-1;b=b+1|0}while((b|0)!=65536);gp(a+1048632|0,-1,16384)|0;if(!(c[a+786452>>2]|0)){b=0;do{c[a+262144+(b<<2)>>2]=b;b=b+1|0}while((b|0)!=256);c[a+524288>>2]=((c[a+786480>>2]|0)>>>3&1)+255;return}c[a+524288>>2]=-1;b=0;do{Va(65535,b,a);b=b+1|0}while((b|0)!=256);return}function Qa(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;c[a>>2]=0;do if((b|0)>0){m=e+786440|0;k=e+786464|0;j=e+786468|0;l=e+786436|0;n=e+1065016|0;o=e+786452|0;f=c[m>>2]|0;i=0;while(1){if(!f){f=c[k>>2]|0;if(f>>>0>=(c[j>>2]|0)>>>0){f=0;g=15;break}c[k>>2]=f+1;h=d[f>>0]|0;c[l>>2]=h;c[m>>2]=8;c[n>>2]=(c[n>>2]|0)+1;f=8}else h=c[l>>2]|0;g=b-i|0;g=(f|0)<(g|0)?f:g;f=i;i=g+i|0;if(!(c[o>>2]|0)){c[a>>2]=c[a>>2]|((1<>2]=c[l>>2]>>g}else{f=(h&255)<>2]=f;if((i|0)>(b|0)){f=0;g=15;break}c[a>>2]=c[a>>2]|f>>8<>2]|0)-g|0;c[m>>2]=f;if((i|0)>=(b|0)){g=12;break}}if((g|0)==12){f=c[a>>2]|0;if((f|0)<0)f=0;else break;return f|0}else if((g|0)==15)return f|0}else f=0;while(0);g=e+786444|0;if((f|0)>=(c[e+786484>>2]|0)){e=0;return e|0}c[g>>2]=(c[g>>2]|0)+1&7;e=1;return e|0}function Ra(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=l;l=l+16|0;e=f;if(c[b+786480>>2]&4|0){l=f;return}d=b+786444|0;while(1){if(!(c[d>>2]|0)){d=5;break}if(!(Qa(e,a,b)|0)){d=5;break}}if((d|0)==5){l=f;return}}function Sa(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0;d=b+(a<<2)|0;a:do if((c[d>>2]|0)==-1){d=0;i=3}else{h=b+786484|0;g=d;f=0;e=b+786488|0;while(1){a=c[b+262144+(a<<2)>>2]|0;if((f|0)>=(c[h>>2]|0)){d=f;break a}d=f+1|0;c[e>>2]=a;a=c[g>>2]|0;g=b+(a<<2)|0;if((c[g>>2]|0)==-1){i=3;break}else{f=d;e=b+786488+(d<<2)|0}}}while(0);if((i|0)==3)a=c[b+262144+(a<<2)>>2]|0;Ua(a,b);if((d|0)<=0)return;do{i=d;d=d+-1|0;Ua(c[b+786488+(d<<2)>>2]|0,b)}while((i|0)>1);return}function Ta(a,b){a=a|0;b=b|0;if((c[b+(a<<2)>>2]|0)!=-1)a=c[b+524292+(a<<2)>>2]|0;return c[b+262144+(a<<2)>>2]|0}function Ua(a,b){a=a|0;b=b|0;if(!(c[b+786448>>2]|0)){Xa(a,b+786464|0);return}else{Na(a,1,b+786456|0,b+786464|0);return}}function Va(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;g=d+524288|0;e=(c[g>>2]|0)+1|0;c[g>>2]=e;h=d+786484|0;f=c[h>>2]|0;if(f&e|0){c[g>>2]=f+-1;return}if(c[d+786452>>2]|0){e=Wa(a,b,d)|0;if((e|0)==-1)return}c[d+262144+(e<<2)>>2]=b;if((c[h>>2]|0)<=(a|0))return;c[d+(e<<2)>>2]=a;if((c[d+(a<<2)>>2]|0)!=-1)a=c[d+524292+(a<<2)>>2]|0;c[d+524292+(e<<2)>>2]=a;return}function Wa(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;b=b+a&63487|2048;b=(O(b,b)|0)>>>6&4095;while(1){if((c[d+262144+(b<<2)>>2]|0)==-1){e=10;break}f=d+1048632+(b<<2)|0;a=c[f>>2]|0;if((a|0)==-1)break;else b=a}if((e|0)==10)return b|0;b=b+101&4095;if((c[d+262144+(b<<2)>>2]|0)!=-1){e=c[d+786484>>2]|0;a:do if((e|0)>=1){a=0;do{a=a+1|0;b=b+1&4095;if((a|0)>=(e|0))break a}while((c[d+262144+(b<<2)>>2]|0)!=-1)}while(0);if((b|0)==(e|0)){d=-1;return d|0}}c[f>>2]=b;d=b;return d|0}function Xa(b,d){b=b|0;d=d|0;var e=0,f=0;f=d+8|0;e=c[f>>2]|0;if(e>>>0>=(c[d+12>>2]|0)>>>0)return;c[f>>2]=e+1;a[e>>0]=b;return}function Ya(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;f=Vm(1065020)|0;if(!f){e=0;return e|0}g=Vm(d)|0;if(g|0?(h=Po(a)|0,Oo(g,1,d,a)|0,d=Oa(g,d,e,f)|0,ep(b|0,d|0,e|0)|0,e=(Ao(a,((c[f+1065016>>2]|0)+3&-4)+h|0,0)|0)<0,Wm(d),Wm(g),!e):0){Wm(f);h=b;return h|0}Wm(f);h=0;return h|0}function Za(a){a=a|0;var b=0,d=0.0,e=0,f=0;b=c[a+140>>2]|0;if((b|0)>0?(f=Xm(764,b)|0,c[a+176>>2]=f,(f|0)==0):0){f=-1;return f|0}e=c[a+144>>2]|0;if((e|0)<=0){f=0;return f|0}f=Xm(52,e)|0;c[a+180>>2]=f;if(!f){f=-1;return f|0}f=Xm(8,e)|0;c[a+7592>>2]=f;if(!f){f=-1;return f|0}d=+(c[a+1264>>2]|0);b=0;do{h[f+(b<<3)>>3]=d;b=b+1|0}while((b|0)!=(e|0));b=0;return b|0}function _a(a,b,d){a=a|0;b=b|0;d=d|0;if(!d){d=0;return d|0}d=Xm(64,d)|0;c[(c[a+176>>2]|0)+(b*764|0)+756>>2]=d;d=((d|0)==0)<<31>>31;return d|0}function $a(a){a=a|0;var b=0;b=Xm(4,c[a+132>>2]|0)|0;c[a+172>>2]=b;if(!b){b=-1;return b|0}b=Xm(4,c[a+128>>2]|0)|0;c[a+168>>2]=b;b=((b|0)==0)<<31>>31;return b|0}function ab(a,b){a=a|0;b=b|0;var d=0,e=0;if((b|0)<0){e=-1;return e|0}if((c[a+128>>2]|0)<=(b|0)){e=-1;return e|0}e=a+168|0;d=(c[e>>2]|0)+(b<<2)|0;if(c[d>>2]|0){e=-1;return e|0}c[d>>2]=Xm(1,(c[a+136>>2]<<2)+4|0)|0;e=((c[(c[e>>2]|0)+(b<<2)>>2]|0)==0)<<31>>31;return e|0}function bb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;if((b|0)<0){d=-1;return d|0}if((c[a+132>>2]|0)<=(b|0)){d=-1;return d|0}e=a+172|0;a=(c[e>>2]|0)+(b<<2)|0;if((d|0)<1|(c[a>>2]|0)!=0){d=-1;return d|0}c[a>>2]=Xm(d<<3|4,1)|0;a=c[(c[e>>2]|0)+(b<<2)>>2]|0;if(!a){d=-1;return d|0}c[a>>2]=d;d=0;return d|0}function cb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;g=a+136|0;d=c[g>>2]|0;if((d|0)<=0){h=0;return h|0}h=a+168|0;e=c[(c[h>>2]|0)+(b<<2)>>2]|0;f=0;while(1){d=(O(d,b)|0)+f|0;if((bb(a,d,c[e>>2]|0)|0)<0){d=-1;e=5;break}e=c[(c[h>>2]|0)+(b<<2)>>2]|0;c[e+4+(f<<2)>>2]=d;f=f+1|0;d=c[g>>2]|0;if((f|0)>=(d|0)){d=0;e=5;break}}if((e|0)==5)return d|0;return 0}function db(a,b,d){a=a|0;b=b|0;d=d|0;if(d>>>0>256){d=-1;return d|0}if((ab(a,b)|0)<0){d=-1;return d|0}c[c[(c[a+168>>2]|0)+(b<<2)>>2]>>2]=d;d=(cb(a,b)|0)>>31;return d|0}function eb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=Ym(a,d*52|0)|0;if(!e){b=0;return b|0}a=c[b>>2]|0;if((a|0)<(d|0))gp(e+(a*52|0)|0,0,(d-a|0)*52|0)|0;c[b>>2]=d;b=e;return b|0}function fb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;gb(a+(b*764|0)|0,c,(d|0)<0?0:(d|0)<31?d:31)|0;return}function gb(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;gp(b|0,0,d+1|0)|0;Ho(b,c,d)|0;c=a[b>>0]|0;if((d|0)>0&c<<24>>24!=0){e=b;f=0;do{if(c<<24>>24<0|(Qn(c<<24>>24)|0)==0)a[e>>0]=46;f=f+1|0;e=b+f|0;c=a[e>>0]|0}while((f|0)<(d|0)&c<<24>>24!=0);c=a[b>>0]|0}if(!(c<<24>>24))return b|0;while(1){c=b+((fo(b)|0)+-1)|0;if((a[c>>0]|0)!=32){c=9;break}a[c>>0]=0;if(!(a[b>>0]|0)){c=9;break}}if((c|0)==9)return b|0;return 0}function hb(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;f=l;l=l+64|0;e=f;d=(d|0)<63?d:63;if(!c){l=f;return}gp(c|0,0,d+1|0)|0;cm(e,1,d,b)|0;a[e+d>>0]=0;gb(c,e,d)|0;l=f;return}function ib(b,c){b=b|0;c=c|0;var d=0,e=0;a:do if((c|0)>0){e=0;while(1){d=a[b+e>>0]|0;if(d<<24>>24<0){d=-1;break a}e=e+1|0;if(!(d<<24>>24==8|(d+-1&255)>30)){d=-1;break a}if((e|0)>=(c|0)){d=0;break}}}else d=0;while(0);return d|0}function jb(b,c){b=b|0;c=c|0;var e=0,f=0;e=b;f=e;a[f>>0]=0;a[f+1>>0]=0;a[f+2>>0]=0;a[f+3>>0]=0;e=e+4|0;a[e>>0]=0;a[e+1>>0]=0;a[e+2>>0]=0;a[e+3>>0]=0;a[b>>0]=Ei((a[c>>0]&15)<<8|(d[c+1>>0]|0))|0;e=c+2|0;a[b+1>>0]=(d[e>>0]|0)>>>4|a[c>>0]&-16&255;e=a[e>>0]&15;if((e&255)>=7?!((e&255)>9&e<<24>>24!=14):0){kb(b);return}a[b+3>>0]=e;a[b+4>>0]=a[c+3>>0]|0;kb(b);return}function kb(b){b=b|0;var c=0,d=0,e=0;d=b+4|0;c=a[d>>0]|0;e=b+3|0;b=a[e>>0]|0;if(!(c<<24>>24)){switch(b<<24>>24){case 5:{b=3;break}case 6:{b=4;break}case 10:case 2:case 1:{b=0;break}default:return}a[e>>0]=b;return}else{if(b<<24>>24!=14)return;switch(c<<24>>24){case -80:case -96:break;default:return}a[d>>0]=0;a[e>>0]=0;return}}function lb(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0;f=c+2|0;e=a[f>>0]&15;g=b;h=g;a[h>>0]=0;a[h+1>>0]=0;a[h+2>>0]=0;a[h+3>>0]=0;g=g+4|0;a[g>>0]=0;a[g+1>>0]=0;a[g+2>>0]=0;a[g+3>>0]=0;a[b>>0]=Ei((a[c>>0]&15)<<8|(d[c+1>>0]|0))|0;a[b+1>>0]=(d[f>>0]|0)>>>4|a[c>>0]&-16&255;if(e<<24>>24==8){kb(b);return}a[b+3>>0]=e;a[b+4>>0]=a[c+3>>0]|0;kb(b);return}function mb(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=Tn(a)|0;if(!d){e=0;return e|0}while(1){a=Vn(d)|0;if(!a){a=0;break}a=a+11|0;if(!(eo(a,b)|0)){e=4;break}}if((e|0)==4){Ho(c,a,256)|0;a=1}Rn(d);e=a;return e|0}function nb(a,b){a=a|0;b=b|0;if(a|0){Ho(b,a,256)|0;return}a=ua(31604)|0;if(!a){Ho(b,37057,256)|0;return}else{Ho(b,a,256)|0;return}}function ob(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;e=l;l=l+16|0;f=e;c[f>>2]=d;pn(a+64|0,64,b,f);l=e;return}function pb(){var a=0;a=Vm(16)|0;if(!a){a=0;return a|0}c[a>>2]=a;c[a+4>>2]=a;c[a+8>>2]=4;c[a+12>>2]=0;return a|0}function qb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;while(1){if(fm(c)|0){e=0;break}e=rb(a,b,c,d)|0;if((e|0)>0){e=0;break}if((e|0)<0){e=-1;break}}return e|0}function rb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0;k=l;l=l+32|0;j=k;g=j;h=g+17|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));i=b+8|0;h=cm(j,1,c[i>>2]|0,e)|0;if((h|0)!=(c[i>>2]|0)){gm(e)|0;f=1;l=k;return f|0}h=b+12|0;g=c[h>>2]|0;do if((g&16|0)!=0?(on(j,31624,4)|0)==0:0){am(e)|0;am(e)|0;g=cm(j,1,c[i>>2]|0,e)|0;if((g|0)==(c[i>>2]|0)){g=c[h>>2]|0;break}else{f=1;l=k;return f|0}}while(0);if(!(g&1))g=am(e)|0;else g=_l(e)|0;if(gm(e)|0){f=-1;l=k;return f|0}h=c[h>>2]|0;do if(h&4)if((g|0)==-1){f=-1;l=k;return f|0}else{g=g+1&-2;break}while(0);do if(h&8)if(g>>>0>4294967292){f=-1;l=k;return f|0}else{g=g+3&-4;break}while(0);do if(h&2){h=(c[i>>2]|0)+4|0;if(g>>>0>>0){f=-1;l=k;return f|0}else{g=g-h|0;break}}while(0);f=sb(b,d,j,g,e,f)|0;l=k;return f|0}function sb(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0;i=em(f)|0;h=c[a>>2]|0;a:do if((h|0)!=(a|0)){k=(d|0)==0;j=a+8|0;while(1){if(!k?(nn(d,h+-8|0,c[j>>2]|0)|0)==0:0)break;h=c[h>>2]|0;if((h|0)==(a|0))break a}if((e|0)>4194304){k=-1;return k|0}if((Da[c[h+-4>>2]&127](b,e,f,g)|0)<0){k=-1;return k|0}}while(0);k=(dm(f,i+e|0,0)|0)>>31;return k|0}function tb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=Vm(16)|0;if(!e){a=-1;return a|0}Ho(e,b,4)|0;c[e+4>>2]=d;ub(e+8|0,a);a=0;return a|0}function ub(a,b){a=a|0;b=b|0;vb(a,c[b+4>>2]|0,b);return}function vb(a,b,d){a=a|0;b=b|0;d=d|0;c[d+4>>2]=a;c[a>>2]=d;c[a+4>>2]=b;c[b>>2]=a;return}function wb(a){a=a|0;var b=0,d=0;b=c[a>>2]|0;if((b|0)==(a|0)){Wm(a);return}do{xb(c[b>>2]|0,c[b+4>>2]|0);d=b;b=c[b>>2]|0;Wm(d+-8|0)}while((b|0)!=(a|0));Wm(a);return}function xb(a,b){a=a|0;b=b|0;yb(b,a);return}function yb(a,b){a=a|0;b=b|0;c[b+4>>2]=a;c[a>>2]=b;return}function zb(a){a=a|0;c[a+8>>2]=2;return}function Ab(a,b){a=a|0;b=b|0;a=a+12|0;c[a>>2]=c[a>>2]|b;return}function Bb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+16|0;s=w+4|0;t=w;c[s>>2]=0;c[t>>2]=0;if(!e){l=w;return}r=(f|0)!=0;i=0;f=0;g=0;h=0;a:while(1){if(!i){Rl(b)|0;c[t>>2]=0;c[s>>2]=0;q=32768;f=9;g=0;h=0}else q=i;p=q>>>0>e>>>0?e:q;n=f;o=0;while(1){m=n&255;f=Cb(b,s,t,m)|0;if(fm(b)|0){v=24;break a}do if((n&255)<7){f=f&65535;if((1<>>0>>0?f:i+2|0)&255;i=o}else v=19}else{if((n&255)>=9){if(n<<24>>24!=9){v=21;break}if((f&65280)>>>0<=255){v=20;break}f=f+1&255;i=o;break}j=255>>>(9-m|0);k=j+65532|0;i=f&65535;if(i>>>0>(k&65535)>>>0?(u=f-k|0,i>>>0<=(j+4&65535)>>>0):0){f=((u&255)>>>0>=m>>>0&1)+u&255;i=o;break}if((n&255)<8){f=i;v=19}else v=20}while(0);if((v|0)==19){m=8-m&255;f=f<>24>>m;v=20}if((v|0)==20){m=(f&65535)+(g&255)|0;g=m&255;h=m+(h&255)&255;a[d+o>>0]=r?h:g;v=21}if((v|0)==21){v=0;f=n;i=o+1|0}if(i>>>0

>>0){n=f;o=i}else break}e=e-p|0;if(!e){v=24;break}else{i=q-p|0;d=d+p|0}}if((v|0)==24){l=w;return}}function Cb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;if((e|0)<=0){a=0;i=32-e|0;i=a>>>i;return i|0}f=c[b>>2]|0;g=c[d>>2]|0;h=e;i=0;do{if(!g){f=(Pl(a)|0)&255;g=8}i=f<<31|i>>>1;f=f>>1;g=g+-1|0;h=h+-1|0}while((h|0)!=0);c[d>>2]=g;c[b>>2]=f;a=i;i=32-e|0;i=a>>>i;return i|0}function Db(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;u=l;l=l+16|0;r=u+4|0;s=u;c[r>>2]=0;c[s>>2]=0;if(!e){t=0;l=u;return t|0}q=(f|0)!=0;i=0;f=0;g=0;h=0;a:while(1){if(!i){Rl(a)|0;c[s>>2]=0;c[r>>2]=0;p=16384;f=17;g=0;h=0}else p=i;o=p>>>0>e>>>0?e:p;n=0;while(1){m=f&255;j=Cb(a,r,s,m)|0;if(fm(a)|0){f=-1;t=22;break a}do if((f&255)<7)if((1<>>0>>0?f:i+2|0)&255;i=n}else t=18;else if((f&255)<17){k=65535>>>(17-m|0);i=k+65528&65535;if(j>>>0<=i>>>0){t=18;break}i=j-i|0;if(j>>>0>(k+8&65535)>>>0){t=18;break}f=((i&255)>>>0>=m>>>0&1)+i&255;i=n;break}else{if(f<<24>>24!=17){t=19;break}if(j>>>0<=65535){t=18;break}f=j+1&255;i=n;break}while(0);if((t|0)==18){m=16-m&255;m=((f&255)<16?j<>16>>m:j)+(g&65535)|0;g=m&65535;h=m+(h&65535)&65535;b[d+(n<<1)>>1]=q?h:g;t=19}if((t|0)==19){t=0;i=n+1|0}if(i>>>0>>0)n=i;else break}e=e-o|0;if((e|0)<=0){f=0;t=22;break}else{i=p-o|0;d=d+(o<<1)|0}}if((t|0)==22){l=u;return f|0}return 0}function Eb(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=l;l=l+16|0;k=s;if(e&4096|0){r=0;l=s;return r|0}n=f+32|0;j=c[n>>2]|0;if((j|0)<1){r=0;l=s;return r|0}do if((j|0)<=268435456){if(b|0?c[b+1296>>2]&1|0:0)break;r=f+36|0;b=c[r>>2]|0;if((b|0)<0){c[r>>2]=0;b=0}q=f+40|0;h=c[q>>2]|0;if((h|0)>(j|0)){c[q>>2]=j;h=j}if((b|0)<(j|0)&(b|0)<(h|0)){p=f+44|0;i=c[p>>2]|0}else{c[q>>2]=0;c[r>>2]=0;p=f+44|0;i=c[p>>2]&-7;c[p>>2]=i;b=0;h=0}if((i&6|0)==4){i=i&-5;c[p>>2]=i}if(!(i&4))b=0;else{b=h-b+(h-j)|0;b=(b|0)>0?b:0}o=i&1;h=b<>2]=b;if(!b){r=-1;l=s;return r|0}c[b>>2]=0;b=b+4|0;c[o>>2]=b;do if(!(e&16)){if(!(e&16384)){b=cm(b,1,m,d)|0;if((m|0)==(b|0))break;gp((c[o>>2]|0)+b|0,0,m-b|0)|0;break}b=m+1>>1;if((cm(k,1,16,d)|0)==16?(cm((c[o>>2]|0)+b|0,1,b,d)|0)==(b|0):0){d=c[o>>2]|0;Fb(d+b|0,d,k,m);break}Wm((c[o>>2]|0)+-4|0);r=-1;l=s;return r|0}else ep(b|0,g|0,m|0)|0;while(0);if(e&8|0)Gb(c[o>>2]|0,c[n>>2]|0);if(!((e&64|0)==0|(c[p>>2]&1|0)==0))Hb(c[o>>2]|0,c[n>>2]|0);if(!(e&1)){if(e&4|0)Ib(c[o>>2]|0,c[n>>2]<<(c[p>>2]&1),0)}else Ib(c[o>>2]|0,c[n>>2]|0,c[p>>2]&1);if(e&2|0)Jb(c[o>>2]|0,c[n>>2]|0,c[p>>2]&1);if(e&128|0)Kb(c[o>>2]|0,c[n>>2]|0);do if(e&512|0?(c[r>>2]|0)==0:0){if((c[n>>2]|0)<=(c[q>>2]|0))break;c[p>>2]=c[p>>2]|16}while(0);b=c[p>>2]|0;if(b&4){Lb(f);b=c[p>>2]|0;m=h+m|0}if(!(b&1)){k=c[o>>2]|0;a[k+m>>0]=a[k+(m+-1)>>0]|0;k=c[o>>2]|0;b=3;h=2;i=2;j=1;g=k;d=1;k=k+m|0}else{f=c[o>>2]|0;a[f+m>>0]=a[f+(m+-2)>>0]|0;f=c[o>>2]|0;h=m+1|0;a[f+h>>0]=a[f+(m+-1)>>0]|0;f=c[o>>2]|0;b=m+2|0;a[f+b>>0]=a[f+m>>0]|0;f=c[o>>2]|0;k=m+3|0;a[f+k>>0]=a[f+h>>0]|0;f=c[o>>2]|0;a[f+(m+4)>>0]=a[f+b>>0]|0;f=c[o>>2]|0;b=7;h=5;i=6;j=4;g=f;d=5;k=f+k|0}a[g+(m+d)>>0]=a[k>>0]|0;f=c[o>>2]|0;a[f+(m+i)>>0]=a[f+(m+j)>>0]|0;f=c[o>>2]|0;a[f+(m+b)>>0]=a[f+(m+h)>>0]|0;b=c[o>>2]|0;h=a[b>>0]|0;if(c[p>>2]&1){a[b+-2>>0]=h;b=c[o>>2]|0;h=a[b+1>>0]|0}a[b+-1>>0]=h;i=c[p>>2]|0;if(!(i&2)){r=0;l=s;return r|0}h=c[q>>2]|0;b=c[r>>2]|0;h=((i&4|0)==0?0:h-b|0)+h|0;if(!(i&1)){r=c[o>>2]|0;a[r+h>>0]=a[r+b>>0]|0;r=c[o>>2]|0;a[r+(h+1)>>0]=a[r+(b+1)>>0]|0;r=c[o>>2]|0;a[r+(h+2)>>0]=a[r+(b+2)>>0]|0;r=c[o>>2]|0;a[r+(h+3)>>0]=a[r+(b+3)>>0]|0;r=0;l=s;return r|0}else{r=h<<1;p=b<<1;q=c[o>>2]|0;a[q+r>>0]=a[q+p>>0]|0;q=c[o>>2]|0;a[q+(r|1)>>0]=a[q+(p|1)>>0]|0;q=c[o>>2]|0;a[q+(r+2)>>0]=a[q+(p+2)>>0]|0;q=c[o>>2]|0;a[q+(r+3)>>0]=a[q+(p+3)>>0]|0;q=c[o>>2]|0;a[q+(r+4)>>0]=a[q+(p+4)>>0]|0;q=c[o>>2]|0;a[q+(r+5)>>0]=a[q+(p+5)>>0]|0;q=c[o>>2]|0;a[q+(r+6)>>0]=a[q+(p+6)>>0]|0;q=c[o>>2]|0;a[q+(r+7)>>0]=a[q+(p+7)>>0]|0;r=0;l=s;return r|0}}while(0);if(e&16|0){r=0;l=s;return r|0}dm(d,j,1)|0;r=0;l=s;return r|0}function Fb(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0;i=(f+1|0)/2|0;if((f|0)>0){g=0;h=0;f=c}else return;while(1){c=a[b>>0]|0;j=(d[e+(c&15)>>0]|0)+g|0;a[f>>0]=j;g=(j<<24>>24)+(a[e+((c&255)>>>4&255)>>0]|0)|0;a[f+1>>0]=g;h=h+1|0;if((h|0)>=(i|0))break;else{b=b+1|0;f=f+2|0}}return}function Gb(b,c){b=b|0;c=c|0;if(!c)return;while(1){c=c+-1|0;a[b>>0]=(d[b>>0]|0)<<1;if(!c)break;else b=b+1|0}return}function Hb(b,c){b=b|0;c=c|0;var d=0,e=0,f=0;if((c|0)>0)d=0;else return;while(1){f=a[b>>0]|0;e=b+1|0;a[b>>0]=a[e>>0]|0;a[e>>0]=f;d=d+1|0;if((d|0)==(c|0))break;else b=b+2|0}return}function Ib(c,f,g){c=c|0;f=f|0;g=g|0;var h=0;h=(f|0)==0;if(!g){if(h)return;else g=0;while(1){f=f+-1|0;g=(d[c>>0]|0)+(g&65535)|0;a[c>>0]=g;if(!f)break;else c=c+1|0}return}if(h)return;g=0;while(1){f=f+-1|0;g=(e[c>>1]|0)+(g&65535)|0;b[c>>1]=g;if(!f)break;else c=c+2|0}return}function Jb(c,f,g){c=c|0;f=f|0;g=g|0;var h=0;h=(f|0)==0;if(!g){if(h)return;while(1){f=f+-1|0;a[c>>0]=(d[c>>0]|0)+128;if(!f)break;else c=c+1|0}return}if(h)return;while(1){f=f+-1|0;b[c>>1]=(e[c>>1]|0)+32768;if(!f)break;else c=c+2|0}return}function Kb(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0;if((c|0)>0)e=0;else return;do{f=b+e|0;h=d[f>>0]|0;g=a[31629+(h>>>1)>>0]|0;a[f>>0]=(h&1|0)==0?g:0-(g&255)&255;e=e+1|0}while((e|0)!=(c|0));return}function Lb(d){d=d|0;var e=0,f=0,g=0;f=c[d+48>>2]|0;e=c[d+32>>2]|0;g=c[d+40>>2]|0;e=(e|0)>(g|0)?g:e;g=g-(c[d+36>>2]|0)|0;if(!(c[d+44>>2]&1)){e=f+e|0;if((g|0)>0)f=0;else return;do{a[e+f>>0]=a[e+(0-f)+-1>>0]|0;f=f+1|0}while((f|0)!=(g|0));return}else{e=f+(e<<1)|0;if((g|0)>0)f=0;else return;do{b[e+(f<<1)>>1]=b[e+(0-f<<1)+-2>>1]|0;f=f+1|0}while((f|0)!=(g|0));return}}function Mb(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+32|0;c=d;if((cm(c,1,17,a)|0)>>>0>=17?(nn(c,31889,17)|0)==0:0){hb(a,b,20);c=0}else c=-1;l=d;return c|0}function Nb(d,f,g){d=d|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;C=l;l=l+384|0;y=C+8|0;u=C;m=C+24|0;x=C+360|0;cm(m,17,1,f)|0;i=m+17|0;cm(i,20,1,f)|0;Pl(f)|0;t=m+38|0;cm(t,20,1,f)|0;z=m+58|0;b[z>>1]=Rl(f)|0;w=m+60|0;c[w>>2]=_l(f)|0;k=m+64|0;b[k>>1]=Rl(f)|0;p=m+66|0;b[p>>1]=Rl(f)|0;j=m+68|0;b[j>>1]=Rl(f)|0;n=m+70|0;b[n>>1]=Rl(f)|0;o=m+72|0;b[o>>1]=Rl(f)|0;s=m+74|0;b[s>>1]=Rl(f)|0;q=m+76|0;b[q>>1]=Rl(f)|0;h=Rl(f)|0;r=m+78|0;b[r>>1]=h;if((e[k>>1]|0)>256|(e[n>>1]|0)>256|(e[o>>1]|0)>255){d=-1;l=C;return d|0}if((e[p>>1]|0)>255|(e[j>>1]|0)>64){d=-1;l=C;return d|0}if((h+-32&65535)>223|(e[q>>1]|0)>31?nn(31773,t,6)|0:0){d=-1;l=C;return d|0}h=(c[w>>2]|0)+-20|0;if(h>>>0>256){d=-1;l=C;return d|0}m=m+80|0;cm(m,h,1,f)|0;Ho(d,i,20)|0;h=e[k>>1]|0;c[d+156>>2]=h;j=e[j>>1]|0;B=d+136|0;c[B>>2]=j;i=e[n>>1]|0;c[d+128>>2]=i;n=d+140|0;c[n>>2]=e[o>>1];c[d+160>>2]=e[p>>1];c[d+148>>2]=e[q>>1];k=d+152|0;c[k>>2]=e[r>>1];c[d+132>>2]=(O(i,j)|0)+1;c[d+1264>>2]=8363;c[d+1292>>2]=b[s>>1]<<1&2;ep(d+952|0,m|0,h|0)|0;h=x+20|0;a[h>>0]=0;c[u>>2]=t;io(x,20,31780,u);switch(a[h>>0]|0){case 32:{a[h>>0]=0;v=8;break}case 0:{v=8;break}default:{}}a:do if((v|0)==8){h=x+19|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+18|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+17|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+16|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+15|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+14|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+13|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+12|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+11|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+10|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+9|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+8|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+7|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+6|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+5|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+4|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+3|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+2|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}h=x+1|0;switch(a[h>>0]|0){case 32:{a[h>>0]=0;break}case 0:break;default:break a}if((a[x>>0]|0)==32)a[x>>0]=0}while(0);if(!((on(x,31789,17)|0)!=0?(on(x,31807,8)|0)!=0:0)){u=d+1284|0;c[u>>2]=c[u>>2]|67108864}if((c[w>>2]|0)!=275){if(!(a[x>>0]|0)){h=x;i=32627;j=h+12|0;do{a[h>>0]=a[i>>0]|0;h=h+1|0;i=i+1|0}while((h|0)<(j|0));v=16}}else{h=x;i=33476;j=h+16|0;do{a[h>>0]=a[i>>0]|0;h=h+1|0;i=i+1|0}while((h|0)<(j|0));v=16}if((v|0)==16){v=d+1284|0;c[v>>2]=c[v>>2]&-67108865}if(!(on(x,31816,19)|0)){h=c[k>>2]|0;if((h|0)<11)c[k>>2]=((53-(h<<1)|0)*125|0)/33|0;v=d+1284|0;c[v>>2]=c[v>>2]&-67108865}if(!(on(x,31836,18)|0)){h=x;i=31855;j=h+20|0;do{a[h>>0]=a[i>>0]|0;h=h+1|0;i=i+1|0}while((h|0)<(j|0));v=d+1284|0;c[v>>2]=c[v>>2]&-67108865}h=e[z>>1]|0;c[y>>2]=x;c[y+4>>2]=h>>>8;c[y+8>>2]=h&255;ob(d,31875,y);dm(f,g+60+(c[w>>2]|0)|0,0)|0;y=b[z>>1]|0;h=y&65535;if((y&65535)<260){if((Ob(d,h,f)|0)<0){d=-1;l=C;return d|0}if((Pb(d,e[z>>1]|0,f)|0)<0){d=-1;l=C;return d|0}}else{if((Pb(d,h,f)|0)<0){d=-1;l=C;return d|0}if((Ob(d,e[z>>1]|0,f)|0)<0){d=-1;l=C;return d|0}}b:do if((e[z>>1]|0)<260?(A=c[n>>2]|0,(A|0)>0):0){k=d+176|0;m=d+180|0;i=c[k>>2]|0;h=A;j=0;c:while(1){if((c[i+(j*764|0)+36>>2]|0)>0){h=0;do{if((Eb(d,f,1,(c[m>>2]|0)+((c[(c[i+(j*764|0)+756>>2]|0)+(h<<6)+40>>2]|0)*52|0)|0,0)|0)<=-1){h=-1;break c}h=h+1|0;i=c[k>>2]|0}while((h|0)<(c[i+(j*764|0)+36>>2]|0));h=c[n>>2]|0}j=j+1|0;if((j|0)>=(h|0))break b}l=C;return h|0}while(0);if((c[B>>2]|0)>0){h=0;do{c[d+184+(h*12|0)>>2]=128;h=h+1|0}while((h|0)<(c[B>>2]|0))}f=d+1284|0;c[f>>2]=c[f>>2]|33554464;c[d+1288>>2]=1;d=0;l=C;return d|0}function Ob(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0;Ra=l;l=l+896|0;Ja=Ra+640|0;Ia=Ra+680|0;Ka=Ra;Qa=f+144|0;c[Qa>>2]=1024;if((Za(f)|0)<0){Qa=-1;l=Ra;return Qa|0}ta=f+140|0;a:do if((c[ta>>2]|0)>0){La=f+176|0;qa=Ja+4|0;Ba=Ja+26|0;za=Ja+28|0;Aa=Ja+32|0;Ea=Ia+192|0;va=Ia+193|0;Ga=Ia+194|0;Fa=Ia+195|0;Ca=Ia+196|0;xa=Ia+197|0;wa=Ia+198|0;ua=Ia+199|0;Ha=Ia+200|0;ya=Ia+201|0;Pa=Ia+202|0;Oa=Ia+203|0;Ma=Ia+204|0;Na=Ia+205|0;Da=Ia+206|0;sa=Ia+144|0;ra=Ia+96|0;oa=(g|0)>259;g=f+180|0;w=Ia+98|0;H=Ia+100|0;M=Ia+102|0;N=Ia+104|0;O=Ia+106|0;P=Ia+108|0;Q=Ia+110|0;R=Ia+112|0;S=Ia+114|0;x=Ia+116|0;y=Ia+118|0;z=Ia+120|0;A=Ia+122|0;B=Ia+124|0;C=Ia+126|0;D=Ia+128|0;E=Ia+130|0;F=Ia+132|0;G=Ia+134|0;I=Ia+136|0;J=Ia+138|0;K=Ia+140|0;L=Ia+142|0;T=Ia+146|0;ca=Ia+148|0;ha=Ia+150|0;ia=Ia+152|0;ja=Ia+154|0;ka=Ia+156|0;la=Ia+158|0;ma=Ia+160|0;na=Ia+162|0;U=Ia+164|0;V=Ia+166|0;W=Ia+168|0;X=Ia+170|0;Y=Ia+172|0;Z=Ia+174|0;_=Ia+176|0;$=Ia+178|0;aa=Ia+180|0;ba=Ia+182|0;da=Ia+184|0;ea=Ia+186|0;fa=Ia+188|0;ga=Ia+190|0;pa=0;j=0;b:while(1){q=c[La>>2]|0;c[Ja>>2]=_l(h)|0;if(fm(h)|0)break a;cm(qa,22,1,h)|0;a[Ba>>0]=Pl(h)|0;b[za>>1]=Rl(h)|0;k=_l(h)|0;c[Aa>>2]=k;i=b[za>>1]|0;if((i&65535)>16){g=-1;i=36;break}if(k>>>0>256&i<<16>>16!=0){g=-1;i=36;break}fb(c[La>>2]|0,pa,qa,22);u=b[za>>1]|0;v=q+(pa*764|0)+36|0;u=(u&65535)<16?u:16;i=u&65535;c[v>>2]=i;if(u<<16>>16){if((_a(f,pa,i)|0)<0){g=-1;i=36;break}i=c[Ja>>2]|0;if(i>>>0<33){g=-1;i=36;break}if(i>>>0<241){gp(Ia|0,0,208)|0;dm(h,i+-33|0,1)|0}else{cm(Ia,96,1,h)|0;b[ra>>1]=Rl(h)|0;b[w>>1]=Rl(h)|0;b[H>>1]=Rl(h)|0;b[M>>1]=Rl(h)|0;b[N>>1]=Rl(h)|0;b[O>>1]=Rl(h)|0;b[P>>1]=Rl(h)|0;b[Q>>1]=Rl(h)|0;b[R>>1]=Rl(h)|0;b[S>>1]=Rl(h)|0;b[x>>1]=Rl(h)|0;b[y>>1]=Rl(h)|0;b[z>>1]=Rl(h)|0;b[A>>1]=Rl(h)|0;b[B>>1]=Rl(h)|0;b[C>>1]=Rl(h)|0;b[D>>1]=Rl(h)|0;b[E>>1]=Rl(h)|0;b[F>>1]=Rl(h)|0;b[G>>1]=Rl(h)|0;b[I>>1]=Rl(h)|0;b[J>>1]=Rl(h)|0;b[K>>1]=Rl(h)|0;b[L>>1]=Rl(h)|0;b[sa>>1]=Rl(h)|0;b[T>>1]=Rl(h)|0;b[ca>>1]=Rl(h)|0;b[ha>>1]=Rl(h)|0;b[ia>>1]=Rl(h)|0;b[ja>>1]=Rl(h)|0;b[ka>>1]=Rl(h)|0;b[la>>1]=Rl(h)|0;b[ma>>1]=Rl(h)|0;b[na>>1]=Rl(h)|0;b[U>>1]=Rl(h)|0;b[V>>1]=Rl(h)|0;b[W>>1]=Rl(h)|0;b[X>>1]=Rl(h)|0;b[Y>>1]=Rl(h)|0;b[Z>>1]=Rl(h)|0;b[_>>1]=Rl(h)|0;b[$>>1]=Rl(h)|0;b[aa>>1]=Rl(h)|0;b[ba>>1]=Rl(h)|0;b[da>>1]=Rl(h)|0;b[ea>>1]=Rl(h)|0;b[fa>>1]=Rl(h)|0;b[ga>>1]=Rl(h)|0;a[Ea>>0]=Pl(h)|0;a[va>>0]=Pl(h)|0;a[Ga>>0]=Pl(h)|0;a[Fa>>0]=Pl(h)|0;a[Ca>>0]=Pl(h)|0;a[xa>>0]=Pl(h)|0;a[wa>>0]=Pl(h)|0;a[ua>>0]=Pl(h)|0;a[Ha>>0]=Pl(h)|0;a[ya>>0]=Pl(h)|0;a[Pa>>0]=Pl(h)|0;a[Oa>>0]=Pl(h)|0;a[Ma>>0]=Pl(h)|0;a[Na>>0]=Pl(h)|0;b[Da>>1]=Rl(h)|0;dm(h,(c[Ja>>2]|0)+-241|0,1)|0;c[q+(pa*764|0)+40>>2]=e[Da>>1]<<1;m=d[Ea>>0]|0;c[q+(pa*764|0)+48>>2]=m;c[q+(pa*764|0)+56>>2]=d[Ga>>0];c[q+(pa*764|0)+64>>2]=d[Fa>>0];c[q+(pa*764|0)+68>>2]=d[Ca>>0];k=d[Ha>>0]|0;n=q+(pa*764|0)+44|0;c[n>>2]=k;i=d[va>>0]|0;o=q+(pa*764|0)+204|0;c[o>>2]=i;c[q+(pa*764|0)+212>>2]=d[xa>>0];c[q+(pa*764|0)+220>>2]=d[wa>>0];c[q+(pa*764|0)+224>>2]=d[ua>>0];p=q+(pa*764|0)+200|0;c[p>>2]=d[ya>>0];if((m+-1|0)>>>0>11)c[n>>2]=k&254;else{ep(q+(pa*764|0)+72|0,ra|0,m<<2|0)|0;i=c[o>>2]|0}if((i+-1|0)>>>0>11){c[p>>2]=c[p>>2]&-2;i=12}else{ep(q+(pa*764|0)+228|0,sa|0,i<<2|0)|0;i=12}do{t=a[Ia+(i+-12)>>0]|0;u=q+(pa*764|0)+512+(i<<1)|0;a[u>>0]=t;a[u>>0]=(t&255|0)<(c[v>>2]|0)?t:-1;i=i+1|0}while((i|0)!=108)}if((c[v>>2]|0)>0){u=q+(pa*764|0)+756|0;t=0;do{m=c[u>>2]|0;k=c[Qa>>2]|0;i=c[g>>2]|0;if((j|0)>=(k|0)){i=eb(i,Qa,(k*3|0)/2|0)|0;c[g>>2]=i;if(!i){g=-1;i=36;break b}}s=_l(h)|0;k=Ka+(t*40|0)|0;c[k>>2]=s;if(s>>>0>268435456){g=-1;i=36;break b}s=Ka+(t*40|0)+4|0;c[s>>2]=_l(h)|0;o=Ka+(t*40|0)+8|0;c[o>>2]=_l(h)|0;Ta=Ka+(t*40|0)+12|0;a[Ta>>0]=Pl(h)|0;r=Ka+(t*40|0)+13|0;a[r>>0]=Nl(h)|0;n=Ka+(t*40|0)+14|0;a[n>>0]=Pl(h)|0;Sa=Ka+(t*40|0)+15|0;a[Sa>>0]=Pl(h)|0;p=Ka+(t*40|0)+16|0;a[p>>0]=Nl(h)|0;a[Ka+(t*40|0)+17>>0]=Pl(h)|0;q=Ka+(t*40|0)+18|0;cm(q,22,1,h)|0;c[m+(t<<6)>>2]=d[Ta>>0];c[m+(t<<6)+8>>2]=d[Sa>>0];c[m+(t<<6)+12>>2]=a[p>>0];c[m+(t<<6)+16>>2]=a[r>>0];c[m+(t<<6)+20>>2]=d[Pa>>0];c[m+(t<<6)+24>>2]=d[Ma>>0]<<2;c[m+(t<<6)+28>>2]=d[Na>>0];c[m+(t<<6)+32>>2]=d[Oa>>0];c[m+(t<<6)+40>>2]=j;gb(i+(j*52|0)|0,q,22)|0;k=c[k>>2]|0;q=i+(j*52|0)+32|0;c[q>>2]=k;m=c[s>>2]|0;s=i+(j*52|0)+36|0;c[s>>2]=m;o=(c[o>>2]|0)+m|0;r=i+(j*52|0)+40|0;c[r>>2]=o;p=i+(j*52|0)+44|0;c[p>>2]=0;n=a[n>>0]|0;if(!(n&16))i=0;else{c[p>>2]=1;c[q>>2]=k>>1;c[s>>2]=m>>1;c[r>>2]=o>>1;i=1}Ta=n&255;c[p>>2]=Ta<<1&2|i|(Ta&2|0?6:0);t=t+1|0;j=j+1|0;i=c[v>>2]|0}while((t|0)<(i|0));if((i|0)>0){k=0;do{if(oa){if((Eb(f,h,(a[Ka+(k*40|0)+17>>0]|0)==-83?16384:1,(c[g>>2]|0)+((c[(c[u>>2]|0)+(k<<6)+40>>2]|0)*52|0)|0,0)|0)<0){g=-1;i=36;break b}i=c[v>>2]|0}k=k+1|0}while((k|0)<(i|0))}}}else dm(h,(c[Ja>>2]|0)+-33|0,1)|0;pa=pa+1|0;if((pa|0)>=(c[ta>>2]|0))break a}if((i|0)==36){l=Ra;return g|0}}else{j=0;g=f+180|0}while(0);Ta=eb(c[g>>2]|0,Qa,j)|0;c[g>>2]=Ta;Ta=((Ta|0)==0)<<31>>31;l=Ra;return Ta|0}function Pb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;f=a+128|0;c[f>>2]=(c[f>>2]|0)+1;if(($a(a)|0)<0){a=-1;return a|0}a:do if((c[f>>2]|0)>1){e=0;while(1){if((Qb(a,e,b,d)|0)<0){e=-1;break}e=e+1|0;if((e|0)>=((c[f>>2]|0)+-1|0))break a}return e|0}else e=0;while(0);f=a+136|0;b=O(c[f>>2]|0,e)|0;if((ab(a,e)|0)<0){a=-1;return a|0}d=a+168|0;c[c[(c[d>>2]|0)+(e<<2)>>2]>>2]=64;if((bb(a,b,64)|0)<0){a=-1;return a|0}if((c[f>>2]|0)<=0){a=0;return a|0}e=c[(c[d>>2]|0)+(e<<2)>>2]|0;d=0;do{c[e+4+(d<<2)>>2]=b;d=d+1|0}while((d|0)<(c[f>>2]|0));e=0;return e|0}function Qb(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;h=(e|0)>258;g=_l(f)|0;Pl(f)|0;if(h)e=(Rl(f)|0)&65535;else e=((Pl(f)|0)&255)+1|0;e=e&65535;if(e>>>0>256){t=-1;return t|0}i=Rl(f)|0;dm(f,g-(h?9:8)|0,1)|0;if(gm(f)|0){t=-1;return t|0}e=(e|0)==0?256:e;if((db(b,d,e)|0)<0){t=-1;return t|0}g=i&65535;if(!(i<<16>>16)){t=0;return t|0}s=Xm(1,g)|0;if(!s){t=-1;return t|0}cm(s,1,g,f)|0;r=c[b+136>>2]|0;q=O(r,e)|0;a:do if((q|0)>0){p=c[b+172>>2]|0;n=c[(c[b+168>>2]|0)+(d<<2)>>2]|0;o=0;f=s;while(1){l=c[p+(c[n+4+(((o|0)%(r|0)|0)<<2)>>2]<<2)>>2]|0;m=(o|0)/(r|0)|0;k=l+4+(m<<3)|0;i=g+-1|0;if((g|0)<1)break;e=f+1|0;h=a[f>>0]|0;b=h&255;if(b&128){if(!(b&1))g=i;else{if((g|0)<2)break;a[k>>0]=a[e>>0]|0;e=f+2|0;g=g+-2|0}if(b&2){if((g|0)<1)break;a[l+4+(m<<3)+1>>0]=a[e>>0]|0;e=e+1|0;g=g+-1|0}if(b&4){if((g|0)<1)break;a[l+4+(m<<3)+2>>0]=a[e>>0]|0;e=e+1|0;g=g+-1|0}if(b&8){if((g|0)<1)break;a[l+4+(m<<3)+3>>0]=a[e>>0]|0;e=e+1|0;g=g+-1|0}if(!(b&16))j=e;else{if((g|0)<1)break;h=e;e=e+1|0;g=g+-1|0;t=30}}else{if((g|0)<5)break;a[k>>0]=h;a[l+4+(m<<3)+1>>0]=a[e>>0]|0;a[l+4+(m<<3)+2>>0]=a[f+2>>0]|0;a[l+4+(m<<3)+3>>0]=a[f+3>>0]|0;h=f+4|0;e=f+5|0;g=g+-5|0;t=30}if((t|0)==30){t=0;a[l+4+(m<<3)+4>>0]=a[h>>0]|0;j=e}d=l+4+(m<<3)+3|0;e=a[d>>0]|0;switch(e<<24>>24){case 32:case 31:case 30:case 28:case 26:case 24:case 23:case 22:case 19:case 18:{t=33;break}default:if((e&255)>34)t=33}if((t|0)==33){t=0;a[d>>0]=0;e=0}h=a[k>>0]|0;b:do switch(h<<24>>24){case 97:{if(e<<24>>24==14?(a[l+4+(m<<3)+4>>0]&-16)<<24>>24==-48:0){h=-127;t=39;break b}h=a[l+4+(m<<3)+1>>0]|0?-125:-127;t=39;break}case 0:break;default:{h=(h&255)+12&255;t=39}}while(0);if((t|0)==39){t=0;a[k>>0]=h}c:do if(e<<24>>24==14){f=l+4+(m<<3)+4|0;h=a[f>>0]|0;i=h&255;if((i&240|0)==80){h=(i+8&15|80)&255;a[f>>0]=h}switch(h<<24>>24){case 115:case 67:break;default:break c}a[f>>0]=h+-1<<24>>24}while(0);b=l+4+(m<<3)+2|0;h=a[b>>0]|0;if(h<<24>>24){f=h&255;d:do if((h+-16&255)<65)e=f+241&255;else do switch((h&255)>>>4&15){case 6:{a[l+4+(m<<3)+5>>0]=-92;a[l+4+(m<<3)+6>>0]=f+160;e=0;break d}case 7:{a[l+4+(m<<3)+5>>0]=-92;a[l+4+(m<<3)+6>>0]=f<<4;e=0;break d}case 8:{a[l+4+(m<<3)+5>>0]=14;a[l+4+(m<<3)+6>>0]=f|176;e=0;break d}case 9:{a[l+4+(m<<3)+5>>0]=14;a[l+4+(m<<3)+6>>0]=f+112|160;e=0;break d}case 10:{a[l+4+(m<<3)+5>>0]=4;a[l+4+(m<<3)+6>>0]=f<<4;e=0;break d}case 11:{a[l+4+(m<<3)+5>>0]=4;a[l+4+(m<<3)+6>>0]=f+80;e=0;break d}case 12:{a[l+4+(m<<3)+5>>0]=8;a[l+4+(m<<3)+6>>0]=f<<4;e=0;break d}case 13:{a[l+4+(m<<3)+5>>0]=-75;a[l+4+(m<<3)+6>>0]=f<<4;e=0;break d}case 14:{a[l+4+(m<<3)+5>>0]=-75;a[l+4+(m<<3)+6>>0]=f+32;e=0;break d}case 15:{a[l+4+(m<<3)+5>>0]=3;h=f<<4&255;i=l+4+(m<<3)+6|0;a[i>>0]=h;switch(e<<24>>24){case 3:case 5:{a[d>>0]=e<<24>>24==3?0:10;a[l+4+(m<<3)+4>>0]=0;a[i>>0]=h<<24>>24>-1?f<<5&255:-1;e=0;break d}case 9:{a[l+4+(m<<3)+4>>0]=0;a[d>>0]=0;e=0;break d}default:{e=0;break d}}}default:{e=0;break d}}while(0);while(0);a[b>>0]=e}o=o+1|0;if((o|0)>=(q|0))break a;else f=j}Wm(s);t=-1;return t|0}while(0);Wm(s);t=0;return t|0}function Rb(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0;m=l;l=l+1040|0;f=m+1024|0;k=m;dm(b,e+1080|0,0)|0;if((cm(f,1,4,b)|0)>>>0<4){d=-1;l=m;return d|0}if(!((((on(f+2|0,31995,2)|0)==0?(g=a[f>>0]|0,(g+-48|0)>>>0<10):0)?(h=a[f+1>>0]|0,(h+-48|0)>>>0<10):0)?(j=(g*10|0)+-480+h|0,(j|0)>48&(j+-48|0)<33):0))i=6;a:do if((i|0)==6){if((on(f+1|0,31998,3)|0)==0?(j=a[f>>0]|0,!(j<<24>>24==48|((j<<24>>24)+-48|0)>>>0>9)):0)break;if((((((((((((nn(f,34915,4)|0?nn(f,31907,4)|0:0)?nn(f,31912,4)|0:0)?nn(f,31917,4)|0:0)?nn(f,31922,4)|0:0)?nn(f,31927,4)|0:0)?nn(f,31932,4)|0:0)?nn(f,31937,4)|0:0)?nn(f,31942,4)|0:0)?nn(f,31947,4)|0:0)?nn(f,31952,4)|0:0)?nn(f,31957,4)|0:0)?nn(f,31962,4)|0:0){d=-1;l=m;return d|0}g=e+20|0;dm(b,g,0)|0;f=0;while(1){dm(b,22,1)|0;Ul(b)|0;j=Pl(b)|0;if(!((j&255)<16|j<<24>>24==32)){f=-1;i=23;break}if(((Pl(b)|0)&255)>64){f=-1;i=23;break}Ul(b)|0;Ul(b)|0;f=f+1|0;if((f|0)>=31){i=14;break}}if((i|0)==14){h=c[b+4>>2]|0;dm(b,g,0)|0;f=0;j=0;do{dm(b,22,1)|0;j=(((Ul(b)|0)&65535)<<1)+j|0;dm(b,6,1)|0;f=f+1|0}while((f|0)!=31);h=mm(h)|0;dm(b,e+952|0,0)|0;f=0;i=0;do{g=Pl(b)|0;n=g&255;g=g<<24>>24<0;i=g?i:(n|0)>(i|0)?n:i;f=f+1|0}while((f|0)<128&(g^1));g=e+1084|0;if((e+1852+j+(i*768|0)|0)==(h|0)){n=-1;l=m;return n|0}if((i|0)<0)break;else f=0;while(1){dm(b,(f<<10)+g|0,0)|0;cm(k,1024,1,b)|0;if((Vb(k)|0)<0){f=-1;break}if((f|0)<(i|0))f=f+1|0;else break a}l=m;return f|0}else if((i|0)==23){l=m;return f|0}}while(0);dm(b,e,0)|0;hb(b,d,20);n=0;l=m;return n|0}function Sb(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0;J=l;l=l+5520|0;I=J+24|0;A=J+16|0;z=J+8|0;u=J+32|0;x=J+5504|0;E=J+1408|0;y=J;s=J+1376|0;H=J+1120|0;gp(E|0,0,4096)|0;r=f+140|0;c[r>>2]=31;G=f+144|0;c[G>>2]=31;D=f+136|0;c[D>>2]=0;F=f+1292|0;c[F>>2]=1;cm(u,20,1,g)|0;i=0;t=0;do{cm(u+20+(i*30|0)|0,22,1,g)|0;w=u+20+(i*30|0)+22|0;b[w>>1]=Ul(g)|0;a[u+20+(i*30|0)+24>>0]=Pl(g)|0;a[u+20+(i*30|0)+25>>0]=Pl(g)|0;b[u+20+(i*30|0)+26>>1]=Ul(g)|0;b[u+20+(i*30|0)+28>>1]=Ul(g)|0;t=(e[w>>1]<<1)+t|0;i=i+1|0}while((i|0)!=31);n=u+950|0;a[n>>0]=Pl(g)|0;w=u+951|0;a[w>>0]=Pl(g)|0;o=u+952|0;cm(o,128,1,g)|0;v=y;c[v>>2]=0;c[v+4>>2]=0;cm(y,1,4,g)|0;if(gm(g)|0){I=-1;l=J;return I|0}if(on(y,34915,4)|0)if(on(y,31907,4)|0)if(on(y,31912,4)|0)if(on(y,31917,4)|0)if(on(y,31922,4)|0)if(on(y,31927,4)|0)if(on(y,31932,4)|0)if(on(y,31937,4)|0)if(on(y,31942,4)|0)if(on(y,31947,4)|0)if(on(y,31952,4)|0)if(on(y,31957,4)|0)if(on(y,31962,4)|0)if(!(c[D>>2]|0)){if(((on(y+2|0,31995,2)|0)==0?(j=a[y>>0]|0,(j+-48|0)>>>0<10):0)?(k=a[y+1>>0]|0,(k+-48|0)>>>0<10):0)i=(j*10|0)+-480+k|0;else{if(on(y+1|0,31998,3)|0){I=-1;l=J;return I|0}i=a[y>>0]|0;if((i+-48|0)>>>0>=10){I=-1;l=J;return I|0}}k=i+-48|0;c[D>>2]=k;q=1;k=k<<1&2|4}else{q=0;k=0}else{i=4;j=12;C=5}else{i=8;j=11;C=5}else{i=6;j=10;C=5}else{i=4;j=9;C=5}else{i=4;j=8;C=5}else{i=8;j=7;C=5}else{i=6;j=6;C=5}else{i=8;j=5;C=5}else{i=6;j=4;C=5}else{i=4;j=3;C=5}else{i=4;j=2;C=5}else{i=4;j=1;C=5}else{i=4;j=0;C=5}if((C|0)==5){c[D>>2]=i;q=c[1048+(j<<4)+4>>2]|0;k=c[1048+(j<<4)+8>>2]|0}Ho(f,u,20)|0;v=d[n>>0]|0;c[f+156>>2]=v;i=f+160|0;if((c[i>>2]|0)>=(v|0))c[i>>2]=0;n=f+952|0;i=o;j=n+128|0;do{b[n>>1]=b[i>>1]|0;n=n+2|0;i=i+2|0}while((n|0)<(j|0));v=f+128|0;i=c[v>>2]|0;n=0;do{p=a[f+952+n>>0]|0;j=p&255;if(p<<24>>24<0)break;if((j|0)>(i|0)){c[v>>2]=j;i=j}n=n+1|0}while((n|0)<128);c[v>>2]=i+1;if((Za(f)|0)<0){I=-1;l=J;return I|0}a:do if((c[r>>2]|0)>0){o=f+176|0;p=f+180|0;i=q;n=0;while(1){if((_a(f,n,1)|0)<0){i=-1;break}P=b[u+20+(n*30|0)+22>>1]|0;j=P<<16>>16<0;k=j?11:k;i=j?1:i;j=c[o>>2]|0;K=c[j+(n*764|0)+756>>2]|0;L=c[p>>2]|0;P=(P&65535)<<1;q=L+(n*52|0)+32|0;c[q>>2]=P;M=e[u+20+(n*30|0)+26>>1]<<1;c[L+(n*52|0)+36>>2]=M;N=b[u+20+(n*30|0)+28>>1]|0;M=((N&65535)<<1)+M|0;M=M>>>0>P>>>0?P:M;c[L+(n*52|0)+40>>2]=M;c[L+(n*52|0)+44>>2]=(N&65535)>1&(M|0)>3?2:0;c[K+16>>2]=d[u+20+(n*30|0)+24>>0]<<28>>24;c[K>>2]=a[u+20+(n*30|0)+25>>0];c[K+8>>2]=128;c[K+40>>2]=n;fb(c[o>>2]|0,n,u+20+(n*30|0)|0,22);if((c[q>>2]|0)>0)c[j+(n*764|0)+36>>2]=1;n=n+1|0;if((n|0)>=(c[r>>2]|0))break a}l=J;return i|0}else i=q;while(0);b:do if(!i){P=t+1084+(O(c[v>>2]<<8,c[D>>2]|0)|0)|0;j=f+1240|0;do if((P|0)<(c[j>>2]|0)){i=em(g)|0;if((i|0)>=0){dm(g,h+1084+t+(O(c[v>>2]<<8,c[D>>2]|0)|0)|0,0)|0;cm(s,1,4,g)|0;dm(g,i+h|0,0)|0;if(!(nn(s,32002,4)|0)){i=0;k=8;C=39;break b}else break}else{P=-1;l=J;return P|0}}while(0);if((on(y,34915,4)|0)==0?(m=c[v>>2]|0,((m<<11|1084)+t|0)==(c[j>>2]|0)):0){c[D>>2]=8;j=8;t=0;k=9;break}if(!(on(y,34915,4)|0)){P=((c[v>>2]<<10)+1084|0)==(c[j>>2]|0);i=P&1;if(P){k=0;C=39;break}}else i=0;k=Tb(f,u,k)|0;C=39}else{i=0;C=39}while(0);do if((C|0)==39){j=c[D>>2]|0;if((j|0)>63){P=-1;l=J;return P|0}else{m=c[v>>2]|0;t=i;break}}while(0);c[f+132>>2]=O(m,j)|0;if(($a(f)|0)<0){P=-1;l=J;return P|0}c:do if((c[v>>2]|0)>0){s=f+172|0;r=f+168|0;n=x+1|0;o=x+2|0;p=x+3|0;q=0;i=0;while(1){if((db(f,q,64)|0)<0){i=-1;C=107;break}m=em(g)|0;if((m|0)<0){i=-1;C=107;break}if((c[D>>2]|0)>0){j=0;do{cm(x,1,4,g)|0;P=(a[x>>0]&15)<<8|d[n>>0];i=(P|0)!=0&(P+-108|0)>>>0>799?1:i;do if((k|0)==20){P=a[o>>0]&15;if((P+-7&255)>=3?P<<24>>24!=14|(a[p>>0]&14)==0:0){k=20;break}k=99}while(0);j=j+1|0}while((j|0)<(c[D>>2]<<6|0))}d:do if(i){k=(k|0)==99&(a[w>>0]|0)==127?10:k;switch(k|0){case 0:case 1:case 2:case 20:break;default:break d}k=99}while(0);dm(g,m,0)|0;j=c[D>>2]|0;e:do if((j|0)>0){m=0;while(1){j=(c[(c[s>>2]|0)+(c[(c[(c[r>>2]|0)+(q<<2)>>2]|0)+4+(((m|0)%(j|0)|0)<<2)>>2]<<2)>>2]|0)+4+(((m|0)/(j|0)|0)<<3)|0;cm(x,1,4,g)|0;switch(k|0){case 1:case 20:{jb(j,x);break}default:lb(j,x)}m=m+1|0;j=c[D>>2]|0;if((m|0)>=(j<<6|0))break e}}while(0);q=q+1|0;if((q|0)>=(c[v>>2]|0)){q=k;break c}}if((C|0)==107){l=J;return i|0}}else{i=0;q=k}while(0);do switch(q|0){case 0:{k=1;j=32143;break}case 1:case 20:{k=f+1284|0;c[k>>2]=c[k>>2]|268435456;k=0;j=32130;break}case 2:{k=f+1284|0;c[k>>2]=c[k>>2]|268435456;k=0;j=33440;break}case 4:case 3:{c[F>>2]=0;k=0;j=32117;break}case 6:{c[F>>2]=0;k=0;j=32104;break}case 5:{k=0;j=32094;break}case 7:{k=0;j=34359;break}case 8:{k=0;j=32085;break}case 9:{k=0;j=32073;break}case 10:{c[F>>2]=0;k=0;j=32058;break}case 97:case 96:{k=0;j=32048;break}case 98:{c[F>>2]=0;k=0;j=32031;break}case 11:{k=1;j=32023;break}default:{c[F>>2]=0;k=0;j=32007}}while(0);if(i|0)c[F>>2]=0;i=f+64|0;if((q|0)==9){c[z>>2]=j;io(i,64,34920,z)}else{c[A>>2]=j;c[A+4>>2]=y;io(i,64,32154,A)}i=c[f+1216>>2]|0;if(i|0?(B=Eo(i,47)|0,B|0):0)Ho(E,i,B-i|0)|0;f:do if((c[G>>2]|0)>0){p=f+180|0;o=(k|0)==0;m=(t|0)==0;n=f+176|0;k=0;g:while(1){i=c[p>>2]|0;do if(c[i+(k*52|0)+32>>2]|0){if(o)i=0;else i=(c[i+(k*52|0)+36>>2]|0)==0?512:0;if(!m){j=(c[n>>2]|0)+(k*764|0)|0;c[I>>2]=E;c[I+4>>2]=j;io(H,64,35104,I);j=hm(H,35139)|0;if(j|0?(P=(Eb(f,j,i,(c[p>>2]|0)+(k*52|0)|0,0)|0)<0,lm(j),P):0){C=92;break g}break}j=em(g)|0;if((j|0)<0){C=99;break g}do if((cm(H,1,5,g)|0)==5){if(nn(H,32160,5)|0){C=97;break}i=i|16384}else C=97;while(0);if((C|0)==97){C=0;dm(g,j,0)|0}if((Eb(f,g,i,(c[p>>2]|0)+(k*52|0)|0,0)|0)<0){C=99;break g}}while(0);k=k+1|0;if((k|0)>=(c[G>>2]|0))break f}if((C|0)==92){P=-1;l=J;return P|0}else if((C|0)==99){P=-1;l=J;return P|0}}while(0);switch(q|0){case 0:case 11:{P=f+1284|0;c[P>>2]=c[P>>2]|4;P=0;l=J;return P|0}case 10:{c[f+1264>>2]=8363;P=f+1284|0;c[P>>2]=c[P>>2]|1224737313;c[f+1288>>2]=2;P=0;l=J;return P|0}case 3:case 4:case 6:case 9:break;default:if((c[D>>2]|0)<=4){P=0;l=J;return P|0}}c[f+1264>>2]=8363;P=f+1284|0;c[P>>2]=c[P>>2]|33558560;c[f+1288>>2]=1;c[F>>2]=0;P=0;l=J;return P|0}function Tb(d,e,f){d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;g=0;while(1){if(!(b[e+20+(g*30|0)+28>>1]|0)){i=1;break}g=g+1|0;if((g|0)>=31){i=0;break}}g=0;while(1){if((b[e+20+(g*30|0)+22>>1]|0)==0?(a[e+20+(g*30|0)+25>>0]|0)>0:0){j=1;break}g=g+1|0;if((g|0)>=31){j=0;break}}g=a[e+951>>0]|0;h=g&255;do if((h|0)!=(c[d+128>>2]|0)){if(g<<24>>24==120){n=(c[d+136>>2]|0)==4?20:99;return n|0}if((g&255)<127){g=c[d+136>>2]|0;c[d+160>>2]=h;f=g;g=(j|0)!=0|(g|0)!=4?99:1;break}if(g<<24>>24!=127){n=99;return n|0}if((c[d+136>>2]|0)==4)return ((i|0)==0?f:98)|0;else{n=10;return n|0}}else{g=c[d+136>>2]|0;f=g;g=(g|0)==4?2:99}while(0);a:do if(!i){h=0;while(1){if((b[e+20+(h*30|0)+22>>1]|0)==1?(a[e+20+(h*30|0)+25>>0]|0)==0:0){m=97;n=42;break}h=h+1|0;if((h|0)>=31){k=0;break}}if((n|0)==42)return m|0;do{if(Ub(e+20+(k*30|0)|0)|0)break a;k=k+1|0}while((k|0)<31);if((k|0)==31){g=0;while(1){if((b[e+20+(g*30|0)+22>>1]|0)==0?(b[e+20+(g*30|0)+28>>1]|0)==1:0)break;g=g+1|0;if((g|0)>=31){n=30;break}}if((n|0)==30)switch(f|0){case 4:{g=0;break a}case 8:case 6:{g=3;break a}default:{g=99;break a}}switch(f|0){case 4:{n=(j|0)==0?1:11;return n|0}case 8:case 6:{n=5;return n|0}default:{n=99;return n|0}}}}else{g=15;while(1){if(fo(e+20+(g*30|0)|0)|0){l=0;break}if(b[e+20+(g*30|0)+22>>1]|0){l=0;break}g=g+1|0;if((g|0)>=31){n=36;break}}if((n|0)==36)if((g|0)==31?(Ub(e+440|0)|0)!=0:0){n=96;return n|0}else l=0;do{if(Ub(e+20+(l*30|0)|0)|0){m=95;n=42;break}l=l+1|0}while((l|0)<31);if((n|0)==42)return m|0;switch(f|0){case 8:case 6:case 4:{m=3;break}default:{g=99;break a}}return m|0}while(0);n=g;return n|0}function Ub(b){b=b|0;switch(a[b>>0]|0){case 83:case 115:break;default:return 0}switch(a[b+1>>0]|0){case 84:case 116:break;default:return 0}if((a[b+2>>0]|0)!=45)return 0;if((a[b+5>>0]|0)!=58)return 0;if(((a[b+3>>0]|0)+-48|0)>>>0<10)return ((a[b+4>>0]|0)+-48|0)>>>0<10|0;else return 0;return 0}function Vb(a){a=a|0;var b=0,c=0;b=0;while(1){c=b<<4;if((d[a+c>>0]|0)>=32){a=-1;b=4;break}if((d[a+(c|4)>>0]|0)>=32){a=-1;b=4;break}if((d[a+(c|8)>>0]|0)>=32){a=-1;b=4;break}if((d[a+(c|12)>>0]|0)>=32){a=-1;b=4;break}b=b+1|0;if((b|0)>=64){a=0;b=4;break}}if((b|0)==4)return a|0;return 0}function Wb(a,b,c){a=a|0;b=b|0;c=c|0;dm(a,c+44|0,0)|0;if((am(a)|0)!=1396920909){b=-1;return b|0}dm(a,c+29|0,0)|0;if((Pl(a)|0)<<24>>24!=16){b=-1;return b|0}dm(a,c,0)|0;hb(a,b,28);b=0;return b|0}function Xb(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0;ea=l;l=l+368|0;D=ea+56|0;A=ea+48|0;y=ea+40|0;x=ea+32|0;w=ea+24|0;B=ea+16|0;z=ea+8|0;v=ea;H=ea+360|0;o=ea+224|0;da=ea+144|0;ca=ea+64|0;C=ea+320|0;cm(o,28,1,g)|0;Pl(g)|0;a[o+29>>0]=Pl(g)|0;Rl(g)|0;p=o+32|0;b[p>>1]=Rl(g)|0;q=o+34|0;b[q>>1]=Rl(g)|0;r=o+36|0;b[r>>1]=Rl(g)|0;k=o+38|0;b[k>>1]=Rl(g)|0;u=o+40|0;b[u>>1]=Rl(g)|0;ba=o+42|0;b[ba>>1]=Rl(g)|0;if(gm(g)|0){h=-1;l=ea;return h|0}if(((b[ba>>1]|0)+-1&65535)>=2){h=-1;l=ea;return h|0}if(((b[q>>1]|b[p>>1]|b[r>>1])&65535)>255){h=-1;l=ea;return h|0}c[o+44>>2]=am(g)|0;a[o+48>>0]=Pl(g)|0;m=o+49|0;a[m>>0]=Pl(g)|0;n=o+50|0;a[n>>0]=Pl(g)|0;t=o+51|0;a[t>>0]=Pl(g)|0;a[o+52>>0]=Pl(g)|0;s=o+53|0;a[s>>0]=Pl(g)|0;_l(g)|0;_l(g)|0;b[o+62>>1]=Rl(g)|0;cm(o+64|0,32,1,g)|0;if(gm(g)|0){h=-1;l=ea;return h|0}if((b[u>>1]|0)==4865?(a[o+27>>0]|0)==-121:0){j=0;do{i=o+j|0;if((a[i>>0]|0)==-121)a[i>>0]=0;j=j+1|0}while((j|0)!=28);if((a[r>>0]|0)==-121)a[r>>0]=0;i=r+1|0;if((a[i>>0]|0)==-121)a[i>>0]=0;if((a[k>>0]|0)==-121)a[k>>0]=0;i=k+1|0;if((a[i>>0]|0)==-121){a[i>>0]=0;aa=1}else aa=1}else aa=0;gb(f,o,28)|0;_=Xm(2,e[q>>1]|0)|0;if(!_){h=-1;l=ea;return h|0}$=Xm(2,e[r>>1]|0)|0;if($|0){i=e[k>>1]|0;if(i&16|0)c[f+1292>>2]=1;if(i&64|0){Z=f+1284|0;c[Z>>2]=c[Z>>2]|64}c[f+148>>2]=d[m>>0];c[f+152>>2]=d[n>>0];G=f+136|0;c[G>>2]=0;m=(a[t>>0]|0)<0;j=0;do{i=a[o+64+j>>0]|0;k=j;j=j+1|0;if(i<<24>>24!=-1){c[G>>2]=j;c[f+184+(k*12|0)>>2]=m?((i&8)<8?48:192):128}}while((j|0)!=32);Z=b[p>>1]|0;i=Z&65535;j=f+156|0;if((Z&65535)<257){c[j>>2]=i;cm(f+952|0,1,i,g)|0}else{c[j>>2]=256;cm(f+952|0,1,256,g)|0;dm(g,(e[p>>1]|0)+-256|0,1)|0}a:do if(!(gm(g)|0)){F=f+128|0;c[F>>2]=-1;k=c[j>>2]|0;if((k|0)>0){j=-1;m=0;do{Z=a[f+952+m>>0]|0;i=Z&255;if((Z&255)<254&(i|0)>(j|0)){c[F>>2]=i;j=i}m=m+1|0}while((m|0)!=(k|0))}else j=-1;i=b[r>>1]|0;Z=i&65535;j=(j|0)<(Z|0)?j+1|0:Z;c[F>>2]=j;if(j|0){c[f+132>>2]=O(c[G>>2]|0,j)|0;Y=b[q>>1]|0;X=Y&65535;Z=f+140|0;c[Z>>2]=X;c[f+144>>2]=X;if(Y<<16>>16){i=0;do{b[_+(i<<1)>>1]=Rl(g)|0;i=i+1|0}while((i|0)<(e[q>>1]|0));i=b[r>>1]|0}if(i<<16>>16){i=0;do{b[$+(i<<1)>>1]=Rl(g)|0;i=i+1|0}while((i|0)<(e[r>>1]|0))}Y=(d[s>>0]|0)+4&255;a[s>>0]=Y;if(!(Y<<24>>24)){j=0;do{i=(Pl(g)|0)&255;if(!(i&32))i=(a[t>>0]&127)==0?128:(0-(j&1)&160)+48|0;else i=i<<4&240;c[f+184+(j*12|0)>>2]=i;j=j+1|0}while((j|0)<32&(a[s>>0]|0)==0)}c[f+1264>>2]=8363;i=b[u>>1]|0;j=i&65535;if(i<<16>>16==4864){Y=f+1284|0;c[Y>>2]=c[Y>>2]|64}b:do switch((i&65535)>>>12&15){case 1:{c[v>>2]=j>>>8&15;c[v+4>>2]=j&255;io(C,40,32183,v);Y=f+1284|0;c[Y>>2]=c[Y>>2]|16;break}case 2:{c[z>>2]=j>>>8&15;c[z+4>>2]=j&255;io(C,40,32206,z);break}case 3:switch(i<<16>>16){case 12822:{i=C;j=32787;k=i+23|0;do{a[i>>0]=a[j>>0]|0;i=i+1|0;j=j+1|0}while((i|0)<(k|0));break b}case 12823:{i=C;j=32810;k=i+23|0;do{a[i>>0]=a[j>>0]|0;i=i+1|0;j=j+1|0}while((i|0)<(k|0));break b}default:{c[B>>2]=j>>>8&15;c[B+4>>2]=j&255;io(C,40,32852,B);break b}}case 5:{c[w>>2]=j>>>8&15;c[w+4>>2]=j&255;io(C,40,32963,w);Y=f+1284|0;c[Y>>2]=c[Y>>2]|16;break}case 4:{if(i<<16>>16==16640){E=56;break b}c[x>>2]=j>>>8&15;c[x+4>>2]=j&255;io(C,40,32228,x);break}case 6:{E=56;break}default:{c[A>>2]=j;io(C,40,32898,A)}}while(0);if((E|0)==56){c[y>>2]=j>>>8&15;c[y+4>>2]=j&255;io(C,40,32995,y)}c[D>>2]=C;ob(f,32251,D);if(($a(f)|0)>=0){if((c[F>>2]|0)>0){p=f+168|0;q=f+172|0;o=0;do{if((db(f,o,64)|0)<0)break a;i=b[$+(o<<1)>>1]|0;c:do if(i<<16>>16){dm(g,((i&65535)<<4)+h|0,0)|0;i=((Rl(g)|0)&65535)+-2|0;if((i|0)>-1)j=0;else break;do{if((j|0)>=(c[c[(c[p>>2]|0)+(o<<2)>>2]>>2]|0))break c;while(1){k=Pl(g)|0;if(gm(g)|0)break a;if(k<<24>>24)break;j=j+1|0;if((j|0)>=(c[c[(c[p>>2]|0)+(o<<2)>>2]>>2]|0))break c}n=k&255;k=n&31;if((k|0)<(c[G>>2]|0))m=(c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+(k<<2)>>2]<<2)>>2]|0)+4+(j<<3)|0;else m=H;if(n&32){Y=Pl(g)|0;k=Y&255;switch(Y<<24>>24){case -1:{k=0;break}case -2:{k=-127;break}default:k=(k&15)+13+((k>>>4)*12|0)&255}a[m>>0]=k;a[m+1>>0]=Pl(g)|0;i=i+-2|0}if(n&64){a[m+2>>0]=((Pl(g)|0)&255)+1;i=i+-1|0}if(n&128){a[m+3>>0]=Pl(g)|0;a[m+4>>0]=Pl(g)|0;Yb(m);i=i+-2|0}}while((i|0)>-1)}while(0);o=o+1|0}while((o|0)<(c[F>>2]|0))}if((Za(f)|0)<0)break;d:do if((c[Z>>2]|0)>0){X=f+176|0;Y=f+180|0;o=ca+12|0;p=ca+15|0;V=ca+27|0;F=ca+28|0;D=ca+32|0;q=ca+36|0;r=ca+48|0;P=ca+76|0;R=da+14|0;L=da+16|0;M=da+20|0;N=da+24|0;W=da+28|0;T=da+29|0;S=da+30|0;G=da+31|0;E=da+32|0;U=da+34|0;s=da+36|0;J=da+40|0;I=da+42|0;K=da+44|0;t=da+48|0;Q=da+76|0;u=L+1|0;v=L+2|0;w=L+3|0;x=M+1|0;y=M+2|0;z=M+3|0;A=N+1|0;B=N+2|0;C=N+3|0;H=0;e:while(1){j=c[X>>2]|0;k=c[Y>>2]|0;n=k+(H*52|0)|0;m=Xm(64,1)|0;c[j+(H*764|0)+756>>2]=m;if(!m)break a;dm(g,(e[_+(H<<1)>>1]<<4)+h|0,0)|0;i=Pl(g)|0;c[m+8>>2]=128;c[m+40>>2]=H;if((i&255)>1){cm(ca,12,1,g)|0;cm(o,3,1,g)|0;cm(p,12,1,g)|0;a[V>>0]=Pl(g)|0;a[F>>0]=Pl(g)|0;Rl(g)|0;b[D>>1]=Rl(g)|0;Rl(g)|0;cm(q,12,1,g)|0;cm(r,28,1,g)|0;k=am(g)|0;c[P>>2]=k;if((k|0)!=1396920905)break a;c[P>>2]=0;fb(c[X>>2]|0,H,r,28);c[j+(H*764|0)+36>>2]=1;c[m>>2]=d[V>>0];j=m+12|0;Gi(e[D>>1]|0,j,m+16|0);c[j>>2]=(c[j>>2]|0)+12;j=58;i=Eb(f,g,4096,n,p)|0}else{cm(da,13,1,g)|0;b[R>>1]=Rl(g)|0;fa=_l(g)|0;c[L>>2]=fa;if(fa>>>0>268435456)break a;c[M>>2]=_l(g)|0;c[N>>2]=_l(g)|0;a[W>>0]=Pl(g)|0;a[T>>0]=Pl(g)|0;a[S>>0]=Pl(g)|0;a[G>>0]=Pl(g)|0;b[E>>1]=Rl(g)|0;b[U>>1]=Rl(g)|0;cm(s,4,1,g)|0;b[J>>1]=Rl(g)|0;b[I>>1]=Rl(g)|0;c[K>>2]=_l(g)|0;cm(t,28,1,g)|0;fa=am(g)|0;c[Q>>2]=fa;if(!(i<<24>>24!=1|(fa|0)==1396920915))break a;do if(aa){if((a[L>>0]|0)==-121)a[L>>0]=0;if((a[u>>0]|0)==-121)a[u>>0]=0;if((a[v>>0]|0)==-121)a[v>>0]=0;if((a[w>>0]|0)==-121)a[w>>0]=0;if((a[M>>0]|0)==-121)a[M>>0]=0;if((a[x>>0]|0)==-121)a[x>>0]=0;if((a[y>>0]|0)==-121)a[y>>0]=0;if((a[z>>0]|0)==-121)a[z>>0]=0;if((a[N>>0]|0)==-121)a[N>>0]=0;if((a[A>>0]|0)==-121)a[A>>0]=0;if((a[B>>0]|0)==-121)a[B>>0]=0;if((a[C>>0]|0)==-121)a[C>>0]=0;i=a[G>>0]|0;if(i<<24>>24!=-121)break;a[G>>0]=0;i=0}else i=a[G>>0]|0;while(0);fa=c[L>>2]|0;c[k+(H*52|0)+32>>2]=fa;c[j+(H*764|0)+36>>2]=(fa|0)!=0&1;c[k+(H*52|0)+36>>2]=c[M>>2];c[k+(H*52|0)+40>>2]=c[N>>2];c[k+(H*52|0)+44>>2]=((i&255)>>>2&1|i<<1&2)&255;c[m>>2]=d[W>>0];c[Q>>2]=0;fb(c[X>>2]|0,H,t,28);Gi(e[E>>1]|0,m+12|0,m+16|0);dm(g,(e[R>>1]<<4)+h|0,0)|0;j=0;i=Eb(f,g,(b[ba>>1]|0)==1?0:2,n,0)|0}switch(((i|0)<0?22:j)&63){case 22:break a;case 58:case 0:break;default:{i=0;break e}}H=H+1|0;if((H|0)>=(c[Z>>2]|0))break d}l=ea;return i|0}while(0);Wm($);Wm(_);fa=f+1284|0;c[fa>>2]=c[fa>>2]|1761608225;c[f+1288>>2]=2;fa=0;l=ea;return fa|0}}}while(0);Wm($)}Wm(_);fa=-1;l=ea;return fa|0}function Yb(b){b=b|0;var c=0,d=0,e=0,f=0,g=0;g=b+4|0;d=a[g>>0]|0;f=d&255;e=f&15;c=b+3|0;b=a[c>>0]|0;if((b&255)>26){a[g>>0]=0;a[c>>0]=0;return}b=a[32258+(b&255)>>0]|0;a[c>>0]=b;switch(b<<24>>24){case -85:{if((d&255)>=32)return;a[c>>0]=0;a[g>>0]=0;return}case -2:{a[c>>0]=14;switch((d&255)>>>4&15){case 1:{a[g>>0]=e|48;return}case 2:{a[g>>0]=f+8&15|80;return}case 3:{a[g>>0]=e|64;return}case 4:{a[g>>0]=e|112;return}case 10:case 9:case 7:case 6:case 5:{a[g>>0]=0;a[c>>0]=0;return}case 8:{a[c>>0]=8;a[g>>0]=f<<4;return}case 11:{a[g>>0]=e|96;return}case 12:{if(e|0)return;a[g>>0]=0;a[c>>0]=0;return}default:return}}case 8:if(d<<24>>24==-92){a[c>>0]=-115;a[g>>0]=1;return}else{f=f<<1;a[g>>0]=f>>>0<255?f:255;return}case -1:{a[g>>0]=0;a[c>>0]=0;return}default:return}}function Zb(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;e=l;l=l+16|0;d=e;dm(a,c+20|0,0)|0;do if((cm(d,1,8,a)|0)>>>0>=8){if(nn(d,33085,8)|0?nn(d,33039,8)|0:0){d=-1;break}Pl(a)|0;if((Pl(a)|0)<<24>>24==2?(Pl(a)|0)<<24>>24!=0:0){dm(a,c,0)|0;hb(a,b,20);d=0}else d=-1}else d=-1;while(0);l=e;return d|0}function _b(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;u=l;l=l+1184|0;n=u+8|0;m=u;q=u+16|0;cm(q,20,1,g)|0;h=q+20|0;cm(h,8,1,g)|0;a[q+28>>0]=Pl(g)|0;a[q+29>>0]=Pl(g)|0;o=q+30|0;a[o>>0]=Pl(g)|0;p=q+31|0;a[p>>0]=Pl(g)|0;k=q+32|0;a[k>>0]=Pl(g)|0;j=q+33|0;a[j>>0]=Pl(g)|0;a[q+34>>0]=Pl(g)|0;cm(q+35|0,13,1,g)|0;i=0;do{cm(q+48+(i*36|0)|0,12,1,g)|0;a[q+48+(i*36|0)+12>>0]=Pl(g)|0;a[q+48+(i*36|0)+13>>0]=Pl(g)|0;b[q+48+(i*36|0)+14>>1]=Rl(g)|0;b[q+48+(i*36|0)+16>>1]=Rl(g)|0;b[q+48+(i*36|0)+18>>1]=Rl(g)|0;b[q+48+(i*36|0)+20>>1]=Rl(g)|0;a[q+48+(i*36|0)+22>>0]=Pl(g)|0;a[q+48+(i*36|0)+23>>0]=Pl(g)|0;b[q+48+(i*36|0)+24>>1]=Rl(g)|0;c[q+48+(i*36|0)+28>>2]=_l(g)|0;b[q+48+(i*36|0)+32>>1]=Rl(g)|0;i=i+1|0}while((i|0)!=31);if(gm(g)|0){f=-1;l=u;return f|0}i=(on(h,33039,8)|0)==0;s=f+136|0;c[s>>2]=4;t=d[j>>0]|0;r=f+128|0;c[r>>2]=t;c[f+132>>2]=t<<2;c[f+148>>2]=(d[k>>0]|0)>>>4;t=f+140|0;c[t>>2]=31;c[f+144>>2]=31;c[f+1264>>2]=8363;gb(f,q,20)|0;h=f+64|0;if(i)io(h,64,32302,m);else{p=d[p>>0]|0;c[n>>2]=d[o>>0];c[n+4>>2]=p;io(h,64,32315,n)}if((Za(f)|0)<0){f=-1;l=u;return f|0}a:do if((c[t>>2]|0)>0){k=f+180|0;j=f+176|0;i=0;while(1){if((_a(f,i,1)|0)<0){h=-1;break}p=b[q+48+(i*36|0)+16>>1]|0;h=c[k>>2]|0;c[h+(i*52|0)+32>>2]=p&65535;c[h+(i*52|0)+36>>2]=e[q+48+(i*36|0)+18>>1];o=b[q+48+(i*36|0)+20>>1]|0;o=o<<16>>16==-1?0:o&65535;c[h+(i*52|0)+40>>2]=o;c[h+(i*52|0)+44>>2]=o|0?2:0;h=c[j>>2]|0;o=c[h+(i*764|0)+756>>2]|0;c[o>>2]=d[q+48+(i*36|0)+22>>0];c[o+8>>2]=128;c[o+40>>2]=i;if(p<<16>>16)c[h+(i*764|0)+36>>2]=1;fb(h,i,q+48+(i*36|0)|0,12);p=c[(c[j>>2]|0)+(i*764|0)+756>>2]|0;Gi(e[q+48+(i*36|0)+24>>1]|0,p+12|0,p+16|0);i=i+1|0;if((i|0)>=(c[t>>2]|0))break a}l=u;return h|0}while(0);cm(f+952|0,1,128,g)|0;i=c[r>>2]|0;h=0;do{if((d[f+952+h>>0]|0)>=(i|0))break;h=h+1|0}while((h|0)<128);c[f+156>>2]=h;if(($a(f)|0)<0){f=-1;l=u;return f|0}b:do if((c[r>>2]|0)>0){q=f+172|0;p=f+168|0;o=0;while(1){if((db(f,o,64)|0)<0){h=-1;break}h=c[s>>2]|0;if((h|0)>0){n=0;do{m=c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+(((n|0)%(h|0)|0)<<2)>>2]<<2)>>2]|0;k=(n|0)/(h|0)|0;h=m+4+(k<<3)|0;i=Pl(g)|0;j=h;v=j;a[v>>0]=0;a[v+1>>0]=0;a[v+2>>0]=0;a[v+3>>0]=0;j=j+4|0;a[j>>0]=0;a[j+1>>0]=0;a[j+2>>0]=0;a[j+3>>0]=0;j=i&255;c:do if((j+-251|0)>>>0>=3){a[h>>0]=i<<24>>24==-1?0:(j&15)+37+((j>>>4)*12|0)&255;h=Pl(g)|0;j=m+4+(k<<3)+2|0;a[j>>0]=h&7;a[m+4+(k<<3)+1>>0]=(h&255)>>>3;h=(Pl(g)|0)&255;i=(h>>>1&120)+(d[j>>0]|0)|0;a[j>>0]=(i&255)>>>0>64?0:(i&255)+1<<24>>24;j=m+4+(k<<3)+3|0;a[j>>0]=a[33074+(h&15)>>0]|0;h=Pl(g)|0;i=m+4+(k<<3)+4|0;a[i>>0]=h;switch(a[j>>0]|0){case 15:{h=(h&255)>>>4;break}case -1:{a[j>>0]=0;h=0;break}default:break c}a[i>>0]=h}while(0);n=n+1|0;h=c[s>>2]|0}while((n|0)<(h<<6|0))}o=o+1|0;if((o|0)>=(c[r>>2]|0))break b}l=u;return h|0}while(0);h=c[t>>2]|0;d:do if((h|0)>0){m=f+180|0;k=f+176|0;j=0;while(1){i=c[m>>2]|0;if((c[i+(j*52|0)+32>>2]|0)>1){if((Eb(f,g,0,i+(j*52|0)|0,0)|0)<0){h=-1;break}h=c[t>>2]|0}else c[(c[k>>2]|0)+(j*764|0)+36>>2]=0;j=j+1|0;if((j|0)>=(h|0))break d}l=u;return h|0}while(0);v=f+1284|0;c[v>>2]=c[v>>2]|1224737377;c[f+1288>>2]=2;v=0;l=u;return v|0}function $b(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=Ul(a)|0;if(d<<16>>16<26982)switch(d<<16>>16){case 19022:{e=2;break}default:d=-1}else switch(d<<16>>16){case 26982:{e=2;break}default:d=-1}if((e|0)==2){dm(a,110,0)|0;if((((Pl(a)|0)&255)<=64?((Pl(a)|0)&255)<=128:0)?(dm(a,240,0)|0,(Pl(a)|0)<<24>>24==-1):0){dm(a,c+2|0,0)|0;hb(a,b,36);d=0}else d=-1}return d|0}function ac(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;x=l;l=l+544|0;j=x;u=x+35|0;r=x+4|0;t=x+32|0;cm(u,2,1,e)|0;k=u+2|0;cm(k,108,1,e)|0;f=u+110|0;a[f>>0]=Pl(e)|0;w=Pl(e)|0;g=u+111|0;a[g>>0]=w;if((w&255)>128|(d[f>>0]|0)>64){b=-1;l=x;return b|0}a[u+112>>0]=Pl(e)|0;i=u+113|0;if((cm(i,1,128,e)|0)!=128){b=-1;l=x;return b|0}if((cm(u+241|0,1,128,e)|0)!=128){b=-1;l=x;return b|0}if((cm(u+369|0,1,128,e)|0)!=128){b=-1;l=x;return b|0}w=b+136|0;c[w>>2]=8;h=d[f>>0]|0;v=b+140|0;c[v>>2]=h;g=a[g>>0]|0;f=g&255;s=b+128|0;c[s>>2]=f;c[b+132>>2]=f<<3;f=0;do{if((d[u+113+f>>0]|0)>(g&255))break;f=f+1|0}while((f|0)<128);c[b+156>>2]=f;ep(b+952|0,i|0,f|0)|0;c[b+148>>2]=6;c[b+152>>2]=78;c[b+144>>2]=h;c[b+1292>>2]=3;c[b+1264>>2]=8363;gb(b,k,36)|0;h=(on(u,32355,2)|0)!=0;ob(b,h?32358:32342,j);h=Vm(109)|0;c[b+1220>>2]=h;i=h;f=k;g=i+108|0;do{a[i>>0]=a[f>>0]|0;i=i+1|0;f=f+1|0}while((i|0)<(g|0));a[h+108>>0]=0;if((Za(b)|0)<0){b=-1;l=x;return b|0}a:do if((c[v>>2]|0)>0){p=b+176|0;q=b+180|0;m=r+16|0;n=r+20|0;o=r+24|0;k=0;while(1){i=c[p>>2]|0;f=c[q>>2]|0;if((_a(b,k,1)|0)<0){f=-1;g=42;break}g=c[i+(k*764|0)+756>>2]|0;cm(r,13,1,e)|0;c[m>>2]=_l(e)|0;c[n>>2]=_l(e)|0;j=_l(e)|0;c[o>>2]=j;h=c[m>>2]|0;if(h>>>0>268435456){f=-1;g=42;break}c[f+(k*52|0)+32>>2]=h;c[f+(k*52|0)+36>>2]=c[n>>2];j=j>>>0>1048574?0:j;c[f+(k*52|0)+40>>2]=j;c[f+(k*52|0)+44>>2]=j|0?2:0;c[g>>2]=64;c[g+8>>2]=128;c[g+40>>2]=k;if(h|0)c[i+(k*764|0)+36>>2]=1;fb(c[p>>2]|0,k,r,13);k=k+1|0;if((k|0)>=(c[v>>2]|0))break a}if((g|0)==42){l=x;return f|0}}while(0);if(($a(b)|0)<0){b=-1;l=x;return b|0}b:do if((c[s>>2]|0)>0){p=b+172|0;o=b+168|0;m=t+2|0;k=t+1|0;n=0;while(1){if((db(b,n,64)|0)<0){f=-1;g=42;break}h=c[p>>2]|0;f=c[(c[o>>2]|0)+(n<<2)>>2]|0;g=c[h+(c[f+4>>2]<<2)>>2]|0;a[g+9>>0]=126;a[g+10>>0]=a[u+241+n>>0]|0;g=a[u+369+n>>0]|0;if((g&255)>63){f=-1;g=42;break}g=g&255;r=c[h+(c[f+8>>2]<<2)>>2]|0;a[r+4+(g<<3)+5>>0]=13;a[r+4+(g<<3)+6>>0]=0;g=0;while(1){i=c[h+(c[f+4+(((g|0)%8|0)<<2)>>2]<<2)>>2]|0;j=(g|0)/8|0;cm(t,1,3,e)|0;f=a[t>>0]|0;h=f&255;if((h&254|0)!=254){a[i+4+(j<<3)>>0]=(h>>>2)+37;a[i+4+(j<<3)+1>>0]=((f<<4&48|1)&255)+((d[k>>0]|0)>>>4)}if(f<<24>>24!=-1)a[i+4+(j<<3)+2>>0]=a[k>>0]<<2&60|1;r=a[m>>0]|0;f=r&255;if((r&255)<=95?(r=f>>>4,a[i+4+(j<<3)+3>>0]=a[32367+r>>0]|0,a[i+4+(j<<3)+4>>0]=f&15,(r|0)==5):0)a[i+4+(j<<3)+5>>0]=127;g=g+1|0;if((g|0)==512)break;f=c[(c[o>>2]|0)+(n<<2)>>2]|0;h=c[p>>2]|0}n=n+1|0;if((n|0)>=(c[s>>2]|0))break b}if((g|0)==42){l=x;return f|0}}while(0);f=c[v>>2]|0;c:do if((f|0)>0){i=b+180|0;h=0;while(1){g=c[i>>2]|0;if((c[g+(h*52|0)+32>>2]|0)>=3){if((Eb(b,e,2,g+(h*52|0)|0,0)|0)<0){f=-1;break}f=c[v>>2]|0}h=h+1|0;if((h|0)>=(f|0))break c}l=x;return f|0}while(0);if((c[w>>2]|0)>0){f=b+1300|0;g=0;do{c[b+184+(g*12|0)>>2]=((O(c[f>>2]|0,(((g|0)%2|0)*255|0)+-128|0)|0)/100|0)+128;g=g+1|0}while((g|0)<(c[w>>2]|0))}b=b+1284|0;c[b>>2]=c[b>>2]|384;b=0;l=x;return b|0}function bc(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1178686206){b=-1;return b|0}hb(a,b,40);b=0;return b|0}function cc(e,f,g){e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;C=l;l=l+944|0;k=C;z=C+60|0;w=C+160|0;A=C+8|0;B=C+936|0;am(f)|0;j=z+4|0;cm(j,40,1,f)|0;cm(z+44|0,3,1,f)|0;b[z+48>>1]=Rl(f)|0;m=z+50|0;a[m>>0]=Pl(f)|0;cm(z+51|0,16,1,f)|0;dm(f,9,1)|0;i=z+76|0;a[i>>0]=Pl(f)|0;cm(z+77|0,16,1,f)|0;_l(f)|0;g=Rl(f)|0;b[z+98>>1]=g;if(!(a[i>>0]|0)){e=-1;l=C;return e|0}dm(f,g&65535,1)|0;cm(w,256,1,f)|0;a[w+256>>0]=Pl(f)|0;h=w+257|0;a[h>>0]=Pl(f)|0;a[w+258>>0]=Pl(f)|0;g=0;do{b[w+260+(g<<1)>>1]=Rl(f)|0;g=g+1|0}while((g|0)!=256);if(gm(f)|0){e=-1;l=C;return e|0}v=e+136|0;c[v>>2]=16;z=d[h>>0]|0;c[e+156>>2]=z;c[e+148>>2]=6;c[e+152>>2]=480/((d[i>>0]|0)>>>0)|0;ep(e+952|0,w|0,z|0)|0;i=0;a:while(1){h=i;while(1){if((h|0)>=256)break a;g=h+1|0;if(!(b[w+260+(h<<1)>>1]|0))h=g;else{i=g;continue a}}}u=e+128|0;c[u>>2]=i;c[e+132>>2]=i<<4;Ho(e,j,40)|0;z=d[m>>0]|0;c[k>>2]=z>>>4;c[k+4>>2]=z&15;ob(e,32392,k);if(($a(e)|0)<0){e=-1;l=C;return e|0}b:do if((c[u>>2]|0)>0){s=e+168|0;t=e+172|0;r=0;g=0;c:while(1){if((ab(e,r)|0)<0){g=-1;h=63;break}h=b[w+260+(r<<1)>>1]|0;d:do if(h<<16>>16){h=h&65535;if((h+-66|0)>>>0>16383){g=-1;h=63;break c}c[c[(c[s>>2]|0)+(r<<2)>>2]>>2]=(h+-2|0)/64|0;if((cb(e,r)|0)<0){g=-1;h=63;break c}h=Pl(f)|0;Pl(f)|0;j=c[(c[s>>2]|0)+(r<<2)>>2]|0;i=c[v>>2]|0;if((O(i,c[j>>2]|0)|0)>0){q=(h&255)+1&255;p=0;while(1){z=(p|0)%(i|0)|0;o=c[(c[t>>2]|0)+(c[j+4+(z<<2)>>2]<<2)>>2]|0;n=(p|0)/(i|0)|0;if((z|0)==0&(n|0)==(q|0))a[o+4+(q<<3)+5>>0]=13;h=Pl(f)|0;j=Pl(f)|0;k=Pl(f)|0;m=Pl(f)|0;i=o+4+(n<<3)|0;if(!(h<<24>>24))h=a[i>>0]|0;else{h=(h&255)+48&255;a[i>>0]=h}if((h|j)<<24>>24)a[o+4+(n<<3)+1>>0]=(j&255)+1;h=k&255;h=h<<4|h>>>4;if((h&255)<<24>>24)a[o+4+(n<<3)+2>>0]=h+240;j=m&255;z=a[32417+(j>>>4)>>0]|0;m=o+4+(n<<3)+3|0;a[m>>0]=z;i=j&15;k=i&255;h=o+4+(n<<3)+4|0;a[h>>0]=k;e:do switch(z<<24>>24){case -1:{a[h>>0]=0;a[m>>0]=0;break}case -7:{a[m>>0]=14;a[h>>0]=k|16;break}case -8:{a[m>>0]=14;a[h>>0]=k|32;break}case -5:{a[m>>0]=14;a[h>>0]=k|-112;break}case -6:{a[m>>0]=14;a[h>>0]=k|-48;break}case -2:{a[h>>0]=0;a[m>>0]=0;g=i;break}case 4:{a[h>>0]=(j<<4)+g;break}case 123:{a[h>>0]=(j<<4)+g;break}case -3:{a[m>>0]=14;a[h>>0]=k|-96;break}case -4:{a[m>>0]=14;a[h>>0]=k|-80;break}case 15:if(!i){a[m>>0]=0;break e}else{a[h>>0]=480/(i>>>0)|0;break e}default:{}}while(0);p=p+1|0;j=c[(c[s>>2]|0)+(r<<2)>>2]|0;i=c[v>>2]|0;if((p|0)>=(O(i,c[j>>2]|0)|0))break d}}}while(0);r=r+1|0;if((r|0)>=(c[u>>2]|0))break b}if((h|0)==63){l=C;return g|0}}while(0);z=e+140|0;c[z>>2]=-1;cm(B,1,8,f)|0;g=0;do{if(d[B+((g|0)/8|0)>>0]&1<<(g&7)|0)c[z>>2]=g;g=g+1|0}while((g|0)!=64);y=(c[z>>2]|0)+1|0;c[z>>2]=y;c[e+144>>2]=y;if((Za(e)|0)<0){e=-1;l=C;return e|0}g=c[z>>2]|0;f:do if((g|0)>0){r=A+32|0;q=A+36|0;w=A+37|0;s=A+40|0;t=A+44|0;v=A+48|0;u=A+49|0;y=e+180|0;x=e+176|0;p=0;while(1){if(d[B+((p|0)/8|0)>>0]&1<<(p&7)){if((_a(e,p,1)|0)<0){g=-1;h=63;break}cm(A,32,1,f)|0;c[r>>2]=_l(f)|0;a[q>>0]=Pl(f)|0;a[w>>0]=Pl(f)|0;c[s>>2]=_l(f)|0;c[t>>2]=_l(f)|0;a[v>>0]=Pl(f)|0;n=Pl(f)|0;a[u>>0]=n;g=c[r>>2]|0;if(g>>>0>65536){g=-1;h=63;break}h=c[s>>2]|0;if(h>>>0>65536){g=-1;h=63;break}i=c[t>>2]|0;if(i>>>0>65536){g=-1;h=63;break}o=c[y>>2]|0;j=o+(p*52|0)+32|0;c[j>>2]=g;m=o+(p*52|0)+36|0;c[m>>2]=h;k=o+(p*52|0)+40|0;c[k>>2]=i;o=o+(p*52|0)+44|0;c[o>>2]=0;if((g|0)>0)c[(c[x>>2]|0)+(p*764|0)+36>>2]=1;if(!(a[v>>0]|0))g=0;else{c[o>>2]=1;c[j>>2]=g>>>1;c[m>>2]=h>>>1;c[k>>2]=i>>>1;g=1}c[o>>2]=(n<<24>>24?2:0)|g;o=c[x>>2]|0;n=c[o+(p*764|0)+756>>2]|0;c[n>>2]=255;c[n+40>>2]=p;fb(o,p,A,32);if((Eb(e,f,0,(c[y>>2]|0)+(p*52|0)|0,0)|0)<0){g=-1;h=63;break}g=c[z>>2]|0}p=p+1|0;if((p|0)>=(g|0))break f}if((h|0)==63){l=C;return g|0}}while(0);c[e+1268>>2]=255;e=0;l=C;return e|0}function dc(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;e=l;l=l+16|0;d=e;if(((cm(d,1,4,b)|0)>>>0>=4?(nn(d,32471,3)|0)==0:0)?(a[d+3>>0]|0)==16:0){hb(b,c,20);d=0}else d=-1;l=e;return d|0}function ec(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;M=l;l=l+320|0;o=M;L=M+48|0;C=M+8|0;D=M+120|0;cm(L,3,1,g)|0;p=L+3|0;a[p>>0]=Pl(g)|0;m=L+4|0;cm(m,20,1,g)|0;h=L+24|0;b[h>>1]=Rl(g)|0;j=L+26|0;a[j>>0]=Pl(g)|0;i=L+27|0;a[i>>0]=Pl(g)|0;J=L+28|0;b[J>>1]=Rl(g)|0;K=Pl(g)|0;k=L+30|0;a[k>>0]=K;if((K&255)>63){f=-1;l=M;return f|0}B=L+31|0;a[B>>0]=Pl(g)|0;K=Pl(g)|0;E=L+32|0;a[E>>0]=K;if(K<<24>>24!=64){f=-1;l=M;return f|0}K=Pl(g)|0;n=L+33|0;a[n>>0]=K;if((K&255)>64){f=-1;l=M;return f|0}cm(L+34|0,32,1,g)|0;if(gm(g)|0){f=-1;l=M;return f|0}K=f+132|0;c[K>>2]=(e[h>>1]|0)+1;I=f+128|0;c[I>>2]=(d[j>>0]|0)+1;c[f+156>>2]=(d[i>>0]|0)+1;H=d[k>>0]|0;G=f+140|0;c[G>>2]=H;c[f+144>>2]=H;H=f+136|0;c[H>>2]=d[n>>0];c[f+148>>2]=6;c[f+152>>2]=125;Ho(f,m,20)|0;A=d[p>>0]|0;c[o>>2]=A>>>4;c[o+4>>2]=A&15;ob(f,32446,o);if((Za(f)|0)<0){f=-1;l=M;return f|0}a:do if((c[G>>2]|0)>0){z=f+176|0;A=f+180|0;v=C+24|0;w=C+28|0;x=C+32|0;t=C+36|0;y=C+37|0;s=C+38|0;u=0;while(1){h=c[z>>2]|0;i=c[A>>2]|0;if((_a(f,u,1)|0)<0){h=-1;i=41;break}j=c[h+(u*764|0)+756>>2]|0;cm(C,22,1,g)|0;r=_l(g)|0;c[v>>2]=r;if(r>>>0>268435456){h=-1;i=41;break}c[w>>2]=_l(g)|0;c[x>>2]=_l(g)|0;a[t>>0]=Pl(g)|0;a[y>>0]=Pl(g)|0;a[s>>0]=Pl(g)|0;k=c[v>>2]|0;p=i+(u*52|0)+32|0;c[p>>2]=k;m=c[w>>2]|0;r=i+(u*52|0)+36|0;c[r>>2]=m;n=c[x>>2]|0;q=i+(u*52|0)+40|0;c[q>>2]=n;o=n|0?2:0;h=i+(u*52|0)+44|0;c[h>>2]=o;if(a[B>>0]&1){c[h>>2]=o|1;c[p>>2]=k>>1;c[r>>2]=m>>1;c[q>>2]=n>>1}c[j>>2]=d[y>>0];c[j+16>>2]=d[t>>0];c[j+8>>2]=128;c[j+40>>2]=u;fb(c[z>>2]|0,u,C,22);if((c[p>>2]|0)>0)c[(c[z>>2]|0)+(u*764|0)+36>>2]=1;u=u+1|0;if((u|0)>=(c[G>>2]|0))break a}if((i|0)==41){l=M;return h|0}}while(0);cm(f+952|0,1,128,g)|0;if(($a(f)|0)<0){f=-1;l=M;return f|0}b:do if((c[K>>2]|0)>0){o=f+172|0;m=0;while(1){if((bb(f,m,d[E>>0]|0)|0)<0){h=-1;i=41;break}if(m|0){if((cm(D,3,64,g)|0)!=64){h=-1;i=41;break}h=c[(c[o>>2]|0)+(m<<2)>>2]|0;n=0;do{i=D+(n*3|0)|0;C=(d[i>>0]|0)>>>2;a[h+4+(n<<3)>>0]=C<<24>>24==0?0:C+37<<24>>24;C=i+1|0;a[h+4+(n<<3)+1>>0]=a[i>>0]<<4&48|(d[C>>0]|0)>>>4;C=a[C>>0]&15;k=h+4+(n<<3)+3|0;a[k>>0]=C;i=a[i+2>>0]|0;j=h+4+(n<<3)+4|0;a[j>>0]=i;if(C<<24>>24==14?(F=i&255,(F&240|0)==128):0){a[k>>0]=8;a[j>>0]=F<<4}n=n+1|0}while((n|0)!=64)}m=m+1|0;if((m|0)>=(c[K>>2]|0))break b}if((i|0)==41){l=M;return h|0}}while(0);c:do if((c[I>>2]|0)>0){k=f+168|0;i=0;while(1){if((ab(f,i)|0)<0){h=-1;break}c[c[(c[k>>2]|0)+(i<<2)>>2]>>2]=64;j=0;do{h=(Rl(g)|0)&65535;if((j|0)<(c[H>>2]|0))c[(c[(c[k>>2]|0)+(i<<2)>>2]|0)+4+(j<<2)>>2]=(h|0)>=(c[K>>2]|0)?0:h;j=j+1|0}while((j|0)!=32);i=i+1|0;if((i|0)>=(c[I>>2]|0))break c}l=M;return h|0}while(0);dm(g,e[J>>1]|0,1)|0;d:do if((c[G>>2]|0)>0){i=f+180|0;h=0;while(1){if((Eb(f,g,2,(c[i>>2]|0)+(h*52|0)|0,0)|0)<0){h=-1;break}h=h+1|0;if((h|0)>=(c[G>>2]|0))break d}l=M;return h|0}while(0);if((c[H>>2]|0)>0)h=0;else{f=0;l=M;return f|0}do{c[f+184+(h*12|0)>>2]=(d[L+34+h>>0]|0)<<4;h=h+1|0}while((h|0)<(c[H>>2]|0));h=0;l=M;return h|0}function fc(a,b,c){a=a|0;b=b|0;c=c|0;dm(a,c+44|0,0)|0;if((am(a)|0)!=1347702086){b=-1;return b|0}dm(a,c,0)|0;hb(a,b,28);b=0;return b|0}function gc(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0;S=l;l=l+1728|0;p=S;Q=S+704|0;R=S+96|0;L=S+8|0;cm(R,28,1,g)|0;a[R+28>>0]=Pl(g)|0;r=R+29|0;a[r>>0]=Pl(g)|0;q=R+30|0;a[q>>0]=Pl(g)|0;a[R+31>>0]=Pl(g)|0;k=R+32|0;b[k>>1]=Rl(g)|0;j=R+34|0;b[j>>1]=Rl(g)|0;m=R+36|0;b[m>>1]=Rl(g)|0;n=R+38|0;b[n>>1]=Rl(g)|0;b[R+40>>1]=Rl(g)|0;b[R+42>>1]=Rl(g)|0;P=am(g)|0;c[R+44>>2]=P;if((P|0)!=1347702086){R=-1;l=S;return R|0}if((e[k>>1]|0)>256|(e[j>>1]|0)>255|(e[m>>1]|0)>128|(e[n>>1]|0)>32){R=-1;l=S;return R|0}cm(R+48|0,16,1,g)|0;cm(R+64|0,32,1,g)|0;o=R+96|0;cm(o,256,1,g)|0;i=0;do{b[R+352+(i<<1)>>1]=Rl(g)|0;i=i+1|0}while((i|0)!=128);c[f+156>>2]=e[k>>1];J=e[j>>1]|0;K=f+140|0;c[K>>2]=J;N=e[m>>1]|0;M=f+128|0;c[M>>2]=N;I=e[n>>1]|0;P=f+136|0;c[P>>2]=I;c[f+132>>2]=O(I,N)|0;N=f+144|0;c[N>>2]=J;c[f+148>>2]=6;c[f+152>>2]=125;ep(f+952|0,o|0,256)|0;c[f+1264>>2]=8363;gb(f,R,28)|0;J=d[r>>0]|0;c[p>>2]=d[q>>0];c[p+4>>2]=J;ob(f,32488,p);if((Za(f)|0)<0){R=-1;l=S;return R|0}a:do if((c[K>>2]|0)>0){I=f+176|0;J=f+180|0;s=L+1|0;H=L+13|0;u=L+14|0;G=L+16|0;F=L+20|0;A=L+24|0;B=L+28|0;C=L+32|0;v=L+36|0;y=L+40|0;x=L+44|0;w=L+48|0;E=L+49|0;t=L+50|0;D=L+80|0;z=0;while(1){i=c[I>>2]|0;j=c[J>>2]|0;a[L>>0]=Pl(g)|0;cm(s,12,1,g)|0;a[H>>0]=Pl(g)|0;b[u>>1]=Rl(g)|0;b[G>>1]=Rl(g)|0;c[F>>2]=_l(g)|0;c[A>>2]=_l(g)|0;c[B>>2]=_l(g)|0;c[C>>2]=_l(g)|0;c[v>>2]=_l(g)|0;c[y>>2]=_l(g)|0;c[x>>2]=_l(g)|0;a[w>>0]=Pl(g)|0;a[E>>0]=Pl(g)|0;cm(t,28,1,g)|0;c[D>>2]=am(g)|0;if(gm(g)|0){i=-1;j=60;break}if((a[L>>0]&3)==1){if((_a(f,z,1)|0)<0){i=-1;j=60;break}k=c[i+(z*764|0)+756>>2]|0;c[Q+(z<<2)>>2]=c[F>>2];m=c[A>>2]|0;p=j+(z*52|0)+32|0;c[p>>2]=m;n=c[B>>2]|0;r=j+(z*52|0)+36|0;c[r>>2]=n;o=c[C>>2]|0;q=j+(z*52|0)+40|0;c[q>>2]=o;if((c[(c[J>>2]|0)+(z*52|0)+32>>2]|0)>0)c[(c[I>>2]|0)+(z*764|0)+36>>2]=1;j=j+(z*52|0)+44|0;T=d[L>>0]|0;i=(T&8|0)==0?T>>>1&2:6;c[j>>2]=i;if(T&16|0){c[j>>2]=i|1;c[p>>2]=m>>1;c[r>>2]=n>>1;c[q>>2]=o>>1}c[k>>2]=d[H>>0];c[k+8>>2]=128;c[k+40>>2]=z;c[D>>2]=0;fb(c[I>>2]|0,z,t,28);Gi(e[u>>1]|0,k+12|0,k+16|0)}z=z+1|0;if((z|0)>=(c[K>>2]|0))break a}if((j|0)==60){l=S;return i|0}}while(0);if(($a(f)|0)<0){T=-1;l=S;return T|0}i=c[M>>2]|0;b:do if((i|0)>0){s=f+172|0;r=f+168|0;q=0;while(1){j=R+352+(q<<1)|0;if(b[j>>1]|0){if((db(f,q,64)|0)<0){i=-1;break}dm(g,(e[j>>1]<<4)+h|0,0)|0;p=0;do{i=Pl(g)|0;if(i<<24>>24)do{o=i&255;i=o&31;if((i|0)<(c[P>>2]|0)){n=c[(c[s>>2]|0)+(c[(c[(c[r>>2]|0)+(q<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0;if(o&32|0){i=Pl(g)|0;switch(i<<24>>24){case -1:{i=0;break}case -2:{i=-127;break}default:i=(i&255)+12&255}a[n+4+(p<<3)>>0]=i;a[n+4+(p<<3)+1>>0]=Pl(g)|0}c:do if(o&64|0){m=n+4+(p<<3)+3|0;a[m>>0]=Pl(g)|0;j=Pl(g)|0;k=n+4+(p<<3)+4|0;a[k>>0]=j;i=a[m>>0]|0;if((i&255)>23){a[k>>0]=0;a[m>>0]=0;break}switch(i<<24>>24){case 14:{i=j&255;if((i&240|0)!=128)break c;a[m>>0]=8;a[k>>0]=i<<4;break c}case 16:{a[m>>0]=16;break c}case 17:{a[m>>0]=27;break c}case 18:{a[m>>0]=-84;break c}case 19:{a[m>>0]=-100;break c}case 20:{a[m>>0]=-99;break c}case 21:{a[m>>0]=-97;break c}case 22:{a[m>>0]=-98;break c}case 23:{a[k>>0]=0;a[m>>0]=0;break c}default:break c}}while(0);if(o&128|0)a[n+4+(p<<3)+2>>0]=((Pl(g)|0)&255)+1}i=Pl(g)|0}while(i<<24>>24!=0);p=p+1|0}while((p|0)!=64);i=c[M>>2]|0}q=q+1|0;if((q|0)>=(i|0))break b}l=S;return i|0}while(0);i=c[N>>2]|0;d:do if((i|0)>0){k=f+176|0;m=f+180|0;j=0;while(1){if((c[(c[k>>2]|0)+(j*764|0)+36>>2]|0)!=0?(c[(c[m>>2]|0)+(j*52|0)+32>>2]|0)!=0:0){dm(g,(c[Q+(j<<2)>>2]|0)+h|0,0)|0;if((Eb(f,g,4,(c[m>>2]|0)+(j*52|0)|0,0)|0)<0){i=-1;break}i=c[N>>2]|0}j=j+1|0;if((j|0)>=(i|0))break d}l=S;return i|0}while(0);c[f+1280>>2]=1356;if((c[P>>2]|0)>0){i=0;do{c[f+184+(i*12|0)>>2]=d[R+64+i>>0]<<4;i=i+1|0}while((i|0)<(c[P>>2]|0))}T=f+1284|0;c[T>>2]=c[T>>2]|1224737313;c[f+1288>>2]=2;T=0;l=S;return T|0}function hc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+16|0;c=d;if((cm(c,1,8,a)|0)>>>0>=8?(on(c,32543,8)|0)==0:0){hb(a,b,0);c=0}else c=-1;l=d;return c|0}function ic(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=l;l=l+304|0;e=f+8|0;dm(b,8,1)|0;d=pb()|0;if(!d){a=-1;l=f;return a|0}gp(e|0,0,296)|0;g=tb(d,32523,1)|0;g=tb(d,34527,2)|0|g;g=g|(tb(d,32528,3)|0);g=g|(tb(d,32533,4)|0);g=g|(tb(d,34517,5)|0);g=g|(tb(d,35016,6)|0);g=g|(tb(d,33925,7)|0);if(g|(tb(d,32538,8)|0)|0){g=-1;l=f;return g|0}ob(a,32513,f);g=(qb(d,a,b,e)|0)<0;wb(d);if(g){g=-1;l=f;return g|0}c[a+1292>>2]=1;g=0;l=f;return g|0}function jc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;g=a+136|0;c[g>>2]=0;h=a+1300|0;i=0;do{b=i;i=i+1|0;f=((O(c[h>>2]|0,((((i|0)/2|0|0)%2|0)*255|0)+-128|0)|0)/100|0)+128|0;j=(Ul(d)|0)<<16>>16==0;e=c[g>>2]|0;if(!j){j=b<<4|4;e=a+184+(e*12|0)+8|0;c[e>>2]=c[e>>2]|j;e=c[g>>2]|0;c[g>>2]=e+1;c[a+184+(e*12|0)>>2]=f;e=a+184+((c[g>>2]|0)*12|0)+8|0;c[e>>2]=c[e>>2]|j;e=c[g>>2]|0}c[g>>2]=e+1;c[a+184+(e*12|0)>>2]=f}while((i|0)!=4);return 0}function kc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;if((b|0)!=1152){e=-1;return e|0}j=a+140|0;c[j>>2]=36;c[a+144>>2]=36;if((Za(a)|0)<0){e=-1;return e|0}k=a+176|0;if((c[j>>2]|0)<=0){e=0;return e|0}l=a+180|0;i=e+144|0;h=0;b=0;while(1){f=c[k>>2]|0;g=c[l>>2]|0;if((_a(a,h,1)|0)<0){b=-1;f=9;break}n=c[f+(h*764|0)+756>>2]|0;cm(f+(h*764|0)|0,1,20,d)|0;m=g+(b*52|0)+32|0;c[m>>2]=(am(d)|0)&-2;p=g+(b*52|0)+36|0;c[p>>2]=((Ul(d)|0)&65535)<<1;o=Ul(d)|0;c[g+(b*52|0)+40>>2]=((o&65535)<<1)+(c[p>>2]|0);c[g+(b*52|0)+44>>2]=(o&65535)>1?2:0;c[n>>2]=(Ul(d)|0)&65535;c[e+(h<<2)>>2]=(Ul(d)|0)&65535;c[n+8>>2]=128;c[n+40>>2]=b;c[i+(b<<2)>>2]=h;if((c[m>>2]|0)>0){c[f+(h*764|0)+36>>2]=1;b=b+1|0}h=h+1|0;if((h|0)>=(c[j>>2]|0)){b=0;f=9;break}}if((f|0)==9)return b|0;return 0}function lc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;c[a+148>>2]=(Ul(d)|0)&65535;c[a+152>>2]=125;return 0}function mc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=(Ul(d)|0)&65535;c[a+128>>2]=b;c[a+132>>2]=O(c[a+136>>2]|0,b)|0;return 0}function nc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=Ul(d)|0;c[a+156>>2]=b&65535;return ((b&65535)>256)<<31>>31|0}function oc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=a+156|0;e=cm(a+952|0,1,c[b>>2]|0,d)|0;return ((e|0)!=(c[b>>2]|0))<<31>>31|0}function pc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=f+288|0;f=c[p>>2]|0;if((f|0)>=(c[b+128>>2]|0)){e=0;return e|0}if((f|0)==0?($a(b)|0)<0:0){e=-1;return e|0}m=Ul(e)|0;m=m&65535;if((db(b,c[p>>2]|0,m)|0)<0){e=-1;return e|0}l=b+136|0;d=c[l>>2]|0;n=(O(d,m)|0)>0;f=c[p>>2]|0;a:do if(n){n=b+172|0;k=b+168|0;j=0;while(1){h=c[(c[n>>2]|0)+(c[(c[(c[k>>2]|0)+(f<<2)>>2]|0)+4+(((j|0)%(d|0)|0)<<2)>>2]<<2)>>2]|0;g=(j|0)/(d|0)|0;f=h+4+(g<<3)|0;d=f;b=d;a[b>>0]=0;a[b+1>>0]=0;a[b+2>>0]=0;a[b+3>>0]=0;d=d+4|0;a[d>>0]=0;a[d+1>>0]=0;a[d+2>>0]=0;a[d+3>>0]=0;d=Pl(e)|0;b=Pl(e)|0;if(d<<24>>24){a[f>>0]=(d&255)+48;a[h+4+(g<<3)+1>>0]=(b&255)+1}f=Pl(e)|0;if((f&255)>31){f=-1;break}i=h+4+(g<<3)+3|0;a[i>>0]=c[1628+((f&255)<<2)>>2];f=Pl(e)|0;b=h+4+(g<<3)+4|0;a[b>>0]=f;d=a[i>>0]|0;b:do if((f&255)>64&d<<24>>24==12){do if((f&255)<81){a[i>>0]=10;d=10;f=(f&255)+192|0}else{if((f&255)<97){a[i>>0]=10;d=10;f=(f&255)<<4;break}if((f&255)<113){a[i>>0]=-82;d=-82;f=(f&255)+160|0;break}if((f&255)>=129)break b;a[i>>0]=-83;d=-83;f=(f&255)+144|0}while(0);f=f&255;a[b>>0]=f;o=20}else o=20;while(0);c:do if((o|0)==20){o=0;switch(d<<24>>24){case 0:{i=f&255;a[b>>0]=(((24-(i>>>4)|0)>>>0)%12|0)<<4|i&15;break c}case -1:{a[b>>0]=0;a[i>>0]=0;break c}default:break c}}while(0);j=j+1|0;d=c[l>>2]|0;i=(j|0)<(O(d,m)|0);f=c[p>>2]|0;if(!i)break a}return f|0}while(0);c[p>>2]=f+1;e=0;return e|0}function qc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;g=e+292|0;b=c[g>>2]|0;if((b|0)>=(c[a+140>>2]|0)){a=0;return a|0}f=c[e+144+(b<<2)>>2]|0;switch(c[e+(f<<2)>>2]|0){case 2:case 0:{b=8;break}default:b=0}if((Eb(a,d,b,(c[a+180>>2]|0)+((c[(c[(c[a+176>>2]|0)+(f*764|0)+756>>2]|0)+40>>2]|0)*52|0)|0,0)|0)<0){a=-1;return a|0}c[g>>2]=(c[g>>2]|0)+1;a=0;return a|0}function rc(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;e=l;l=l+16|0;d=e;if(((cm(d,1,15,b)|0)>>>0>=15?(nn(d,32611,14)|0)==0:0)?((a[d+14>>0]|0)+-48&255)<=4:0){hb(b,c,32);d=0}else d=-1;l=e;return d|0}function sc(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0;S=l;l=l+400|0;R=S;N=S+344|0;A=S+80|0;v=S+8|0;Q=S+76|0;cm(N,15,1,g)|0;M=N+15|0;cm(M,32,1,g)|0;P=N+47|0;a[P>>0]=Pl(g)|0;N=d[N+14>>0]|0;B=N+-48|0;Ho(f,M,32)|0;a[M>>0]=0;c[R>>2]=c[1768+(N+-49<<2)>>2];c[R+4>>2]=B;ob(f,32566,R);c[f+1264>>2]=8363;dm(g,(d[P>>0]|0)<<5,1)|0;P=(Pl(g)|0)&255;c[f+144>>2]=P;R=f+140|0;c[R>>2]=P;if((Za(f)|0)<0){f=-1;l=S;return f|0}a:do if((c[R>>2]|0)>0){j=v+32|0;r=v+44|0;s=v+48|0;u=v+52|0;t=v+56|0;w=v+60|0;k=v+61|0;p=v+62|0;n=(B|0)<4;m=v+64|0;y=f+180|0;x=f+176|0;q=0;while(1){if((_a(f,q,1)|0)<0){h=-1;break}cm(v,32,1,g)|0;cm(j,12,1,g)|0;c[r>>2]=_l(g)|0;c[s>>2]=_l(g)|0;c[u>>2]=_l(g)|0;c[t>>2]=_l(g)|0;a[w>>0]=Pl(g)|0;a[k>>0]=Pl(g)|0;b[p>>1]=Rl(g)|0;if(n){o=0;h=0}else{o=Rl(g)|0;h=b[p>>1]|0;b[m>>1]=h^o;b[p>>1]=o;o=1}b[m>>1]=h;P=(c[t>>2]|0)-(c[u>>2]|0)|0;i=c[y>>2]|0;c[i+(q*52|0)+32>>2]=P;c[i+(q*52|0)+36>>2]=c[r>>2];c[i+(q*52|0)+40>>2]=c[s>>2];if((P|0)>0)c[(c[x>>2]|0)+(q*764|0)+36>>2]=1;P=(d[k>>0]|0)+-4|0;switch(P>>>2|P<<30|0){case 0:case 4:{h=1;z=14;break}case 1:{h=2;z=14;break}case 2:{h=3;z=14;break}case 5:{h=10;z=14;break}case 6:{h=11;z=14;break}default:{}}if((z|0)==14){z=0;c[i+(q*52|0)+44>>2]=h}P=c[x>>2]|0;N=c[P+(q*764|0)+756>>2]|0;c[N>>2]=d[w>>0];c[N+8>>2]=128;c[N+40>>2]=q;fb(P,q,v,24);if(o){P=c[(c[x>>2]|0)+(q*764|0)+756>>2]|0;Gi(e[m>>1]|0,P+12|0,P+16|0)}q=q+1|0;if((q|0)>=(c[R>>2]|0))break a}l=S;return h|0}while(0);cm(A,256,1,g)|0;j=A+256|0;a[j>>0]=Pl(g)|0;k=Pl(g)|0;a[A+257>>0]=k;h=0;do{i=a[A+h>>0]|0;if(i<<24>>24==-1)break;a[f+952+h>>0]=i;h=h+1|0}while((h|0)<256);c[f+156>>2]=h;j=(d[j>>0]|0)+1|0;P=f+136|0;c[P>>2]=j;i=(k&255)+1|0;N=f+128|0;c[N>>2]=i;c[f+148>>2]=6;c[f+152>>2]=125;c[f+132>>2]=O(j,i)|0;i=(B|0)>2;j=f+1300|0;k=0;do{m=k;k=k+1|0;if(i)h=((Pl(g)|0)&255)*17|0;else h=((O(c[j>>2]|0,((((k|0)/2|0|0)%2|0)*255|0)+-128|0)|0)/100|0)+128|0;c[f+184+(m*12|0)>>2]=h}while((k|0)<(c[P>>2]|0));if(($a(f)|0)<0){f=-1;l=S;return f|0}h=c[N>>2]|0;b:do if((h|0)>0){i=0;while(1){if((db(f,i,64)|0)<0){h=-1;break}i=i+1|0;h=c[N>>2]|0;if((i|0)>=(h|0))break b}l=S;return h|0}while(0);i=c[P>>2]|0;if((i|0)>0){M=f+172|0;L=f+168|0;K=Q+1|0;J=Q+3|0;I=Q+2|0;H=0;k=0;j=0;do{if((h|0)>0){m=0;while(1){h=Pl(g)|0;if(h<<24>>24==-4){i=(Pl(g)|0)&255;h=Pl(g)|0}else i=1;cm(Q,4,1,g)|0;D=((i|0)==0&1)+i|0;c:do if(!D)i=m;else{E=h<<24>>24==0;z=a[Q>>0]|0;G=a[K>>0]|0;F=(G&255)>>>4;A=G&15;B=a[J>>0]|0;C=a[I>>0]|0;s=(h&255)+36&255;y=C<<24>>24!=0;w=C&255;v=w<<4&255;w=w<<2&255;x=B<<24>>24!=0;u=B&255;t=u<<4&255;u=u<<2&255;i=m;r=0;while(1){m=c[(c[M>>2]|0)+(c[(c[(c[L>>2]|0)+(i>>6<<2)>>2]|0)+4+(H<<2)>>2]<<2)>>2]|0;n=i&63;h=m+4+(n<<3)|0;q=h;p=q;a[p>>0]=0;a[p+1>>0]=0;a[p+2>>0]=0;a[p+3>>0]=0;q=q+4|0;a[q>>0]=0;a[q+1>>0]=0;a[q+2>>0]=0;a[q+3>>0]=0;if(!E)a[h>>0]=s;a[m+4+(n<<3)+1>>0]=z;p=m+4+(n<<3)+3|0;a[p>>0]=F;q=m+4+(n<<3)+5|0;a[q>>0]=A;o=m+4+(n<<3)+4|0;a[o>>0]=B;h=m+4+(n<<3)+6|0;a[h>>0]=C;switch(F&15){case 0:{if((k|0)==0|x)k=0;else{a[p>>0]=3;k=k+-1|0}break}case 3:{k=32;break}case 6:case 5:{a[o>>0]=0;a[p>>0]=0;break}case 11:{a[p>>0]=8;a[o>>0]=t;break}case 9:{a[o>>0]=u;break}default:{}}switch(G&15){case 0:{if((j|0)==0|y)j=0;else{a[q>>0]=3;j=j+-1|0}break}case 3:{j=32;break}case 6:case 5:{a[h>>0]=0;a[q>>0]=0;break}case 11:{a[q>>0]=8;a[h>>0]=v;break}case 9:{a[h>>0]=w;break}default:{}}r=r+1|0;i=i+1|0;if((r|0)>=(D|0))break c}}while(0);h=c[N>>2]|0;if((i|0)<(h<<6|0))m=i;else break}i=c[P>>2]|0}H=H+1|0}while((H|0)<(i|0))}h=c[R>>2]|0;d:do if((h|0)>0){k=f+180|0;j=0;while(1){i=c[k>>2]|0;if(c[i+(j*52|0)+32>>2]|0){if((Eb(f,g,0,i+(j*52|0)|0,0)|0)<0){h=-1;break}h=c[R>>2]|0}j=j+1|0;if((j|0)>=(h|0))break d}l=S;return h|0}while(0);c[f+1268>>2]=256;f=0;l=S;return f|0}function tc(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1145914444){b=-1;return b|0}Pl(a)|0;if((Ul(a)|0)<<16>>16==18766){am(a)|0;hb(a,b,32);b=0;return b|0}else{hb(a,b,0);b=0;return b|0}return 0}function uc(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;E=l;l=l+64|0;i=E;h=E+56|0;D=E+8|0;f=D;g=f+48|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));am(e)|0;cm(h,1,1,e)|0;j=pb()|0;if(!j){b=-1;l=E;return b|0}tb(j,32639,9)|0;tb(j,32642,10)|0;tb(j,32645,11)|0;tb(j,32648,12)|0;tb(j,32651,13)|0;tb(j,32654,14)|0;if((d[h>>0]|0)<16){tb(j,32660,18)|0;tb(j,32663,19)|0}else{tb(j,32657,15)|0;tb(j,32660,16)|0;tb(j,32663,17)|0}zb(j);Ab(j,1);w=a[h>>0]|0;c[i>>2]=w>>>4&15;c[i+4>>2]=w&15;ob(b,32666,i);c[b+1268>>2]=255;c[b+1264>>2]=8363;w=D+32|0;c[w>>2]=0;x=D+28|0;c[x>>2]=0;y=D+24|0;c[y>>2]=0;B=D+4|0;c[B>>2]=Xm(256,4)|0;c[D>>2]=Xm(256,4)|0;f=Vm(1024)|0;C=D+8|0;c[C>>2]=f;g=Vm(1024)|0;A=D+12|0;c[A>>2]=g;h=Vm(1024)|0;z=D+16|0;c[z>>2]=h;i=0;do{c[h+(i<<2)>>2]=-1;c[g+(i<<2)>>2]=-1;c[f+(i<<2)>>2]=-1;i=i+1|0}while((i|0)!=256);v=(qb(j,b,e,D)|0)<0;wb(j);if(!v){f=c[b+132>>2]|0;if((f|0)>0){g=c[b+172>>2]|0;o=b+140|0;h=c[D>>2]|0;n=0;do{i=c[g+(n<<2)>>2]|0;j=c[i>>2]|0;if((j|0)>0){e=c[o>>2]|0;k=(e|0)>0;q=0;do{a:do if(k){p=i+4+(q<<3)+1|0;m=a[p>>0]|0;s=m<<24>>24==0;m=m&255;r=0;while(1){v=r;r=r+1|0;if(!s?(m|0)==(c[h+(v<<2)>>2]|0):0)break;if((r|0)>=(e|0))break a}a[p>>0]=r}while(0);q=q+1|0}while((q|0)!=(j|0))}n=n+1|0}while((n|0)!=(f|0))}else o=b+140|0;if((c[o>>2]|0)>0){v=b+176|0;u=D+36|0;q=D+40|0;m=D+44|0;s=b+144|0;h=c[v>>2]|0;n=0;while(1){Gc(n,h+(n*764|0)+44|0,c[u>>2]|0,c[C>>2]|0,c[y>>2]|0);Gc(n,(c[v>>2]|0)+(n*764|0)+200|0,c[q>>2]|0,c[A>>2]|0,c[x>>2]|0);Gc(n,(c[v>>2]|0)+(n*764|0)+356|0,c[m>>2]|0,c[z>>2]|0,c[w>>2]|0);h=c[v>>2]|0;i=c[h+(n*764|0)+36>>2]|0;if((i|0)>0){j=c[B>>2]|0;g=c[s>>2]|0;k=(g|0)>0;t=h+(n*764|0)+756|0;p=0;do{b:do if(k){r=(c[t>>2]|0)+(p<<6)+40|0;e=c[r>>2]|0;f=0;while(1){if((e|0)==(c[j+(f<<2)>>2]|0))break;f=f+1|0;if((f|0)>=(g|0))break b}c[r>>2]=f}while(0);p=p+1|0}while((p|0)!=(i|0))}n=n+1|0;if((n|0)>=(c[o>>2]|0)){f=0;break}}}else f=0}else f=-1;Wm(c[z>>2]|0);Wm(c[A>>2]|0);Wm(c[C>>2]|0);Wm(c[D>>2]|0);Wm(c[B>>2]|0);Wm(c[D+36>>2]|0);Wm(c[D+40>>2]|0);Wm(c[D+44>>2]|0);Wm(c[D+20>>2]|0);D=b+1284|0;c[D>>2]=c[D>>2]|33816608;c[b+1288>>2]=1;b=f;l=E;return b|0}function vc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;cm(a,1,32,d)|0;dm(d,20,1)|0;f=a+156|0;c[f>>2]=(Rl(d)|0)&65535;e=a+160|0;c[e>>2]=(Rl(d)|0)&65535;Pl(d)|0;c[a+148>>2]=(Pl(d)|0)&255;c[a+152>>2]=(Pl(d)|0)&255;if((c[f>>2]|0)>256){a=-1;return a|0}if((c[e>>2]|0)>255){a=-1;return a|0}else e=0;do{b=(Pl(d)|0)&255;if(b&128|0)break;c[a+184+(e*12|0)>>2]=b<<1;e=e+1|0}while((e|0)<32);c[a+136>>2]=e;dm(d,31-e|0,1)|0;cm(a+952|0,1,c[f>>2]|0,d)|0;a=0;return a|0}function wc(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;m=(Rl(f)|0)&65535;k=m+1|0;p=b+132|0;c[p>>2]=k;i=c[b+128>>2]|0;if((i|0)>0){j=c[b+136>>2]|0;l=(j|0)>0;o=b+168|0;n=0;g=0;do{if(l){e=c[(c[o>>2]|0)+(n<<2)>>2]|0;h=0;do{q=c[e+4+(h<<2)>>2]|0;g=(g|0)<(q|0)?q:g;h=h+1|0}while((h|0)!=(j|0))}n=n+1|0}while((n|0)!=(i|0));if((g|0)>(m|0)){q=-1;return q|0}}q=Xm(4,k)|0;o=b+172|0;c[o>>2]=q;if(!q){q=-1;return q|0}l=Xm(1,2052)|0;if(!l){q=-1;return q|0}a:do if((bb(b,0,256)|0)>=0){b:do if((c[p>>2]|0)>1){m=l+4|0;n=1;c:while(1){g=Rl(f)|0;gp(l|0,0,2052)|0;d:do if(!(g<<16>>16))g=0;else{h=g&65535;g=0;while(1){if((g|0)>255)break a;k=m+(g<<3)|0;q=Pl(f)|0;i=q&255;e=h+-1|0;switch(q&3){case 0:{g=(i>>>2)+g|0;break}case 1:{j=i>>>2;g=j+g|0;if((g|0)>255)break a;h=k+-8|0;i=0;while(1){r=h;t=r;t=d[t>>0]|d[t+1>>0]<<8|d[t+2>>0]<<16|d[t+3>>0]<<24;r=r+4|0;r=d[r>>0]|d[r+1>>0]<<8|d[r+2>>0]<<16|d[r+3>>0]<<24;q=k+(i<<3)|0;s=q;a[s>>0]=t;a[s+1>>0]=t>>8;a[s+2>>0]=t>>16;a[s+3>>0]=t>>24;q=q+4|0;a[q>>0]=r;a[q+1>>0]=r>>8;a[q+2>>0]=r>>16;a[q+3>>0]=r>>24;if((i|0)==(j|0))break;else i=i+1|0}break}case 2:{h=i>>>2;if((h|0)==(g|0))break a;s=m+(h<<3)|0;q=s;q=d[q>>0]|d[q+1>>0]<<8|d[q+2>>0]<<16|d[q+3>>0]<<24;s=s+4|0;s=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;t=k;r=t;a[r>>0]=q;a[r+1>>0]=q>>8;a[r+2>>0]=q>>16;a[r+3>>0]=q>>24;t=t+4|0;a[t>>0]=s;a[t+1>>0]=s>>8;a[t+2>>0]=s>>16;a[t+3>>0]=s>>24;break}case 3:{if(i&4){e=Pl(f)|0;a[k>>0]=e<<24>>24==-1?-127:(e&255)+12&255;e=h+-2|0}if(i&8){a[m+(g<<3)+1>>0]=Pl(f)|0;e=e+-1|0}if(i&16){a[m+(g<<3)+2>>0]=Pl(f)|0;e=e+-1|0}if(i&32){t=Pl(f)|0;a[m+(g<<3)+3>>0]=t&15;a[m+(g<<3)+5>>0]=(t&255)>>>4;e=e+-1|0}if(i&64){a[m+(g<<3)+4>>0]=Pl(f)|0;e=e+-1|0}if(i&128){a[m+(g<<3)+6>>0]=Pl(f)|0;e=e+-1|0}break}default:break c}g=g+1|0;if(!e)break d;else h=e}}while(0);e=(g|0)<65?64:(g|0)<129?128:256;if((bb(b,n,e)|0)<0)break a;ep(c[(c[o>>2]|0)+(n<<2)>>2]|0,l|0,e<<3|4|0)|0;g=c[(c[o>>2]|0)+(n<<2)>>2]|0;c[g>>2]=e;Kc(g+7|0,g+8|0);Lc(g+9|0,g+10|0);g=1;do{t=c[(c[o>>2]|0)+(n<<2)>>2]|0;Kc(t+4+(g<<3)+3|0,t+4+(g<<3)+4|0);Lc(t+4+(g<<3)+5|0,t+4+(g<<3)+6|0);g=g+1|0}while((g|0)<(e|0));n=n+1|0;if((n|0)>=(c[p>>2]|0))break b}}while(0);Wm(l);t=0;return t|0}while(0);Wm(l);t=-1;return t|0}function xc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;l=a+144|0;if((c[l>>2]|0)<=0){n=0;return n|0}m=a+180|0;j=e+20|0;h=0;a:while(1){f=c[m>>2]|0;g=f+(h*52|0)|0;i=f+(h*52|0)+32|0;f=f+(h*52|0)+44|0;b=c[i>>2]<<(c[f>>2]&1);k=Xm(1,b)|0;if(!k){b=-1;n=20;break}switch(c[(c[j>>2]|0)+(h<<2)>>2]|0){case 0:{cm(k,1,b,d)|0;break}case 1:{e=_l(d)|0;if((e+-1|0)>>>0>524287|(c[f>>2]&1|0)!=0)break a;b=Vm(e+4|0)|0;if(!b)break a;if((cm(b,1,e,d)|0)!=(e|0)){n=18;break a}if((Hc(k,b,e,c[i>>2]|0)|0)<0){n=18;break a}Wm(b);break}case 2:{e=_l(d)|0;if((e+-1|0)>>>0>268435455|(c[f>>2]&1|0)==0)break a;b=Vm(e+4|0)|0;if(!b)break a;if((cm(b,1,e,d)|0)!=(e|0)){n=18;break a}if((Ic(k,b,e,c[i>>2]|0)|0)<0){n=18;break a}Wm(b);break}default:break a}if((Eb(a,0,16,g,k)|0)<0)break;Wm(k);h=h+1|0;if((h|0)>=(c[l>>2]|0)){b=0;n=20;break}}if((n|0)==18)Wm(b);else if((n|0)==20)return b|0;Wm(k);n=-1;return n|0}function yc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0;d=Pl(e)|0;b=d&255;g=f+24|0;c[g>>2]=b;if(!(d<<24>>24))return 0;d=f+36|0;c[d>>2]=Xm(b,33)|0;b=0;do{h=Pl(e)|0;f=c[d>>2]|0;a[f+(b*33|0)>>0]=h;cm(f+(b*33|0)+1|0,1,30,e)|0;f=Pl(e)|0;a[(c[d>>2]|0)+(b*33|0)+31>>0]=f;f=Pl(e)|0;a[(c[d>>2]|0)+(b*33|0)+32>>0]=f;b=b+1|0}while((b|0)<(c[g>>2]|0));return 0}function zc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0;d=Pl(e)|0;b=d&255;g=f+28|0;c[g>>2]=b;if(!(d<<24>>24))return 0;d=f+40|0;c[d>>2]=Xm(b,33)|0;b=0;do{h=Pl(e)|0;f=c[d>>2]|0;a[f+(b*33|0)>>0]=h;cm(f+(b*33|0)+1|0,1,30,e)|0;f=Pl(e)|0;a[(c[d>>2]|0)+(b*33|0)+31>>0]=f;f=Pl(e)|0;a[(c[d>>2]|0)+(b*33|0)+32>>0]=f;b=b+1|0}while((b|0)<(c[g>>2]|0));return 0}function Ac(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0;d=Pl(e)|0;b=d&255;g=f+32|0;c[g>>2]=b;if(!(d<<24>>24))return 0;d=f+44|0;c[d>>2]=Xm(b,33)|0;b=0;do{h=Pl(e)|0;f=c[d>>2]|0;a[f+(b*33|0)>>0]=h;cm(f+(b*33|0)+1|0,1,30,e)|0;f=Pl(e)|0;a[(c[d>>2]|0)+(b*33|0)+31>>0]=f;f=Pl(e)|0;a[(c[d>>2]|0)+(b*33|0)+32>>0]=f;b=b+1|0}while((b|0)<(c[g>>2]|0));return 0}function Bc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;y=l;l=l+48|0;r=y;u=b+140|0;c[u>>2]=(Pl(e)|0)&255;if((Za(b)|0)<0){f=-1;l=y;return f|0}x=b+176|0;if((c[u>>2]|0)<=0){f=0;l=y;return f|0}q=r+32|0;w=f+8|0;v=f+12|0;s=f+16|0;p=c[x>>2]|0;t=0;while(1){o=(Pl(e)|0)&255;c[(c[f>>2]|0)+(t<<2)>>2]=o;o=p+(t*764|0)+36|0;c[o>>2]=(Pl(e)|0)&255;cm(r,1,32,e)|0;a[q>>0]=0;Ho(p+(t*764|0)|0,r,31)|0;if((_a(b,t,c[o>>2]|0)|0)<0){d=-1;g=27;break}else d=0;do{a[p+(t*764|0)+512+(d<<1)>>0]=-1;d=d+1|0}while((d|0)!=121);d=c[x>>2]|0;if((c[d+(t*764|0)+36>>2]|0)>0){o=p+(t*764|0)+756|0;n=p+(t*764|0)+40|0;m=0;d=0;while(1){j=c[o>>2]|0;c[j+(m<<6)+40>>2]=(Pl(e)|0)&255;k=(Pl(e)|0)&255;g=k+12|0;i=j+(m<<6)|0;c[i>>2]=(Pl(e)|0)&255;if((d|0)<=(g|0)){h=m&255;while(1){if((d|0)<121)a[p+(t*764|0)+512+(d<<1)>>0]=h;if((d|0)<(g|0))d=d+1|0;else break}}d=(Pl(e)|0)&255;g=(m|0)==0;if(g)c[(c[w>>2]|0)+(t<<2)>>2]=d&128|0?d&63:-1;if(!(d&64))c[i>>2]=255;d=((Pl(e)|0)&255)<<1;c[(c[(c[x>>2]|0)+(t*764|0)+756>>2]|0)+(m<<6)+8>>2]=d;d=(Pl(e)|0)&255;if(g)c[(c[v>>2]|0)+(t<<2)>>2]=d&128|0?d&63:-1;if(!(d&64))c[j+(m<<6)+8>>2]=128;d=Rl(e)|0;if(g)c[n>>2]=d&65535;c[j+(m<<6)+28>>2]=(Pl(e)|0)&255;c[j+(m<<6)+24>>2]=((Pl(e)|0)&255)<<1;c[j+(m<<6)+32>>2]=(Pl(e)|0)&255;c[j+(m<<6)+20>>2]=(Pl(e)|0)&255;Pl(e)|0;d=(Pl(e)|0)&255;if(g)c[(c[s>>2]|0)+(t<<2)>>2]=d&128|0?d&63:-1;m=m+1|0;d=c[x>>2]|0;if((m|0)>=(c[d+(t*764|0)+36>>2]|0))break;else d=k+13|0}}t=t+1|0;if((t|0)>=(c[u>>2]|0)){d=0;g=27;break}else p=d}if((g|0)==27){l=y;return d|0}return 0}function Cc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;i=a+128|0;if(c[i>>2]|0){a=-1;return a|0}e=Pl(d)|0;h=e&255;c[i>>2]=h;h=Xm(4,h)|0;j=a+168|0;c[j>>2]=h;if(!h){a=-1;return a|0}if(!(e<<24>>24)){a=0;return a|0}b=a+136|0;g=0;while(1){if((ab(a,g)|0)<0){e=-1;b=11;break}h=Pl(d)|0;f=h&255;e=((Pl(d)|0)&255)+1|0;c[c[(c[j>>2]|0)+(g<<2)>>2]>>2]=e;dm(d,16,1)|0;if(h<<24>>24){h=0;do{e=Rl(d)|0;if((h|0)<(c[b>>2]|0))c[(c[(c[j>>2]|0)+(g<<2)>>2]|0)+4+(h<<2)>>2]=e&65535;h=h+1|0}while((h|0)!=(f|0))}g=g+1|0;if((g|0)>=(c[i>>2]|0)){e=0;b=11;break}}if((b|0)==11)return e|0;return 0}function Dc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;u=l;l=l+64|0;r=u;g=Pl(e)|0;d=g&255;s=b+144|0;c[s>>2]=d;i=Xm(52,d)|0;t=b+180|0;c[t>>2]=i;if(!i){e=-1;l=u;return e|0}p=Xm(8,d)|0;q=b+7592|0;c[q>>2]=p;if(!p){e=-1;l=u;return e|0}o=Xm(4,d)|0;p=f+20|0;c[p>>2]=o;if(!o){e=-1;l=u;return e|0}if(!(g<<24>>24)){e=0;l=u;return e|0}o=f+4|0;n=r+32|0;d=0;while(1){g=(Pl(e)|0)&255;c[(c[o>>2]|0)+(d<<2)>>2]=g;cm(r,1,32,e)|0;a[n>>0]=0;Ho(i+(d*52|0)|0,r,31)|0;dm(e,8,1)|0;g=_l(e)|0;j=i+(d*52|0)+32|0;c[j>>2]=_l(e)|0;m=i+(d*52|0)+36|0;c[m>>2]=_l(e)|0;b=_l(e)|0;k=i+(d*52|0)+40|0;f=i+(d*52|0)+44|0;c[f>>2]=(b|0)>0?2:0;c[k>>2]=(c[m>>2]|0)+b;h[(c[q>>2]|0)+(d<<3)>>3]=+(g|0);Pl(e)|0;g=(Pl(e)|0)&255;b=c[f>>2]|0;if(g&1){b=b|1;c[f>>2]=b;c[j>>2]=c[j>>2]>>1;c[m>>2]=c[m>>2]>>1;c[k>>2]=c[k>>2]>>1}c[f>>2]=b|g<<1&4;c[(c[p>>2]|0)+(d<<2)>>2]=g>>>2&3;d=d+1|0;if((d|0)>=(c[s>>2]|0)){d=0;break}i=c[t>>2]|0}l=u;return d|0}function Ec(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;h=a+128|0;if(c[h>>2]|0){a=-1;return a|0}e=Pl(d)|0;g=e&255;c[h>>2]=g;g=Xm(4,g)|0;i=a+168|0;c[i>>2]=g;if(!g){a=-1;return a|0}if(!(e<<24>>24)){a=0;return a|0}b=a+136|0;f=0;while(1){if((ab(a,f)|0)<0){e=-1;b=11;break}c[c[(c[i>>2]|0)+(f<<2)>>2]>>2]=64;g=0;do{e=Rl(d)|0;if((g|0)<(c[b>>2]|0))c[(c[(c[i>>2]|0)+(f<<2)>>2]|0)+4+(g<<2)>>2]=e&65535;g=g+1|0}while((g|0)!=32);f=f+1|0;if((f|0)>=(c[h>>2]|0)){e=0;b=11;break}}if((b|0)==11)return e|0;return 0}function Fc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;w=l;l=l+64|0;u=w;t=(Pl(e)|0)&255;d=b+144|0;c[d>>2]=t;v=b+140|0;c[v>>2]=t;if((Za(b)|0)<0){f=-1;l=w;return f|0}t=Xm(4,c[d>>2]|0)|0;p=f+20|0;c[p>>2]=t;if(!t){f=-1;l=w;return f|0}t=b+180|0;if((c[v>>2]|0)<=0){f=0;l=w;return f|0}s=b+176|0;q=f+4|0;n=u+32|0;r=b+7592|0;o=0;while(1){d=c[t>>2]|0;c[(c[s>>2]|0)+(o*764|0)+36>>2]=1;if((_a(b,o,1)|0)<0){d=-1;g=9;break}x=c[(c[s>>2]|0)+(o*764|0)+756>>2]|0;g=(Pl(e)|0)&255;c[(c[q>>2]|0)+(o<<2)>>2]=g;c[(c[f>>2]|0)+(o<<2)>>2]=g;c[x+40>>2]=g;cm(u,1,32,e)|0;a[n>>0]=0;dm(e,8,1)|0;Ho((c[s>>2]|0)+(o*764|0)|0,u,31)|0;g=Rl(e)|0;j=d+(o*52|0)+32|0;c[j>>2]=_l(e)|0;m=d+(o*52|0)+36|0;c[m>>2]=_l(e)|0;y=_l(e)|0;k=d+(o*52|0)+40|0;i=d+(o*52|0)+44|0;c[i>>2]=(y|0)>0?2:0;c[k>>2]=(c[m>>2]|0)+y;c[x>>2]=(Pl(e)|0)&255;c[x+8>>2]=128;h[(c[r>>2]|0)+(o<<3)>>3]=+(g&65535);g=(Pl(e)|0)&255;d=c[i>>2]|0;if(g&1){d=d|1;c[i>>2]=d;c[j>>2]=c[j>>2]>>1;c[m>>2]=c[m>>2]>>1;c[k>>2]=c[k>>2]>>1}c[i>>2]=d|g<<1&4;c[(c[p>>2]|0)+(o<<2)>>2]=g>>>2&3;o=o+1|0;if((o|0)>=(c[v>>2]|0)){d=0;g=9;break}}if((g|0)==9){l=w;return d|0}return 0}function Gc(e,f,g,h,i){e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0;e=h+(e<<2)|0;if((c[e>>2]|0)<=-1)return;c[f>>2]=1;l=f+4|0;c[l>>2]=15;if((i|0)<=0)return;h=c[e>>2]|0;k=0;while(1){if((h|0)==(d[g+(k*33|0)>>0]|0|0))break;e=k+1|0;if((e|0)<(i|0))k=e;else{j=10;break}}if((j|0)==10)return;e=d[g+(k*33|0)+31>>0]|0;c[f>>2]=e>>>3&6|1;c[f+12>>2]=e&15;e=d[g+(k*33|0)+32>>0]|0;c[f+20>>2]=e&15;c[f+24>>2]=e&240;e=0;i=-1;while(1){j=e<<1;h=a[g+(k*33|0)+1+j>>0]|0;if(!(h<<24>>24))break;h=(h&255)+i|0;b[f+28+(j<<1)>>1]=h;j=j|1;b[f+28+(j<<1)>>1]=d[g+(k*33|0)+1+j>>0]|0;e=e+1|0;if((e|0)<(c[l>>2]|0))i=h<<16>>16;else break}c[l>>2]=e;return}function Hc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0;n=l;l=l+32|0;k=n+16|0;m=n;j=n+8|0;c[k>>2]=d;c[m>>2]=e;Jc(0,k,m,j)|0;if((f|0)>0){h=0;i=0}else{m=0;l=n;return m|0}a:while(1){if((c[m>>2]|0)<0){d=-1;e=11;break}g=Jc(1,k,m,j)|0;if(!(Jc(1,k,m,j)|0)){b:do if((c[m>>2]|0)>-1){e=8;while(1){if(Jc(1,k,m,j)|0){d=e;break b}d=e+16|0;if(e>>>0>239){d=-1;e=11;break a}if((c[m>>2]|0)>-1)e=d;else break}}else d=8;while(0);d=(Jc(4,k,m,j)|0)+(d&255)|0}else d=Jc(3,k,m,j)|0;h=(((g|0)==0?d:d^255)&255)+(h&255)|0;a[b>>0]=h;i=i+1|0;if((i|0)>=(f|0)){d=0;e=11;break}else b=b+1|0}if((e|0)==11){l=n;return d|0}return 0}function Ic(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0;o=l;l=l+32|0;m=o+16|0;n=o;k=o+8|0;c[m>>2]=d;c[n>>2]=e;Jc(0,m,n,k)|0;if((f|0)>0){i=0;j=0}else{n=0;l=o;return n|0}a:while(1){if((c[n>>2]|0)<0){d=-1;e=11;break}g=Jc(8,m,n,k)|0;h=Jc(1,m,n,k)|0;if(!(Jc(1,m,n,k)|0)){b:do if((c[n>>2]|0)>-1){e=8;while(1){if(Jc(1,m,n,k)|0){d=e;break b}d=e+16|0;if(e>>>0>239){d=-1;e=11;break a}if((c[n>>2]|0)>-1)e=d;else break}}else d=8;while(0);d=(Jc(4,m,n,k)|0)+(d&255)|0}else d=Jc(3,m,n,k)|0;i=(((h|0)==0?d:d^255)&255)+(i&255)|0;a[b>>0]=g;a[b+1>>0]=i;j=j+1|0;if((j|0)>=(f|0)){d=0;e=11;break}else b=b+2|0}if((e|0)==11){l=o;return d|0}return 0}function Jc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;i=a<<24>>24;if(!(a<<24>>24)){g=c[b>>2]|0;c[e>>2]=Uj(g)|0;c[b>>2]=g+4;c[d>>2]=(c[d>>2]|0)+-4;g=e+4|0;c[g>>2]=32;a=32}else{g=e+4|0;a=c[g>>2]|0}h=c[e>>2]|0;f=h&(1<>>i;c[e>>2]=h;a=a-i|0;c[g>>2]=a;if(a>>>0>=25)return f|0;if((c[d>>2]|0)<1)return f|0;i=c[b>>2]|0;c[b>>2]=i+1;c[e>>2]=h|(Uj(i)|0)<>2]=a+8;c[d>>2]=(c[d>>2]|0)+-1;return f|0}function Kc(b,c){b=b|0;c=c|0;var d=0,e=0;switch(a[b>>0]|0){case 0:{d=c;e=4;break}case 5:{d=b;e=4;break}case 6:{a[c>>0]=0;d=b;e=4;break}default:{}}if((e|0)==4)a[d>>0]=0;Mc(b,c);return}function Lc(b,c){b=b|0;c=c|0;switch(a[b>>0]|0){case 0:{a[c>>0]=0;break}case 1:{a[b>>0]=-96;break}case 2:{a[b>>0]=-95;break}case 3:{a[b>>0]=27;break}case 4:{a[b>>0]=7;break}case 5:{a[b>>0]=29;break}case 6:{a[c>>0]=0;a[b>>0]=0;break}default:{}}Mc(b,c);return}function Mc(b,c){b=b|0;c=c|0;switch(a[b>>0]|0){case 7:{a[b>>0]=-85;return}case 10:case 9:case 8:{a[c>>0]=0;a[b>>0]=0;return}case 15:{a[b>>0]=-93;return}case 14:switch((d[c>>0]|0)>>>4&15){case 8:case 3:case 0:{a[c>>0]=0;a[b>>0]=0;return}case 1:{a[b>>0]=25;a[c>>0]=d[c>>0]<<4;return}case 2:{a[b>>0]=25;a[c>>0]=a[c>>0]&15;return}default:return}default:return}}function Nc(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1229803597){b=-1;return b|0}hb(a,b,26);b=0;return b|0}function Oc(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0;I=l;l=l+256|0;t=I;y=I+192|0;H=am(g)|0;c[t>>2]=H;if((H|0)!=1229803597){f=-1;l=I;return f|0}i=t+4|0;cm(i,26,1,g)|0;a[t+30>>0]=Pl(g)|0;a[t+31>>0]=Pl(g)|0;k=t+32|0;b[k>>1]=Rl(g)|0;j=t+34|0;b[j>>1]=Rl(g)|0;m=t+36|0;b[m>>1]=Rl(g)|0;n=t+38|0;b[n>>1]=Rl(g)|0;b[t+40>>1]=Rl(g)|0;w=t+42|0;b[w>>1]=Rl(g)|0;G=t+44|0;b[G>>1]=Rl(g)|0;D=t+46|0;b[D>>1]=Rl(g)|0;H=t+48|0;a[H>>0]=Pl(g)|0;F=t+49|0;a[F>>0]=Pl(g)|0;o=t+50|0;a[o>>0]=Pl(g)|0;p=t+51|0;a[p>>0]=Pl(g)|0;a[t+52>>0]=Pl(g)|0;a[t+53>>0]=Pl(g)|0;if((d[H>>0]|0)>128|(d[F>>0]|0)>128){f=-1;l=I;return f|0}F=t+54|0;b[F>>1]=Rl(g)|0;E=t+56|0;c[E>>2]=_l(g)|0;c[t+60>>2]=_l(g)|0;cm(t+64|0,64,1,g)|0;cm(t+128|0,64,1,g)|0;Ho(f,i,64)|0;r=f+156|0;c[r>>2]=e[k>>1];i=b[j>>1]|0;j=i&65535;u=f+140|0;c[u>>2]=j;C=b[m>>1]|0;k=C&65535;v=f+144|0;c[v>>2]=k;A=b[n>>1]|0;m=A&65535;B=f+128|0;c[B>>2]=m;if(((i|(A|C))&65535)>255){f=-1;l=I;return f|0}if(i<<16>>16){i=Xm(4,j)|0;if(!i){f=-1;l=I;return f|0}else{A=i;s=i}}else{A=0;s=0}z=Xm(4,k)|0;if(z|0){x=Xm(4,m)|0;if(x|0){c[f+148>>2]=d[o>>0];c[f+152>>2]=d[p>>0];i=b[G>>1]|0;C=i&65535;p=C&4^4;if(C&8|0)c[f+1292>>2]=2;C=(p|0)!=0;o=C^1;if((e[w>>1]|0)>511&o){n=f+1284|0;c[n>>2]=c[n>>2]|16384}n=(i&1)==0;m=0;do{i=f+184+(m*12|0)|0;k=a[t+64+m>>0]|0;if(k<<24>>24!=100){if(k<<24>>24<0){a[t+128+m>>0]=0;j=2;q=16}}else{j=16;q=16}if((q|0)==16){q=0;J=f+184+(m*12|0)+8|0;c[J>>2]=c[J>>2]|j}if(!n){c[i>>2]=(k&255)<<2;if((k&255)>63){j=255;q=20}}else{j=128;q=20}if((q|0)==20){q=0;c[i>>2]=j}c[f+184+(m*12|0)+4>>2]=d[t+128+m>>0];m=m+1|0}while((m|0)!=64);i=c[r>>2]|0;j=f+952|0;if((i|0)<257)cm(j,1,i,g)|0;else{cm(j,1,256,g)|0;dm(g,(c[r>>2]|0)+-256|0,1)|0;c[r>>2]=256}r=(e[G>>1]|0)>>>4&1^1;q=r&65535;if((c[u>>2]|0)>0){i=0;do{c[s+(i<<2)>>2]=_l(g)|0;i=i+1|0}while((i|0)<(c[u>>2]|0))}if((c[v>>2]|0)>0){i=0;do{c[z+(i<<2)>>2]=_l(g)|0;i=i+1|0}while((i|0)<(c[v>>2]|0))}if((c[B>>2]|0)>0){i=0;do{c[x+(i<<2)>>2]=_l(g)|0;i=i+1|0}while((i|0)<(c[B>>2]|0))}c[f+1264>>2]=8363;Pc(f,t);if(C)c[u>>2]=c[v>>2];a:do if((Za(f)|0)>=0){i=c[v>>2]|0;if((i|0)>0?(J=Xm(52,i)|0,c[f+7596>>2]=J,(J|0)==0):0)break;if((c[u>>2]|0)>0){k=f+176|0;j=0;do{i=(c[k>>2]|0)+(j*764|0)|0;do if((e[w>>1]|0)>511&o){if((dm(g,(c[s+(j<<2)>>2]|0)+h|0,0)|0)<0)break a;if((Qc(i,g)|0)<0)break a}else{if(C)break;if((dm(g,(c[s+(j<<2)>>2]|0)+h|0,0)|0)<0)break a;if((Rc(i,g)|0)<0)break a}while(0);j=j+1|0}while((j|0)<(c[u>>2]|0));i=c[v>>2]|0}if((i|0)>0){i=0;do{if((dm(g,(c[z+(i<<2)>>2]|0)+h|0,0)|0)<0)break a;if((Sc(f,i,h,p,g)|0)<0)break a;i=i+1|0}while((i|0)<(c[v>>2]|0))}i=c[B>>2]|0;if((i|0)>0){n=0;j=0;do{k=c[x+(n<<2)>>2]|0;if(k){dm(g,k+h|0,0)|0;i=(Rl(g)|0)&65535;Rl(g)|0;k=y;m=k+64|0;do{a[k>>0]=0;k=k+1|0}while((k|0)<(m|0));Rl(g)|0;Rl(g)|0;b:while(1){while(1){m=i+-1|0;if((i|0)<=0)break b;k=Pl(g)|0;if(!(k<<24>>24))i=m;else break}J=k&255;k=J+63&63;j=(k|0)>(j|0)?k:j;if(!(J&128)){k=a[y+k>>0]|0;i=m}else{J=Pl(g)|0;a[y+k>>0]=J;k=J;i=i+-2|0}k=k&255;if(k&1){Pl(g)|0;i=i+-1|0}if(k&2){Pl(g)|0;i=i+-1|0}if(k&4){Pl(g)|0;i=i+-1|0}if(!(k&8))continue;Pl(g)|0;Pl(g)|0;i=i+-2|0}i=c[B>>2]|0}n=n+1|0}while((n|0)<(i|0))}else j=0;J=j+1|0;n=f+136|0;c[n>>2]=J;c[f+132>>2]=O(i,J)|0;if(($a(f)|0)<0)break;if((c[B>>2]|0)>0){m=f+168|0;k=0;do{if((ab(f,k)|0)<0)break a;i=c[x+(k<<2)>>2]|0;do if(i){if((dm(g,i+h|0,0)|0)<0)break a;if((Tc(f,k,q,g)|0)<0)break a}else{c[c[(c[m>>2]|0)+(k<<2)>>2]>>2]=64;i=c[n>>2]|0;if((i|0)>0)j=0;else break;do{i=(O(i,k)|0)+j|0;if((bb(f,i,64)|0)<0)break a;c[(c[(c[m>>2]|0)+(k<<2)>>2]|0)+4+(j<<2)>>2]=i;j=j+1|0;i=c[n>>2]|0}while((j|0)<(i|0))}while(0);k=k+1|0}while((k|0)<(c[B>>2]|0))}Wm(x);Wm(z);Wm(A);do if(b[D>>1]&1){J=Vm((e[F>>1]|0)+1|0)|0;k=f+1220|0;c[k>>2]=J;if(!J)break;dm(g,(c[E>>2]|0)+h|0,0)|0;if(!(b[F>>1]|0))i=0;else{i=0;do{j=Pl(g)|0;if(j<<24>>24==13)j=10;else j=(j+-9&255)>1&((j&255)<32|j<<24>>24<0)?46:j&255;a[(c[k>>2]|0)+i>>0]=j;i=i+1|0}while((i|0)<(e[F>>1]|0))}a[(c[k>>2]|0)+i>>0]=0}while(0);j=f+1284|0;i=(b[G>>1]&32?4194304:1024)|(c[j>>2]|1763149859);c[j>>2]=i;if(!(r<<16>>16)){i=i&-1048577;c[j>>2]=i;i=i|8388608}else i=i|2621440;c[j>>2]=C?i&-1073774593:i;c[f+1272>>2]=128;c[f+1276>>2]=d[H>>0];c[f+1288>>2]=3;J=0;l=I;return J|0}while(0);Wm(x)}Wm(z)}Wm(A);J=-1;l=I;return J|0}function Pc(d,f){d=d|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;x=l;l=l+176|0;w=x+64|0;j=x+56|0;h=x+48|0;g=x+40|0;p=x+32|0;q=x+16|0;i=x+8|0;o=x;v=x+128|0;r=x+80|0;s=x+76|0;k=b[f+44>>1]|0;u=k&4;m=b[f+40>>1]|0;n=m&65535;a:do switch(((m&65535)>>>8&255)<<24>>24){case 0:{a[v>>0]=a[32741]|0;a[v+1>>0]=a[32742]|0;a[v+2>>0]=a[32743]|0;a[v+3>>0]=a[32744]|0;a[v+4>>0]=a[32745]|0;a[v+5>>0]=a[32746]|0;break}case 2:case 1:{j=f+42|0;b:do if((b[j>>1]|0)==512){switch(m<<16>>16){case 534:{t=22;break b}case 532:break;case 535:{g=v;h=32766;i=g+21|0;do{a[g>>0]=a[h>>0]|0;g=g+1|0;h=h+1|0}while((g|0)<(i|0));b[j>>1]=u<<16>>16==0?256:532;break a}default:break b}if(((((((((((((k<<16>>16==9?(b[f+46>>1]|0)==0:0)?(a[f+31>>0]|0)==0:0)?(a[f+30>>0]|0)==0:0)?(b[f+34>>1]|0)==0:0)?((e[f+38>>1]|0)+1|0)==(e[f+32>>1]|0):0)?(a[f+48>>0]|0)==-128:0)?(a[f+49>>0]|0)==100:0)?(a[f+50>>0]|0)==1:0)?(a[f+52>>0]|0)==-128:0)?(a[f+53>>0]|0)==0:0)?(b[f+54>>1]|0)==0:0)?(c[f+56>>2]|0)==0:0)?(c[f+60>>2]|0)==0:0){g=v;h=32747;i=g+19|0;do{a[g>>0]=a[h>>0]|0;g=g+1|0;h=h+1|0}while((g|0)<(i|0));break a}else t=24}else{switch(m<<16>>16){case 534:{t=22;break b}case 532:{t=24;break b}case 535:break;default:break b}g=v;h=32810;i=g+23|0;do{a[g>>0]=a[h>>0]|0;g=g+1|0;h=h+1|0}while((g|0)<(i|0));break a}while(0);if((t|0)==22){g=v;h=32787;i=g+23|0;do{a[g>>0]=a[h>>0]|0;g=g+1|0;h=h+1|0}while((g|0)<(i|0));break a}if((t|0)==24?(nn(f+60|0,32833,4)|0)==0:0){g=v;h=32838;i=g+14|0;do{a[g>>0]=a[h>>0]|0;g=g+1|0;h=h+1|0}while((g|0)<(i|0));break a}c[o>>2]=n>>>8&15;c[o+4>>2]=n&255;io(v,40,32852,o);break}case 127:case 8:{c:do if(m<<16>>16<32767){switch(m<<16>>16){case 2184:break;default:break c}g=v;h=32876;i=g+13|0;do{a[g>>0]=a[h>>0]|0;g=g+1|0;h=h+1|0}while((g|0)<(i|0));break a}else{switch(m<<16>>16){case 32767:break;default:break c}g=v;h=32889;i=g+9|0;do{a[g>>0]=a[h>>0]|0;g=g+1|0;h=h+1|0}while((g|0)<(i|0));break a}while(0);c[i>>2]=n;io(v,40,32898,i);break}default:switch((m&65535)>>>12&15){case 1:{g=n&4095;if(g>>>0>80){c[s>>2]=(g*86400|0)+1247443200;if(xa(s|0,r|0)|0){t=(c[r+16>>2]|0)+1|0;u=c[r+12>>2]|0;c[q>>2]=(c[r+20>>2]|0)+1900;c[q+4>>2]=t;c[q+8>>2]=u;io(v,40,32913,q)}}else{c[p>>2]=g;io(v,40,32943,p)}break a}case 5:{c[g>>2]=n>>>8&15;c[g+4>>2]=n&255;io(v,40,32963,g);if(!(nn(f+60|0,32979,4)|0))break a;g=v+(fo(v)|0)|0;h=32984;i=g+11|0;do{a[g>>0]=a[h>>0]|0;g=g+1|0;h=h+1|0}while((g|0)<(i|0));break a}case 6:{c[h>>2]=n>>>8&15;c[h+4>>2]=n&255;io(v,40,32995,h);break a}default:{c[j>>2]=n;io(v,40,32898,j);break a}}}while(0);f=e[f+42>>1]|0;c[w>>2]=v;c[w+4>>2]=f>>>8;c[w+8>>2]=f&255;ob(d,33015,w);l=x;return}function Qc(f,g){f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0;D=l;l=l+1392|0;t=D+792|0;C=D+304|0;s=D;p=D+1272|0;B=am(g)|0;c[s>>2]=B;if((B|0)!=1229803593){C=-1;l=D;return C|0}cm(s+4|0,12,1,g)|0;a[s+16>>0]=Pl(g)|0;u=s+17|0;a[u>>0]=Pl(g)|0;v=s+18|0;a[v>>0]=Pl(g)|0;i=Pl(g)|0;w=s+19|0;a[w>>0]=(i&255)>3?0:i;i=s+20|0;b[i>>1]=Rl(g)|0;a[s+22>>0]=Pl(g)|0;a[s+23>>0]=Pl(g)|0;r=s+24|0;a[r>>0]=Pl(g)|0;x=s+25|0;a[x>>0]=Pl(g)|0;B=s+26|0;a[B>>0]=Pl(g)|0;A=s+27|0;a[A>>0]=Pl(g)|0;b[s+28>>1]=Rl(g)|0;a[s+30>>0]=Pl(g)|0;a[s+31>>0]=Pl(g)|0;if(gm(g)|0){C=-1;l=D;return C|0}h=s+32|0;if((cm(h,1,26,g)|0)!=26){C=-1;l=D;return C|0}Wc(h);y=s+58|0;a[y>>0]=Pl(g)|0;z=s+59|0;a[z>>0]=Pl(g)|0;a[s+60>>0]=Pl(g)|0;a[s+61>>0]=Pl(g)|0;b[s+62>>1]=Rl(g)|0;if((cm(s+64|0,1,240,g)|0)!=240){C=-1;l=D;return C|0}gb(f,h,25)|0;c[f+40>>2]=e[i>>1]<<6;i=f+44|0;Xc(i,p,g);j=f+200|0;Xc(j,p,g);k=f+356|0;Xc(k,p,g);if(c[j>>2]&1|0?(m=f+204|0,(c[m>>2]|0)>0):0){h=0;do{g=f+228+((h<<1|1)<<1)|0;b[g>>1]=(e[g>>1]|0)+32;h=h+1|0}while((h|0)<(c[m>>2]|0))}if(c[i>>2]&1|0?(n=f+48|0,(c[n>>2]|0)==0):0)c[n>>2]=1;if(c[j>>2]&1|0?(o=f+204|0,(c[o>>2]|0)==0):0)c[o>>2]=1;h=c[k>>2]|0;if(h&1|0?(q=f+360|0,(c[q>>2]|0)==0):0)c[q>>2]=1;if((a[p>>0]|0)<0){c[k>>2]=h|8;h=a[p+1>>0]|0;if(h<<24>>24){h=h&255;i=0;do{q=f+384+((i<<1|1)<<1)|0;b[q>>1]=((e[q>>1]<<16)+2097152|0)>>>14;i=i+1|0}while((i|0)!=(h|0))}}else{h=a[p+1>>0]|0;if(h<<24>>24){h=h&255;i=0;do{q=f+384+((i<<1|1)<<1)|0;b[q>>1]=(b[q>>1]|0)*50;i=i+1|0}while((i|0)!=(h|0))}}gp(t|0,-1,480)|0;m=0;i=0;while(1){k=m<<1;q=a[(k|1)+(s+64)>>0]|0;g=(q&255)+-1|0;if(q<<24>>24==0|(g|0)>119){a[f+512+(m<<1)>>0]=-1;h=0;q=i}else{j=t+(g<<2)|0;h=c[j>>2]|0;if((h|0)==-1){c[j>>2]=i;c[C+(i<<2)>>2]=g;h=i;i=i+1|0}a[f+512+(m<<1)>>0]=h;h=(d[s+64+k>>0]|0)-m&255;q=i}a[f+512+(m<<1)+1>>0]=h;m=m+1|0;if((m|0)==120)break;else i=q}c[f+36>>2]=q;c[f+32>>2]=(d[r>>0]|0)>>>1;if(!q){C=0;l=D;return C|0}p=Xm(64,q)|0;c[f+756>>2]=p;if(!p){C=-1;l=D;return C|0}if((q|0)<=0){C=0;l=D;return C|0}o=d[u>>0]|0;n=d[v>>0]|0;m=c[1808+(d[w>>0]<<2)>>2]|0;k=d[x>>0]|0;k=(k&128|0)==0?k<<2:-1;g=d[y>>0]|0;j=d[z>>0]|0;i=d[A>>0]<<8|d[B>>0];h=0;do{c[p+(h<<6)+40>>2]=c[C+(h<<2)>>2];c[p+(h<<6)+44>>2]=o;c[p+(h<<6)+48>>2]=n;c[p+(h<<6)+52>>2]=m;c[p+(h<<6)+8>>2]=k;c[p+(h<<6)+56>>2]=g;c[p+(h<<6)+60>>2]=j;c[p+(h<<6)+36>>2]=i;h=h+1|0}while((h|0)!=(q|0));h=0;l=D;return h|0}function Rc(f,g){f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;x=l;l=l+1520|0;r=x+1040|0;w=x+556|0;q=x;c[q>>2]=am(g)|0;cm(q+4|0,12,1,g)|0;a[q+16>>0]=Pl(g)|0;j=q+17|0;a[j>>0]=Pl(g)|0;o=q+18|0;a[o>>0]=Pl(g)|0;n=q+19|0;a[n>>0]=Pl(g)|0;m=q+20|0;a[m>>0]=Pl(g)|0;k=q+21|0;a[k>>0]=Pl(g)|0;b[q+22>>1]=Rl(g)|0;i=q+24|0;b[i>>1]=Rl(g)|0;u=q+26|0;a[u>>0]=Pl(g)|0;v=q+27|0;a[v>>0]=Pl(g)|0;b[q+28>>1]=Rl(g)|0;a[q+30>>0]=Pl(g)|0;a[q+31>>0]=Pl(g)|0;if(gm(g)|0){w=-1;l=x;return w|0}h=q+32|0;if((cm(h,1,26,g)|0)!=26){w=-1;l=x;return w|0}Wc(h);if((cm(q+58|0,1,6,g)|0)!=6){w=-1;l=x;return w|0}if((cm(q+64|0,1,240,g)|0)!=240){w=-1;l=x;return w|0}if((cm(q+304|0,1,200,g)|0)!=200){w=-1;l=x;return w|0}if((cm(q+504|0,1,50,g)|0)!=50){w=-1;l=x;return w|0}gb(f,h,25)|0;c[f+40>>2]=e[i>>1]<<7;h=a[j>>0]|0;j=h&255;h=j<<1&4|h&1;h=(j&4|0)==0?h:h|18;c[f+44>>2]=(j&8|0)==0?h:h|34;c[f+64>>2]=d[o>>0];c[f+68>>2]=d[n>>0];c[f+56>>2]=d[m>>0];c[f+60>>2]=d[k>>0];h=0;while(1){if((a[(h<<1)+(q+504)>>0]|0)==-1)break;h=h+1|0;if((h|0)>=25){h=-1;p=25;break}}if((p|0)==25){l=x;return h|0}c[f+48>>2]=h;if(h|0)do{h=h+-1|0;p=h<<1;b[f+72+(p<<1)>>1]=d[q+504+p>>0]|0;p=p|1;b[f+72+(p<<1)>>1]=d[q+504+p>>0]|0}while((h|0)!=0);gp(r|0,-1,480)|0;j=0;i=0;while(1){if((j|0)!=120?(s=j<<1,t=(d[(s|1)+(q+64)>>0]|0)+-1|0,t>>>0<=119):0){g=r+(t<<2)|0;h=c[g>>2]|0;if((h|0)==-1){c[g>>2]=i;c[w+(i<<2)>>2]=t;h=i;g=i+1|0}else g=i;a[f+512+(j<<1)>>0]=h;h=(d[q+64+s>>0]|0)-j&255;k=g}else{a[f+512+(j<<1)>>0]=0;h=0;k=i}a[f+512+(j<<1)+1>>0]=h;j=j+1|0;if((j|0)==121)break;else i=k}c[f+36>>2]=k;c[f+32>>2]=64;if(!k){w=0;l=x;return w|0}j=Xm(64,k)|0;c[f+756>>2]=j;if(!j){w=-1;l=x;return w|0}if((k|0)<=0){w=0;l=x;return w|0}i=d[u>>0]|0;h=(a[v>>0]|0)!=0&1;g=0;do{c[j+(g<<6)+40>>2]=c[w+(g<<2)>>2];c[j+(g<<6)+44>>2]=i;c[j+(g<<6)+48>>2]=h;c[j+(g<<6)+8>>2]=-1;g=g+1|0}while((g|0)!=(k|0));h=0;l=x;return h|0}function Sc(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0;K=l;l=l+80|0;i=K;z=(g|0)!=0;if(z?(J=Xm(64,1)|0,c[(c[b+176>>2]|0)+(e*764|0)+756>>2]=J,(J|0)==0):0){b=-1;l=K;return b|0}J=am(h)|0;c[i>>2]=J;if((J|0)!=1229803603){b=-1;l=K;return b|0}J=b+180|0;k=c[J>>2]|0;r=k+(e*52|0)|0;I=b+7596|0;n=c[I>>2]|0;cm(i+4|0,12,1,h)|0;a[i+16>>0]=Pl(h)|0;x=i+17|0;a[x>>0]=Pl(h)|0;H=i+18|0;a[H>>0]=Pl(h)|0;E=i+19|0;a[E>>0]=Pl(h)|0;if(gm(h)|0){b=-1;l=K;return b|0}q=i+20|0;if((cm(q,1,26,h)|0)!=26){b=-1;l=K;return b|0}Wc(q);F=i+46|0;a[F>>0]=Pl(h)|0;w=i+47|0;a[w>>0]=Pl(h)|0;g=i+48|0;c[g>>2]=_l(h)|0;j=i+52|0;c[j>>2]=_l(h)|0;m=i+56|0;c[m>>2]=_l(h)|0;v=i+60|0;c[v>>2]=_l(h)|0;o=i+64|0;c[o>>2]=_l(h)|0;p=i+68|0;c[p>>2]=_l(h)|0;y=i+72|0;c[y>>2]=_l(h)|0;C=i+76|0;a[C>>0]=Pl(h)|0;A=i+77|0;a[A>>0]=Pl(h)|0;B=i+78|0;a[B>>0]=Pl(h)|0;D=i+79|0;a[D>>0]=Pl(h)|0;if((c[i>>2]|0)!=1229803603){b=0;l=K;return b|0}i=d[H>>0]|0;if(i&2|0)c[k+(e*52|0)+44>>2]=1;u=c[g>>2]|0;G=k+(e*52|0)+32|0;c[G>>2]=u;if((u|0)>268435456){b=-1;l=K;return b|0}u=k+(e*52|0)+36|0;c[u>>2]=c[j>>2];t=k+(e*52|0)+40|0;c[t>>2]=c[m>>2];s=k+(e*52|0)+44|0;m=i&32;c[s>>2]=i>>>3&2|m|i>>>4&4|i>>>1&64|c[s>>2];if(m|0){g=n+(e*52|0)|0;i=r;j=g+52|0;do{c[g>>2]=c[i>>2];g=g+4|0;i=i+4|0}while((g|0)<(j|0));c[n+(e*52|0)+36>>2]=c[o>>2];c[n+(e*52|0)+40>>2]=c[p>>2];i=n+(e*52|0)+44|0;g=c[i>>2]|0;c[i>>2]=g&-7|2;if((a[H>>0]|0)<0)c[i>>2]=g|6}if(z){r=c[b+176>>2]|0;p=c[r+(e*764|0)+756>>2]|0;c[p>>2]=d[E>>0];c[p+8>>2]=128;c[p+40>>2]=e;c[r+(e*764|0)+36>>2]=(c[G>>2]|0)!=0&1;fb(r,e,q,25)}else gb(r,q,25)|0;m=b+140|0;g=c[m>>2]|0;if((g|0)>0){n=b+176|0;i=c[n>>2]|0;k=0;do{if((c[i+(k*764|0)+36>>2]|0)>0){j=0;do{g=c[i+(k*764|0)+756>>2]|0;do if((c[g+(j<<6)+40>>2]|0)==(e|0)){c[g+(j<<6)>>2]=d[E>>0];c[g+(j<<6)+4>>2]=d[x>>0];c[g+(j<<6)+28>>2]=d[C>>0];c[g+(j<<6)+24>>2]=(d[A>>0]|0)>>>1;c[g+(j<<6)+20>>2]=d[D>>0];c[g+(j<<6)+32>>2]=((a[B>>0]^-2)&255)>>>1;Gi(c[v>>2]|0,g+(j<<6)+12|0,g+(j<<6)+16|0);i=d[w>>0]|0;if(i&128|0){c[g+(j<<6)+8>>2]=i<<2&508;break}if(z)c[g+(j<<6)+8>>2]=-1}while(0);j=j+1|0;i=c[n>>2]|0}while((j|0)<(c[i+(k*764|0)+36>>2]|0));g=c[m>>2]|0}k=k+1|0}while((k|0)<(g|0))}if(!(a[H>>0]&1)){b=0;l=K;return b|0}if((c[G>>2]|0)<=1){b=0;l=K;return b|0}a:do if(!(dm(h,(c[y>>2]|0)+f|0,0)|0)){f=c[t>>2]|0;i=c[G>>2]|0;if(!((f|0)<=(i|0)?(c[u>>2]|0)<(f|0):0))c[s>>2]=c[s>>2]&-3;j=a[F>>0]|0;n=(j<<1&2^2)&255;k=a[H>>0]|0;g=k&255;if(!(g&8)){if(g&32|0){g=em(h)|0;if((g|0)<0)break;if((Eb(b,h,n,(c[I>>2]|0)+(e*52|0)|0,0)|0)<0)break;dm(h,g,0)|0}if((Eb(b,h,n,(c[J>>2]|0)+(e*52|0)|0,0)|0)<0)break;else g=0;l=K;return g|0}m=Xm(1,i<<1)|0;if(m|0){i=c[G>>2]|0;g=j&4;if(!(k&2))Bb(h,m,i,g);else Db(h,m,i,g)|0;do if(a[H>>0]&32){i=em(h)|0;if((i|0)<0){Wm(m);break a}g=n|16;if((Eb(b,0,g,(c[I>>2]|0)+(e*52|0)|0,m)|0)<0){Wm(m);break a}else{dm(h,i,0)|0;break}}else g=n|16;while(0);b=(Eb(b,0,g,(c[J>>2]|0)+(e*52|0)|0,m)|0)<0;Wm(m);if(!b){b=0;l=K;return b|0}}}while(0);b=-1;l=K;return b|0}function Tc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;u=l;l=l+656|0;p=u;r=u+136|0;s=u+72|0;q=u+8|0;g=q;h=g+64|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));gp(r|0,0,512)|0;i=p;c[i>>2]=0;c[i+4>>2]=0;i=Rl(f)|0;n=(Rl(f)|0)&65535;t=b+168|0;c[c[(c[t>>2]|0)+(d<<2)>>2]>>2]=n;if((cb(b,d)|0)<0){t=-1;l=u;return t|0}g=s;h=g+64|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));Rl(f)|0;Rl(f)|0;if(!(i<<16>>16)){t=0;l=u;return t|0}n=b+136|0;m=b+172|0;g=i&65535;k=0;a:while(1){b=g;while(1){g=b+-1|0;h=Pl(f)|0;if(!(h<<24>>24))break;i=h&255;j=i+63&63;if(i&128){a[s+j>>0]=Pl(f)|0;g=b+-2|0}if((j|0)<(c[n>>2]|0)?(o=c[(c[t>>2]|0)+(d<<2)>>2]|0,(k|0)<(c[o>>2]|0)):0)i=(c[(c[m>>2]|0)+(c[o+4+(j<<2)>>2]<<2)>>2]|0)+4+(k<<3)|0;else i=p;b=a[s+j>>0]|0;if(b&1){h=Pl(f)|0;switch(h<<24>>24){case -1:{h=-127;break}case -2:{h=-126;break}default:h=(h&255)>119?-125:h+1<<24>>24}a[i>>0]=h;a[r+(j<<3)>>0]=h;g=g+-1|0}b=b&255;if(b&2){h=Pl(f)|0;a[i+1>>0]=h;a[r+(j<<3)+1>>0]=h;g=g+-1|0}if(b&4){h=Pl(f)|0;a[i+2>>0]=h;a[r+(j<<3)+2>>0]=h;Uc(i);g=g+-1|0}if(b&8){h=Pl(f)|0;if((h&255)>26){g=-1;h=33;break a}v=i+3|0;a[v>>0]=h;h=i+4|0;a[h>>0]=Pl(f)|0;Vc(j,i,q,e);a[r+(j<<3)+3>>0]=a[v>>0]|0;a[r+(j<<3)+4>>0]=a[h>>0]|0;g=g+-2|0}if(b&16|0)a[i>>0]=a[r+(j<<3)>>0]|0;if(b&32|0)a[i+1>>0]=a[r+(j<<3)+1>>0]|0;if(b&64|0){a[i+2>>0]=a[r+(j<<3)+2>>0]|0;Uc(i)}if(b&128|0){a[i+3>>0]=a[r+(j<<3)+3>>0]|0;a[i+4>>0]=a[r+(j<<3)+4>>0]|0}if((g|0)>0)b=g;else{g=0;h=33;break a}}if((b|0)>1)k=k+1|0;else{g=0;h=33;break}}if((h|0)==33){l=u;return g|0}return 0}function Uc(b){b=b|0;var c=0,d=0,e=0;e=b+2|0;c=a[e>>0]|0;d=c&255;a[e>>0]=0;if((c&255)<65){a[e>>0]=d+1;return}if((c&255)<75){a[b+5>>0]=-62;a[b+6>>0]=d+191;return}if((c&255)<85){a[b+5>>0]=-61;a[b+6>>0]=d+181;return}if((c&255)<95){a[b+5>>0]=-64;a[b+6>>0]=d+171;return}if((c&255)<105){a[b+5>>0]=-63;a[b+6>>0]=d+161;return}if((c&255)<115){a[b+5>>0]=2;a[b+6>>0]=(d<<2)+92;return}if((c&255)<125){a[b+5>>0]=1;a[b+6>>0]=(d<<2)+52;return}if(c<<24>>24<0&(c&255)<193){a[b+6>>0]=c<<24>>24==-64?-1:d<<2&255;a[b+5>>0]=8;return}if((c+63&255)<10){a[b+5>>0]=3;a[b+6>>0]=a[32731+(d+-193)>>0]|0;return}if((c+53&255)>=10)return;a[b+5>>0]=4;a[b+6>>0]=d+53;return}function Vc(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0;j=c+4|0;h=a[j>>0]|0;g=(h&255)>>>4;i=c+3|0;c=a[32704+(d[i>>0]|0)>>0]|0;a[i>>0]=c;switch(c<<24>>24){case -2:{a[i>>0]=14;c=e+b|0;if(!((g|h)<<24>>24)){g=a[c>>0]|0;a[j>>0]=g;b=g&15;g=(g&255)>>>4}else{a[c>>0]=h;b=h&15}c=b&255;do switch(g&15){case 1:{a[j>>0]=b|48;return}case 2:{a[j>>0]=0;a[i>>0]=0;return}case 3:{a[j>>0]=b|64;return}case 4:{a[j>>0]=b|112;return}case 5:if(b>>>0<4){a[i>>0]=-117;a[j>>0]=c;return}else{a[j>>0]=0;a[i>>0]=0;return}case 6:{a[j>>0]=b|224;return}case 7:{a[i>>0]=-125;a[j>>0]=a[j>>0]&15;return}case 8:{a[i>>0]=8;a[j>>0]=b<<4;return}case 9:{a[i>>0]=-115;a[j>>0]=c;return}case 10:{a[i>>0]=-116;a[j>>0]=c;return}case 11:{a[j>>0]=b|96;return}case 13:case 12:{a[j>>0]=((b|0)==0&1)+c<<24>>24|g<<4&255;return}case 14:{a[i>>0]=-120;a[j>>0]=c;return}default:{a[j>>0]=0;a[i>>0]=0;return}}while(0)}case -124:{c=h&255;if(h<<24>>24<0&(h&255)<144){a[i>>0]=-123;a[j>>0]=c<<4;return}else{a[j>>0]=c<<1;return}}case 29:{if(f|0)return;c=h&255;if(!(h<<24>>24))return;a[j>>0]=c+16&240|(c&15)+1;return}case 16:{if((h&255)<=128)return;a[j>>0]=0;a[i>>0]=0;return}case -1:{a[j>>0]=0;a[i>>0]=0;return}default:return}}function Wc(b){b=b|0;var c=0,d=0;d=0;do{c=b+d|0;if(!(a[c>>0]|0))a[c>>0]=32;d=d+1|0}while((d|0)!=25);c=b+24|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+23|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+22|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+21|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+20|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+19|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+18|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+17|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+16|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+15|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+14|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+13|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+12|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+11|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+10|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+9|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+8|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+7|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+6|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+5|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+4|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+3|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+2|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;c=b+1|0;if((a[c>>0]|0)!=32)return;a[c>>0]=0;if((a[b>>0]|0)!=32)return;a[b>>0]=0;return}function Xc(e,f,g){e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;a[f>>0]=Pl(g)|0;n=Pl(g)|0;j=f+1|0;a[j>>0]=n;if((n&255)>31){a[f>>0]=0;a[j>>0]=0;return}k=f+2|0;a[k>>0]=Pl(g)|0;l=f+3|0;a[l>>0]=Pl(g)|0;m=f+4|0;a[m>>0]=Pl(g)|0;n=f+5|0;a[n>>0]=Pl(g)|0;h=Pl(g)|0;i=0;do{a[f+6+(i<<2)>>0]=h;b[f+6+(i<<2)+2>>1]=Rl(g)|0;i=i+1|0;h=Pl(g)|0}while((i|0)!=25);a[f+106>>0]=h;i=d[f>>0]|0;g=i<<1&4|i&1;g=(i&4|0)==0?g:g|18;i=i<<2&32;c[e>>2]=i|g;h=a[j>>0]|0;o=h&255;j=e+4|0;c[j>>2]=o;c[e+12>>2]=d[m>>0];c[e+16>>2]=d[n>>0];c[e+20>>2]=d[k>>0];c[e+24>>2]=d[l>>0];if((o+-1|0)>>>0>=25){c[e>>2]=i|g&22;return}if(!(h<<24>>24))return;else h=0;do{o=h<<1;b[e+28+(o<<1)>>1]=b[f+6+(h<<2)+2>>1]|0;b[e+28+((o|1)<<1)>>1]=a[f+6+(h<<2)>>0]|0;h=h+1|0}while((h|0)<(c[j>>2]|0));return}function Yc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;e=l;l=l+16|0;d=e;dm(a,c+20|0,0)|0;do if((cm(d,1,8,a)|0)>>>0>=8){if(nn(d,33085,8)|0?nn(d,33039,8)|0:0){d=-1;break}dm(a,c+60|0,0)|0;if((cm(d,1,4,a)|0)>>>0>=4?(nn(d,33094,4)|0)==0:0){dm(a,c,0)|0;hb(a,b,20);d=0}else d=-1}else d=-1;while(0);l=e;return d|0} +function Je(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0;e=g+12|0;if(!(c[e>>2]|0)){c[e>>2]=1;e=g+24|0;c[e>>2]=0;h=b+128|0;c[b+132>>2]=O(c[b+136>>2]|0,c[h>>2]|0)|0;if(($a(b)|0)<0){f=-1;return f|0}}else{e=g+24|0;h=b+128|0}m=c[e>>2]|0;if((m|0)>63?1:(m|0)>=(c[h>>2]|0)){f=-1;return f|0}j=g+36+m|0;if((db(b,m,d[j>>0]|0)|0)<0){f=-1;return f|0}h=a[j>>0]|0;if(h<<24>>24){k=b+136|0;l=b+172|0;i=b+168|0;g=c[k>>2]|0;b=0;do{if((g|0)>0){h=0;do{n=c[(c[l>>2]|0)+(c[(c[(c[i>>2]|0)+(m<<2)>>2]|0)+4+(h<<2)>>2]<<2)>>2]|0;g=n+4+(b<<3)|0;a[n+4+(b<<3)+4>>0]=Pl(f)|0;a[n+4+(b<<3)+3>>0]=Pl(f)|0;a[n+4+(b<<3)+1>>0]=Pl(f)|0;n=Pl(f)|0;a[g>>0]=n<<24>>24==0?0:(n&255)+48&255;Le(g);h=h+1|0;g=c[k>>2]|0}while((h|0)<(g|0));h=a[j>>0]|0}b=b+1|0}while((b|0)<(h&255|0))}c[e>>2]=(c[e>>2]|0)+1;n=0;return n|0}function Ke(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;b=e+16|0;do if(!(c[b>>2]|0)){c[a+140>>2]=36;c[a+144>>2]=36;if((Za(a)|0)<0){a=-1;return a|0}else{c[b>>2]=1;b=e+20|0;c[b>>2]=0;e=0;break}}else{b=e+20|0;e=c[b>>2]|0;if((e|0)>35){a=0;return a|0}}while(0);g=a+176|0;c[(c[g>>2]|0)+(e*764|0)+36>>2]=1;if((_a(a,e,1)|0)<0){a=-1;return a|0}if((am(d)|0)!=1397637453){a=-1;return a|0}f=_l(d)|0;if(f>>>0>32){a=-1;return a|0}cm((c[g>>2]|0)+(e*764|0)|0,1,f,d)|0;if((am(d)|0)!=1398165324){a=-1;return a|0}_l(d)|0;h=(_l(d)|0)&255;c[c[(c[g>>2]|0)+(e*764|0)+756>>2]>>2]=h;if((am(d)|0)!=1397507406){a=-1;return a|0}_l(d)|0;h=_l(d)|0;f=a+180|0;c[(c[f>>2]|0)+(e*52|0)+32>>2]=h;if((am(d)|0)!=1380927059){a=-1;return a|0}_l(d)|0;h=_l(d)|0;c[(c[f>>2]|0)+(e*52|0)+36>>2]=h;if((am(d)|0)!=1380730190){a=-1;return a|0}_l(d)|0;h=_l(d)|0;c[(c[f>>2]|0)+(e*52|0)+40>>2]=h;if((am(d)|0)!=1396982100){a=-1;return a|0}_l(d)|0;_l(d)|0;h=c[(c[g>>2]|0)+(e*764|0)+756>>2]|0;c[h+40>>2]=e;c[h+8>>2]=128;c[a+1280>>2]=8;c[a+1268>>2]=255;f=c[f>>2]|0;h=f+(e*52|0)+40|0;g=c[h>>2]|0;if((g|0)<=2){if((g|0)==2?(c[f+(e*52|0)+36>>2]|0)>0:0){c[f+(e*52|0)+44>>2]=2;c[h>>2]=c[f+(e*52|0)+32>>2]}}else{c[f+(e*52|0)+44>>2]=2;c[h>>2]=g+(c[f+(e*52|0)+36>>2]|0)}if((Eb(a,d,128,f+(e*52|0)|0,0)|0)<0){a=-1;return a|0}c[b>>2]=(c[b>>2]|0)+1;a=0;return a|0}function Le(b){b=b|0;var c=0,d=0;d=b+3|0;do switch(a[d>>0]|0){case 0:{a[d>>0]=0;return}case 1:{a[d>>0]=1;return}case 2:{a[d>>0]=2;return}case 3:{a[d>>0]=3;return}case 11:{a[d>>0]=13;return}case 12:{c=b+4|0;b=a[c>>0]|0;if((b&255)<65){a[d>>0]=12;b=a[34532+(b&255)>>0]|0}else{a[d>>0]=0;b=0}a[c>>0]=b;return}case 25:case 14:{c=b+4|0;b=a[c>>0]|0;if((b+-1&255)<7){a[d>>0]=8;a[c>>0]=((b&255)*42|0)+216;return}else{a[c>>0]=0;a[d>>0]=0;return}}case 16:{a[d>>0]=-96;return}case 17:{a[d>>0]=-95;return}case 19:{a[d>>0]=11;return}case 21:{a[b+4>>0]=0;a[d>>0]=0;return}case 28:{a[d>>0]=15;return}case 31:{a[d>>0]=12;return}default:{a[b+4>>0]=0;a[d>>0]=0;return}}while(0)}function Me(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;if(c[a>>2]|0){b=-1;return b|0}e=am(a)|0;if((e|0)!=33624851|(am(a)|0)!=336724235){b=-1;return b|0}if(((Pl(a)|0)&255)>1){b=-1;return b|0}Pl(a)|0;Rl(a)|0;Rl(a)|0;Wl(a)|0;d=Pl(a)|0;e=0;do{if(d<<24>>24>-1)Wl(a)|0;e=e+1|0;d=Pl(a)|0}while((e|0)!=63);hb(a,b,d&255);b=0;return b|0}function Ne(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;w=l;l=l+400|0;t=w;s=w+128|0;p=w+384|0;dm(e,8,1)|0;Pl(e)|0;ob(b,34597,t);u=b+136|0;c[u>>2]=(Pl(e)|0)&255;r=Rl(e)|0;q=r&65535;c[b+128>>2]=q;n=b+156|0;c[n>>2]=q;if((c[u>>2]|0)>8|(r&65535)>256){b=-1;l=w;return b|0}q=b+132|0;c[q>>2]=(Rl(e)|0)&65535;Wl(e)|0;c[b+144>>2]=63;r=b+140|0;c[r>>2]=63;if((Za(b)|0)<0){b=-1;l=w;return b|0}a:do if((c[r>>2]|0)>0){h=b+180|0;g=b+176|0;f=0;while(1){if((_a(b,f,1)|0)<0){f=-1;v=65;break}o=(Pl(e)|0)&255;c[s+(f<<2)>>2]=o;if((o&128|0)==0?(o=(Wl(e)|0)<<1,c[(c[h>>2]|0)+(f*52|0)+32>>2]=o,c[(c[g>>2]|0)+(f*764|0)+36>>2]=1,(o|0)>524288):0){f=-1;v=65;break}f=f+1|0;if((f|0)>=(c[r>>2]|0))break a}if((v|0)==65){l=w;return f|0}}while(0);o=Pl(e)|0;f=o&255;if((o&255)>32){cm(b,1,32,e)|0;dm(e,f+-32|0,0)|0}else cm(b,1,f,e)|0;cm(p,1,8,e)|0;c[q>>2]=(c[q>>2]|0)+1;if(($a(b)|0)<0){b=-1;l=w;return b|0}f=Pl(e)|0;if((f&255)>1){b=-1;l=w;return b|0}g=O(c[n>>2]<<1,c[u>>2]|0)|0;m=Vm(g)|0;if(!m){b=-1;l=w;return b|0}if(!(f<<24>>24)){if((cm(m,1,g,e)|0)!=(g|0)){Wm(m);b=-1;l=w;return b|0}}else if(!(Ya(c[e+8>>2]|0,m,g,g)|0)){Wm(m);b=-1;l=w;return b|0}b:do if((c[n>>2]|0)>0){k=b+168|0;j=0;c:while(1){if((ab(b,j)|0)<0){v=23;break}i=c[(c[k>>2]|0)+(j<<2)>>2]|0;c[i>>2]=64;f=c[u>>2]|0;if((f|0)>0){h=0;do{f=m+((O(f,j)|0)+h<<1)|0;f=Oe(a[f>>0]|0,a[f+1>>0]|0)|0;g=(c[q>>2]|0)+-1|0;if((f|0)>=(g|0)){v=26;break c}c[i+4+(h<<2)>>2]=(f|0)==4096?g:f;h=h+1|0;f=c[u>>2]|0}while((h|0)<(f|0))}a[b+952+j>>0]=j;j=j+1|0;if((j|0)>=(c[n>>2]|0))break b}if((v|0)==23){Wm(m);b=-1;l=w;return b|0}else if((v|0)==26){Wm(m);b=-1;l=w;return b|0}}while(0);Wm(m);f=Pl(e)|0;if((f&255)>1){b=-1;l=w;return b|0}g=(c[q>>2]<<8)+-256|0;o=Vm(g)|0;if(!o){b=-1;l=w;return b|0}if(!(f<<24>>24)){if((cm(o,1,g,e)|0)!=(g|0)){Wm(o);b=-1;l=w;return b|0}}else if(!(Ya(c[e+8>>2]|0,o,g,g)|0)){Wm(o);b=-1;l=w;return b|0}d:do if((c[q>>2]|0)>1){n=b+172|0;f=0;while(1){if((bb(b,f,64)|0)<0)break;h=c[n>>2]|0;g=c[h+(f<<2)>>2]|0;if((c[g>>2]|0)>0){m=f<<6;k=0;do{i=g+4+(k<<3)|0;j=Pe(o+(k+m<<2)|0)|0;x=j&63;a[i>>0]=(x|0)==0?0:x+48&255;a[g+4+(k<<3)+1>>0]=j>>>6&127;x=j>>>14;y=x&63;g=g+4+(k<<3)+3|0;a[g>>0]=y;if(!((d[p+(y>>>3)>>0]|0)&1<<(x&7)))a[g>>0]=0;else{Qe(i,j>>>20);h=c[n>>2]|0}k=k+1|0;g=c[h+(f<<2)>>2]|0}while((k|0)<(c[g>>2]|0))}f=f+1|0;if((f|0)>=((c[q>>2]|0)+-1|0))break d}Wm(o);y=-1;l=w;return y|0}else f=0;while(0);Wm(o);if((bb(b,f,64)|0)<0){y=-1;l=w;return y|0}e:do if((c[r>>2]|0)>0){m=b+180|0;k=b+176|0;i=e+8|0;j=0;f:while(1){f=t;g=f+128|0;do{a[f>>0]=0;f=f+1|0}while((f|0)<(g|0));y=c[s+(j<<2)>>2]|0;cm(t,1,y&127,e)|0;fb(c[k>>2]|0,j,t,32);do if(!(y&128)){h=(Wl(e)|0)<<1;c[(c[m>>2]|0)+(j*52|0)+36>>2]=h;h=(Wl(e)|0)<<1;f=c[m>>2]|0;g=f+(j*52|0)+44|0;if((h|0)>2)c[g>>2]=c[g>>2]|2;c[f+(j*52|0)+40>>2]=(c[f+(j*52|0)+36>>2]|0)+h;y=(Pl(e)|0)&255;x=c[(c[k>>2]|0)+(j*764|0)+756>>2]|0;c[x>>2]=y;c[x+8>>2]=128;x=((Pl(e)|0)&255)<<28>>24;y=c[(c[k>>2]|0)+(j*764|0)+756>>2]|0;c[y+16>>2]=x;c[y+40>>2]=j;if(!(c[(c[m>>2]|0)+(j*52|0)+32>>2]|0)){v=61;break}g=Pl(e)|0;do if((g&255)>1){ko(34614,32,1,21640)|0;f=c[m>>2]|0;v=60}else{f=c[m>>2]|0;if(g<<24>>24!=1){v=60;break}f=f+(j*52|0)+32|0;y=Vm(c[f>>2]|0)|0;f=c[f>>2]|0;Ya(c[i>>2]|0,y,f,f)|0;f=Eb(b,0,17,(c[m>>2]|0)+(j*52|0)|0,y)|0;Wm(y)}while(0);if((v|0)==60){v=0;f=Eb(b,e,128,f+(j*52|0)|0,0)|0}if((f|0)<0){f=-1;break f}}else v=61;while(0);if((v|0)==61)v=0;j=j+1|0;if((j|0)>=(c[r>>2]|0))break e}l=w;return f|0}while(0);if((c[u>>2]|0)<=0){y=0;l=w;return y|0}f=b+1300|0;g=0;do{c[b+184+(g*12|0)>>2]=((O(c[f>>2]|0,((((g+3|0)/2|0|0)%2|0)*255|0)+-128|0)|0)/100|0)+128;g=g+1|0}while((g|0)<(c[u>>2]|0));f=0;l=w;return f|0}function Oe(a,b){a=a|0;b=b|0;return (b&255)<<8|a&255|0}function Pe(a){a=a|0;return (d[a+1>>0]|0)<<8|(d[a>>0]|0)|(d[a+2>>0]|0)<<16|(d[a+3>>0]|0)<<24|0}function Qe(b,c){b=b|0;c=c|0;var d=0,e=0;d=b+3|0;e=a[d>>0]|0;do switch(e<<24>>24){case 2:case 1:case 0:{a[b+4>>0]=c;d=c>>8;if(!d)return;a[b+5>>0]=-96;a[b+6>>0]=d;return}case 7:case 4:case 3:{a[b+4>>0]=c;return}case 6:case 5:{a[b+4>>0]=c;if(c|0)return;a[d>>0]=(e&255)+254;return}case 9:{a[b+4>>0]=c>>>1;return}case 10:{if(!(c&255))a[d>>0]=0;else a[b+4>>0]=c;a[b+5>>0]=14;a[b+6>>0]=c>>>8&15|16;return}case 15:case 13:case 12:case 11:{a[b+4>>0]=c;return}case 19:{a[d>>0]=14;a[b+4>>0]=c&15|48;return}case 20:{a[d>>0]=14;a[b+4>>0]=c&15|64;return}case 21:{a[d>>0]=14;a[b+4>>0]=c&15|80;return}case 22:{a[d>>0]=14;a[b+4>>0]=c&15|96;return}case 23:{a[d>>0]=14;a[b+4>>0]=c&15|112;return}case 25:if((c|0)<16){a[d>>0]=14;a[b+4>>0]=c&15|144;return}else{a[d>>0]=0;return}case 27:case 26:case 18:case 17:{if(((c&255)+-1|0)>>>0<15){a[d>>0]=14;a[b+4>>0]=(e<<24>>24==17|e<<24>>24==26?16:32)|c&15}else a[d>>0]=0;d=c>>8;if(!d)return;a[b+5>>0]=14;a[b+6>>0]=((e+-17&255)<2?160:176)|d;return}case 28:{a[d>>0]=14;a[b+4>>0]=c&15|192;return}case 29:{a[d>>0]=14;a[b+4>>0]=c&15|208;return}case 30:{a[d>>0]=14;a[b+4>>0]=c&15|224;return}case 31:{a[d>>0]=0;return}case 32:{a[d>>0]=0;a[b+4>>0]=c;d=c>>8;if(!d)return;a[b+5>>0]=-95;a[b+6>>0]=d;return}case 33:{a[d>>0]=1;a[b+4>>0]=c;d=c>>8;if(!d)return;a[b+5>>0]=-95;a[b+6>>0]=d;return}case 34:{a[d>>0]=2;a[b+4>>0]=c;d=c>>8;if(!d)return;a[b+5>>0]=-95;a[b+6>>0]=d;return}case 47:{if((c+-256|0)>>>0>=1793)return;a[d>>0]=15;a[b+4>>0]=(c+4|0)>>>3;return}default:{a[d>>0]=0;return}}while(0)}function Re(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1296385026){b=-1;return b|0}hb(a,b,0);b=0;return b|0}function Se(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;t=l;l=l+4656|0;s=t+4096|0;r=t;e=t+4616|0;o=t+4360|0;q=t+4104|0;if((am(d)|0)!=1296385026){w=-1;l=t;return w|0}ob(b,34647,r);c[b+144>>2]=32;c[b+140>>2]=32;if((Za(b)|0)<0){w=-1;l=t;return w|0}cm(e,1,40,d)|0;p=b+176|0;f=0;do{cm(e,1,40,d)|0;fb(c[p>>2]|0,f,e,32);if((_a(b,f,1)|0)<0){v=-1;w=40;break}f=f+1|0}while((f|0)<31);if((w|0)==40){l=t;return v|0}Pl(d)|0;e=0;do{m=(Pl(d)|0)&255;n=c[(c[p>>2]|0)+(e*764|0)+756>>2]|0;c[n>>2]=m;c[n+8>>2]=128;c[n+16>>2]=0;c[n+40>>2]=e;e=e+1|0}while((e|0)!=31);Ul(d)|0;n=b+180|0;e=Ul(d)|0;f=0;do{c[(c[n>>2]|0)+(f*52|0)+36>>2]=e&65535;f=f+1|0;e=Ul(d)|0}while((f|0)!=31);e=0;do{k=Ul(d)|0;m=c[n>>2]|0;c[m+(e*52|0)+40>>2]=(c[m+(e*52|0)+36>>2]|0)+(k&65535);c[m+(e*52|0)+44>>2]=(k&65535)>1?2:0;e=e+1|0}while((e|0)!=31);j=b+136|0;c[j>>2]=4;k=(Ul(d)|0)&65535;m=b+128|0;c[m>>2]=k;c[b+132>>2]=O(c[j>>2]|0,k)|0;if((cm(b+952|0,1,100,d)|0)!=100){w=-1;l=t;return w|0}k=Ul(d)|0;c[b+156>>2]=k&65535;if((k&65535)>100|(c[m>>2]|0)>256){w=-1;l=t;return w|0}e=Ul(d)|0;if(!(e<<16>>16)){w=-1;l=t;return w|0}c[b+148>>2]=192/((e&65535)>>>0)|0;Ul(d)|0;k=Ul(d)|0;am(d)|0;dm(d,16,1)|0;if(k<<16>>16==6){k=b+1284|0;c[k>>2]=c[k>>2]|192}if(($a(b)|0)<0){w=-1;l=t;return w|0}a:do if((c[m>>2]|0)>0){k=b+172|0;j=b+168|0;f=0;while(1){if((db(b,f,64)|0)<0){v=-1;break}am(d)|0;g=0;do{h=0;do{i=c[(c[k>>2]|0)+(c[(c[(c[j>>2]|0)+(f<<2)>>2]|0)+4+(h<<2)>>2]<<2)>>2]|0;a[i+4+(g<<3)>>0]=Ei((Ul(d)|0)&65535)|0;x=Pl(d)|0;a[i+4+(g<<3)+1>>0]=(x&255)>>>4;e=i+4+(g<<3)+3|0;a[e>>0]=x&15;a[i+4+(g<<3)+4>>0]=Pl(d)|0;i=(a[e>>0]|0)+-13<<24>>24;if((i&255)<3)a[e>>0]=789002>>>((i&255)<<3&16777215);h=h+1|0}while((h|0)!=4);g=g+1|0}while((g|0)!=64);f=f+1|0;if((f|0)>=(c[m>>2]|0))break a}l=t;return v|0}while(0);j=b+7580|0;i=0;while(1){nb(c[j>>2]|0,o);if((mb(o,(c[p>>2]|0)+(i*764|0)|0,q)|0)!=0?(c[s>>2]=o,c[s+4>>2]=q,io(r,4096,34661,s),u=hm(r,35139)|0,(u|0)!=0):0){k=mm(c[u+4>>2]|0)|0;c[(c[n>>2]|0)+(i*52|0)+32>>2]=k;k=u}else k=0;e=c[n>>2]|0;f=c[e+(i*52|0)+32>>2]|0;g=c[p>>2]|0;if((f|0)>0)c[g+(i*764|0)+36>>2]=1;h=(k|0)!=0;if(!(fo(g+(i*764|0)|0)|0|f)){if(h)lm(k)}else if(h?(x=Eb(b,k,0,e+(i*52|0)|0,0)|0,lm(k),(x|0)<=-1):0)break;i=i+1|0;if((i|0)>=31){v=0;w=40;break}}if((w|0)==40){l=t;return v|0}x=-1;l=t;return x|0}function Te(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1296385027){b=-1;return b|0}hb(a,b,0);b=0;return b|0}function Ue(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0;p=l;l=l+48|0;g=p;am(d)|0;ob(b,34667,g);c[b+144>>2]=32;c[b+140>>2]=32;if((Za(b)|0)<0){b=-1;l=p;return b|0}o=b+176|0;e=0;do{f=0;do{k=Pl(d)|0;a[g+f>>0]=k;f=f+1|0}while(k<<24>>24!=0&(f|0)<40);fb(c[o>>2]|0,e,g,32);if((_a(b,e,1)|0)<=-1){n=-1;h=60;break}e=e+1|0}while((e|0)<32);if((h|0)==60){l=p;return n|0}f=0;g=am(d)|0;while(1){if((g|0)<0)e=(Pl(d)|0)&255;else e=0;k=c[(c[o>>2]|0)+(f*764|0)+756>>2]|0;c[k>>2]=e;c[k+8>>2]=128;c[k+16>>2]=0;c[k+40>>2]=f;f=f+1|0;if((f|0)==32)break;else g=g<<1}k=b+180|0;f=0;g=am(d)|0;while(1){if((g|0)<0)e=(Ul(d)|0)&65535;else e=0;c[(c[k>>2]|0)+(f*52|0)+36>>2]=e;f=f+1|0;if((f|0)==32)break;else g=g<<1}f=0;g=am(d)|0;while(1){if((g|0)<0)e=(Ul(d)|0)&65535;else e=0;j=c[k>>2]|0;i=(c[j+(f*52|0)+36>>2]|0)+e|0;c[j+(f*52|0)+32>>2]=i;c[j+(f*52|0)+40>>2]=i;c[j+(f*52|0)+44>>2]=e>>>0>1?2:0;f=f+1|0;if((f|0)==32)break;else g=g<<1}e=b+136|0;c[e>>2]=4;i=(Ul(d)|0)&65535;j=b+128|0;c[j>>2]=i;c[b+132>>2]=O(c[e>>2]|0,i)|0;i=Ul(d)|0;e=i&65535;c[b+156>>2]=e;if((i&65535)>256){b=-1;l=p;return b|0}if((c[j>>2]|0)>256){b=-1;l=p;return b|0}cm(b+952|0,1,e,d)|0;i=Ul(d)|0;e=i&65535;f=b+148|0;c[f>>2]=e;if((i&65535)>10){c[b+152>>2]=((e*125|0)>>>0)/33|0;c[f>>2]=6}g=Nl(d)|0;Pl(d)|0;h=Ul(d)|0;am(d)|0;dm(d,16,1)|0;e=0;f=am(d)|0;while(1){if((f|0)<0)Pl(d)|0;e=e+1|0;if((e|0)==32)break;else f=f<<1}e=0;f=am(d)|0;while(1){if((f|0)<0)Pl(d)|0;e=e+1|0;if((e|0)==32)break;else f=f<<1}e=g<<24>>24;if(h<<16>>16==6){i=b+1284|0;c[i>>2]=c[i>>2]|192}i=c[o>>2]|0;c[(c[i+756>>2]|0)+12>>2]=e;c[(c[i+1520>>2]|0)+12>>2]=e;c[(c[i+2284>>2]|0)+12>>2]=e;c[(c[i+3048>>2]|0)+12>>2]=e;c[(c[i+3812>>2]|0)+12>>2]=e;c[(c[i+4576>>2]|0)+12>>2]=e;c[(c[i+5340>>2]|0)+12>>2]=e;c[(c[i+6104>>2]|0)+12>>2]=e;c[(c[i+6868>>2]|0)+12>>2]=e;c[(c[i+7632>>2]|0)+12>>2]=e;c[(c[i+8396>>2]|0)+12>>2]=e;c[(c[i+9160>>2]|0)+12>>2]=e;c[(c[i+9924>>2]|0)+12>>2]=e;c[(c[i+10688>>2]|0)+12>>2]=e;c[(c[i+11452>>2]|0)+12>>2]=e;c[(c[i+12216>>2]|0)+12>>2]=e;c[(c[i+12980>>2]|0)+12>>2]=e;c[(c[i+13744>>2]|0)+12>>2]=e;c[(c[i+14508>>2]|0)+12>>2]=e;c[(c[i+15272>>2]|0)+12>>2]=e;c[(c[i+16036>>2]|0)+12>>2]=e;c[(c[i+16800>>2]|0)+12>>2]=e;c[(c[i+17564>>2]|0)+12>>2]=e;c[(c[i+18328>>2]|0)+12>>2]=e;c[(c[i+19092>>2]|0)+12>>2]=e;c[(c[i+19856>>2]|0)+12>>2]=e;c[(c[i+20620>>2]|0)+12>>2]=e;c[(c[i+21384>>2]|0)+12>>2]=e;c[(c[i+22148>>2]|0)+12>>2]=e;c[(c[i+22912>>2]|0)+12>>2]=e;c[(c[i+23676>>2]|0)+12>>2]=e;c[(c[i+24440>>2]|0)+12>>2]=e;if(($a(b)|0)<0){b=-1;l=p;return b|0}a:do if((c[j>>2]|0)>0){i=0;while(1){if((db(b,i,64)|0)<0){n=-1;h=60;break}Pl(d)|0;e=Pl(d)|0;g=Ul(d)|0;h=g&65535;m=Xm(1,h+16|0)|0;if(!m){n=-1;h=60;break}f=e&255;if(!(f&16))if(!(f&1))e=am(d)|0;else e=-1;else e=0;c[m>>2]=e;if(!(f&32))if(!(f&2))e=am(d)|0;else e=-1;else e=0;c[m+4>>2]=e;if(!(f&64))if(!(f&4))e=am(d)|0;else e=-1;else e=0;c[m+8>>2]=e;if(!(f&128))if(!(f&8))e=am(d)|0;else e=-1;else e=0;c[m+12>>2]=e;if((cm(m+16|0,1,h,d)|0)!=(h|0)){h=51;break}h=Ve(b,i&65535,m,g)|0;Wm(m);i=i+1|0;if((h|0)<=-1){n=-1;h=60;break}if((i|0)>=(c[j>>2]|0))break a}if((h|0)==51){Wm(m);b=-1;l=p;return b|0}else if((h|0)==60){l=p;return n|0}}while(0);e=0;f=am(d)|0;while(1){if((f|0)<=-1){c[(c[o>>2]|0)+(e*764|0)+36>>2]=1;n=am(d)|0;c[(c[k>>2]|0)+(e*52|0)+32>>2]=n;if(!n)c[(c[o>>2]|0)+(e*764|0)+36>>2]=0;if((Ul(d)|0)<<16>>16==0?(Eb(b,d,0,(c[k>>2]|0)+(e*52|0)|0,0)|0)<0:0){n=-1;h=60;break}}e=e+1|0;if((e|0)>=32){n=0;h=60;break}else f=f<<1}if((h|0)==60){l=p;return n|0}return 0}function Ve(d,e,f,g){d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;A=l;l=l+32|0;i=A+12|0;x=A+8|0;h=A+4|0;w=A;v=A+16|0;c[i>>2]=c[f>>2];c[x>>2]=c[f+4>>2];c[h>>2]=c[f+8>>2];c[w>>2]=c[f+12>>2];b[v>>1]=0;p=f+16|0;o=c[d+136>>2]|0;z=Xm(3,256)|0;if(!z){z=-1;l=A;return z|0}s=(o|0)/2|0;r=((o|0)/4|0)&255;u=16-o|0;q=(o|0)>0;t=o*3|0;n=0;m=z;while(1){k=(n|0)==32;h=k?w:h;i=k?x:i;if((c[i>>2]|0)<0){f=g&65535;if((f|0)<(s|0)){y=36;break}g=f-s&65535;f=We(p,v,r)|0;if(q){k=0;f=(f&65535)<>0]=We(p,v,2)|0;a[j+1>>0]=((Xe(p,v)|0)&255)<<4}k=k+1<<24>>24;if((k&255|0)>=(o|0))break;else{f=f<<1&131070;j=j+3|0}}}}if((c[h>>2]|0)<0){f=g&65535;if((f|0)<(s|0)){y=36;break}g=f-s&65535;f=We(p,v,r)|0;if(q){k=0;f=(f&65535)<>0]=a[B>>0]|C;a[j+2>>0]=We(p,v,2)|0}k=k+1<<24>>24;if((k&255|0)>=(o|0))break;else{f=f<<1&131070;j=j+3|0}}}}c[i>>2]=c[i>>2]<<1;c[h>>2]=c[h>>2]<<1;n=n+1|0;if((n|0)>=64)break;else m=m+t|0}if((y|0)==36){Wm(z);C=-1;l=A;return C|0}o=c[d+172>>2]|0;h=c[(c[d+168>>2]|0)+((e&65535)<<2)>>2]|0;k=0;do{n=k*12|0;m=0;do{f=c[o+(c[h+4+(m<<2)>>2]<<2)>>2]|0;g=(m*3|0)+n|0;C=a[z+g>>0]|0;a[f+4+(k<<3)>>0]=C<<24>>24==0?0:(C&255)+48&255;C=a[z+(g+1)>>0]|0;j=(C&255)>>>4;a[f+4+(k<<3)+1>>0]=j<<24>>24==0?0:j+1<<24>>24;j=f+4+(k<<3)+3|0;a[j>>0]=C&15;g=a[z+(g+2)>>0]|0;i=f+4+(k<<3)+4|0;a[i>>0]=g;a:do switch(C&15){case 4:case 3:case 2:case 1:case 0:break;case 12:{C=g&255;a[i>>0]=((C>>>4)*10|0)+(C&15);break}case 13:{a[j>>0]=10;break}case 15:switch(g<<24>>24){case 0:{a[j>>0]=13;break a}case -1:{a[j>>0]=0;a[i>>0]=0;a[f+4+(k<<3)+2>>0]=1;break a}case -2:{a[j>>0]=0;a[i>>0]=0;break a}case -15:{a[j>>0]=14;a[i>>0]=-109;break a}case -14:{a[j>>0]=14;a[i>>0]=-61;break a}case -13:{a[j>>0]=14;a[i>>0]=-45;break a}default:{if((g&255)<=10)break a;a[j>>0]=-85;a[i>>0]=(((g&255)*125|0)>>>0)/33|0;break a}}default:{a[j>>0]=0;a[i>>0]=0}}while(0);m=m+1|0}while((m|0)!=4);k=k+1|0}while((k|0)!=64);Wm(z);C=0;l=A;return C|0}function We(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;if(!(c<<24>>24)){b=0;return b|0}else d=0;do{c=c+-1<<24>>24;d=(Xe(a,b)|0)&255|d<<4&1048560}while(c<<24>>24!=0);b=d&65535;return b|0}function Xe(c,d){c=c|0;d=d|0;var e=0;e=b[d>>1]|0;c=a[c+((e&65535)>>>1&65535)>>0]|0;b[d>>1]=e+1<<16>>16;return ((e&1)==0?(c&255)>>>4:c&15)|0}function Ye(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1296385028){b=-1;return b|0}hb(a,b,0);b=0;return b|0}function Ze(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0;N=l;l=l+4736|0;K=N;r=N+4712|0;M=N+3688|0;J=N+616|0;H=N+584|0;G=N+552|0;I=N+536|0;am(g)|0;k=em(g)|0;if((k|0)<0){f=-1;l=N;return f|0}dm(g,0,2)|0;a:do if((em(g)|0)>2e3){dm(g,-1024,1)|0;cm(M,1,1024,g)|0;i=0;while(1){j=M+i|0;i=i+1|0;if(!(nn(j,34695,8)|0))break;if((i|0)>=1013){q=2;i=10;break a}}q=d[j+10>>0]|0;i=d[j+11>>0]|0}else{q=2;i=10}while(0);dm(g,k+h|0,0)|0;c[K>>2]=q;c[K+4>>2]=i;io(f+64|0,64,34704,K);i=Pl(g)|0;if(!(i<<24>>24)){k=0;j=0;i=0}else{k=0;j=0;h=i&255;m=0;i=0;while(1){if(h&128){k=cp(k|0,j|0,8)|0;j=z;k=(Pl(g)|0)&255|k;i=i+1|0}m=m+1|0;h=h<<1;if(!((h&255)<<24>>24!=0&(m|0)<8))break;else h=h&254}}j=cp(k|0,j|0,((i|0)>0?8-i<<3:0)|0)|0;i=z;gp(J|0,0,3072)|0;if((j|0)==0&(i|0)==0)k=0;else{p=0;k=0;do{o=p;p=p+1|0;if(!((i|0)>0|(i|0)==0&j>>>0>0)){n=Pl(g)|0;F=Pl(g)|0;k=F&255;if(!(F<<24>>24))k=0;else{h=0;do{a[K+h>>0]=Pl(g)|0;h=h+1|0}while((h|0)!=(k|0))}a[K+k>>0]=0;m=J+(o*48|0)+40|0;c[m>>2]=64;k=n&255;if(!(k&1))c[J+(o*48|0)+32>>2]=((Ul(g)|0)&65535)<<1;if(!(k&2))h=((Ul(g)|0)&65535)<<1;else h=0;if(!(k&4))Pl(g)|0;if(!(k&8))Pl(g)|0;if(!(k&48))c[m>>2]=(Pl(g)|0)&255;if(!(k&64))c[J+(o*48|0)+44>>2]=(Nl(g)|0)<<24>>24;c[J+(o*48|0)+36>>2]=(c[J+(o*48|0)+32>>2]|0)+(h&65534);gb(J+(o*48|0)|0,K,32)|0;k=p}j=cp(j|0,i|0,1)|0;i=z}while(((j|0)!=0|(i|0)!=0)&(p|0)<64)}F=f+128|0;c[F>>2]=(Ul(g)|0)&65535;i=f+156|0;c[i>>2]=(Ul(g)|0)&65535;if(gm(g)|0){f=-1;l=N;return f|0}if((c[F>>2]|0)>256){f=-1;l=N;return f|0}i=c[i>>2]|0;if((i|0)>256){f=-1;l=N;return f|0}cm(f+952|0,1,i,g)|0;E=Ul(g)|0;i=E&65535;if((E&65535)<11){h=f+148|0;c[h>>2]=i;i=125}else{i=((i*125|0)>>>0)/33|0;h=f+148|0}c[f+152>>2]=i;j=(Nl(g)|0)<<24>>24;Nl(g)|0;i=(Nl(g)|0)<<24>>24;c[h>>2]=(Pl(g)|0)&255;if(!(i&32)){E=f+1284|0;c[E>>2]=c[E>>2]|192}if((q|0)==2)c[h>>2]=6-(i>>>5&1);dm(g,20,1)|0;cm(r,1,16,g)|0;Pl(g)|0;i=0;do{E=J+(i*48|0)+44|0;c[E>>2]=(c[E>>2]|0)+j;i=i+1|0}while((i|0)!=64);E=f+136|0;c[E>>2]=0;m=em(g)|0;if((m|0)<0){f=-1;l=N;return f|0}i=c[F>>2]|0;if((i|0)>0){h=0;do{i=(Pl(g)|0)&255;j=(Pl(g)|0)&255;if((j|0)>(c[E>>2]|0))c[E>>2]=j;Pl(g)|0;dm(g,i+-4+((Ul(g)|0)&65535)|0,1)|0;h=h+1|0;i=c[F>>2]|0}while((h|0)<(i|0))}j=c[E>>2]|0;if((j|0)>16){f=-1;l=N;return f|0}c[f+132>>2]=O(j,i)|0;if(($a(f)|0)<0){f=-1;l=N;return f|0}dm(g,m,0)|0;b:do if((c[F>>2]|0)>0){D=f+172|0;C=f+168|0;B=0;while(1){o=(Pl(g)|0)&255;n=em(g)|0;if((n|0)<0)break;p=Pl(g)|0;y=p&255;if((y|0)>(c[E>>2]|0))break;A=(Pl(g)|0)&255;j=Ul(g)|0;i=A>>>6;h=0;while(1){a[K+h>>0]=Pl(g)|0;if((h|0)==(i|0))break;else h=h+1|0}x=j&65535;if((db(f,B,A+1|0)|0)<0)break;c[H>>2]=0;c[H+4>>2]=0;c[H+8>>2]=0;c[H+12>>2]=0;c[H+16>>2]=0;c[H+20>>2]=0;c[H+24>>2]=0;c[H+28>>2]=0;c[G>>2]=0;c[G+4>>2]=0;c[G+8>>2]=0;c[G+12>>2]=0;c[G+16>>2]=0;c[G+20>>2]=0;c[G+24>>2]=0;c[G+28>>2]=0;w=(A>>>5)+1|0;m=0;do{j=d[K+((m|0)/2|0)>>0]|0;h=((m|0)%2|0)<<2;do if(!(j&128>>>h)){if(j&64>>>h|0){i=0;break}i=am(g)|0}else i=-1;while(0);c[H+(m<<2)>>2]=i;do if(!(j&32>>>h)){if(j&16>>>h|0){i=0;break}i=am(g)|0}else i=-1;while(0);c[G+(m<<2)>>2]=i;m=m+1|0}while((m|0)!=(w|0));v=n+o|0;dm(g,v,0)|0;_e(g,I);r=p<<24>>24==0;u=0;do{t=u<<5;p=H+(u<<2)|0;q=G+(u<<2)|0;s=0;do{o=s+t|0;if((o|0)>(A|0))break;n=c[p>>2]|0;do if((n|0)<0){i=$e(I,y)|0;if(r)break;j=i&65535;h=0;while(1){i=c[(c[D>>2]|0)+(c[(c[(c[C>>2]|0)+(B<<2)>>2]|0)+4+(h<<2)>>2]<<2)>>2]|0;if(j&32768|0){m=af(I)|0;P=m>>>4;a[i+4+(o<<3)>>0]=(P&255)<<24>>24==0?0:P+48&255;a[i+4+(o<<3)+1>>0]=m&15}h=h+1|0;if((h|0)==(y|0))break;else j=j<<1}}while(0);m=c[q>>2]|0;do if((m|0)<0){i=$e(I,y)|0;if(r)break;j=i&65535;h=0;while(1){i=c[(c[D>>2]|0)+(c[(c[(c[C>>2]|0)+(B<<2)>>2]|0)+4+(h<<2)>>2]<<2)>>2]|0;if(j&32768|0){P=af(I)|0;a[i+4+(o<<3)+3>>0]=P>>>8;a[i+4+(o<<3)+4>>0]=P;bf(i+4+(o<<3)|0)}h=h+1|0;if((h|0)==(y|0))break;else j=j<<1}}while(0);c[p>>2]=n<<1;c[q>>2]=m<<1;s=s+1|0}while((s|0)<32);u=u+1|0}while((u|0)!=(w|0));dm(g,x+v|0,0)|0;B=B+1|0;if((B|0)>=(c[F>>2]|0))break b}P=-1;l=N;return P|0}while(0);c[f+140>>2]=k;if(Ak(f)|0){P=-1;l=N;return P|0}i=am(g)|0;do if((i|0)==1296385110){c[f+144>>2]=0;if((Za(f)|0)<0){P=-1;l=N;return P|0}else{dm(g,-4,1)|0;break}}else{s=cp(am(g)|0,i|0,1)|0;r=z;q=em(g)|0;if((q|0)<0){P=-1;l=N;return P|0}c:do if((s|0)==0&(r|0)==0)i=0;else{n=r;o=s;p=0;i=0;d:while(1){do if((n|0)>0|(n|0)==0&o>>>0>0)j=57;else{h=am(g)|0;j=Ul(g)|0;m=em(g)|0;if((m|0)<0){j=1;break}switch(j<<16>>16){case 0:case -2:{i=i+1|0;break}case -1:{dm(g,20,1)|0;i=((Ul(g)|0)&65535)+i|0;break}default:{}}dm(g,m+h|0,0)|0;j=0}while(0);switch(j&63){case 57:case 0:break;default:break d}p=p+1|0;o=cp(o|0,n|0,1)|0;n=z;if(!(((o|0)!=0|(n|0)!=0)&(p|0)<64))break c}if(!j)break;else i=-1;l=N;return i|0}while(0);dm(g,q,0)|0;E=f+144|0;c[E>>2]=i;if((Za(f)|0)<0){P=-1;l=N;return P|0}e:do if(((s|0)!=0|(r|0)!=0)&(k|0)>0){C=f+176|0;u=K+10|0;v=K+12|0;x=K+14|0;B=K+16|0;w=K+18|0;A=K+19|0;y=K+20|0;q=K+22|0;t=K+150|0;D=f+180|0;p=0;i=0;f:while(1){g:do if((r|0)>0|(r|0)==0&s>>>0>0)L=129;else{n=c[C>>2]|0;m=n+(p*764|0)|0;o=am(g)|0;P=Ul(g)|0;Ho(m,J+(p*48|0)|0,32)|0;switch(P<<16>>16){case -2:{h=em(g)|0;if((h|0)<0)break f;am(g)|0;Ul(g)|0;Ul(g)|0;Ul(g)|0;b[u>>1]=Ul(g)|0;b[v>>1]=Ul(g)|0;b[x>>1]=Ul(g)|0;b[B>>1]=Ul(g)|0;a[w>>0]=Pl(g)|0;a[A>>0]=Pl(g)|0;P=Ul(g)|0;b[y>>1]=P;j=b[x>>1]|0;if((P&65535)>256|((j&65535)>128|(e[B>>1]|0)>128))break f;cm(q,1,j&65535,g)|0;cm(t,1,e[B>>1]|0,g)|0;dm(g,(am(g)|0)+h|0,0)|0;j=am(g)|0;Ul(g)|0;if(wk(m)|0)break f;c[n+(p*764|0)+36>>2]=1;if((_a(f,p,1)|0)<0)break f;P=c[n+(p*764|0)+756>>2]|0;I=c[n+(p*764|0)+760>>2]|0;c[I+4>>2]=d[w>>0];c[I+8>>2]=d[A>>0];c[P+8>>2]=128;c[P>>2]=c[J+(p*48|0)+40>>2];c[P+12>>2]=c[J+(p*48|0)+44>>2];c[P+40>>2]=i;c[P+16>>2]=0;P=c[D>>2]|0;c[P+(i*52|0)+32>>2]=j;c[P+(i*52|0)+36>>2]=c[J+(p*48|0)+32>>2];I=c[J+(p*48|0)+36>>2]|0;c[P+(i*52|0)+40>>2]=I;c[P+(i*52|0)+44>>2]=(I|0)>2?2:0;if((Eb(f,g,0,P+(i*52|0)|0,0)|0)<0)break f;if(!(ae(f,p,K)|0)){i=i+1|0;break g}else{i=-1;L=142;break f}}case -1:{m=em(g)|0;if((m|0)<0)break f;am(g)|0;Ul(g)|0;Ul(g)|0;Ul(g)|0;b[u>>1]=Ul(g)|0;b[v>>1]=Ul(g)|0;b[x>>1]=Ul(g)|0;b[B>>1]=Ul(g)|0;a[w>>0]=Pl(g)|0;a[A>>0]=Pl(g)|0;P=Ul(g)|0;b[y>>1]=P;j=b[x>>1]|0;if((P&65535)>256|((j&65535)>128|(e[B>>1]|0)>128))break f;cm(q,1,j&65535,g)|0;cm(t,1,e[B>>1]|0,g)|0;j=b[y>>1]|0;if(j<<16>>16==-1){L=129;break g}if((j&65535)>64)break f;if(j<<16>>16){j=0;do{c[K+280+(j<<2)>>2]=am(g)|0;j=j+1|0}while((j|0)<(e[y>>1]|0))}if(wk((c[C>>2]|0)+(p*764|0)|0)|0)break f;P=e[y>>1]|0;c[(c[C>>2]|0)+(p*764|0)+36>>2]=P;if((_a(f,p,P)|0)<0)break f;P=c[n+(p*764|0)+760>>2]|0;c[P+4>>2]=d[w>>0];c[P+8>>2]=d[A>>0];if(b[y>>1]|0){h=n+(p*764|0)+756|0;j=0;do{P=c[h>>2]|0;c[P+(j<<6)+8>>2]=128;c[P+(j<<6)>>2]=64;c[P+(j<<6)+12>>2]=-24;c[P+(j<<6)+40>>2]=i;c[P+(j<<6)+16>>2]=0;dm(g,(c[K+280+(j<<2)>>2]|0)+m|0,0)|0;P=c[D>>2]|0;I=((Ul(g)|0)&65535)<<1;c[P+(i*52|0)+32>>2]=I;c[P+(i*52|0)+36>>2]=0;c[P+(i*52|0)+40>>2]=I;c[P+(i*52|0)+44>>2]=2;if((Eb(f,g,0,P+(i*52|0)|0,0)|0)<0)break f;i=i+1|0;j=j+1|0}while((j|0)<(e[y>>1]|0))}if(ae(f,p,K)|0)break f;dm(g,m+o|0,0)|0;L=129;break g}case 0:{c[n+(p*764|0)+36>>2]=1;if((_a(f,p,1)|0)<0)break f;P=c[n+(p*764|0)+756>>2]|0;c[P>>2]=c[J+(p*48|0)+40>>2];c[P+8>>2]=128;c[P+12>>2]=c[J+(p*48|0)+44>>2];c[P+40>>2]=i;if((i|0)>=(c[E>>2]|0))break f;P=c[D>>2]|0;c[P+(i*52|0)+32>>2]=o;c[P+(i*52|0)+36>>2]=c[J+(p*48|0)+32>>2];I=c[J+(p*48|0)+36>>2]|0;c[P+(i*52|0)+40>>2]=I;c[P+(i*52|0)+44>>2]=(I|0)>2?2:0;if((Eb(f,g,0,P+(i*52|0)|0,0)|0)<0)break f;a[n+(p*764|0)+513>>0]=48;a[n+(p*764|0)+515>>0]=48;a[n+(p*764|0)+517>>0]=48;a[n+(p*764|0)+519>>0]=48;a[n+(p*764|0)+521>>0]=48;a[n+(p*764|0)+523>>0]=48;a[n+(p*764|0)+525>>0]=48;a[n+(p*764|0)+527>>0]=48;a[n+(p*764|0)+529>>0]=48;a[n+(p*764|0)+531>>0]=48;a[n+(p*764|0)+533>>0]=48;a[n+(p*764|0)+535>>0]=48;a[n+(p*764|0)+537>>0]=36;a[n+(p*764|0)+539>>0]=36;a[n+(p*764|0)+541>>0]=36;a[n+(p*764|0)+543>>0]=36;a[n+(p*764|0)+545>>0]=36;a[n+(p*764|0)+547>>0]=36;a[n+(p*764|0)+549>>0]=36;a[n+(p*764|0)+551>>0]=36;a[n+(p*764|0)+553>>0]=36;a[n+(p*764|0)+555>>0]=36;a[n+(p*764|0)+557>>0]=36;a[n+(p*764|0)+559>>0]=36;a[n+(p*764|0)+561>>0]=24;a[n+(p*764|0)+563>>0]=24;a[n+(p*764|0)+565>>0]=24;a[n+(p*764|0)+567>>0]=24;a[n+(p*764|0)+569>>0]=24;a[n+(p*764|0)+571>>0]=24;a[n+(p*764|0)+573>>0]=24;a[n+(p*764|0)+575>>0]=24;a[n+(p*764|0)+577>>0]=24;a[n+(p*764|0)+579>>0]=24;a[n+(p*764|0)+581>>0]=24;a[n+(p*764|0)+583>>0]=24;a[n+(p*764|0)+585>>0]=12;a[n+(p*764|0)+587>>0]=12;a[n+(p*764|0)+589>>0]=12;a[n+(p*764|0)+591>>0]=12;a[n+(p*764|0)+593>>0]=12;a[n+(p*764|0)+595>>0]=12;a[n+(p*764|0)+597>>0]=12;a[n+(p*764|0)+599>>0]=12;a[n+(p*764|0)+601>>0]=12;a[n+(p*764|0)+603>>0]=12;a[n+(p*764|0)+605>>0]=12;a[n+(p*764|0)+607>>0]=12;a[n+(p*764|0)+609>>0]=0;a[n+(p*764|0)+611>>0]=0;a[n+(p*764|0)+613>>0]=0;a[n+(p*764|0)+615>>0]=0;a[n+(p*764|0)+617>>0]=0;a[n+(p*764|0)+619>>0]=0;a[n+(p*764|0)+621>>0]=0;a[n+(p*764|0)+623>>0]=0;a[n+(p*764|0)+625>>0]=0;a[n+(p*764|0)+627>>0]=0;a[n+(p*764|0)+629>>0]=0;a[n+(p*764|0)+631>>0]=0;a[n+(p*764|0)+633>>0]=0;a[n+(p*764|0)+635>>0]=0;a[n+(p*764|0)+637>>0]=0;a[n+(p*764|0)+639>>0]=0;a[n+(p*764|0)+641>>0]=0;a[n+(p*764|0)+643>>0]=0;a[n+(p*764|0)+645>>0]=0;a[n+(p*764|0)+647>>0]=0;a[n+(p*764|0)+649>>0]=0;a[n+(p*764|0)+651>>0]=0;a[n+(p*764|0)+653>>0]=0;a[n+(p*764|0)+655>>0]=0;a[n+(p*764|0)+657>>0]=0;a[n+(p*764|0)+659>>0]=0;a[n+(p*764|0)+661>>0]=0;a[n+(p*764|0)+663>>0]=0;a[n+(p*764|0)+665>>0]=0;a[n+(p*764|0)+667>>0]=0;a[n+(p*764|0)+669>>0]=0;a[n+(p*764|0)+671>>0]=0;a[n+(p*764|0)+673>>0]=0;a[n+(p*764|0)+675>>0]=0;a[n+(p*764|0)+677>>0]=0;a[n+(p*764|0)+679>>0]=0;a[n+(p*764|0)+681>>0]=-12;a[n+(p*764|0)+683>>0]=-12;a[n+(p*764|0)+685>>0]=-12;a[n+(p*764|0)+687>>0]=-12;a[n+(p*764|0)+689>>0]=-12;a[n+(p*764|0)+691>>0]=-12;a[n+(p*764|0)+693>>0]=-12;a[n+(p*764|0)+695>>0]=-12;a[n+(p*764|0)+697>>0]=-12;a[n+(p*764|0)+699>>0]=-12;a[n+(p*764|0)+701>>0]=-12;a[n+(p*764|0)+703>>0]=-12;a[n+(p*764|0)+705>>0]=-24;a[n+(p*764|0)+707>>0]=-24;a[n+(p*764|0)+709>>0]=-24;a[n+(p*764|0)+711>>0]=-24;a[n+(p*764|0)+713>>0]=-24;a[n+(p*764|0)+715>>0]=-24;a[n+(p*764|0)+717>>0]=-24;a[n+(p*764|0)+719>>0]=-24;a[n+(p*764|0)+721>>0]=-24;a[n+(p*764|0)+723>>0]=-24;a[n+(p*764|0)+725>>0]=-24;a[n+(p*764|0)+727>>0]=-24;i=i+1|0;L=129;break g}default:{dm(g,o,1)|0;L=129;break g}}}while(0);if((L|0)==129)L=0;p=p+1|0;s=cp(s|0,r|0,1)|0;r=z;if(!(((s|0)!=0|(r|0)!=0)&(p|0)<(k|0)))break e}if((L|0)==142){l=N;return i|0}P=-1;l=N;return P|0}while(0);Ul(g)|0}while(0);h:do if(!(fm(g)|0)){while(1){i=am(g)|0;if((i|0)<1)break h;j=am(g)|0;if((j|0)<1)break h;k=em(g)|0;if((k|0)<0){i=-1;break}i:do if((i|0)<1296385110){switch(i|0){case 1095650895:break;default:break i}P=(j|0)<1023?j:1023;cm(M,1,P,g)|0;a[M+P>>0]=0}else{switch(i|0){case 1296385110:break;default:break i}am(g)|0}while(0);dm(g,k+j|0,0)|0;if(fm(g)|0)break h}l=N;return i|0}while(0);c[f+1288>>2]=4;P=0;l=N;return P|0}function _e(b,d){b=b|0;d=d|0;c[d>>2]=b;a[d+8>>0]=0;c[d+4>>2]=0;return}function $e(a,b){a=a|0;b=b|0;if((b|0)<5){a=(cf(a)|0)<<12&65535;return a|0}if((b|0)<9){a=(df(a)|0)<<8&65535;return a|0}if((b|0)<13){a=(af(a)|0)<<4&65535;return a|0}else{a=ef(a)|0;return a|0}return 0}function af(a){a=a|0;var b=0,c=0;b=cf(a)|0;c=cf(a)|0;return c<<4|b<<8|(cf(a)|0)|0}function bf(b){b=b|0;var c=0,e=0,f=0;f=b+3|0;switch(a[f>>0]|0){case 12:{f=b+4|0;e=d[f>>0]|0;a[f>>0]=((e>>>4)*10|0)+(e&15);return}case 13:{a[f>>0]=10;return}case 15:{e=b+4|0;c=a[e>>0]|0;switch(c<<24>>24){case 0:{a[f>>0]=13;return}case -1:{a[f>>0]=0;a[e>>0]=0;a[b+2>>0]=1;return}case -15:{a[f>>0]=14;a[e>>0]=-109;return}case -14:{a[f>>0]=14;a[e>>0]=-61;return}case -13:{a[f>>0]=14;a[e>>0]=-45;return}default:{if((c&255)>240){a[f>>0]=0;a[e>>0]=0;return}if((c&255)<=10)return;a[f>>0]=-85;a[e>>0]=(((c&255)*125|0)>>>0)/33|0;return}}}case 4:case 3:case 2:case 1:case 0:return;default:{a[f>>0]=0;a[b+4>>0]=0;return}}}function cf(b){b=b|0;var d=0,e=0;e=b+4|0;d=(c[e>>2]|0)==0;c[e>>2]=d&1;if(d){e=Pl(c[b>>2]|0)|0;a[b+8>>0]=e;e=(e&255)>>>4;return e|0}else{e=a[b+8>>0]&15;return e|0}return 0}function df(a){a=a|0;var b=0;b=cf(a)|0;return b<<4|(cf(a)|0)|0}function ef(a){a=a|0;var b=0,c=0,d=0;c=cf(a)|0;d=cf(a)|0;b=cf(a)|0;return (d<<8|c<<12|b<<4|(cf(a)|0))&65535|0}function ff(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1145195824){b=-1;return b|0}dm(a,12,1)|0;hb(a,b,44);b=0;return b|0}function gf(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0;i=l;l=l+64|0;h=i;g=i+12|0;f=i+8|0;am(b)|0;c[f>>2]=0;d=Ul(b)|0;dm(b,10,1)|0;cm(g,1,44,b)|0;e=pb()|0;if(!e){a=-1;l=i;return a|0}c[a+1264>>2]=8363;j=tb(e,34737,51)|0;j=tb(e,34742,52)|0|j;j=j|(tb(e,35021,53)|0);j=j|(tb(e,35016,54)|0);j=j|(tb(e,34747,55)|0);if(j|(tb(e,34752,56)|0)|0){j=-1;l=i;return j|0}Ho(a,g,64)|0;j=d&65535;c[h>>2]=j>>>8;c[h+4>>2]=j&255;io(a+64|0,64,34757,h);j=(qb(e,a,b,f)|0)<0;wb(e);if(j){j=-1;l=i;return j|0}d=a+136|0;if((c[d>>2]|0)>0)e=0;else{j=0;l=i;return j|0}do{c[a+184+(e*12|0)>>2]=128;e=e+1|0}while((e|0)<(c[d>>2]|0));d=0;l=i;return d|0}function hf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;g=a+140|0;if(c[g>>2]|0){a=-1;return a|0}e=Ul(d)|0;if((e&65535)>255){a=-1;return a|0}c[g>>2]=e&65535;f=a+144|0;c[f>>2]=(Ul(d)|0)&65535;Ul(d)|0;e=Ul(d)|0;do if((e&65535)<=256){b=a+128|0;c[b>>2]=e&65535;d=Ul(d)|0;e=d&65535;if((d&65535)>64){c[b>>2]=0;break}c[a+136>>2]=e;c[a+132>>2]=O(c[b>>2]|0,e)|0;a=(Za(a)|0)>>31;return a|0}while(0);c[f>>2]=0;c[g>>2]=0;a=-1;return a|0}function jf(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0;g=l;l=l+64|0;if(!(c[f>>2]|0)){c[f>>2]=1;cm(g,44,1,e)|0;d=Ul(e)|0;f=b+156|0;c[f>>2]=d&65535;if((d&65535)<=256)if(!(d<<16>>16))d=0;else{d=0;do{a[b+952+d>>0]=Ul(e)|0;d=d+1|0}while((d|0)<(c[f>>2]|0));d=0}else d=-1}else d=0;l=g;return d|0}function kf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0;k=l;l=l+64|0;e=k;i=a+176|0;g=a+140|0;if((c[g>>2]|0)<=0){a=0;l=k;return a|0}h=a+144|0;j=a+180|0;f=0;while(1){c[(c[i>>2]|0)+(f*764|0)+36>>2]=1;if((_a(a,f,1)|0)<0){e=-1;b=8;break}cm(e,30,1,d)|0;fb(c[i>>2]|0,f,e,30);m=Ul(d)|0;b=m&65535;if(m<<16>>16?(b|0)<=(c[h>>2]|0):0){m=b+-1|0;c[(c[(c[i>>2]|0)+(f*764|0)+756>>2]|0)+40>>2]=m;b=(Ul(d)|0)&65535;c[c[(c[i>>2]|0)+(f*764|0)+756>>2]>>2]=b;b=am(d)|0;o=am(d)|0;n=c[j>>2]|0;c[n+(m*52|0)+36>>2]=o;n=c[n+(f*52|0)+36>>2]|0;n=(am(d)|0)+n|0;c[(c[j>>2]|0)+(m*52|0)+40>>2]=n;n=((Ul(d)|0)<<16>>16)+128|0;c[(c[(c[i>>2]|0)+(f*764|0)+756>>2]|0)+8>>2]=(n|0)<255?n:255;n=(Ul(d)|0)&65535;c[(c[j>>2]|0)+(m*52|0)+44>>2]=(n&3|0?2:0)|n<<1&4;m=c[(c[i>>2]|0)+(f*764|0)+756>>2]|0;Gi(b,m+12|0,m+16|0)}f=f+1|0;if((f|0)>=(c[g>>2]|0)){e=0;b=8;break}}if((b|0)==8){l=k;return e|0}return 0}function lf(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;s=l;l=l+16|0;m=s;if(($a(b)|0)<0){u=-1;l=s;return u|0}o=b+128|0;if((c[o>>2]|0)<=0){u=0;l=s;return u|0}k=b+136|0;q=b+168|0;r=b+172|0;n=0;while(1){if((db(b,n,(Ul(e)|0)&65535)|0)<0){f=-1;u=36;break}f=am(e)|0;a:do if((f|0)>0){p=0;while(1){while(1){d=Pl(e)|0;g=d&255;if((f|0)==1)break a;if(!(d<<24>>24))break;d=g+-1|0;i=(Pl(e)|0)&255;h=f+-2|0;if((h|0)<1)break a;if((g|0)<=(c[k>>2]|0)?(t=c[(c[q>>2]|0)+(n<<2)>>2]|0,(p|0)<(c[t>>2]|0)):0)j=(c[(c[r>>2]|0)+(c[t+4+(d<<2)>>2]<<2)>>2]|0)+4+(p<<3)|0;else j=m;g=j;d=g;a[d>>0]=0;a[d+1>>0]=0;a[d+2>>0]=0;a[d+3>>0]=0;g=g+4|0;a[g>>0]=0;a[g+1>>0]=0;a[g+2>>0]=0;a[g+3>>0]=0;if(i&1){h=(Pl(e)|0)&255;a[j>>0]=(h&15)+13+((h>>>4)*12|0);f=f+-3|0;if((f|0)<1)break a}else f=h;if(i&2){a[j+1>>0]=Pl(e)|0;if((f|0)<2)break a;else f=f+-1|0}if(i&4){a[j+3>>0]=Pl(e)|0;if((f|0)<2)break a;else f=f+-1|0}if(i&8){a[j+4>>0]=Pl(e)|0;if((f|0)<2)break a;else f=f+-1|0}if(i&16){a[j+5>>0]=Pl(e)|0;if((f|0)<2)break a;else f=f+-1|0}if(i&32){a[j+6>>0]=Pl(e)|0;if((f|0)<2)break a;else f=f+-1|0}g=j+3|0;d=a[g>>0]|0;if(d<<24>>24!=28){if((d&255)>28)u=29}else{a[g>>0]=-85;u=29}if((u|0)==29){u=0;a[j+6>>0]=0;a[g>>0]=0}g=j+5|0;d=a[g>>0]|0;if(d<<24>>24!=28){if((d&255)>28)u=33}else{a[g>>0]=-85;u=33}if((u|0)==33){u=0;a[j+6>>0]=0;a[g>>0]=0}if((f|0)<=0)break a}if((f|0)>1){p=p+1|0;f=f+-1|0}else break}}while(0);n=n+1|0;if((n|0)>=(c[o>>2]|0)){f=0;u=36;break}}if((u|0)==36){l=s;return f|0}return 0}function mf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;j=a+144|0;if((c[j>>2]|0)<=0){a=0;return a|0}k=a+180|0;h=0;while(1){b=am(d)|0;f=am(d)|0;e=c[k>>2]|0;i=e+(h*52|0)+32|0;c[i>>2]=f;g=e+(h*52|0)+44|0;if(b&2|0)c[g>>2]=c[g>>2]|1;if(!(b&4)){if((Eb(a,d,64,e+(h*52|0)|0,0)|0)<0){e=-1;b=9;break}}else{g=f<<2;c[i>>2]=g;dm(d,g,1)|0}h=h+1|0;if((h|0)>=(c[j>>2]|0)){e=0;b=9;break}}if((b|0)==9)return e|0;return 0}function nf(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0;g=Ul(e)|0;h=g&65535;if(!(g<<16>>16))return 0;g=a+176|0;f=0;do{a=((Ul(e)|0)&65535)+-1|0;d=(Pl(e)|0)&7;c[(c[g>>2]|0)+(a*764|0)+44>>2]=d;d=(Pl(e)|0)&255;c[(c[g>>2]|0)+(a*764|0)+48>>2]=d;d=(Pl(e)|0)&255;c[(c[g>>2]|0)+(a*764|0)+56>>2]=d;d=(Pl(e)|0)&255;c[(c[g>>2]|0)+(a*764|0)+64>>2]=d;d=(Pl(e)|0)&255;c[(c[g>>2]|0)+(a*764|0)+68>>2]=d;Pl(e)|0;d=0;do{j=Ul(e)|0;i=d<<1;b[(c[g>>2]|0)+(a*764|0)+72+(i<<1)>>1]=j;j=Ul(e)|0;b[(c[g>>2]|0)+(a*764|0)+72+((i|1)<<1)>>1]=j;d=d+1|0}while((d|0)!=32);f=f+1|0}while((f|0)!=(h|0));return 0}function of(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=l;l=l+1504|0;c=d;if((cm(c,1,1500,a)|0)>>>0<1500){e=-1;l=d;return e|0}if((Vj(c)|0)==-1048368482){a=c;c=0}else{e=-1;l=d;return e|0}while(1){b=Vj(a)|0;if((b|0)==1229803597|(nn(a,34801,16)|0)==0)break;if((c|0)>44&(b|0)==1396920909){e=5;break}if((c|0)>1080&(b|0)==1294879534){e=7;break}c=c+1|0;if((c|0)<1500)a=a+1|0;else{c=-1;break}}if((e|0)==5)c=c+-44|0;else if((e|0)==7)c=c+-1080|0;e=c>>31;l=d;return e|0}function pf(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0;g=l;l=l+1504|0;e=g;cm(e,1,1500,b)|0;c=0;while(1){d=Vj(e)|0;if(!(nn(e,34801,16)|0)){f=3;break}if((d|0)==1229803597){f=6;break}if((c|0)>44&(d|0)==1396920909){f=9;break}if((c|0)>1080&(d|0)==1294879534){f=12;break}c=c+1|0;if((c|0)<1500)e=e+1|0;else{c=-1;break}}if((f|0)==3)if((dm(b,c,0)|0)<0)c=-1;else c=Nb(a,b,c)|0;else if((f|0)==6)if((dm(b,c,0)|0)<0)c=-1;else c=Oc(a,b,c)|0;else if((f|0)==9){c=c+-44|0;if((dm(b,c,0)|0)<0)c=-1;else c=Xb(a,b,c)|0}else if((f|0)==12){c=c+-1080|0;if((dm(b,c,0)|0)<0)c=-1;else c=Sb(a,b,c)|0}l=g;return c|0}function qf(a,b,c){a=a|0;b=b|0;c=c|0;if((am(a)|0)!=1195658750){b=-1;return b|0}dm(a,c+71|0,0)|0;if((am(a)|0)!=1196246611){b=-1;return b|0}dm(a,c+4|0,0)|0;hb(a,b,32);b=0;return b|0}function rf(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;z=l;l=l+96|0;k=z+16|0;j=z;q=z+64|0;m=z+32|0;am(d)|0;cm(b,1,32,d)|0;dm(d,32,1)|0;dm(d,7,1)|0;f=(Pl(d)|0)&255;i=(Pl(d)|0)&255;y=Rl(d)|0;g=(Pl(d)|0)&255;h=(Pl(d)|0)&255;if(!(y<<16>>16)){c[j>>2]=f;c[j+4>>2]=i;c[j+8>>2]=g;c[j+12>>2]=h;ob(b,34840,j)}else{c[k>>2]=f;c[k+4>>2]=i;c[k+8>>2]=g;c[k+12>>2]=h;ob(b,34867,k)}cm(m,32,1,d)|0;h=0;do{g=m+h|0;f=a[g>>0]|0;switch(f<<24>>24){case -1:{a[g>>0]=8;c[b+184+(h*12|0)+4>>2]=0;f=b+184+(h*12|0)+8|0;c[f>>2]=c[f>>2]|2;f=8;break}case 16:{a[g>>0]=8;f=8;break}default:{}}c[b+184+(h*12|0)>>2]=(f&255)<<4;h=h+1|0}while((h|0)!=32);c[b+164>>2]=(Pl(d)|0)&255;c[b+148>>2]=(Pl(d)|0)&255;c[b+152>>2]=(Pl(d)|0)&255;Rl(d)|0;r=_l(d)|0;h=b+156|0;c[h>>2]=((Pl(d)|0)&255)+1;p=_l(d)|0;x=b+128|0;c[x>>2]=((Pl(d)|0)&255)+1;f=_l(d)|0;w=_l(d)|0;o=((Pl(d)|0)&255)+1|0;c[b+144>>2]=o;y=b+140|0;c[y>>2]=o;c[b+1264>>2]=8363;dm(d,r+e|0,0)|0;if((c[h>>2]|0)>0){g=0;do{a[b+952+g>>0]=Pl(d)|0;g=g+1|0}while((g|0)<(c[h>>2]|0))}dm(d,f+e|0,0)|0;if((Za(b)|0)<0){b=-1;l=z;return b|0}a:do if((c[y>>2]|0)>0){o=b+180|0;n=b+176|0;k=0;while(1){if((_a(b,k,1)|0)<0){v=-1;f=69;break}if((cm(q,1,32,d)|0)!=32){v=-1;f=69;break}fb(c[n>>2]|0,k,q,32);dm(d,12,1)|0;Pl(d)|0;i=_l(d)|0;c[(c[o>>2]|0)+(k*52|0)+32>>2]=i;i=_l(d)|0;c[(c[o>>2]|0)+(k*52|0)+36>>2]=i;i=_l(d)|0;c[(c[o>>2]|0)+(k*52|0)+40>>2]=i;i=(Pl(d)|0)&255;g=(Rl(d)|0)&65535;m=(Pl(d)|0)&255;j=Pl(d)|0;f=c[(c[n>>2]|0)+(k*764|0)+756>>2]|0;c[f>>2]=m>>>0<64?m:64;c[f+8>>2]=(j&255)>15?128:(j&255)<<4;Gi(g,f+12|0,f+16|0);f=c[n>>2]|0;c[(c[f+(k*764|0)+756>>2]|0)+40>>2]=k;g=c[o>>2]|0;j=g+(k*52|0)+44|0;c[j>>2]=0;m=g+(k*52|0)+32|0;h=c[m>>2]|0;if((h|0)>0)c[f+(k*764|0)+36>>2]=1;if(!(i&1))f=1;else{c[j>>2]=2;f=3}if(i&2|0){c[j>>2]=f;c[m>>2]=h>>1;r=g+(k*52|0)+36|0;c[r>>2]=c[r>>2]>>1;r=g+(k*52|0)+40|0;c[r>>2]=c[r>>2]>>1}k=k+1|0;if((k|0)>=(c[y>>2]|0))break a}if((f|0)==69){l=z;return v|0}}while(0);m=p+e|0;dm(d,m,0)|0;r=b+136|0;c[r>>2]=0;f=c[x>>2]|0;do if((f|0)>0){k=0;b:while(1){f=Rl(d)|0;c:do if((f&65535)>2){f=(f&65535)+-2|0;j=0;while(1){while(1){q=Pl(d)|0;i=q&255;h=f+-1|0;if(!(q<<24>>24))break;g=i&31;if((c[r>>2]|0)<=(g|0))c[r>>2]=g+1;if(!(i&32))f=h;else{Pl(d)|0;Pl(d)|0;f=f+-3|0}if(i&64)do{g=(Pl(d)|0)&255;if((g&192|0)==192)f=f+-1|0;else{Pl(d)|0;f=f+-2|0}}while((g&32|0)!=0);if((f|0)<=0)break c}if(!h)break;if((j|0)>62){v=-1;f=69;break b}if((f|0)>1){f=h;j=j+1|0}else break c}if((j|0)>63){v=-1;f=69;break b}}while(0);k=k+1|0;t=c[x>>2]|0;if((k|0)>=(t|0)){f=42;break}}if((f|0)==42){s=t;u=c[r>>2]|0;break}else if((f|0)==69){l=z;return v|0}}else{s=f;u=0}while(0);c[b+132>>2]=O(u,s)|0;if(($a(b)|0)<0){b=-1;l=z;return b|0}dm(d,m,0)|0;d:do if((c[x>>2]|0)>0){q=b+172|0;p=b+168|0;o=0;e:while(1){if((db(b,o,64)|0)<0){v=-1;f=69;break}f=Rl(d)|0;f:do if((f&65535)>2){f=(f&65535)+-2|0;n=0;while(1){m=(n|0)>63;while(1){v=Pl(d)|0;i=v&255;h=f+-1|0;if(!(v<<24>>24))break;g=i&31;if(m|(g|0)>=(c[r>>2]|0)){v=-1;f=69;break e}g=c[(c[q>>2]|0)+(c[(c[(c[p>>2]|0)+(o<<2)>>2]|0)+4+(g<<2)>>2]<<2)>>2]|0;if(!(i&32))f=h;else{v=(Pl(d)|0)&255;a[g+4+(n<<3)>>0]=(v&15)+12+((v>>>4&7)*12|0);a[g+4+(n<<3)+1>>0]=Pl(d)|0;f=f+-3|0}g:do if(i&64){k=g+4+(n<<3)+3|0;j=g+4+(n<<3)+4|0;i=g+4+(n<<3)+5|0;h=g+4+(n<<3)+6|0;while(1){v=Pl(d)|0;g=v&255;switch((v&255)>>>6&3){case 0:{a[k>>0]=g&31;a[j>>0]=Pl(d)|0;sf(k,j);f=f+-2|0;break}case 1:{a[i>>0]=g&31;a[h>>0]=Pl(d)|0;sf(i,h);f=f+-2|0;break}case 2:{Pl(d)|0;f=f+-2|0;break}default:f=f+-1|0}if(!(g&32))break g}}while(0);if((f|0)<=0)break f}if((f|0)>1){f=h;n=n+1|0}else break}}while(0);o=o+1|0;if((o|0)>=(c[x>>2]|0))break d}if((f|0)==69){l=z;return v|0}}while(0);dm(d,w+e|0,0)|0;h:do if((c[y>>2]|0)>0){g=b+180|0;f=0;while(1){if((Eb(b,d,2,(c[g>>2]|0)+(f*52|0)|0,0)|0)<0){v=-1;break}f=f+1|0;if((f|0)>=(c[y>>2]|0))break h}l=z;return v|0}while(0);b=b+1284|0;c[b>>2]=c[b>>2]|536870912;b=0;l=z;return b|0}function sf(b,c){b=b|0;c=c|0;do switch(a[b>>0]|0){case 0:{a[c>>0]=0;break}case 15:case 14:case 13:case 12:case 11:case 10:case 9:case 7:case 6:case 5:case 4:case 3:case 2:case 1:break;case 8:{a[b>>0]=29;break}case 16:{a[b>>0]=-76;break}case 17:{a[c>>0]=0;a[b>>0]=0;break}case 18:{a[b>>0]=27;break}case 19:{a[b>>0]=16;break}case 20:{a[b>>0]=-84;break}case 30:{a[c>>0]=0;a[b>>0]=0;break}case 31:{a[b>>0]=-85;break}default:{a[c>>0]=0;a[b>>0]=0}}while(0);return}function tf(a,b,c){a=a|0;b=b|0;c=c|0;return vf(a)|0}function uf(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=l;l=l+1120|0;p=v+8|0;o=v;q=v+20|0;t=v+1104|0;n=v+16|0;u=v+12|0;i=Uh(u)|0;if(!i){u=-1;l=v;return u|0}if((cg(g,i,n)|0)>=0){s=km(i)|0;if(s|0){a:do if((dm(s,0,h)|0)>=0){cm(q,20,1,s)|0;i=0;do{cm(q+20+(i*30|0)|0,22,1,s)|0;b[q+20+(i*30|0)+22>>1]=Ul(s)|0;a[q+20+(i*30|0)+24>>0]=Pl(s)|0;a[q+20+(i*30|0)+25>>0]=Pl(s)|0;b[q+20+(i*30|0)+26>>1]=Ul(s)|0;b[q+20+(i*30|0)+28>>1]=Ul(s)|0;i=i+1|0}while((i|0)!=31);i=q+950|0;a[i>>0]=Pl(s)|0;g=q+951|0;a[g>>0]=Pl(s)|0;h=q+952|0;cm(h,128,1,s)|0;r=q+1080|0;cm(r,4,1,s)|0;if(!(nn(r,34915,4)|0)){m=f+140|0;c[m>>2]=31;r=f+144|0;c[r>>2]=31;c[f+136>>2]=4;c[f+156>>2]=d[i>>0];c[f+160>>2]=d[g>>0];j=f+952|0;i=h;g=j+128|0;do{b[j>>1]=b[i>>1]|0;j=j+2|0;i=i+2|0}while((j|0)<(g|0));k=f+128|0;i=c[k>>2]|0;h=0;do{g=d[f+952+h>>0]|0;if((g|0)>(i|0)){c[k>>2]=g;i=g}h=h+1|0}while((h|0)!=128);j=i+1|0;c[k>>2]=j;c[f+132>>2]=j<<2;c[o>>2]=q;io(f,64,34920,o);c[p>>2]=c[n>>2];io(f+64|0,64,34920,p);if((Za(f)|0)>=0){if((c[m>>2]|0)>0){j=f+180|0;h=f+176|0;g=0;do{if((_a(f,g,1)|0)<0)break a;p=b[q+20+(g*30|0)+22>>1]|0;i=c[j>>2]|0;c[i+(g*52|0)+32>>2]=(p&65535)<<1;n=e[q+20+(g*30|0)+26>>1]<<1;c[i+(g*52|0)+36>>2]=n;o=b[q+20+(g*30|0)+28>>1]|0;c[i+(g*52|0)+40>>2]=((o&65535)<<1)+n;c[i+(g*52|0)+44>>2]=(o&65535)>1?2:0;i=c[h>>2]|0;o=c[i+(g*764|0)+756>>2]|0;c[o+16>>2]=d[q+20+(g*30|0)+24>>0]<<28>>24;c[o>>2]=a[q+20+(g*30|0)+25>>0];c[o+8>>2]=128;c[o+40>>2]=g;c[i+(g*764|0)+40>>2]=4095;if(p<<16>>16)c[i+(g*764|0)+36>>2]=1;fb(i,g,q+20+(g*30|0)|0,22);g=g+1|0}while((g|0)<(c[m>>2]|0))}if(($a(f)|0)>=0){if((c[k>>2]|0)>0){j=f+172|0;h=f+168|0;i=0;do{if((db(f,i,64)|0)<0)break a;else g=0;do{q=(c[(c[j>>2]|0)+(c[(c[(c[h>>2]|0)+(i<<2)>>2]|0)+4+(((g|0)%4|0)<<2)>>2]<<2)>>2]|0)+4+(((g|0)/4|0)<<3)|0;cm(t,1,4,s)|0;lb(q,t);g=g+1|0}while((g|0)!=256);i=i+1|0}while((i|0)<(c[k>>2]|0))}c[f+1292>>2]=1;if((c[r>>2]|0)>0){g=f+180|0;i=0;do{if((Eb(f,s,0,(c[g>>2]|0)+(i*52|0)|0,0)|0)<0)break a;i=i+1|0}while((i|0)<(c[r>>2]|0))}lm(s);Wh(c[u>>2]|0);u=0;l=v;return u|0}}}}while(0);lm(s)}}else vo(i)|0;Wh(c[u>>2]|0);u=-1;l=v;return u|0}function vf(a){a=a|0;var b=0,c=0,d=0,e=0,f=0;b=Xm(1,65536)|0;if(!b){f=-1;return f|0}f=b;b=cm(b,1,65536,a)|0;while(1){d=dg(f,b)|0;if((d|0)<=0){b=8;break}c=b;b=d+b|0;e=Ym(f,b)|0;if(!e){b=5;break}if(!(cm(e+c|0,d,1,a)|0)){b=7;break}else f=e}if((b|0)==5){Wm(f);f=-1;return f|0}else if((b|0)==7){Wm(e);f=-1;return f|0}else if((b|0)==8){Wm(f);f=((d|0)!=0)<<31>>31;return f|0}return 0}function wf(a,b,c){a=a|0;b=b|0;c=c|0;if(((am(a)|0)==1380533830?(am(a)|0,(am(a)|0)==1095573536):0)?(am(a)|0)==1229867348:0){am(a)|0;hb(a,b,64);a=0}else a=-1;return a|0}function xf(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0;n=l;l=l+64|0;m=n;am(b)|0;am(b)|0;am(b)|0;g=em(b)|0;h=a+140|0;c[h>>2]=0;i=a+144|0;c[i>>2]=0;f=pb()|0;if(!f){a=-1;l=n;return a|0}c[a+1264>>2]=8363;k=tb(f,34953,57)|0;k=tb(f,35011,58)|0|k;k=k|(tb(f,35016,59)|0);if(k|(tb(f,35021,60)|0)|0){a=-1;l=n;return a|0}Ab(f,1);Ab(f,16);Ab(f,4);k=(qb(f,a,b,m)|0)<0;wb(f);if(k){a=-1;l=n;return a|0}j=a+128|0;k=a+136|0;c[a+132>>2]=O(c[k>>2]|0,c[j>>2]|0)|0;c[i>>2]=c[h>>2];if((Za(a)|0)<0){a=-1;l=n;return a|0}if(($a(a)|0)<0){a=-1;l=n;return a|0}dm(b,g+e|0,0)|0;f=pb()|0;if(!f){a=-1;l=n;return a|0}e=tb(f,35016,61)|0;if(tb(f,35021,62)|0|e|0){a=-1;l=n;return a|0}Ab(f,1);Ab(f,16);Ab(f,4);b=(qb(f,a,b,m)|0)<0;wb(f);if(b){a=-1;l=n;return a|0}f=c[j>>2]|0;a:do if((f|0)>0){h=a+168|0;g=0;while(1){if(!(c[(c[h>>2]|0)+(g<<2)>>2]|0)){if((db(a,g,64)|0)<0){f=-1;break}f=c[j>>2]|0}g=g+1|0;if((g|0)>=(f|0))break a}l=n;return f|0}while(0);if((c[k>>2]|0)>0){f=0;do{c[a+184+(f*12|0)>>2]=(d[m+f>>0]|0)<<1;f=f+1|0}while((f|0)<(c[k>>2]|0))}m=a+1284|0;c[m>>2]=c[m>>2]|33554464;c[a+1288>>2]=1;a=0;l=n;return a|0}function yf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;b=l;l=l+80|0;f=b+8|0;cm(f,1,64,d)|0;Ho(a,f,63)|0;ob(a,34958,b);if(!((Pl(d)|0)&1))c[a+1292>>2]=2;c[a+136>>2]=(Pl(d)|0)&255;c[a+148>>2]=(Pl(d)|0)&255;c[a+152>>2]=(Pl(d)|0)&255;Rl(d)|0;Rl(d)|0;Pl(d)|0;cm(e,1,64,d)|0;l=b;return 0}function zf(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;d=b+156|0;c[d>>2]=((Pl(e)|0)&255)+1;f=0;do{a[b+952+f>>0]=Pl(e)|0;f=f+1|0}while((f|0)<(c[d>>2]|0));return 0}function Af(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;e=(Pl(d)|0)&255;d=a+128|0;if((e|0)<(c[d>>2]|0))return 0;c[d>>2]=e+1;return 0}function Bf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;am(d)|0;Pl(d)|0;e=(Pl(d)|0)&255;d=a+140|0;if((e|0)<(c[d>>2]|0))return 0;c[d>>2]=e+1;return 0}function Cf(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0;r=l;l=l+16|0;p=r;o=r+8|0;m=(Pl(e)|0)&255;_l(e)|0;n=(Pl(e)|0)&255;if((db(b,m,n+1|0)|0)<0){e=-1;l=r;return e|0}k=b+136|0;q=b+172|0;j=b+168|0;i=0;while(1){f=Pl(e)|0;if(f<<24>>24){h=f&255;while(1){f=h&31;if((f|0)<(c[k>>2]|0))g=(c[(c[q>>2]|0)+(c[(c[(c[j>>2]|0)+(m<<2)>>2]|0)+4+(f<<2)>>2]<<2)>>2]|0)+4+(i<<3)|0;else g=o;if(h&128|0){d=Pl(e)|0;f=Pl(e)|0;b=f&255;if(f<<24>>24!=20){if((f&255)>15){c[p>>2]=b;c[p+4>>2]=d&255;Qo(35026,p);d=0;f=0}}else f=-93;a[g+3>>0]=f;a[g+4>>0]=d}if(h&64|0){a[g+1>>0]=Pl(e)|0;b=Pl(e)|0;a[g>>0]=b<<24>>24==-128?-127:b}if(h&32|0)a[g+2>>0]=(((Pl(e)|0)&255)>>>1)+1<<24>>24;f=Pl(e)|0;if(!(f<<24>>24))break;else h=f&255}}if((i|0)==(n|0)){f=0;break}else i=i+1|0}l=r;return f|0}function Df(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;am(d)|0;Pl(d)|0;g=(Pl(d)|0)&255;f=a+176|0;cm((c[f>>2]|0)+(g*764|0)|0,1,28,d)|0;dm(d,290,1)|0;b=Rl(d)|0;e=b&65535;c[(c[f>>2]|0)+(g*764|0)+36>>2]=e;if(!(b<<16>>16)){a=0;return a|0}if((_a(a,g,e)|0)<0){a=-1;return a|0}am(d)|0;am(d)|0;am(d)|0;am(d)|0;am(d)|0;am(d)|0;e=a+180|0;cm((c[e>>2]|0)+(g*52|0)|0,1,28,d)|0;am(d)|0;Pl(d)|0;c[(c[(c[f>>2]|0)+(g*764|0)+756>>2]|0)+40>>2]=g;i=(Pl(d)|0)&255;b=c[f>>2]|0;c[b+(g*764|0)+32>>2]=i;c[(c[b+(g*764|0)+756>>2]|0)+8>>2]=128;b=(((Rl(d)|0)&65535)+1|0)>>>9;c[c[(c[f>>2]|0)+(g*764|0)+756>>2]>>2]=b;b=(Rl(d)|0)&65535;Rl(d)|0;i=_l(d)|0;c[(c[e>>2]|0)+(g*52|0)+32>>2]=i;i=_l(d)|0;c[(c[e>>2]|0)+(g*52|0)+36>>2]=i;i=_l(d)|0;h=c[e>>2]|0;c[h+(g*52|0)+40>>2]=i;c[h+(g*52|0)+44>>2]=b>>>2&1|((b&16|0)==0?b>>>2&2:6);h=_l(d)|0;f=c[(c[f>>2]|0)+(g*764|0)+756>>2]|0;Gi(h,f+12|0,f+16|0);_l(d)|0;_l(d)|0;e=c[e>>2]|0;if((c[e+(g*52|0)+32>>2]|0)>1?(Eb(a,d,b>>>6&2^2,e+(g*52|0)|0,0)|0)<0:0){i=-1;return i|0}i=0;return i|0}function Ef(a,b,c){a=a|0;b=b|0;c=c|0;if(((am(a)|0)==1380533830?(am(a)|0,(am(a)|0)==1095583302):0)?(am(a)|0)==1296124238:0){am(a)|0;hb(a,b,64);a=0}else a=-1;return a|0}function Ff(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0;j=l;l=l+16|0;g=j;am(b)|0;am(b)|0;am(b)|0;f=em(b)|0;c[a+140>>2]=0;c[a+144>>2]=0;e=pb()|0;if(!e){a=-1;l=j;return a|0}c[a+1264>>2]=8363;i=tb(e,35006,63)|0;i=tb(e,35011,64)|0|i;i=i|(tb(e,35016,65)|0);if(i|(tb(e,35021,66)|0)|0){a=-1;l=j;return a|0}Ab(e,1);Ab(e,32);i=(qb(e,a,b,g)|0)<0;wb(e);if(i){a=-1;l=j;return a|0}h=a+128|0;i=a+136|0;c[a+132>>2]=O(c[i>>2]|0,c[h>>2]|0)|0;if((Za(a)|0)<0){a=-1;l=j;return a|0}if(($a(a)|0)<0){a=-1;l=j;return a|0}dm(b,f+d|0,0)|0;c[g>>2]=0;e=pb()|0;if(!e){a=-1;l=j;return a|0}d=tb(e,35016,67)|0;if(tb(e,35021,68)|0|d|0){a=-1;l=j;return a|0}Ab(e,1);Ab(e,32);b=(qb(e,a,b,g)|0)<0;wb(e);if(b){a=-1;l=j;return a|0}e=c[h>>2]|0;a:do if((e|0)>0){d=a+168|0;f=0;while(1){if(!(c[(c[d>>2]|0)+(f<<2)>>2]|0)){if((db(a,f,64)|0)<0){e=-1;break}e=c[h>>2]|0}f=f+1|0;if((f|0)>=(e|0))break a}l=j;return e|0}while(0);if((c[i>>2]|0)>0){e=0;do{c[a+184+(e*12|0)>>2]=128;e=e+1|0}while((e|0)<(c[i>>2]|0))}i=a+1284|0;c[i>>2]=c[i>>2]|33554464;c[a+1288>>2]=1;a=0;l=j;return a|0}function Gf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;e=l;l=l+80|0;b=e+8|0;cm(b,1,64,d)|0;Ho(a,b,63)|0;ob(a,34982,e);if(!((Pl(d)|0)&1))c[a+1292>>2]=2;b=a+136|0;c[b>>2]=(Pl(d)|0)&255;c[a+148>>2]=(Pl(d)|0)&255;c[a+152>>2]=(Pl(d)|0)&255;Rl(d)|0;Rl(d)|0;Pl(d)|0;l=e;return ((c[b>>2]|0)>32)<<31>>31|0}function Hf(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;d=b+156|0;c[d>>2]=((Pl(e)|0)&255)+1;if(gm(e)|0){b=-1;return b|0}if((c[d>>2]|0)>0)f=0;else{b=0;return b|0}do{a[b+952+f>>0]=Pl(e)|0;f=f+1|0}while((f|0)<(c[d>>2]|0));f=0;return f|0}function If(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;e=(Pl(d)|0)&255;d=a+128|0;if((e|0)<(c[d>>2]|0))return 0;c[d>>2]=e+1;return 0}function Jf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;Pl(d)|0;e=(Pl(d)|0)&255;b=a+140|0;if((e|0)>=(c[b>>2]|0))c[b>>2]=e+1;dm(d,28,1)|0;d=(Pl(d)|0)&255;a=a+144|0;c[a>>2]=(c[a>>2]|0)+d;return 0}function Kf(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0;r=l;l=l+16|0;p=r;o=r+8|0;m=(Pl(e)|0)&255;q=_l(e)|0;if((q|0)<1?1:(m|0)>=(c[b+128>>2]|0)){e=-1;l=r;return e|0}n=(Pl(e)|0)&255;if((db(b,m,n+1|0)|0)<0){e=-1;l=r;return e|0}k=b+136|0;q=b+172|0;j=b+168|0;i=0;while(1){f=Pl(e)|0;if(f<<24>>24){h=f&255;while(1){f=h&31;if((f|0)<(c[k>>2]|0))g=(c[(c[q>>2]|0)+(c[(c[(c[j>>2]|0)+(m<<2)>>2]|0)+4+(f<<2)>>2]<<2)>>2]|0)+4+(i<<3)|0;else g=o;if(h&128|0){d=Pl(e)|0;f=Pl(e)|0;b=f&255;if(f<<24>>24!=20){if((f&255)>15){c[p>>2]=b;c[p+4>>2]=d&255;Qo(35026,p);d=0;f=0}}else f=-93;a[g+3>>0]=f;a[g+4>>0]=d}if(h&64|0){a[g+1>>0]=Pl(e)|0;b=Pl(e)|0;a[g>>0]=b<<24>>24==-128?-127:b}if(h&32|0)a[g+2>>0]=(((Pl(e)|0)&255)>>>1)+1<<24>>24;f=Pl(e)|0;if(!(f<<24>>24))break;else h=f&255}}if((i|0)==(n|0)){f=9;break}else i=i+1|0}l=r;return f|0}function Lf(e,f,g,h){e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;s=l;l=l+32|0;k=s;Pl(g)|0;q=(Pl(g)|0)&255;r=e+176|0;cm((c[r>>2]|0)+(q*764|0)|0,1,28,g)|0;f=(Pl(g)|0)&255;c[(c[r>>2]|0)+(q*764|0)+36>>2]=f;f=0;do{p=Pl(g)|0;a[(c[r>>2]|0)+(q*764|0)+512+(f<<1)>>0]=p;f=f+1|0}while((f|0)!=108);dm(g,11,1)|0;m=(Pl(g)|0)&255;n=(Pl(g)|0)&255;Pl(g)|0;Pl(g)|0;o=(Pl(g)|0)&255;p=((Rl(g)|0)&65535)>>>4&65535;Pl(g)|0;f=(Pl(g)|0)&255;if(f&1|0){j=(c[r>>2]|0)+(q*764|0)+44|0;c[j>>2]=c[j>>2]|1}if(f&2|0){j=(c[r>>2]|0)+(q*764|0)+44|0;c[j>>2]=c[j>>2]|2}if(f&4|0){j=(c[r>>2]|0)+(q*764|0)+44|0;c[j>>2]=c[j>>2]|4}f=f>>>4;if(f&1|0){j=(c[r>>2]|0)+(q*764|0)+200|0;c[j>>2]=c[j>>2]|1}if(f&2|0){j=(c[r>>2]|0)+(q*764|0)+200|0;c[j>>2]=c[j>>2]|2}if(f&4|0){j=(c[r>>2]|0)+(q*764|0)+200|0;c[j>>2]=c[j>>2]|4}f=(Pl(g)|0)&255;j=c[r>>2]|0;c[j+(q*764|0)+48>>2]=(f&15)+1;c[j+(q*764|0)+204>>2]=(f>>>4)+1;j=(Pl(g)|0)&255;f=c[r>>2]|0;c[f+(q*764|0)+56>>2]=j&15;c[f+(q*764|0)+212>>2]=j>>>4;f=(Pl(g)|0)&255;j=f&15;i=c[r>>2]|0;c[i+(q*764|0)+64>>2]=j;f=f>>>4;c[i+(q*764|0)+220>>2]=f;Pl(g)|0;i=c[r>>2]|0;c[i+(q*764|0)+68>>2]=j;c[i+(q*764|0)+224>>2]=f;f=i+(q*764|0)+44|0;if(((c[i+(q*764|0)+48>>2]|0)+-1|0)>>>0>30)c[f>>2]=c[f>>2]&-2;f=i+(q*764|0)+200|0;if(((c[i+(q*764|0)+204>>2]|0)+-1|0)>>>0>30)c[f>>2]=c[f>>2]&-2;cm(k,1,30,g)|0;f=c[r>>2]|0;j=f+(q*764|0)+48|0;if((c[j>>2]|0)>0){i=0;do{u=i*3|0;v=k+u|0;t=i<<1;b[f+(q*764|0)+72+(t<<1)>>1]=((Qj(a[v>>0]|0,a[v+1>>0]|0)|0)&65535)>>>4;b[f+(q*764|0)+72+((t|1)<<1)>>1]=d[k+(u+2)>>0]|0;i=i+1|0}while((i|0)<(c[j>>2]|0))}cm(k,1,30,g)|0;f=c[r>>2]|0;j=f+(q*764|0)+204|0;if((c[j>>2]|0)>0){i=0;do{u=i*3|0;t=k+u|0;v=i<<1;b[f+(q*764|0)+228+(v<<1)>>1]=((Qj(a[t>>0]|0,a[t+1>>0]|0)|0)&65535)>>>4;b[f+(q*764|0)+228+((v|1)<<1)>>1]=d[k+(u+2)>>0]|0;i=i+1|0}while((i|0)<(c[j>>2]|0))}Pl(g)|0;Pl(g)|0;f=c[(c[r>>2]|0)+(q*764|0)+36>>2]|0;if(!f){v=0;l=s;return v|0}if((_a(e,q,f)|0)<0){v=-1;l=s;return v|0}if((c[(c[r>>2]|0)+(q*764|0)+36>>2]|0)<=0){v=0;l=s;return v|0}k=e+180|0;j=0;while(1){am(g)|0;am(g)|0;cm((c[k>>2]|0)+((c[h>>2]|0)*52|0)|0,1,28,g)|0;v=Pl(g)|0;c[(c[(c[r>>2]|0)+(q*764|0)+756>>2]|0)+(j<<6)+8>>2]=v<<24>>24==0?128:(v&255)<<2;v=(Pl(g)|0)&255;c[(c[(c[r>>2]|0)+(q*764|0)+756>>2]|0)+(j<<6)>>2]=v;v=(Pl(g)|0)&255;Pl(g)|0;u=c[(c[r>>2]|0)+(q*764|0)+756>>2]|0;c[u+(j<<6)+20>>2]=m;c[u+(j<<6)+24>>2]=o;c[u+(j<<6)+28>>2]=p;c[u+(j<<6)+32>>2]=n;c[u+(j<<6)+40>>2]=c[h>>2];u=_l(g)|0;c[(c[k>>2]|0)+((c[h>>2]|0)*52|0)+32>>2]=u;u=_l(g)|0;c[(c[k>>2]|0)+((c[h>>2]|0)*52|0)+36>>2]=u;u=_l(g)|0;i=c[k>>2]|0;f=c[h>>2]|0;c[i+(f*52|0)+40>>2]=u;c[i+(f*52|0)+44>>2]=v>>>2&4|(v>>>2&2|v>>>2&1);f=_l(g)|0;i=c[(c[r>>2]|0)+(q*764|0)+756>>2]|0;Gi(f,i+(j<<6)+12|0,i+(j<<6)+16|0);_l(g)|0;_l(g)|0;i=c[k>>2]|0;f=c[h>>2]|0;if((c[i+(f*52|0)+32>>2]|0)>1){if((Eb(e,g,0,i+(f*52|0)|0,0)|0)<=-1){f=-1;i=31;break}f=c[h>>2]|0}j=j+1|0;c[h>>2]=f+1;if((j|0)>=(c[(c[r>>2]|0)+(q*764|0)+36>>2]|0)){f=0;i=31;break}}if((i|0)==31){l=s;return f|0}return 0}function Mf(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0;m=l;l=l+384|0;k=m;if(c[b>>2]|0){e=-1;l=m;return e|0}if((cm(k,1,384,b)|0)>>>0<384){e=-1;l=m;return e|0}if((a[k+249>>0]|0)==127)j=0;else{e=-1;l=m;return e|0}while(1){f=j<<3;g=k+f|0;i=Rj(a[g>>0]|0,a[g+1>>0]|0)|0;if(i<<16>>16<0){f=-1;g=14;break}if((d[k+(f|2)>>0]|0)>15){f=-1;g=14;break}if((d[k+(f|3)>>0]|0)>64){f=-1;g=14;break}h=Rj(a[g+4>>0]|0,a[g+5>>0]|0)|0;if((h&65535)>(i&65535)){f=-1;g=14;break}f=Rj(a[g+6>>0]|0,a[g+7>>0]|0)|0;if(((h&65535)+-1+(f&65535)|0)>(i&65535|0)){f=-1;g=14;break}j=j+1|0;if(i<<16>>16!=0&f<<16>>16==0){f=-1;g=14;break}if((j|0)>=31){g=11;break}}if((g|0)==11){j=d[k+248>>0]|0;f=Rj(a[k+378>>0]|0,a[k+379>>0]|0)|0;if((j|0)!=(f&65535|0)){e=-1;l=m;return e|0}if(f<<16>>16!=(Rj(a[k+380>>0]|0,a[k+381>>0]|0)|0)<<16>>16){e=-1;l=m;return e|0}hb(b,e,0);e=0;l=m;return e|0}else if((g|0)==14){l=m;return f|0}return 0}function Nf(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;F=l;l=l+7296|0;A=F+32|0;x=F+24|0;w=F+16|0;v=F+8|0;u=F+2088|0;z=F+3192|0;t=F+40|0;r=F+2168|0;s=F+36|0;ob(b,35052,F);h=b+136|0;c[h>>2]=4;c[b+144>>2]=31;C=b+140|0;c[C>>2]=31;if((Za(b)|0)<0){E=-1;l=F;return E|0}E=b+180|0;D=b+176|0;g=0;do{if((_a(b,g,1)|0)<0){f=-1;B=40;break}f=((Ul(e)|0)&65535)<<1;c[(c[E>>2]|0)+(g*52|0)+32>>2]=f;f=((Pl(e)|0)&255)<<28>>24;c[(c[(c[D>>2]|0)+(g*764|0)+756>>2]|0)+16>>2]=f;f=(Pl(e)|0)&255;c[c[(c[D>>2]|0)+(g*764|0)+756>>2]>>2]=f;f=((Ul(e)|0)&65535)<<1;c[(c[E>>2]|0)+(g*52|0)+36>>2]=f;f=Ul(e)|0;q=c[E>>2]|0;c[q+(g*52|0)+40>>2]=(c[q+(g*52|0)+36>>2]|0)+((f&65535)<<1);c[q+(g*52|0)+44>>2]=(f&65535)>1?2:0;f=c[D>>2]|0;p=c[f+(g*764|0)+756>>2]|0;c[p+8>>2]=128;c[p+40>>2]=g;c[f+(g*764|0)+40>>2]=4095;if((c[q+(g*52|0)+32>>2]|0)>0)c[f+(g*764|0)+36>>2]=1;g=g+1|0}while((g|0)<31);if((B|0)==40){l=F;return f|0}f=(Pl(e)|0)&255;q=b+128|0;c[q>>2]=f;c[b+156>>2]=f;Pl(e)|0;f=0;do{a[b+952+f>>0]=Pl(e)|0;f=f+1|0}while((f|0)!=128);if(gm(e)|0){E=-1;l=F;return E|0}c[b+132>>2]=O(c[h>>2]|0,c[q>>2]|0)|0;if(($a(b)|0)<0){E=-1;l=F;return E|0}p=Ul(e)|0;f=p&65535;Ul(e)|0;if(p<<16>>16){g=0;do{c[t+(g<<4)>>2]=(Ul(e)|0)&65535;c[t+(g<<4)+4>>2]=(Ul(e)|0)&65535;c[t+(g<<4)+8>>2]=(Ul(e)|0)&65535;c[t+(g<<4)+12>>2]=(Ul(e)|0)&65535;g=g+1|0}while((g|0)!=(f|0))}g=em(e)|0;a:do if((c[q>>2]|0)>0){p=b+172|0;o=b+168|0;h=0;while(1){if((db(b,h,64)|0)<0){f=-1;break}else i=0;do{dm(e,(c[t+(h<<4)+(i<<2)>>2]|0)+g|0,0)|0;cm(r,1,1024,e)|0;j=0;k=0;while(1){f=r+j|0;m=k;n=0;while(1){G=(c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(h<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+(m<<3)|0;H=r+(d[r+(d[r+((d[f>>0]|0)+n)>>0]|0)>>0]<<1)|0;c[s>>2]=d[H>>0]|d[H+1>>0]<<8|d[H+2>>0]<<16|d[H+3>>0]<<24;lb(G,s);G=m|1;H=(c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(h<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+(G<<3)|0;I=r+(d[r+((d[r+((d[f>>0]|0)+n)>>0]|0)+1)>>0]<<1)|0;c[s>>2]=d[I>>0]|d[I+1>>0]<<8|d[I+2>>0]<<16|d[I+3>>0]<<24;lb(H,s);G=(c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(h<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+(G+1<<3)|0;H=r+(d[r+((d[r+((d[f>>0]|0)+n)>>0]|0)+2)>>0]<<1)|0;c[s>>2]=d[H>>0]|d[H+1>>0]<<8|d[H+2>>0]<<16|d[H+3>>0]<<24;lb(G,s);G=(c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(h<<2)>>2]|0)+4+(i<<2)>>2]<<2)>>2]|0)+4+((m|3)<<3)|0;H=r+(d[r+((d[r+((d[f>>0]|0)+n)>>0]|0)+3)>>0]<<1)|0;c[s>>2]=d[H>>0]|d[H+1>>0]<<8|d[H+2>>0]<<16|d[H+3>>0]<<24;lb(G,s);n=n+1|0;if((n|0)==4)break;else m=m+4|0}j=j+1|0;if((j|0)==4)break;else k=k+16|0}i=i+1|0}while((i|0)!=4);h=h+1|0;if((h|0)>=(c[q>>2]|0))break a}l=F;return f|0}while(0);g=b+1212|0;f=c[g>>2]|0;do if((fo(f)|0)>>>0>=5?(a[f+3>>0]|0)==46:0){a[f>>0]=115;a[(c[g>>2]|0)+1>>0]=109;a[(c[g>>2]|0)+2>>0]=112;I=c[g>>2]|0;c[w>>2]=c[b+1208>>2];c[w+4>>2]=I;io(z,4096,35104,w);if((no(z,u)|0)<0){if(go(c[g>>2]|0,45)|0?(y=Eo(z,45)|0,y|0):0){a[y>>0]=a[35109]|0;a[y+1>>0]=a[35110]|0;a[y+2>>0]=a[35111]|0;a[y+3>>0]=a[35112]|0;a[y+4>>0]=a[35113]|0}if((no(z,u)|0)<0){c[x>>2]=z;Bo(0,35114,x);break}}g=hm(z,35139)|0;if(!g){c[A>>2]=z;Bo(0,35142,A);break}b:do if((c[C>>2]|0)>0){f=0;while(1){if((Eb(b,g,512,(c[E>>2]|0)+((c[(c[(c[D>>2]|0)+(f*764|0)+756>>2]|0)+40>>2]|0)*52|0)|0,0)|0)<0)break;f=f+1|0;if((f|0)>=(c[C>>2]|0))break b}Wm(g);I=-1;l=F;return I|0}while(0);lm(g);c[b+1292>>2]=1;I=0;l=F;return I|0}else B=24;while(0);if((B|0)==24){c[v>>2]=f;Bo(0,35075,v)}if((c[C>>2]|0)>0)f=0;else{I=0;l=F;return I|0}do{c[(c[D>>2]|0)+(f*764|0)+36>>2]=0;g=(c[E>>2]|0)+(f*52|0)|0;h=g+52|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));f=f+1|0}while((f|0)<(c[C>>2]|0));f=0;l=F;return f|0}function Of(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=l;l=l+32|0;c=d;if((cm(c,1,32,a)|0)>>>0>=32?(nn(c,35202,32)|0)==0:0){hb(a,b,0);c=0}else c=-1;l=d;return c|0}function Pf(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;u=l;l=l+48|0;q=u;dm(e,32,1)|0;c[b+148>>2]=(Pl(e)|0)&255;c[b+152>>2]=(Pl(e)|0)&255;t=b+140|0;c[t>>2]=(Pl(e)|0)&255;s=b+128|0;c[s>>2]=(Pl(e)|0)&255;r=b+156|0;c[r>>2]=(Pl(e)|0)&255;Pl(e)|0;cm(b+952|0,1,c[r>>2]|0,e)|0;dm(e,f+294|0,0)|0;r=b+136|0;c[r>>2]=8;c[b+144>>2]=c[t>>2];c[b+132>>2]=c[s>>2]<<3;io(b+64|0,64,35177,q);if((Za(b)|0)<0){b=-1;l=u;return b|0}f=c[t>>2]|0;a:do if((f|0)>0){j=q+22|0;o=b+176|0;k=q+23|0;m=q+24|0;g=q+25|0;p=b+180|0;h=q+29|0;i=q+33|0;n=0;while(1){if((_a(b,n,1)|0)<0)break;if((cm(q,1,37,e)|0)!=37)break;fb(c[o>>2]|0,n,q,22);v=c[(c[o>>2]|0)+(n*764|0)+756>>2]|0;c[v+16>>2]=d[j>>0]<<28>>24;c[v>>2]=d[k>>0];c[v+12>>2]=a[m>>0];c[v+8>>2]=128;c[v+40>>2]=n;v=Uj(g)|0;f=c[p>>2]|0;c[f+(n*52|0)+32>>2]=v;v=Uj(h)|0;c[f+(n*52|0)+36>>2]=v;v=(Uj(i)|0)+v|0;c[f+(n*52|0)+40>>2]=v;c[f+(n*52|0)+44>>2]=(v|0)>2?2:0;n=n+1|0;f=c[t>>2]|0;if((n|0)>=(f|0))break a}v=-1;l=u;return v|0}while(0);dm(e,(64-f|0)*37|0,1)|0;if(($a(b)|0)<0){v=-1;l=u;return v|0}b:do if((c[s>>2]|0)>0){n=b+172|0;m=b+168|0;k=0;c:while(1){if((db(b,k,64)|0)<0){f=-1;g=24;break}f=c[r>>2]|0;if((f|0)>0){j=0;do{i=c[(c[n>>2]|0)+(c[(c[(c[m>>2]|0)+(k<<2)>>2]|0)+4+(((j|0)%(f|0)|0)<<2)>>2]<<2)>>2]|0;h=(j|0)/(f|0)|0;f=i+4+(h<<3)|0;g=f;v=g;a[v>>0]=0;a[v+1>>0]=0;a[v+2>>0]=0;a[v+3>>0]=0;g=g+4|0;a[g>>0]=0;a[g+1>>0]=0;a[g+2>>0]=0;a[g+3>>0]=0;g=Pl(e)|0;if(g<<24>>24)a[f>>0]=(g&255)+13;a[i+4+(h<<3)+1>>0]=Pl(e)|0;a[i+4+(h<<3)+3>>0]=Pl(e)|0;a[i+4+(h<<3)+4>>0]=Pl(e)|0;j=j+1|0;if(gm(e)|0){f=-1;g=24;break c}f=c[r>>2]|0}while((j|0)<(f<<6|0))}k=k+1|0;if((k|0)>=(c[s>>2]|0))break b}if((g|0)==24){l=u;return f|0}}while(0);f=c[t>>2]|0;if((f|0)<=0){v=0;l=u;return v|0}j=b+180|0;i=b+176|0;h=0;while(1){g=c[j>>2]|0;if((c[g+(h*52|0)+32>>2]|0)>1){if((Eb(b,e,0,g+(h*52|0)|0,0)|0)<0){f=-1;g=24;break}c[(c[i>>2]|0)+(h*764|0)+36>>2]=1;f=c[t>>2]|0}h=h+1|0;if((h|0)>=(f|0)){f=0;g=24;break}}if((g|0)==24){l=u;return f|0}return 0}function Qf(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;dm(a,c+1080|0,0)|0;d=am(a)|0;if((d|0)<1294355233)switch(d|0){case 1178948436:{e=2;break}default:d=-1}else switch(d|0){case 1294355233:{e=2;break}default:d=-1}if((e|0)==2){dm(a,c,0)|0;hb(a,b,20);d=0}return d|0}function Rf(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;B=l;l=l+1232|0;u=B+8|0;n=B;t=B+20|0;A=B+1108|0;x=B+1104|0;i=A;k=i+124|0;do{a[i>>0]=0;i=i+1|0}while((i|0)<(k|0));cm(t,20,1,g)|0;j=0;i=0;do{v=t+20+(j*30|0)|0;cm(v,22,1,g)|0;if(!(nn(v,35254,4)|0)){a[A+(j<<2)>>0]=1;a[A+(j<<2)+1>>0]=a[t+20+(j*30|0)+4>>0]|0;a[A+(j<<2)+2>>0]=a[t+20+(j*30|0)+5>>0]|0;a[A+(j<<2)+3>>0]=a[t+20+(j*30|0)+6>>0]|0;i=i+1|0}b[t+20+(j*30|0)+22>>1]=Ul(g)|0;a[t+20+(j*30|0)+24>>0]=Pl(g)|0;a[t+20+(j*30|0)+25>>0]=Pl(g)|0;b[t+20+(j*30|0)+26>>1]=Ul(g)|0;b[t+20+(j*30|0)+28>>1]=Ul(g)|0;j=j+1|0}while((j|0)!=31);v=t+950|0;a[v>>0]=Pl(g)|0;k=t+951|0;a[k>>0]=Pl(g)|0;j=t+952|0;cm(j,128,1,g)|0;m=t+1080|0;cm(m,4,1,g)|0;c[f+136>>2]=4;s=f+140|0;c[s>>2]=31;c[f+144>>2]=(i*28|0)+31;c[f+156>>2]=d[v>>0];c[f+160>>2]=d[k>>0];i=f+952|0;k=i+128|0;do{b[i>>1]=b[j>>1]|0;i=i+2|0;j=j+2|0}while((i|0)<(k|0));v=f+128|0;i=c[v>>2]|0;k=0;do{j=d[f+952+k>>0]|0;if((j|0)>(i|0)){c[v>>2]=j;i=j}k=k+1|0}while((k|0)!=128);r=i+1|0;c[v>>2]=r;c[f+132>>2]=r<<2;if(sm(f)|0){A=-1;l=B;return A|0}Ho(f,t,20)|0;c[n>>2]=35235;c[n+4>>2]=m;ob(f,35259,n);if((Za(f)|0)<0){A=-1;l=B;return A|0}a:do if((c[s>>2]|0)>0){q=f+176|0;r=f+180|0;o=0;p=c[q>>2]|0;while(1){i=p+(o*764|0)+36|0;if(a[A+(o<<2)>>0]|0){c[i>>2]=28;m=d[A+(o<<2)+2>>0]|0;n=d[A+(o<<2)+3>>0]|0;c[u>>2]=d[A+(o<<2)+1>>0];c[u+4>>2]=m;c[u+8>>2]=n;io(p+(o*764|0)|0,32,35270,u);if(om((c[q>>2]|0)+(o*764|0)|0)|0){y=-1;z=40;break}}else{c[i>>2]=1;fb(p,o,t+20+(o*30|0)|0,22);p=c[r>>2]|0;c[p+(o*52|0)+32>>2]=e[t+20+(o*30|0)+22>>1]<<1;m=e[t+20+(o*30|0)+26>>1]<<1;c[p+(o*52|0)+36>>2]=m;n=b[t+20+(o*30|0)+28>>1]|0;c[p+(o*52|0)+40>>2]=((n&65535)<<1)+m;c[p+(o*52|0)+44>>2]=(n&65535)>1?2:0}if((_a(f,o,c[(c[q>>2]|0)+(o*764|0)+36>>2]|0)|0)<0){y=-1;z=40;break}p=c[q>>2]|0;j=c[p+(o*764|0)+36>>2]|0;if((j|0)>0){n=0-(d[t+20+(o*30|0)+24>>0]<<27>>24)|0;k=a[t+20+(o*30|0)+25>>0]|0;i=c[p+(o*764|0)+756>>2]|0;m=0;do{c[i+(m<<6)+16>>2]=n;c[i+(m<<6)>>2]=k;c[i+(m<<6)+8>>2]=128;c[i+(m<<6)+40>>2]=o;m=m+1|0}while((m|0)!=(j|0))}o=o+1|0;if((o|0)>=(c[s>>2]|0))break a}if((z|0)==40){l=B;return y|0}}while(0);if(($a(f)|0)<0){A=-1;l=B;return A|0}b:do if((c[v>>2]|0)>0){p=f+172|0;o=f+168|0;m=0;while(1){if((db(f,m,64)|0)<0){y=-1;break}else n=0;do{i=c[(c[p>>2]|0)+(c[(c[(c[o>>2]|0)+(m<<2)>>2]|0)+4+(((n|0)%4|0)<<2)>>2]<<2)>>2]|0;j=(n|0)/4|0;cm(x,1,4,g)|0;lb(i+4+(j<<3)|0,x);k=i+4+(j<<3)+3|0;switch(a[k>>0]|0){case 7:{w=-78;z=27;break}case 14:case 9:case 8:{a[i+4+(j<<3)+4>>0]=0;w=0;z=27;break}default:{}}if((z|0)==27){z=0;a[k>>0]=w}n=n+1|0}while((n|0)!=256);m=m+1|0;if((m|0)>=(c[v>>2]|0))break b}l=B;return y|0}while(0);c[f+1292>>2]=1;q=f+180|0;i=0;do{if((Eb(f,g,512,(c[q>>2]|0)+(i*52|0)|0,0)|0)<0){y=-1;z=40;break}i=i+1|0}while((i|0)<31);if((z|0)==40){l=B;return y|0}p=f+176|0;n=h+1084|0;o=0;i=0;c:while(1){j=c[(c[p>>2]|0)+(o*764|0)+760>>2]|0;if(a[A+(o<<2)>>0]|0){dm(g,n+(d[A+(o<<2)+1>>0]<<10)|0,0)|0;k=(i*28|0)+31|0;m=0;do{h=k+m|0;c[(c[(c[p>>2]|0)+(o*764|0)+756>>2]|0)+(m<<6)+40>>2]=h;z=c[q>>2]|0;c[z+(h*52|0)+32>>2]=32;c[z+(h*52|0)+36>>2]=0;c[z+(h*52|0)+40>>2]=32;c[z+(h*52|0)+44>>2]=2;m=m+1|0;if((Eb(f,g,0,z+(h*52|0)|0,0)|0)<=-1){y=-1;z=40;break c}}while((m|0)<28);c[j+4>>2]=d[A+(o<<2)+2>>0];c[j+8>>2]=d[A+(o<<2)+3>>0];cm(j+12|0,1,64,g)|0;cm(j+76|0,1,64,g)|0;i=i+1|0}o=o+1|0;if((o|0)>=31){y=0;z=40;break}}if((z|0)==40){l=B;return y|0}return 0}function Sf(a,b,c){a=a|0;b=b|0;c=c|0;if((Yl(a)|0)!=5064532){b=-1;return b|0}Pl(a)|0;if((am(a)|0)!=-1119009965){b=-1;return b|0}dm(a,18,1)|0;dm(a,(am(a)|0)+c|0,0)|0;hb(a,b,32);b=0;return b|0}function Tf(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;y=l;l=l+272|0;t=y;x=y+8|0;Yl(d)|0;i=(Pl(d)|0)&255;am(d)|0;c[t>>2]=i>>>4;c[t+4>>2]=i&15;ob(b,35302,t);t=b+136|0;c[t>>2]=(Ul(d)|0)&65535;Ul(d)|0;i=b+156|0;c[i>>2]=(Ul(d)|0)&65535;u=b+128|0;c[u>>2]=(Ul(d)|0)&65535;v=b+132|0;c[v>>2]=(Ul(d)|0)&65535;q=(Ul(d)|0)&65535;c[b+144>>2]=q;w=b+140|0;c[w>>2]=q;Ul(d)|0;am(d)|0;if((c[t>>2]|0)>64){e=-1;l=y;return e|0}if((c[w>>2]|0)>64){e=-1;l=y;return e|0}g=am(d)|0;am(d)|0;h=am(d)|0;q=am(d)|0;j=am(d)|0;am(d)|0;am(d)|0;am(d)|0;dm(d,g+e|0,0)|0;cm(b,1,32,d)|0;g=am(d)|0;c[i>>2]=(Ul(d)|0)&65535;f=b+160|0;c[f>>2]=(Ul(d)|0)&65535;c[b+152>>2]=(Pl(d)|0)&255;c[b+148>>2]=(Pl(d)|0)&255;Ul(d)|0;Pl(d)|0;Pl(d)|0;if((c[i>>2]|0)>256){e=-1;l=y;return e|0}if((c[f>>2]|0)>255){e=-1;l=y;return e|0}if((c[t>>2]|0)>0){f=0;do{Ul(d)|0;f=f+1|0}while((f|0)<(c[t>>2]|0))}c[b+1264>>2]=8363;dm(d,g+e|0,0)|0;a:do if((c[i>>2]|0)>0){f=0;while(1){o=Ul(d)|0;a[b+952+f>>0]=o;f=f+1|0;if((o&255|0)>=(c[u>>2]|0)){f=-1;break}if((f|0)>=(c[i>>2]|0))break a}l=y;return f|0}while(0);if((Za(b)|0)<0){e=-1;l=y;return e|0}dm(d,h+e|0,0)|0;b:do if((c[w>>2]|0)>0){g=b+176|0;h=b+180|0;f=0;while(1){if((_a(b,f,1)|0)<0){f=-1;s=78;break}cm((c[g>>2]|0)+(f*764|0)|0,1,32,d)|0;c[x+(f<<2)>>2]=am(d)|0;o=am(d)|0;c[(c[h>>2]|0)+(f*52|0)+32>>2]=o;if((o|0)>268435456){f=-1;s=78;break}n=am(d)|0;c[(c[h>>2]|0)+(f*52|0)+36>>2]=n;n=(am(d)|0)+n|0;c[(c[h>>2]|0)+(f*52|0)+40>>2]=n;am(d)|0;am(d)|0;n=am(d)|0;o=c[(c[g>>2]|0)+(f*764|0)+756>>2]|0;Gi(n,o+12|0,o+16|0);o=((Ul(d)|0)&65535)>>>4;c[c[(c[g>>2]|0)+(f*764|0)+756>>2]>>2]=o;Pl(d)|0;Pl(d)|0;c[(c[(c[g>>2]|0)+(f*764|0)+756>>2]|0)+8>>2]=128;o=(Pl(d)|0)&255;c[(c[h>>2]|0)+(f*52|0)+44>>2]=(o&3|0?2:0)|o<<1&4;Pl(d)|0;Pl(d)|0;Pl(d)|0;Pl(d)|0;Pl(d)|0;Ul(d)|0;am(d)|0;am(d)|0;o=c[g>>2]|0;c[o+(f*764|0)+36>>2]=(c[(c[h>>2]|0)+(f*52|0)+32>>2]|0)!=0&1;c[(c[o+(f*764|0)+756>>2]|0)+40>>2]=f;f=f+1|0;if((f|0)>=(c[w>>2]|0))break b}if((s|0)==78){l=y;return f|0}}while(0);if(($a(b)|0)<0){e=-1;l=y;return e|0}f=c[v>>2]|0;c:do if((f|0)>1){m=j+e|0;o=b+172|0;n=1;d:while(1){dm(d,m+(n<<2)|0,0)|0;dm(d,(am(d)|0)+e|0,0)|0;f=Ul(d)|0;k=f&65535;if((f&65535)>255){f=-1;s=78;break}if((bb(b,n,k)|0)<0){f=-1;s=78;break}e:do if(f<<16>>16){f=0;f:while(1){g=(Pl(d)|0)&255;j=(g&3)+f|0;if((j|0)<(k|0)){i=c[(c[o>>2]|0)+(n<<2)>>2]|0;if(!(g&4))h=0;else h=Pl(d)|0;if(g&8|0)a[i+4+(j<<3)+1>>0]=Pl(d)|0;if(g&16|0)a[i+4+(j<<3)+2>>0]=Pl(d)|0;if(g&32|0)a[i+4+(j<<3)+3>>0]=Pl(d)|0;if(g&64|0)a[i+4+(j<<3)+4>>0]=Pl(d)|0;if(g&128|0)Pl(d)|0;f=h&255;do if(h<<24>>24==1){r=-127;s=38}else{if((h&255)<=11)break;r=f+1&255;s=38}while(0);if((s|0)==38){s=0;a[i+4+(j<<3)>>0]=r}g=i+4+(j<<3)+3|0;f=a[g>>0]|0;g:do if((f&255)>=16)switch(f<<24>>24){case 30:case 29:case 28:case 23:case 21:case 20:case 19:{a[g>>0]=14;h=i+4+(j<<3)+4|0;a[h>>0]=a[h>>0]&15|-32;break g}default:{a[i+4+(j<<3)+4>>0]=0;a[g>>0]=0;break g}}while(0);h=i+4+(j<<3)+2|0;f=a[h>>0]|0;g=f&255;h:do if((f+-16&255)<65){g=g+241&255;f=26}else{do switch((f&255)>>>4&15){case 6:{a[i+4+(j<<3)+5>>0]=-92;f=g+-96|0;break}case 7:{a[i+4+(j<<3)+5>>0]=-92;f=(g<<4)+-1792|0;break}case 8:{a[i+4+(j<<3)+5>>0]=14;f=g+-128|176;break}case 9:{a[i+4+(j<<3)+5>>0]=14;f=g+-144|160;break}case 10:{a[i+4+(j<<3)+5>>0]=4;f=(g<<4)+-2560|0;break}case 11:{a[i+4+(j<<3)+5>>0]=4;f=g+-176|0;break}case 12:{a[i+4+(j<<3)+5>>0]=8;f=(g<<4)+-3064|0;break}case 13:{a[i+4+(j<<3)+5>>0]=25;f=(g<<4)+-3328|0;break}case 14:{a[i+4+(j<<3)+5>>0]=25;f=g+-224|0;break}case 15:{a[i+4+(j<<3)+5>>0]=3;f=g<<4;break}default:{g=0;f=0;break h}}while(0);a[i+4+(j<<3)+6>>0]=f;g=0;f=0}while(0);a[h>>0]=g}else f=1;switch(f&31){case 26:case 0:break;default:break f}f=j+1|0;if((f|0)>=(k|0))break e}if(f|0){f=-1;s=78;break d}}while(0);n=n+1|0;f=c[v>>2]|0;if((n|0)>=(f|0)){p=f;break c}}if((s|0)==78){l=y;return f|0}}else p=f;while(0);if((p|0)>0){r=Xm(523,1)|0;s=b+172|0;c[c[s>>2]>>2]=r;c[c[c[s>>2]>>2]>>2]=64}dm(d,q+e|0,0)|0;i:do if((c[u>>2]|0)>0){i=b+168|0;h=0;j:while(1){if((ab(b,h)|0)<0){f=-1;s=78;break}f=Ul(d)|0;if((f&65535)>256){f=-1;s=78;break}c[c[(c[i>>2]|0)+(h<<2)>>2]>>2]=f&65535;if((c[t>>2]|0)>0){g=0;do{f=(Ul(d)|0)&65535;if((f|0)>(c[v>>2]|0)){f=-1;s=78;break j}c[(c[(c[i>>2]|0)+(h<<2)>>2]|0)+4+(g<<2)>>2]=f+-1;g=g+1|0}while((g|0)<(c[t>>2]|0))}h=h+1|0;if((h|0)>=(c[u>>2]|0))break i}if((s|0)==78){l=y;return f|0}}while(0);f=c[w>>2]|0;if((f|0)<=0){e=0;l=y;return e|0}h=b+176|0;i=b+180|0;g=0;while(1){if(c[(c[h>>2]|0)+(g*764|0)+36>>2]|0){dm(d,(c[x+(g<<2)>>2]|0)+e|0,0)|0;if((Eb(b,d,0,(c[i>>2]|0)+(g*52|0)|0,0)|0)<0){f=-1;s=78;break}f=c[w>>2]|0}g=g+1|0;if((g|0)>=(f|0)){f=0;s=78;break}}if((s|0)==78){l=y;return f|0}return 0}function Uf(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;e=l;l=l+16|0;d=e;dm(a,c+952|0,0)|0;if((cm(d,1,4,a)|0)>>>0>=4?(nn(d,35337,4)|0)==0:0){dm(a,c,0)|0;hb(a,b,20);d=0}else d=-1;l=e;return d|0}function Vf(f,g,h){f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;u=l;l=l+1088|0;r=u;p=u+4|0;t=Xm(1,1024)|0;if(!t){f=-1;l=u;return f|0}cm(p,20,1,g)|0;Ul(g)|0;h=0;do{cm(p+20+(h*30|0)|0,22,1,g)|0;b[p+20+(h*30|0)+22>>1]=Ul(g)|0;a[p+20+(h*30|0)+24>>0]=Pl(g)|0;a[p+20+(h*30|0)+25>>0]=Pl(g)|0;b[p+20+(h*30|0)+26>>1]=Ul(g)|0;b[p+20+(h*30|0)+28>>1]=Ul(g)|0;h=h+1|0}while((h|0)!=31);cm(p+1080|0,4,1,g)|0;s=Pl(g)|0;h=p+950|0;a[h>>0]=s;a:do if((s&255)<=128){m=p+951|0;a[m>>0]=Pl(g)|0;cm(t,1024,1,g)|0;Ul(g)|0;c[f+136>>2]=4;n=f+140|0;c[n>>2]=31;s=f+144|0;c[s>>2]=31;q=a[h>>0]|0;k=q&255;o=f+156|0;c[o>>2]=k;c[f+128>>2]=k;c[f+160>>2]=d[m>>0];if(!(q<<24>>24))h=1;else{h=0;i=0;do{a[f+952+h>>0]=h;m=h<<3;q=d[t+m>>0]|0;q=(q|0)>(i|0)?q:i;k=d[t+(m|2)>>0]|0;q=(k|0)>(q|0)?k:q;k=d[t+(m|4)>>0]|0;q=(k|0)>(q|0)?k:q;m=d[t+(m|6)>>0]|0;i=(m|0)>(q|0)?m:q;h=h+1|0}while((h|0)<(c[o>>2]|0));h=i+1|0}q=f+132|0;c[q>>2]=h;Ho(f,p,20)|0;ob(f,35325,r);if((Za(f)|0)>=0){if((c[n>>2]|0)>0){k=f+176|0;m=f+180|0;j=0;do{h=c[k>>2]|0;i=c[m>>2]|0;if((_a(f,j,1)|0)<0)break a;w=c[h+(j*764|0)+756>>2]|0;v=b[p+20+(j*30|0)+22>>1]|0;c[i+(j*52|0)+32>>2]=(v&65535)<<1;y=e[p+20+(j*30|0)+26>>1]|0;c[i+(j*52|0)+36>>2]=y;x=b[p+20+(j*30|0)+28>>1]|0;c[i+(j*52|0)+40>>2]=((x&65535)<<1)+y;c[i+(j*52|0)+44>>2]=(x&65535)>1?2:0;c[w+16>>2]=d[p+20+(j*30|0)+24>>0]<<28>>24;c[w>>2]=a[p+20+(j*30|0)+25>>0];c[w+8>>2]=128;c[w+40>>2]=j;if(v<<16>>16)c[h+(j*764|0)+36>>2]=1;fb(c[k>>2]|0,j,p+20+(j*30|0)|0,22);j=j+1|0}while((j|0)<(c[n>>2]|0))}if(($a(f)|0)>=0){if((c[o>>2]|0)>0){i=f+168|0;h=0;do{if((ab(f,h)|0)<0)break a;y=c[(c[i>>2]|0)+(h<<2)>>2]|0;c[y>>2]=64;x=h<<3;c[y+4>>2]=d[t+x>>0];c[y+8>>2]=d[t+(x|2)>>0];c[y+12>>2]=d[t+(x|4)>>0];c[y+16>>2]=d[t+(x|6)>>0];h=h+1|0}while((h|0)<(c[o>>2]|0))}if((c[q>>2]|0)>0){p=f+172|0;j=r+1|0;k=r+2|0;m=r+3|0;n=0;do{if((bb(f,n,64)|0)<0)break a;else o=0;do{h=c[(c[p>>2]|0)+(n<<2)>>2]|0;cm(r,1,4,g)|0;i=a[r>>0]|0;switch(i<<24>>24){case -88:case 0:break;default:a[h+4+(o<<3)>>0]=((i&255)>>>1)+13<<24>>24}a[h+4+(o<<3)+1>>0]=a[j>>0]|0;a[h+4+(o<<3)+3>>0]=a[k>>0]&15;a[h+4+(o<<3)+4>>0]=a[m>>0]|0;o=o+1|0}while((o|0)!=64);n=n+1|0}while((n|0)<(c[q>>2]|0))}c[f+1292>>2]=1;h=c[s>>2]|0;if((h|0)>0){k=f+180|0;j=0;do{i=c[k>>2]|0;if(c[i+(j*52|0)+32>>2]|0){if((Eb(f,g,512,i+(j*52|0)|0,0)|0)<0)break a;h=c[s>>2]|0}j=j+1|0}while((j|0)<(h|0))}Wm(t);y=0;l=u;return y|0}}}while(0);Wm(t);y=-1;l=u;return y|0}function Wf(a,b,c){a=a|0;b=b|0;c=c|0;b=l;l=l+16|0;c=b;if((am(a)|0)==1097679467?(Ul(a)|0)<<16>>16==3:0){dm(a,6,1)|0;cm(c,1,8,a)|0;c=((nn(c,35358,8)|0)!=0)<<31>>31}else c=-1;l=b;return c|0}function Xf(d,f,g){d=d|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;w=l;l=l+64|0;p=w+16|0;u=w+8|0;dm(f,20,0)|0;h=am(f)|0;g=am(f)|0;o=am(f)|0;if(h>>>0>1048576|g>>>0>1048576|o>>>0>1048576){d=-1;l=w;return d|0}ob(d,35342,w);if((Yf(f,p,g+20|0)|0)<0){d=-1;l=w;return d|0}gb(d,p+18|0,16)|0;q=o+20|0;dm(f,q,0)|0;r=d+136|0;c[r>>2]=4;v=Ul(f)|0;g=v&65535;s=d+128|0;c[s>>2]=g;if((v&65535)>256){d=-1;l=w;return d|0}c[d+132>>2]=O(c[r>>2]|0,g)|0;h=h+20|0;dm(f,h,0)|0;t=Ul(f)|0;g=t&65535;v=d+140|0;c[v>>2]=g;if((t&65535)>255){d=-1;l=w;return d|0}c[d+144>>2]=g;if((Za(d)|0)<0){d=-1;l=w;return d|0}n=Zf(f,c[v>>2]|0)|0;if(!n){d=-1;l=w;return d|0}t=(c[n>>2]|0)+h|0;a:do if((c[v>>2]|0)>0){m=d+180|0;k=d+176|0;i=0;while(1){if((_a(d,i,1)|0)<0)break;j=c[n+(i<<5)+4>>2]<<1;g=c[m>>2]|0;c[g+(i*52|0)+32>>2]=j;if((j|0)>0)c[(c[k>>2]|0)+(i*764|0)+36>>2]=1;h=c[n+(i<<5)+8>>2]|0;x=c[n+(i<<5)>>2]|0;c[g+(i*52|0)+36>>2]=h>>>0>x>>>0?h-x<<1:0;x=b[n+(i<<5)+12>>1]|0;h=x&65535;j=g+(i*52|0)+40|0;c[j>>2]=h;if((x&65535)>2){c[j>>2]=h<<1;c[g+(i*52|0)+44>>2]=2}x=c[k>>2]|0;j=c[x+(i*764|0)+756>>2]|0;c[j>>2]=e[n+(i<<5)+14>>1];c[j+8>>2]=128;c[j+40>>2]=i;fb(x,i,n+(i<<5)+16|0,16);i=i+1|0;if((i|0)>=(c[v>>2]|0))break a}Wm(n);x=-1;l=w;return x|0}while(0);Wm(n);if(($a(d)|0)<0){x=-1;l=w;return x|0}_f(f,c[p>>2]|0,u);dm(f,o+22|0,0)|0;j=d+156|0;c[j>>2]=0;b:do if((c[s>>2]|0)>0){i=d+172|0;g=0;c:while(1){if((db(d,g,64)|0)<0){h=21;break}if((c[r>>2]|0)>0){h=0;do{x=Ul(f)|0;if(($f(f,(c[(c[i>>2]|0)+((O(c[r>>2]|0,g)|0)+h<<2)>>2]|0)+4|0,(x&65535)+q|0)|0)<0){h=24;break c}h=h+1|0}while((h|0)<(c[r>>2]|0))}g=g+1|0;if((g|0)>=(c[s>>2]|0))break b}if((h|0)==21){Wm(c[u+4>>2]|0);x=-1;l=w;return x|0}else if((h|0)==24){Wm(c[u+4>>2]|0);x=-1;l=w;return x|0}}while(0);g=b[u>>1]|0;i=g&65535;h=c[u+4>>2]|0;if((g&65535)>256){Wm(h);x=-1;l=w;return x|0}c[j>>2]=i;if(g<<16>>16){g=0;do{a[d+952+g>>0]=b[h+(g<<1)>>1];g=g+1|0}while((g|0)!=(i|0))}Wm(h);dm(f,t,0)|0;g=c[v>>2]|0;if((g|0)<=0){x=0;l=w;return x|0}j=d+180|0;i=0;while(1){h=c[j>>2]|0;if((c[h+(i*52|0)+32>>2]|0)>=3){if((Eb(d,f,0,h+(i*52|0)|0,0)|0)<0){g=-1;h=36;break}g=c[v>>2]|0}i=i+1|0;if((i|0)>=(g|0)){g=0;h=36;break}}if((h|0)==36){l=w;return g|0}return 0}function Yf(a,d,e){a=a|0;d=d|0;e=e|0;dm(a,e,0)|0;if((Ul(a)|0)<<16>>16!=1){d=-1;return d|0}e=(am(a)|0)+e|0;if((dm(a,e,0)|0)<0){d=-1;return d|0}c[d>>2]=e+((Ul(a)|0)&65535);c[d+4>>2]=e+((Ul(a)|0)&65535);c[d+8>>2]=e+((Ul(a)|0)&65535);c[d+12>>2]=e+((Ul(a)|0)&65535);b[d+16>>1]=Ul(a)|0;Ul(a)|0;d=((cm(d+18|0,1,16,a)|0)!=16)<<31>>31;return d|0}function Zf(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0;i=d<<5;e=Vm(i)|0;gp(e|0,0,i|0)|0;if((d|0)>0){g=0;h=0}else{j=e;return j|0}while(1){c[e+(g<<5)>>2]=am(a)|0;c[e+(g<<5)+8>>2]=am(a)|0;i=e+(g<<5)+4|0;c[i>>2]=(Ul(a)|0)&65535;b[e+(g<<5)+12>>1]=Ul(a)|0;b[e+(g<<5)+14>>1]=Ul(a)|0;f=Ul(a)|0;if((f&65535)>4)c[i>>2]=f&65535;h=h+1<<16>>16;if((cm(e+(g<<5)+16|0,1,16,a)|0)!=16)break;g=h&65535;if((g|0)>=(d|0)){j=7;break}}if((j|0)==7)return e|0;Wm(e);j=0;return j|0}function _f(a,d,e){a=a|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;b[e>>1]=0;dm(a,d,0)|0;i=e+4|0;c[i>>2]=Vm(128)|0;d=Ul(a)|0;if((d&65535)>65533)return;else g=64;do{f=b[e>>1]|0;if((f&65535|0)<(g|0))h=c[i>>2]|0;else{h=Ym(c[i>>2]|0,g<<2)|0;c[i>>2]=h;f=b[e>>1]|0;g=g<<1}b[e>>1]=f+1<<16>>16;b[h+((f&65535)<<1)>>1]=d;d=Ul(a)|0}while((d&65535)<=65533);return}function $f(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;m=em(b)|0;if((m|0)<0){n=-1;return n|0}dm(b,d,0)|0;i=0;d=0;f=Ul(b)|0;h=0;j=0;e=0;a:while(1){l=f&65535;if(d<<24>>24)break;if(f<<16>>16<-28416)switch(f<<16>>16){case -32768:break a;default:{}}else switch(f<<16>>16){case -28416:break a;default:{}}b:do if(!(l&32768)){if(!(l&16384)){d=e&255;a[c+(d<<3)>>0]=Ei(l&4095)|0;a[c+(d<<3)+1>>0]=i;d=0;g=j;break}f=Ul(b)|0;g=f<<16>>16==0;if((l&255|0)==0&g)break a;d=e&255;if(!g){a[c+(d<<3)>>0]=Ei(f&4095)|0;a[c+(d<<3)+1>>0]=i}l=l+d|0;e=l&255;if((l&192)>>>0>63)break a;else{d=0;g=j}}else{d=l>>>8;k=l&127;g=k&255;f=d&255;switch(f&127){case 13:case 12:case 11:case 9:case 3:break;default:{d=(d&112)>>>0<16;h=d?0:h;j=d?0:j}}do switch(f&127){case 4:{d=0;g=j;break b}case 14:case 1:{d=e&255;a[c+(d<<3)+3>>0]=1;a[c+(d<<3)+4>>0]=g;d=0;g=j;break b}case 15:case 2:{d=e&255;a[c+(d<<3)+3>>0]=2;a[c+(d<<3)+4>>0]=g;d=0;g=j;break b}case 3:{d=e&255;a[c+(d<<3)+3>>0]=12;a[c+(d<<3)+4>>0]=g;d=0;g=j;break b}case 5:{d=e&255;a[c+(d<<3)+3>>0]=14;a[c+(d<<3)+4>>0]=(k|0)==0?80:(l&15|96)&255;d=0;g=j;break b}case 6:{d=e&255;a[c+(d<<3)+3>>0]=14;a[c+(d<<3)+4>>0]=0;d=0;g=j;break b}case 7:{d=e&255;a[c+(d<<3)+3>>0]=14;a[c+(d<<3)+4>>0]=1;d=0;g=j;break b}case 8:{d=e&255;if(!k){d=0;g=j;break b}a[c+(d<<3)+3>>0]=15;a[c+(d<<3)+4>>0]=100/(k>>>0)|0;d=0;g=j;break b}case 9:{i=k+1&255;d=0;g=j;break b}case 10:{d=0;h=0;break b}case 11:{d=0;h=3;break b}case 12:{d=0;h=4;break b}case 13:{d=0;h=(k|0)==0?0:10;break b}case 16:{if((j|h)<<24>>24){if((e&255)<64&(k|0)!=0){f=0;d=e&255;do{a[c+(d<<3)+3>>0]=h;a[c+(d<<3)+4>>0]=j;d=d+1|0;f=f+1|0}while(d>>>0<64&(f|0)<(k|0));e=d&255}}else e=k+(e&255)&255;d=(e&255)>63&1;g=j;break b}case 17:{d=e&255;a[c+(d<<3)+3>>0]=11;a[c+(d<<3)+4>>0]=g;d=1;g=j;break b}default:{d=-1;n=40;break a}}while(0)}while(0);f=Ul(b)|0;if(fm(b)|0)break;else j=g}if((n|0)==40)return d|0;d=e&255;if((e&255)<64)a[c+(d+-1<<3)+5>>0]=13;dm(b,m,0)|0;n=d;return n|0}function ag(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0;e=l;l=l+1024|0;d=e;do{f=cm(d,1,(c|0)<1024?c:1024,b)|0;ko(d,1,f,a)|0;c=c-f|0}while((f|0)>0&(c|0)>0);l=e;return}function bg(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;d=l;l=l+1024|0;c=d;do{f=(b|0)<1024?b:1024;gp(c|0,0,f|0)|0;ko(c,1,f,a)|0;e=b;b=b-f|0}while((e|0)>0&(b|0)>0);l=d;return}function cg(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0;j=l;l=l+32|0;i=j;g=mm(c[a+4>>2]|0)|0;if((g|0)<2048){i=-2;l=j;return i|0}h=Vm(g)|0;if(!h){i=-1;l=j;return i|0}a:do if((cm(h,1,g,a)|0)==(g|0)){f=2488;e=0;while(1){e=e+1|0;if((Ca[c[(c[f>>2]|0)+4>>2]&255](h,i,g)|0)>-1)break;if((e|0)==43)break a;else f=2488+(e<<2)|0}gm(a)|0;dm(a,0,0)|0;if((Ba[c[(c[f>>2]|0)+8>>2]&63](a,b)|0)>=0?(gm(a)|0)==0:0){wo(b)|0;Wm(h);if(!d){i=0;l=j;return i|0}c[d>>2]=c[c[f>>2]>>2];i=0;l=j;return i|0}}while(0);Wm(h);i=-1;l=j;return i|0}function dg(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;g=l;l=l+32|0;f=g;d=2488;e=0;while(1){d=Ca[c[(c[d>>2]|0)+4>>2]&255](a,f,b)|0;if((d|0)>0)break;e=e+1|0;if(!d){d=0;break}if((e|0)==43){d=-1;break}else d=2488+(e<<2)|0}l=g;return d|0}function eg(b,c,d){b=b|0;c=c|0;d=d|0;if(!c)return;d=(d|0)<20?d:20;if(b){ep(c|0,b|0,d|0)|0;c=c+d|0}a[c>>0]=0;return}function fg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0;if((e|0)<896){h=896-e|0;return h|0}if((a[b+2>>0]|0)!=-84){h=-1;return h|0}if((a[b+3>>0]|0)!=29){h=-1;return h|0}if((a[b>>0]|0)<0){h=-1;return h|0}else e=0;while(1){if((d[b+((e<<3)+10)>>0]|0)>15){g=-1;h=11;break}e=e+1|0;if((e|0)>=31){f=0;break}}if((h|0)==11)return g|0;do{if((a[b+(f+768)>>0]|0)<0){g=-1;h=11;break}f=f+1|0}while((f|0)<128);if((h|0)==11)return g|0;eg(0,c,0);h=0;return h|0}function gg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+1536|0;v=w+512|0;t=w;gp(t|0,0,512)|0;i=Pl(b)|0;j=Pl(b)|0;Ul(b)|0;s=am(b)|0;bg(e,20);f=0;u=0;do{bg(e,22);r=Ul(b)|0;Xj(e,r);u=((r&65535)<<1)+u|0;Wj(e,Pl(b)|0);Wj(e,Pl(b)|0);Xj(e,Ul(b)|0);Xj(e,Ul(b)|0);f=f+1|0}while((f|0)!=31);f=0;while(1){r=am(b)|0;c[t+(f<<2)>>2]=r;if(!r){h=5;break}g=f+1|0;f=g&255;if(f<<24>>24>-1)f=g;else break}if((h|0)==5){f=f&255;if(!(f<<24>>24)){v=-1;l=w;return v|0}}q=f+-1<<24>>24;r=q&255;Wj(e,i);Wj(e,j);dm(b,768,0)|0;ag(e,b,128);Yj(e,1294879534);if(q<<24>>24){o=0;do{dm(b,c[t+(o<<2)>>2]|0,0)|0;am(b)|0;am(b)|0;am(b)|0;gp(v|0,0,1024)|0;p=0;do{q=p<<2;f=0;do{k=(f<<4)+q|0;h=Pl(b)|0;g=h&255;do if(!(g&128)){m=Pl(b)|0;j=g>>>2;n=m&255;switch(h&63){case 63:{g=-1;break}case 0:{g=0;break}default:g=(g&63)+245&255}i=(g<<24>>24==0&1)+g<<24>>24;g=j&48;h=v+k|0;a[h>>0]=g;if(i<<24>>24!=-1){j=i&255;a[h>>0]=d[35367+(j<<1)>>0]|0|g;a[v+(k|1)>>0]=a[35367+(j<<1)+1>>0]|0}if((n&15|0)==7){a[v+(k|2)>>0]=n&240;break}else{n=Pl(b)|0;a[v+(k|2)>>0]=m;a[v+(k|3)>>0]=n;break}}else f=f+-1+(g&127)|0;while(0);f=f+1|0}while((f|0)<64);p=p+1|0}while((p|0)!=4);ko(v,1024,1,e)|0;o=o+1|0}while((o|0)!=(r|0))}dm(b,s,0)|0;ag(e,b,u);v=0;l=w;return v|0}function hg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;if((e|0)<21){c=21-e|0;return c|0}k=Rj(a[b>>0]|0,a[b+1>>0]|0)|0;l=k&65535;if((k+-1&65535)>30){c=-1;return c|0}f=Rj(a[b+14>>0]|0,a[b+15>>0]|0)|0;j=(f&65535)<<1;h=Rj(a[b+18>>0]|0,a[b+19>>0]|0)|0;i=Rj(a[b+20>>0]|0,a[b+21>>0]|0)|0;f=(h|f|i)<<16>>16<0;h=(i&65535)+(h&65535)<<1>>>0>j>>>0;i=0;k=0;while(1){g=b+(i<<3)|0;if(f|h){f=-1;g=18;break}if((d[g+16>>0]|0)>15){f=-1;g=18;break}if((d[g+17>>0]|0)>64){f=-1;g=18;break}k=j+k|0;i=i+1|0;if((i|0)>=(l|0)){g=9;break}}if((g|0)==9){if((k|0)<3){c=-1;return c|0}f=Vj(b+2|0)|0;g=Vj(b+6|0)|0;h=Vj(b+10|0)|0;if((f|0)<(l<<3|2|0)|((g-f|0)>128|(h|0)>(g|0)&((g|0)>(f|0)&(h|0)>(f|0))^1)){c=-1;return c|0}g=g+-1|0;if((g|0)>(e|0)){c=g-e|0;return c|0}a:do if((f|0)<(g|0)){while(1){if((d[b+f>>0]|0)>128){f=-1;break}f=f+1|0;if((f|0)>=(g|0))break a}return f|0}while(0);if((h|0)>65535?1:(a[b+g>>0]|0)!=-1){c=-1;return c|0}eg(0,c,0);c=0;return c|0}else if((g|0)==18)return f|0;return 0}function ig(d,f){d=d|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+448|0;p=t+320|0;r=t+8|0;m=t+264|0;s=t;i=p;j=i+128|0;do{a[i>>0]=0;i=i+1|0}while((i|0)<(j|0));gp(r|0,0,256)|0;bg(f,20);k=(Ul(d)|0)&255;g=k&65535;if((k&65535)>31){s=-1;l=t;return s|0}o=am(d)|0;am(d)|0;q=am(d)|0;if(k<<16>>16){i=0;h=0;do{bg(f,22);j=Ul(d)|0;Xj(f,j);h=((j&65535)<<1)+h|0;Wj(f,Pl(d)|0);Wj(f,Pl(d)|0);Xj(f,Ul(d)|0);Xj(f,Ul(d)|0);i=i+1|0}while((i|0)!=(g|0));i=m;j=i+50|0;do{a[i>>0]=0;i=i+1|0}while((i|0)<(j|0));if((k&65535)<31)n=6;else k=h}else{i=m;j=i+50|0;do{a[i>>0]=0;i=i+1|0}while((i|0)<(j|0));h=0;n=6}if((n|0)==6){do{ko(m,30,1,f)|0;g=g+1|0}while((g|0)!=31);k=h}i=em(d)|0;if((i|0)<0){s=-1;l=t;return s|0}dm(d,o,0)|0;h=0;while(1){o=Pl(d)|0;g=p+h|0;a[g>>0]=o;if(o<<24>>24==-1)break;else h=h+1|0}a[g>>0]=0;Wj(f,h&255);Wj(f,127);g=0;h=0;do{o=a[p+g>>0]|0;Wj(f,o);h=(o&255)>(h&255)?o:h;g=g+1|0}while((g|0)!=128);Yj(f,1294879534);dm(d,i,0)|0;j=(h&255)+1|0;g=0;do{b[r+(g<<1)>>1]=Ul(d)|0;g=g+1|0}while((g|0)!=(j|0));h=0;do{dm(d,e[r+(h<<1)>>1]|0,0)|0;i=0;do{g=Pl(d)|0;do if(g<<24>>24<=-1)if(g<<24>>24==-1){c[s>>2]=0;ko(s,1,4,f)|0;break}else{p=Pl(d)|0;jg(g,p,Pl(d)|0,f);break}else jg(g,Pl(d)|0,0,f);while(0);i=i+1|0}while((i|0)!=256);h=h+1|0}while((h|0)!=(j|0));dm(d,q,0)|0;ag(f,d,k);s=0;l=t;return s|0}function jg(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0;j=l;l=l+16|0;h=j+4|0;i=j;g=b&255;b=d&255;d=g<<4&48|b>>>4;if(d>>>0>36){c[i>>2]=0;ko(i,4,1,f)|0;l=j;return}else{k=a[35367+(d<<1)>>0]|0;a[h+1>>0]=a[35367+(d<<1)+1>>0]|0;i=g>>>2;a[h>>0]=k&255|i&16;a[h+2>>0]=i<<4|b&15;a[h+3>>0]=e;ko(h,4,1,f)|0;l=j;return}}function kg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;if((e|0)<1084){c=1084-e|0;return c|0}l=a[b+950>>0]|0;m=l&255;if(l<<24>>24<1){c=-1;return c|0}else k=0;while(1){g=b+(k*30|0)|0;h=g+42|0;h=Rj(a[h>>0]|0,a[h+1>>0]|0)|0;i=g+46|0;i=Rj(a[i>>0]|0,a[i+1>>0]|0)|0;j=g+48|0;j=Rj(a[j>>0]|0,a[j+1>>0]|0)|0;if((i|h|j)<<16>>16<0){p=-1;j=31;break}if((j&65535)+(i&65535)<<1>>>0>(((h&65535)<<1)+2|0)>>>0){p=-1;j=31;break}if((d[g+44>>0]|0)>15){p=-1;j=31;break}k=k+1|0;if((d[g+45>>0]|0)>64){p=-1;j=31;break}if((k|0)>=31){j=9;break}}if((j|0)==9){k=Vj(b+1080|0)|0;if((k|0)<1084){c=-1;return c|0}do if(l<<24>>24){i=0;h=0;while(1){l=a[b+(i+952)>>0]|0;g=l&255;if(l<<24>>24<0){p=-1;j=31;break}h=(g|0)>(h|0)?g:h;i=i+1|0;if((i|0)>=(m|0)){j=11;break}}if((j|0)==11){g=(h<<2)+4|0;if((i|0)<128){f=i;n=g;j=12;break}else{o=g;break}}else if((j|0)==31)return p|0}else{f=0;n=4;j=12}while(0);a:do if((j|0)==12){while(1){if(a[b+(f+952)>>0]|0){p=-1;break}f=f+1|0;if((f|0)>=128){o=n;break a}}return p|0}while(0);f=(o<<1)+1085|0;if((f|0)>(e|0)){c=f-e|0;return c|0}b:do if((o|0)>0){h=0;i=0;f=999999;do{e=b+(h<<1)+1084|0;e=Rj(a[e>>0]|0,a[e+1>>0]|0)|0;g=e&65535;if((e&65535)<1084|(g|0)>(k|0)){p=-1;j=31;break}f=(g|0)<(f|0)?g:f;i=(g|0)>(i|0)?g:i;h=h+1|0}while((h|0)<(o|0));if((j|0)==31)return p|0;if((f|0)<(i|0)){c:while(1){g=a[b+f>>0]|0;h=g&255;switch((h&192)<<24>>24){case 0:{if((g&255)>19){p=-1;j=31;break c}f=f+3|0;break}case -128:{f=f+2|0;break}case 64:{f=f+1|0;if((h&63|0)==0?(a[b+f>>0]|0)==0:0){p=-1;j=31;break c}break}default:{}}f=f+1|0;if((f|0)>=(i|0))break b}if((j|0)==31)return p|0}}while(0);eg(b,c,20);c=0;return c|0}else if((j|0)==31)return p|0;return 0}function lg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=l;l=l+3136|0;p=s+2048|0;q=s;cm(p,1080,1,b)|0;ko(p,1080,1,e)|0;f=0;r=0;do{o=p+(f*30|0)|0;r=(((Rj(a[o+42>>0]|0,a[o+43>>0]|0)|0)&65535)<<1)+r|0;f=f+1|0}while((f|0)!=31);f=0;o=0;do{n=d[p+(f+952)>>0]|0;o=(n|0)>(o|0)?n:o;f=f+1|0}while((f|0)!=128);Yj(e,1294879534);n=am(b)|0;f=0;while(1){c[q+(f<<4)>>2]=(Ul(b)|0)&65535;c[q+(f<<4)+4>>2]=(Ul(b)|0)&65535;c[q+(f<<4)+8>>2]=(Ul(b)|0)&65535;c[q+(f<<4)+12>>2]=(Ul(b)|0)&65535;if((f|0)<(o|0))f=f+1|0;else{j=0;break}}a:while(1){gp(p|0,0,1024)|0;k=0;do{dm(b,c[q+(j<<4)+(k<<2)>>2]|0,0)|0;m=k<<2;f=0;do{g=p+((f<<4)+m)|0;h=Pl(b)|0;i=h&255;switch((h&255)>>>6&3){case 0:{a[g>>0]=h;a[g+1>>0]=Pl(b)|0;a[g+2>>0]=Pl(b)|0;a[g+3>>0]=Pl(b)|0;break}case 3:{f=(i&63)+f|0;break}case 1:{a[g+2>>0]=i&15;a[g+3>>0]=Pl(b)|0;break}case 2:{a[g>>0]=Pl(b)|0;a[g+1>>0]=Pl(b)|0;a[g+2>>0]=i<<4;break}default:{f=13;break a}}f=f+1|0}while((f|0)<64);k=k+1|0}while((k|0)<4);ko(p,1024,1,e)|0;if((j|0)<(o|0))j=j+1|0;else{f=17;break}}if((f|0)!=13)if((f|0)==17){dm(b,n,0)|0;ag(e,b,r);l=s;return 0}return 0}function mg(b,c,e){b=b|0;c=c|0;e=e|0;a:do if((e|0)>=285)if((((((a[b>>0]|0)==70?(a[b+1>>0]|0)==67:0)?(a[b+2>>0]|0)==45:0)?(a[b+3>>0]|0)==77:0)?(a[b+4>>0]|0)==1:0)?(a[b+5>>0]|0)==0:0){e=0;do{if((d[b+((e<<3)+37)>>0]|0)>64){e=-1;break a}e=e+1|0}while((e|0)<31);eg(b+10|0,c,20);e=0}else e=-1;else e=285-e|0;while(0);return e|0}function ng(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0;am(a)|0;Ul(a)|0;am(a)|0;ag(b,a,20);am(a)|0;c=0;h=0;do{bg(b,22);f=Ul(a)|0;Xj(b,f);h=((f&65535)<<1)+h|0;Wj(b,Pl(a)|0);Wj(b,Pl(a)|0);Xj(b,Ul(a)|0);f=Ul(a)|0;Xj(b,f<<16>>16==0?1:f);c=c+1|0}while((c|0)!=31);am(a)|0;e=Pl(a)|0;Wj(b,e);Wj(b,Pl(a)|0);am(a)|0;c=e&255;if(e<<24>>24){f=0;d=0;do{i=Pl(a)|0;Wj(b,i);d=(i&255)>(d&255)?i:d;f=f+1|0}while((f|0)!=(c|0));if(e<<24>>24>-1)g=5;else c=d}else{c=0;d=0;g=5}if((g|0)==5){do{Wj(b,0);c=c+1|0}while((c|0)!=128);c=d}Yj(b,1294879534);am(a)|0;c=c&255;d=0;while(1){ag(b,a,1024);if((d|0)==(c|0))break;else d=d+1|0}am(a)|0;ag(b,a,h);return 0}function og(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;if((Vj(b+192|0)|0)!=1397706311){j=-1;return j|0}f=Vj(b+10|0)|0;if((f+-3|0)>>>0>1048556){j=-1;return j|0}else{g=0;h=0}do{k=b+(g<<1)|0;e=k+14|0;e=Rj(a[e>>0]|0,a[e+1>>0]|0)|0;l=k+78|0;l=Rj(a[l>>0]|0,a[l+1>>0]|0)|0;if((e&65535)<(l&65535)|(d[k+46>>0]|0)>64){i=-1;j=9;break}h=(e&65535)+h|0;g=g+1|0}while((g|0)<16);if((j|0)==9)return i|0;if((h|0)<3|(h|0)>(f|0)){l=-1;return l|0}else e=0;do{if((d[b+((e<<1)+113)>>0]|0)>=41){i=-1;j=9;break}e=e+1|0}while((e|0)<40);if((j|0)==9)return i|0;eg(0,c,0);l=0;return l|0}function pg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0;m=l;l=l+1216|0;j=m+128|0;k=m+64|0;i=m;f=k;g=f+64|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));f=i;g=f+64|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));gp(j|0,0,1080)|0;cm(j,1,10,b)|0;am(b)|0;f=0;do{g=Ul(b)|0;c[k+(f<<2)>>2]=g&65535;h=f*30|0;a[j+(h+42)>>0]=(g&65535)>>>9;a[j+(h+43)>>0]=(g&65535)>>>1;f=f+1|0}while((f|0)!=16);a[j+45>>0]=Ul(b)|0;a[j+75>>0]=Ul(b)|0;a[j+105>>0]=Ul(b)|0;a[j+135>>0]=Ul(b)|0;a[j+165>>0]=Ul(b)|0;a[j+195>>0]=Ul(b)|0;a[j+225>>0]=Ul(b)|0;a[j+255>>0]=Ul(b)|0;a[j+285>>0]=Ul(b)|0;a[j+315>>0]=Ul(b)|0;a[j+345>>0]=Ul(b)|0;a[j+375>>0]=Ul(b)|0;a[j+405>>0]=Ul(b)|0;a[j+435>>0]=Ul(b)|0;a[j+465>>0]=Ul(b)|0;a[j+495>>0]=Ul(b)|0;f=0;do{h=Ul(b)|0;c[i+(f<<2)>>2]=h&65535;a[j+((f*30|0)+46)>>0]=(h&65535)>>>1;f=f+1|0}while((f|0)!=16);h=0;do{g=c[i+(h<<2)>>2]|0;f=(c[k+(h<<2)>>2]|0)-g|0;if((g|0)==0|(f|0)==0){f=1;g=h*30|0}else{g=h*30|0;a[j+(g+48)>>0]=f>>>9;f=f>>>1&255}a[j+(g+49)>>0]=f;h=h+1|0}while((h|0)!=16);a[j+529>>0]=1;a[j+559>>0]=1;a[j+589>>0]=1;a[j+619>>0]=1;a[j+649>>0]=1;a[j+679>>0]=1;a[j+709>>0]=1;a[j+739>>0]=1;a[j+769>>0]=1;a[j+799>>0]=1;a[j+829>>0]=1;a[j+859>>0]=1;a[j+889>>0]=1;a[j+919>>0]=1;a[j+949>>0]=1;a[j+950>>0]=Ul(b)|0;a[j+951>>0]=127;f=0;do{a[j+(f+952)>>0]=Ul(b)|0;f=f+1|0}while((f|0)!=40);if((ko(j,1,1080,e)|0)!=1080){k=-1;l=m;return k|0}Yj(e,1294879534);am(b)|0;f=am(b)|0;if((f+-1|0)>>>0>131071){k=-1;l=m;return k|0}g=Vm(f)|0;if((cm(g,1,f,b)|0)==(f|0))h=0;else{Wm(g);k=-1;l=m;return k|0}do{if((a[g+(h|2)>>0]&15)==12){j=g+(h|3)|0;i=d[j>>0]|0;a[j>>0]=((i>>>4)*10|0)+(i&15)}h=h+4|0}while(h>>>0>>0);ko(g,f,1,e)|0;Wm(g);am(b)|0;g=0;do{f=c[k+(g<<2)>>2]|0;if(f|0)ag(e,b,f);g=g+1|0}while((g|0)!=16);f=0;l=m;return f|0}function qg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0;if((Vj(b)|0)==1295068720)e=0;else{i=-1;return i|0}while(1){if((d[b+((e*68|0)+72)>>0]|0)>15){h=-1;i=10;break}e=e+1|0;if((e|0)>=31){f=0;break}}if((i|0)==10)return h|0;while(1){if((d[b+((f*68|0)+73)>>0]|0)>64){h=-1;i=10;break}f=f+1|0;if((f|0)>=31){g=0;break}}if((i|0)==10)return h|0;do{f=b+(g*68|0)+66|0;g=g+1|0;if(((Rj(a[f>>0]|0,a[f+1>>0]|0)|0)&65535)>=32769){h=-1;i=10;break}}while((g|0)<31);if((i|0)==10)return h|0;if(!(a[b+2114>>0]|0)){i=-1;return i|0}eg(0,c,0);i=0;return i|0}function rg(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;u=l;l=l+4736|0;r=u+3712|0;p=u+3584|0;o=u+1536|0;s=u+1024|0;t=u;gp(o|0,0,2048)|0;gp(s|0,0,512)|0;e=p;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));am(b)|0;Ul(b)|0;bg(c,20);e=0;q=0;do{ag(c,b,22);dm(b,38,1)|0;m=Ul(b)|0;Xj(c,m);q=((m&65535)<<1)+q|0;m=Ul(b)|0;n=Ul(b)|0;Wj(c,Pl(b)|0);Wj(c,Pl(b)|0);Xj(c,m);Xj(c,n<<16>>16?n:1);e=e+1|0}while((e|0)!=31);e=Pl(b)|0;k=e&255;if((e&255)>128){t=-1;l=u;return t|0}Wj(c,e);f=Pl(b)|0;Wj(c,127);dm(b,2118,0)|0;if(!(e<<24>>24)){n=f&255;m=0}else{e=0;do{cm(o+(e<<4)|0,1,4,b)|0;e=e+1|0}while((e|0)!=(k|0));e=0;do{cm(o+(e<<4)+4|0,1,4,b)|0;e=e+1|0}while((e|0)!=(k|0));e=0;do{cm(o+(e<<4)+8|0,1,4,b)|0;e=e+1|0}while((e|0)!=(k|0));e=0;do{cm(o+(e<<4)+12|0,1,4,b)|0;e=e+1|0}while((e|0)!=(k|0));n=f&255;j=0;m=0;do{do if(j){if((j|0)>0){f=a[o+(j<<4)>>0]|0;g=o+(j<<4)+4|0;h=o+(j<<4)+8|0;i=o+(j<<4)+12|0;e=0;while(1){if((((a[o+(e<<4)>>0]|0)==f<<24>>24?(a[o+(e<<4)+4>>0]|0)==(a[g>>0]|0):0)?(a[o+(e<<4)+8>>0]|0)==(a[h>>0]|0):0)?(a[o+(e<<4)+12>>0]|0)==(a[i>>0]|0):0){i=32;break}e=e+1|0;if((e|0)>=(j|0)){i=13;break}}if((i|0)==13){i=0;a[p+j>>0]=m;m=m+1|0;break}else if((i|0)==32){i=0;a[p+j>>0]=a[p+e>>0]|0;break}}}else{a[p>>0]=m;m=m+1|0}while(0);j=j+1|0}while((j|0)!=(k|0));f=0;h=0;e=1;do{a:do if(!h)i=21;else{if((h|0)<=0)if(!(e<<24>>24)){e=0;break}else{e=1;i=21;break}e=a[p+h>>0]|0;g=0;while(1){if(e<<24>>24==(a[p+g>>0]|0)){e=0;break a}g=g+1|0;if((g|0)>=(h|0)){e=1;i=21;break}}}while(0);if((i|0)==21){i=0;j=f&255;a[s+(j<<2)>>0]=a[o+(h<<4)>>0]|0;a[s+(j<<2)+1>>0]=a[o+(h<<4)+4>>0]|0;a[s+(j<<2)+2>>0]=a[o+(h<<4)+8>>0]|0;a[s+(j<<2)+3>>0]=a[o+(h<<4)+12>>0]|0;f=f+1<<24>>24}h=h+1|0}while((h|0)!=(k|0))}ko(p,128,1,c)|0;Yj(c,1294879534);k=k<<4;e=k+2118|0;if((m|0)>0){f=t+256|0;g=t+512|0;h=t+768|0;i=0;do{gp(r|0,0,1024)|0;gp(t|0,0,1024)|0;dm(b,(d[s+(i<<2)>>0]<<8)+e|0,0)|0;cm(t,256,1,b)|0;dm(b,(d[s+(i<<2)+1>>0]<<8)+e|0,0)|0;cm(f,256,1,b)|0;dm(b,(d[s+(i<<2)+2>>0]<<8)+e|0,0)|0;cm(g,256,1,b)|0;dm(b,(d[s+(i<<2)+3>>0]<<8)+e|0,0)|0;cm(h,256,1,b)|0;j=0;do{p=j<<4;v=r+p|0;o=j<<2;w=t+o|0;w=d[w>>0]|d[w+1>>0]<<8|d[w+2>>0]<<16|d[w+3>>0]<<24;a[v>>0]=w;a[v+1>>0]=w>>8;a[v+2>>0]=w>>16;a[v+3>>0]=w>>24;v=r+(p|4)|0;w=t+256+o|0;w=d[w>>0]|d[w+1>>0]<<8|d[w+2>>0]<<16|d[w+3>>0]<<24;a[v>>0]=w;a[v+1>>0]=w>>8;a[v+2>>0]=w>>16;a[v+3>>0]=w>>24;v=r+(p|8)|0;w=t+512+o|0;w=d[w>>0]|d[w+1>>0]<<8|d[w+2>>0]<<16|d[w+3>>0]<<24;a[v>>0]=w;a[v+1>>0]=w>>8;a[v+2>>0]=w>>16;a[v+3>>0]=w>>24;v=r+(p|12)|0;w=t+768+o|0;w=d[w>>0]|d[w+1>>0]<<8|d[w+2>>0]<<16|d[w+3>>0]<<24;a[v>>0]=w;a[v+1>>0]=w>>8;a[v+2>>0]=w>>16;a[v+3>>0]=w>>24;a[r+(p|15)>>0]=a[(o|3)+(t+768)>>0]|0;j=j+1|0}while((j|0)!=64);ko(r,1024,1,c)|0;i=i+1|0}while((i|0)!=(m|0))}dm(b,k+2122+(n<<8)|0,0)|0;ag(c,b,q);w=0;l=u;return w|0}function sg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;if((e|0)<1024){c=1024-e|0;return c|0}else{g=0;i=0}while(1){f=b+(g<<4)|0;if((d[f+7>>0]|0)>64){n=-1;j=28;break}l=f+4|0;l=Rj(a[l>>0]|0,a[l+1>>0]|0)|0;h=(l&65535)<<1;m=f+12|0;if(l<<16>>16<0|((Rj(a[m>>0]|0,a[m+1>>0]|0)|0)&65535)>>>0>h>>>0){n=-1;j=28;break}i=h+i|0;g=g+1|0;if((g|0)>=15){j=6;break}}if((j|0)==6){if((i|0)<5){c=-1;return c|0}l=a[b+243>>0]|0;if((l+-1&255)>99){c=-1;return c|0}f=b+244|0;h=0;m=0;do{g=f+(h<<1)|0;g=(Rj(a[g>>0]|0,a[g+1>>0]|0)|0)&65535;if(g&1023|0){n=-1;j=28;break}k=g>>>10;m=(k|0)>(m|0)?k:m;h=h+1|0}while((h|0)<100);if((j|0)==28)return n|0;if((m|0)==0|(m|0)>99){c=-1;return c|0}f=(g<<10|447)+(h<<2)|0;if((f|0)>(e|0)){c=f-e|0;return c|0}else i=0;a:while(1){g=i<<10|444;j=0;do{f=(j<<2)+g|0;k=f+4|0;if((k|0)>(e|0)){j=16;break a}h=b+f|0;if((f|0)>65532){n=-1;j=28;break a}f=a[h+2>>0]|0;switch(f&15){case 3:{if((d[h+3>>0]|0)>64){n=-1;j=28;break a}break}case 4:{if((d[h+3>>0]|0)>99){n=-1;j=28;break a}break}case 5:{if((d[h+3>>0]|0)>>>0>((l&255)+1|0)>>>0){n=-1;j=28;break a}break}case 6:{if((d[h+3>>0]|0)>1){n=-1;j=28;break a}break}default:{}}if((f&15)==7?(d[h+3>>0]|0)>1:0){n=-1;j=28;break a}j=j+1|0}while((j|0)<256);if((i|0)<(m|0))i=i+1|0;else{j=27;break}}if((j|0)==16){c=k-e|0;return c|0}else if((j|0)==27){eg(0,c,0);c=0;return c|0}else if((j|0)==28)return n|0}else if((j|0)==28)return n|0;return 0}function tg(b,c){b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0;n=l;l=l+1152|0;k=n+128|0;f=n;d=f;e=d+128|0;do{a[d>>0]=0;d=d+1|0}while((d|0)<(e|0));bg(c,20);d=0;j=0;do{bg(c,22);am(b)|0;h=Ul(b)|0;Xj(c,h);h=h&65535;j=(h<<1)+j|0;Pl(b)|0;Wj(c,0);Wj(c,Pl(b)|0);am(b)|0;i=Ul(b)|0;Xj(c,(i&65535)>2?h-(i&65535)&65535:0);Xj(c,(i&65535)<3?1:i);Ul(b)|0;d=d+1|0}while((d|0)!=15);d=k;e=d+29|0;do{a[d>>0]=0;d=d+1|0}while((d|0)<(e|0));a[k+29>>0]=1;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;ko(k,30,1,c)|0;dm(b,243,0)|0;Wj(c,Pl(b)|0);Wj(c,127);d=0;do{a[f+d>>0]=((Ul(b)|0)&65535)>>>10;d=d+1|0}while((d|0)!=100);ko(f,128,1,c)|0;d=0;e=0;do{i=a[f+d>>0]|0;e=(i&255)>(e&255)?i:e;d=d+1|0}while((d|0)!=128);Yj(c,1294879534);dm(b,444,0)|0;f=e&255;g=0;while(1){gp(k|0,0,1024)|0;cm(k,1024,1,b)|0;h=0;do{e=k+(h<<2|2)|0;i=a[e>>0]|0;switch(i&15){case 4:case 3:{d=9;m=14;break}case 5:{d=6;m=14;break}case 6:{d=8;m=14;break}case 7:{d=7;m=14;break}case 8:{d=7;m=14;break}default:{}}if((m|0)==14){m=0;a[e>>0]=(i&255)+d}h=h+1|0}while((h|0)!=256);ko(k,1024,1,c)|0;if((g|0)==(f|0))break;else g=g+1|0}ag(c,b,j);l=n;return 0}function ug(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;if((e|0)<378){c=378-e|0;return c|0}if((a[b+248>>0]|0)<1){c=-1;return c|0}if((a[b+249>>0]|0)==127){h=0;j=0}else{c=-1;return c|0}while(1){f=b+(h<<3)|0;if((d[f+2>>0]|0)>15){t=-1;l=26;break}if((d[f+3>>0]|0)>64){t=-1;l=26;break}l=Rj(a[f>>0]|0,a[f+1>>0]|0)|0;i=(l&65535)<<1;g=f+4|0;g=Rj(a[g>>0]|0,a[g+1>>0]|0)|0;f=f+6|0;f=Rj(a[f>>0]|0,a[f+1>>0]|0)|0;if((g|l|f)<<16>>16<0){t=-1;l=26;break}if((f&65535)>1){if((f&65535)+(g&65535)<<1>>>0>i>>>0){t=-1;l=26;break}}else if(g<<16>>16){t=-1;l=26;break}j=i+j|0;h=h+1|0;if((h|0)>=31){l=12;break}}if((l|0)==12){if((j|0)<5){c=-1;return c|0}g=b+250|0;h=0;k=0;do{f=a[g+h>>0]|0;if(f<<24>>24<0){t=-1;l=26;break}j=f&255;k=(j|0)>(k|0)?j:k;h=h+1|0}while((h|0)<128);if((l|0)==26)return t|0;f=k<<10|379;if((f|0)>(e|0)){c=f-e|0;return c|0}b=b+378|0;e=0;f=0;a:while(1){i=0;b:while(1){j=b+f|0;g=d[j>>0]|0;switch((g&192)<<24>>24){case -64:{l=23;break b}case 0:{if((g&12)>>>0>3){t=-1;l=26;break a}else{h=f+4|0;g=i}break}case -128:{if(a[j+1>>0]|0){t=-1;l=26;break a}h=f+4|0;g=(d[j+3>>0]|0)+i|0;break}default:{h=f;g=i}}i=g+1|0;if((i|0)>=64){p=h;m=0;break}else f=h}if((l|0)==23){l=0;if(!(a[j+1>>0]|0)){p=f+4|0;m=0}else{t=-1;l=26;break}}c:while(1){h=b+p|0;f=d[h>>0]|0;switch((f&192)<<24>>24){case -64:{l=28;break c}case 0:{if((f&12)>>>0>3){t=-1;l=26;break a}else{g=p+4|0;f=m}break}case -128:{if(a[h+1>>0]|0){t=-1;l=26;break a}g=p+4|0;f=(d[h+3>>0]|0)+m|0;break}default:{g=p;f=m}}m=f+1|0;if((m|0)>=64){q=g;n=0;break}else p=g}if((l|0)==28){l=0;if(!(a[h+1>>0]|0)){q=p+4|0;n=0}else{t=-1;l=26;break}}d:while(1){h=b+q|0;f=d[h>>0]|0;switch((f&192)<<24>>24){case -64:{l=34;break d}case 0:{if((f&12)>>>0>3){t=-1;l=26;break a}else{g=q+4|0;f=n}break}case -128:{if(a[h+1>>0]|0){t=-1;l=26;break a}g=q+4|0;f=(d[h+3>>0]|0)+n|0;break}default:{g=q;f=n}}n=f+1|0;if((n|0)>=64){r=g;o=0;break}else q=g}if((l|0)==34){l=0;if(!(a[h+1>>0]|0)){r=q+4|0;o=0}else{t=-1;l=26;break}}e:while(1){h=b+r|0;f=d[h>>0]|0;switch((f&192)<<24>>24){case -64:{l=40;break e}case 0:{if((f&12)>>>0>3){t=-1;l=26;break a}else{g=r+4|0;f=o}break}case -128:{if(a[h+1>>0]|0){t=-1;l=26;break a}g=r+4|0;f=(d[h+3>>0]|0)+o|0;break}default:{g=r;f=o}}o=f+1|0;if((o|0)>=64){s=g;break}else r=g}if((l|0)==40){l=0;if(!(a[h+1>>0]|0))s=r+4|0;else{t=-1;l=26;break}}if((e|0)<(k|0)){e=e+1|0;f=s}else{l=25;break}}if((l|0)==25){eg(0,c,0);c=0;return c|0}else if((l|0)==26)return t|0}else if((l|0)==26)return t|0;return 0}function vg(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+3072|0;p=t+2048|0;r=t;gp(r|0,0,2048)|0;bg(d,20);e=0;q=0;do{bg(d,22);o=Ul(b)|0;Xj(d,o);q=((o&65535)<<1)+q|0;Wj(d,Pl(b)|0);Wj(d,Pl(b)|0);Xj(d,Ul(b)|0);o=Ul(b)|0;Xj(d,o<<16>>16?o:1);e=e+1|0}while((e|0)!=31);Wj(d,Pl(b)|0);Wj(d,Pl(b)|0);e=0;f=0;do{o=Pl(b)|0;Wj(d,o);f=(o&255)>(f&255)?o:f;e=e+1|0}while((e|0)!=128);o=f+1<<24>>24;Yj(d,1294879534);k=o&255;a:do if(o<<24>>24){m=0;b:while(1){gp(p|0,0,1024)|0;o=m<<2;n=0;do{e=em(b)|0;if((e|0)<0){e=-1;s=25;break b}c[r+(n+o<<2)>>2]=e;j=n<<2;e=0;c:do{f=(e<<4)+j|0;g=Pl(b)|0;switch(g<<24>>24){case -128:{f=16;e=(Yl(b)|0)+e|0;break}case -64:{f=Yl(b)|0;i=em(b)|0;if((f|0)>2047|(i|0)<0)f=1;else{dm(b,c[r+(f>>2<<2)>>2]|0,0)|0;f=0;do{g=(f<<4)+j|0;h=Pl(b)|0;if(h<<24>>24==-128)f=(Yl(b)|0)+f|0;else{a[p+g>>0]=h;a[p+(g|1)>>0]=Pl(b)|0;a[p+(g|2)>>0]=Pl(b)|0;a[p+(g|3)>>0]=Pl(b)|0}f=f+1|0}while((f|0)<64);dm(b,i,0)|0;f=16;e=e+100|0}break}default:{a[p+f>>0]=g;a[p+(f|1)>>0]=Pl(b)|0;a[p+(f|2)>>0]=Pl(b)|0;a[p+(f|3)>>0]=Pl(b)|0;f=0}}switch(f&31){case 16:case 0:break;default:{s=21;break c}}e=e+1|0}while((e|0)<64);if((s|0)==21?(s=0,f|0):0){e=-1;s=25;break b}n=n+1|0}while((n|0)<4);ko(p,1024,1,d)|0;m=m+1|0;if((m|0)>=(k|0))break a}if((s|0)==25){l=t;return e|0}}while(0);ag(d,b,q);s=0;l=t;return s|0}function wg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;if((e|0)<1536){j=1536-e|0;return j|0}if((a[b>>0]|0)!=77){j=-1;return j|0}if((a[b+1>>0]|0)!=46){j=-1;return j|0}if((a[b+15>>0]|0)!=97){j=-1;return j|0}if((d[b+54>>0]|0)>64){j=-1;return j|0}if((d[b+86>>0]|0)>64){j=-1;return j|0}if((d[b+118>>0]|0)>64){j=-1;return j|0}if((d[b+150>>0]|0)>64){j=-1;return j|0}if((d[b+182>>0]|0)>64){j=-1;return j|0}if((d[b+214>>0]|0)>64){j=-1;return j|0}if((d[b+246>>0]|0)>64){j=-1;return j|0}if((d[b+278>>0]|0)>64){j=-1;return j|0}if((d[b+310>>0]|0)>64){j=-1;return j|0}if((d[b+342>>0]|0)>64){j=-1;return j|0}if((d[b+374>>0]|0)>64){j=-1;return j|0}if((d[b+406>>0]|0)>64){j=-1;return j|0}if((d[b+438>>0]|0)>64){j=-1;return j|0}if((d[b+470>>0]|0)>64){j=-1;return j|0}if((d[b+502>>0]|0)>64){j=-1;return j|0}else{f=0;g=0}while(1){i=a[b+(f+512)>>0]|0;h=i&255;h=(h|0)>(g|0)?h:g;if(i<<24>>24==-1)break;f=f+1|0;if((f|0)<1024)g=h;else{g=h;break}}if((f|0)==1024|(g|0)==0){j=-1;return j|0}f=(g*192|0)+1725|0;if((f|0)>(e|0)){j=f-e|0;return j|0}f=b+1536|0;e=0;a:while(1){h=f+(e*192|0)|0;i=0;do{if((d[h+(i*3|0)>>0]|0)>36){f=-1;j=19;break a}i=i+1|0}while((i|0)<64);if((e|0)<(g|0))e=e+1|0;else break}if((j|0)==19)return f|0;eg(b+2|0,c,13);j=0;return j|0}function xg(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=l;l=l+2944|0;u=v+1920|0;q=v+1792|0;p=v+1280|0;r=v+768|0;t=v;e=q;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));gp(p|0,0,512)|0;gp(r|0,0,512)|0;dm(b,2,0)|0;ag(c,b,13);bg(c,7);dm(b,32,0)|0;e=0;s=0;do{bg(c,22);dm(b,20,1)|0;n=Ul(b)|0;m=n&65535;Xj(c,(n&65535)>>>1);s=m+s|0;Wj(c,0);Wj(c,Pl(b)|0);Pl(b)|0;n=Ul(b)|0;Xj(c,(n&65535)>>>1);Xj(c,n<<16>>16==0?1:((m-(n&65535)|0)/2|0)&65535);dm(b,6,1)|0;e=e+1|0}while((e|0)!=15);e=u;f=e+29|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));a[u+29>>0]=1;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;ko(u,30,1,c)|0;dm(b,512,0)|0;e=0;f=0;k=0;while(1){g=p+(e<<2)|0;cm(g,1,1,b)|0;h=p+(e<<2)+1|0;cm(h,1,1,b)|0;i=p+(e<<2)+2|0;cm(i,1,1,b)|0;j=p+(e<<2)+3|0;cm(j,1,1,b)|0;g=a[g>>0]|0;if(g<<24>>24==-1){n=e;f=e&255;break}g=(g&255)>(k&255)?g:k;n=a[h>>0]|0;g=(n&255)>(g&255)?n:g;n=a[i>>0]|0;g=(n&255)>(g&255)?n:g;n=a[j>>0]|0;g=(n&255)>(g&255)?n:g;e=e+1|0;f=f+1<<24>>24;if((e&255)<<24>>24>-1)k=g;else{n=e;k=g;break}}Wj(c,f);Wj(c,127);if((n|0)>0){e=0;m=0;do{do if(m){if((m|0)>0){g=a[p+(m<<2)>>0]|0;h=p+(m<<2)+1|0;i=p+(m<<2)+2|0;j=p+(m<<2)+3|0;f=0;while(1){if((((a[p+(f<<2)>>0]|0)==g<<24>>24?(a[p+(f<<2)+1>>0]|0)==(a[h>>0]|0):0)?(a[p+(f<<2)+2>>0]|0)==(a[i>>0]|0):0)?(a[p+(f<<2)+3>>0]|0)==(a[j>>0]|0):0){o=45;break}f=f+1|0;if((f|0)>=(m|0)){o=13;break}}if((o|0)==13){f=q+m|0;o=14;break}else if((o|0)==45){o=0;a[q+m>>0]=a[q+f>>0]|0;break}}}else{f=q;o=14}while(0);if((o|0)==14){o=0;a[f>>0]=e;e=e+1<<24>>24}m=m+1|0}while((m|0)!=(n|0));g=0;i=0;f=1;do{a:do if(!i)o=22;else{if((i|0)<=0)if(!(f<<24>>24)){f=0;break}else{f=1;o=22;break}f=a[q+i>>0]|0;h=0;while(1){if(f<<24>>24==(a[q+h>>0]|0)){f=0;break a}h=h+1|0;if((h|0)>=(i|0)){f=1;o=22;break}}}while(0);if((o|0)==22){o=0;m=g&255;a[r+(m<<2)>>0]=a[p+(i<<2)>>0]|0;a[r+(m<<2)+1>>0]=a[p+(i<<2)+1>>0]|0;a[r+(m<<2)+2>>0]=a[p+(i<<2)+2>>0]|0;a[r+(m<<2)+3>>0]=a[p+(i<<2)+3>>0]|0;g=g+1<<24>>24}i=i+1|0}while((i|0)!=(n|0))}else e=0;ko(q,128,1,c)|0;Yj(c,1294879534);p=e&255;b:do if(e<<24>>24){i=t+192|0;j=t+384|0;m=t+576|0;n=0;c:while(1){gp(u|0,0,1024)|0;gp(t|0,0,768)|0;dm(b,((d[r+(n<<2)>>0]|0)*192|0)+1536|0,0)|0;cm(t,192,1,b)|0;dm(b,((d[r+(n<<2)+1>>0]|0)*192|0)+1536|0,0)|0;cm(i,192,1,b)|0;dm(b,((d[r+(n<<2)+2>>0]|0)*192|0)+1536|0,0)|0;cm(j,192,1,b)|0;dm(b,((d[r+(n<<2)+3>>0]|0)*192|0)+1536|0,0)|0;cm(m,192,1,b)|0;o=0;do{g=o*3|0;h=u+(o<<4)|0;f=t+g|0;e=a[f>>0]|0;if((e&255)>36){e=-1;o=33;break c}e=35367+((e&255)<<1)|0;e=d[e>>0]|d[e+1>>0]<<8;a[h>>0]=e;a[h+1>>0]=e>>8;e=f+1|0;f=d[e>>0]|0;if((f&15|0)==13)a[e>>0]=f+253;f=h+2|0;e=d[e>>0]|d[e+1>>0]<<8;a[f>>0]=e;a[f+1>>0]=e>>8;f=t+192+g|0;e=a[f>>0]|0;if((e&255)>36){e=-1;o=33;break c}q=h+4|0;e=35367+((e&255)<<1)|0;e=d[e>>0]|d[e+1>>0]<<8;a[q>>0]=e;a[q+1>>0]=e>>8;e=f+1|0;f=d[e>>0]|0;if((f&15|0)==13)a[e>>0]=f+253;f=h+6|0;e=d[e>>0]|d[e+1>>0]<<8;a[f>>0]=e;a[f+1>>0]=e>>8;f=t+384+g|0;e=a[f>>0]|0;if((e&255)>36){e=-1;o=33;break c}q=h+8|0;e=35367+((e&255)<<1)|0;e=d[e>>0]|d[e+1>>0]<<8;a[q>>0]=e;a[q+1>>0]=e>>8;e=f+1|0;f=d[e>>0]|0;if((f&15|0)==13)a[e>>0]=f+253;f=h+10|0;e=d[e>>0]|d[e+1>>0]<<8;a[f>>0]=e;a[f+1>>0]=e>>8;f=t+576+g|0;e=a[f>>0]|0;if((e&255)>36){e=-1;o=33;break c}q=h+12|0;e=35367+((e&255)<<1)|0;e=d[e>>0]|d[e+1>>0]<<8;a[q>>0]=e;a[q+1>>0]=e>>8;e=f+1|0;f=d[e>>0]|0;if((f&15|0)==13)a[e>>0]=f+253;q=h+14|0;h=d[e>>0]|d[e+1>>0]<<8;a[q>>0]=h;a[q+1>>0]=h>>8;o=o+1|0}while((o|0)<64);ko(u,1024,1,c)|0;n=n+1|0;if((n|0)>=(p|0))break b}if((o|0)==33){l=v;return e|0}}while(0);dm(b,((k&255)*192|0)+1728|0,0)|0;ag(c,b,s);u=0;l=v;return u|0}function yg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;if((Vj(b)|0)==1414679345)e=0;else{c=-1;return c|0}do{if((d[b+(e<<3|6)>>0]|0)>15){h=-1;i=11;break}e=e+1|0}while((e|0)<31);if((i|0)==11)return h|0;if((a[b+252>>0]|0)<1){c=-1;return c|0}else{f=0;g=0}do{j=a[b+(f+254)>>0]|0;e=j&255;if(j<<24>>24<0){h=-1;i=11;break}g=(e|0)>(g|0)?e:g;f=f+1|0}while((f|0)<128);if((i|0)==11)return h|0;f=(g<<8)+256|0;a:do if((f|0)>0){e=0;while(1){if((d[b+((e<<2)+382)>>0]|0)>=20){h=-1;break}e=e+1|0;if((e|0)>=(f|0))break a}return h|0}while(0);eg(0,c,0);j=0;return j|0}function zg(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;bg(b,20);if((am(a)|0)==1414679345){c=0;e=0}else{dm(a,-4,1)|0;c=0;e=0}do{bg(b,22);d=Ul(a)|0;Xj(b,d);e=((d&65535)<<1)+e|0;Wj(b,Pl(a)|0);Wj(b,Pl(a)|0);Xj(b,Ul(a)|0);Xj(b,Ul(a)|0);c=c+1|0}while((c|0)!=31);Wj(b,Pl(a)|0);Wj(b,Pl(a)|0);c=0;d=0;do{f=Pl(a)|0;Wj(b,f);d=(f&255)>(d&255)?f:d;c=c+1|0}while((c|0)!=128);c=d+1<<24>>24;Yj(b,1294879534);if(!(am(a)|0)){f=c&255;f=f<<10;ag(b,a,f);ag(b,a,e);return 0}dm(a,-4,1)|0;f=c&255;f=f<<10;ag(b,a,f);ag(b,a,e);return 0}function Ag(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;l=0;i=0;while(1){o=b+(i<<3)|0;f=Rj(a[o>>0]|0,a[o+1>>0]|0)|0;j=(f&65535)<<1;g=o+4|0;g=Rj(a[g>>0]|0,a[g+1>>0]|0)|0;h=o+6|0;h=Rj(a[h>>0]|0,a[h+1>>0]|0)|0;k=(h&65535)<<1;l=j+l|0;if((d[o+2>>0]|0)>15){n=-1;k=22;break}if(k>>>0>(j+2|0)>>>0|(h<<16>>16!=1?(k+((g&65535)<<1)|0)>>>0>j>>>0:0)){n=-1;k=22;break}if(g<<16>>16!=0&(h&65535)<2){n=-1;k=22;break}i=i+1|0;if(!(f<<16>>16==0|h<<16>>16!=0)){n=-1;k=22;break}if((i|0)>=31){k=7;break}}if((k|0)==7){if((l|0)<3){o=-1;return o|0}f=a[b+248>>0]|0;if(f<<24>>24<1){o=-1;return o|0}f=(f&255)+3|0;h=0;i=0;do{o=a[b+(h+250)>>0]|0;g=o&255;if(o<<24>>24<0|(h|0)>(f|0)&o<<24>>24!=0){n=-1;k=22;break}i=(g|0)>(i|0)?g:i;h=h+1|0}while((h|0)<128);if((k|0)==22)return n|0;j=(i<<8)+256|0;f=j<<2|378;if((f|0)>(e|0)){o=f-e|0;return o|0}a:do if((j|0)>0){h=b+378|0;i=0;while(1){g=h+(i<<2)|0;f=a[g>>0]|0;if(!((f&255)<20|f<<24>>24==74)){n=-1;k=22;break}i=i+1|0;if((((Rj(f,a[g+1>>0]|0)|0)&4095)+-1&65535)<112){n=-1;k=22;break}if((i|0)>=(j|0)){m=0;break a}}if((k|0)==22)return n|0}else m=0;while(0);do{l=b+(m<<3)|0;o=((Rj(a[l>>0]|0,a[l+1>>0]|0)|0)&65535)<<1;e=l+4|0;e=(Rj(a[e>>0]|0,a[e+1>>0]|0)|0)&65535;l=l+6|0;m=m+1|0;if(((Rj(a[l>>0]|0,a[l+1>>0]|0)|0)&65535)+e<<1>>>0>(o+2|0)>>>0){n=-1;k=22;break}}while((m|0)<31);if((k|0)==22)return n|0;eg(0,c,0);o=0;return o|0}else if((k|0)==22)return n|0;return 0}function Bg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if((e|0)<10){c=10-e|0;return c|0}f=Rj(a[b+2>>0]|0,a[b+3>>0]|0)|0;m=f&65535;if(!(f<<16>>16)){c=-1;return c|0}if((f&65535)>255|(m&1|0)!=0){c=-1;return c|0}f=d[b+1>>0]|0;if((f&15|0)!=12){c=-1;return c|0}j=(d[b>>0]|0)<<4&240|f>>>4;if((j+-1|0)>>>0>30){c=-1;return c|0}i=j<<4;f=i|15;if((f|0)>(e|0)){c=f-e|0;return c|0}else f=0;while(1){if((d[b+(f<<4|15)>>0]|0)>64){o=-1;n=26;break}f=f+1|0;if((f|0)>=(j|0)){k=0;l=0;break}}if((n|0)==26)return o|0;while(1){g=b+(k<<4)|0;n=g+12|0;n=Rj(a[n>>0]|0,a[n+1>>0]|0)|0;h=(n&65535)<<1;f=g+20|0;f=Rj(a[f>>0]|0,a[f+1>>0]|0)|0;g=g+22|0;g=Rj(a[g>>0]|0,a[g+1>>0]|0)|0;if((f|n)<<16>>16<0){o=-1;n=26;break}if(f<<16>>16==0&g<<16>>16!=0|(((f&65535)<<1)+(g&65535)|0)>>>0>(h+2|0)>>>0){o=-1;n=26;break}l=h+l|0;k=k+1|0;if((k|0)>=(j|0)){n=14;break}}if((n|0)==14){if((l|0)<5){c=-1;return c|0}j=i|12;f=m+2+j|0;if((f|0)>(e|0)){c=f-e|0;return c|0}f=b+j|0;h=0;i=0;do{l=f+h|0;l=Rj(a[l>>0]|0,a[l+1>>0]|0)|0;g=l&65535;if((l&65535)>1023|(g&7|0)!=0){o=-1;n=26;break}i=(g|0)>(i|0)?g:i;h=h+2|0}while((h|0)<(m|0));if((n|0)==26)return o|0;g=m+8+j+i|0;m=Rj(a[b+6>>0]|0,a[b+7>>0]|0)|0;h=m&65535;if(!((m&65535)>191&(h&63|0)==0)){c=-1;return c|0}f=h+g|0;if((f|0)>(e|0)){c=f-e|0;return c|0}else f=0;do{if((d[b+(f+g)>>0]|0)>73){o=-1;n=26;break}f=f+3|0}while((f|0)<(h|0));if((n|0)==26)return o|0;eg(0,c,0);c=0;return c|0}else if((n|0)==26)return o|0;return 0}function Cg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;v=l;l=l+3200|0;s=v+2176|0;k=v+2048|0;t=v;g=k;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));gp(t|0,0,2048)|0;g=Pl(b)|0;g=(g&255)<<4&240|((Pl(b)|0)&255)>>>4;bg(e,20);r=Ul(b)|0;j=(r&65535)>>>1;if((r&65535)>257){u=-1;l=v;return u|0}Ul(b)|0;Ul(b)|0;if(g){f=0;i=0;do{am(b)|0;bg(e,22);r=Ul(b)|0;Xj(e,r);i=((r&65535)<<1)+i|0;Wj(e,Pl(b)|0);Wj(e,Pl(b)|0);am(b)|0;r=Ul(b)|0;Xj(e,((Ul(b)|0)&65535)>>>1);Xj(e,r);f=f+1|0}while((f|0)<(g|0));g=s;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[s+29>>0]=1;if((f|0)<31){g=i;u=6}else g=i}else{g=s;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[s+29>>0]=1;f=0;g=0;u=6}if((u|0)==6)do{ko(s,30,1,e)|0;f=f+1|0}while((f|0)!=31);Wj(e,j&255);Wj(e,127);dm(b,2,1)|0;dm(b,2,1)|0;if(!j)r=0;else{h=0;f=0;do{r=((Ul(b)|0)&65535)>>>3;a[k+h>>0]=r;r=r&255;f=(r|0)>(f|0)?r:f;h=h+1|0}while((h|0)!=(j|0));r=f}ko(k,128,1,e)|0;Yj(e,1294879534);f=0;q=0;while(1){p=(Ul(b)|0)&65535;c[t+(f<<4)>>2]=p;p=(p|0)>(q|0)?p:q;o=(Ul(b)|0)&65535;c[t+(f<<4)+4>>2]=o;p=(o|0)>(p|0)?o:p;o=(Ul(b)|0)&65535;c[t+(f<<4)+8>>2]=o;p=(o|0)>(p|0)?o:p;o=(Ul(b)|0)&65535;c[t+(f<<4)+12>>2]=o;q=(o|0)>(p|0)?o:p;if((f|0)>=(r|0))break;else f=f+1|0}k=em(b)|0;m=0;a:while(1){gp(s|0,0,1024)|0;n=0;do{dm(b,(c[t+(m<<4)+(3-n<<2)>>2]|0)+k|0,0)|0;p=n<<2;o=0;do{j=(o<<4)+p|0;i=Pl(b)|0;f=Pl(b)|0;h=Pl(b)|0;if((i&255)>73|(gm(b)|0)!=0){f=-1;u=25;break a}w=(i&255)>>>1&255;a[s+j>>0]=d[35367+(w<<1)>>0]|0|(i&255)<<4&16;a[s+(j|1)>>0]=a[35367+(w<<1)+1>>0]|0;i=f&255;switch(f&15){case 8:{f=i&240;break}case 7:{f=(i&240|10)&255;u=19;break}case 5:case 6:{u=19;break}case 11:{h=((h&255)+4|0)>>>1&255;break}default:{}}if((u|0)==19){u=0;w=h&255;h=((h&255)>128?256-w|0:w<<4)&255}a[s+(j|2)>>0]=f;a[s+(j|3)>>0]=h;o=o+1|0}while((o|0)<64);n=n+1|0}while((n|0)<4);ko(s,1024,1,e)|0;if((m|0)<(r|0))m=m+1|0;else break}if((u|0)==25){l=v;return f|0}dm(b,q+192+k|0,0)|0;ag(e,b,g);w=0;l=v;return w|0} +function Dg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if((e|0)<10){c=10-e|0;return c|0}f=Rj(a[b+2>>0]|0,a[b+3>>0]|0)|0;m=f&65535;if(!(f<<16>>16)){c=-1;return c|0}if((f&65535)>255|(m&1|0)!=0){c=-1;return c|0}f=d[b+1>>0]|0;if((f&15|0)!=12){c=-1;return c|0}n=d[b>>0]<<4&240|f>>>4;if((n+-1|0)>>>0>30){c=-1;return c|0}i=n<<4;f=i|15;if((f|0)>(e|0)){c=f-e|0;return c|0}else f=0;while(1){if((d[b+(f<<4|15)>>0]|0)>64){o=-1;l=30;break}f=f+1|0;if((f|0)>=(n|0)){j=0;k=0;break}}if((l|0)==30)return o|0;while(1){g=b+(j<<4)|0;l=g+12|0;l=Rj(a[l>>0]|0,a[l+1>>0]|0)|0;h=(l&65535)<<1;f=g+20|0;f=Rj(a[f>>0]|0,a[f+1>>0]|0)|0;g=g+22|0;g=Rj(a[g>>0]|0,a[g+1>>0]|0)|0;if((f|l|g)<<16>>16<0){o=-1;l=30;break}if(f<<16>>16==0&g<<16>>16!=0|(g&65535)+(f&65535)<<1>>>0>(h+2|0)>>>0){o=-1;l=30;break}k=h+k|0;j=j+1|0;if((j|0)>=(n|0)){l=14;break}}if((l|0)==14){if((k|0)<5){c=-1;return c|0}j=i|12;f=m+2+j|0;if((f|0)>(e|0)){c=f-e|0;return c|0}f=b+j|0;h=0;i=0;do{k=f+h|0;k=Rj(a[k>>0]|0,a[k+1>>0]|0)|0;g=k&65535;if((k&65535)>1024|(g&7|0)!=0){o=-1;l=30;break}i=(g|0)>(i|0)?g:i;h=h+2|0}while((h|0)<(m|0));if((l|0)==30)return o|0;f=m+8+j+i|0;m=Rj(a[b+6>>0]|0,a[b+7>>0]|0)|0;k=m&65535;if(!((m&65535)>191&(k&63|0)==0)){c=-1;return c|0}g=f+16+k|0;if((g|0)>(e|0)){c=g-e|0;return c|0}g=b+f|0;j=0;while(1){h=g+j|0;f=a[h>>0]|0;if((f&255)>73){o=-1;l=30;break}i=d[h+1>>0]|0;if((i>>>4|(f&255)<<4&16)>>>0>n>>>0){o=-1;l=30;break}if((i&15|0)==0?a[h+2>>0]|0:0){o=-1;l=30;break}j=j+3|0;if((j|0)>=(k|0)){l=29;break}}if((l|0)==29){eg(0,c,0);c=0;return c|0}else if((l|0)==30)return o|0}else if((l|0)==30)return o|0;return 0}function Eg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;v=l;l=l+3200|0;s=v+2176|0;k=v+2048|0;t=v;g=k;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));gp(t|0,0,2048)|0;g=Pl(b)|0;g=(g&255)<<4&240|((Pl(b)|0)&255)>>>4;bg(e,20);r=Ul(b)|0;j=(r&65535)>>>1;if((r&65535)>257){u=-1;l=v;return u|0}Ul(b)|0;Ul(b)|0;if(g){f=0;i=0;do{am(b)|0;bg(e,22);r=Ul(b)|0;Xj(e,r);i=((r&65535)<<1)+i|0;Wj(e,Pl(b)|0);Wj(e,Pl(b)|0);am(b)|0;r=Ul(b)|0;Xj(e,Ul(b)|0);Xj(e,r);f=f+1|0}while((f|0)<(g|0));g=s;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[s+29>>0]=1;if((f|0)<31){g=i;u=6}else g=i}else{g=s;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[s+29>>0]=1;f=0;g=0;u=6}if((u|0)==6)do{ko(s,30,1,e)|0;f=f+1|0}while((f|0)!=31);Wj(e,j&255);Wj(e,127);dm(b,2,1)|0;dm(b,2,1)|0;if(!j)r=0;else{h=0;f=0;do{r=((Ul(b)|0)&65535)>>>3;a[k+h>>0]=r;r=r&255;f=(r|0)>(f|0)?r:f;h=h+1|0}while((h|0)!=(j|0));r=f}ko(k,128,1,e)|0;Yj(e,1294879534);f=0;q=0;while(1){p=(Ul(b)|0)&65535;c[t+(f<<4)>>2]=p;p=(p|0)>(q|0)?p:q;o=(Ul(b)|0)&65535;c[t+(f<<4)+4>>2]=o;p=(o|0)>(p|0)?o:p;o=(Ul(b)|0)&65535;c[t+(f<<4)+8>>2]=o;p=(o|0)>(p|0)?o:p;o=(Ul(b)|0)&65535;c[t+(f<<4)+12>>2]=o;q=(o|0)>(p|0)?o:p;if((f|0)>=(r|0))break;else f=f+1|0}k=em(b)|0;m=0;a:while(1){gp(s|0,0,1024)|0;n=0;do{dm(b,(c[t+(m<<4)+(3-n<<2)>>2]|0)+k|0,0)|0;p=n<<2;o=0;do{j=(o<<4)+p|0;i=Pl(b)|0;f=Pl(b)|0;h=Pl(b)|0;if((i&255)>73|(gm(b)|0)!=0){f=-1;u=26;break a}w=(i&255)>>>1&255;a[s+j>>0]=d[35367+(w<<1)>>0]|0|(i&255)<<4&16;a[s+(j|1)>>0]=a[35367+(w<<1)+1>>0]|0;i=f&255;switch(f&15){case 8:{f=i&240;break}case 7:{f=(i&240|10)&255;u=19;break}case 5:case 6:{u=19;break}case 14:{h=h+-1<<24>>24;break}case 11:{h=((h&255)+4|0)>>>1&255;break}default:{}}if((u|0)==19){u=0;w=h&255;h=((h&255)>128?256-w|0:w<<4)&255}a[s+(j|2)>>0]=f;a[s+(j|3)>>0]=h;o=o+1|0}while((o|0)<64);n=n+1|0}while((n|0)<4);ko(s,1024,1,e)|0;if((m|0)<(r|0))m=m+1|0;else break}if((u|0)==26){l=v;return f|0}dm(b,q+192+k|0,0)|0;ag(e,b,g);w=0;l=v;return w|0}function Fg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if((e|0)<10){c=10-e|0;return c|0}f=Rj(a[b+2>>0]|0,a[b+3>>0]|0)|0;m=f&65535;if(!(f<<16>>16)){c=-1;return c|0}if((f&65535)>255|(m&1|0)!=0){c=-1;return c|0}f=d[b+1>>0]|0;if((f&15|0)!=12){c=-1;return c|0}n=d[b>>0]<<4&240|f>>>4;if((n+-1|0)>>>0>30){c=-1;return c|0}i=n<<4;f=i|15;if((f|0)>(e|0)){c=f-e|0;return c|0}else f=0;while(1){if((d[b+(f<<4|9)>>0]|0)>64){o=-1;l=34;break}f=f+1|0;if((f|0)>=(n|0)){j=0;k=0;break}}if((l|0)==34)return o|0;while(1){g=b+(j<<4)|0;l=g+14|0;l=Rj(a[l>>0]|0,a[l+1>>0]|0)|0;h=(l&65535)<<1;f=g+20|0;f=Rj(a[f>>0]|0,a[f+1>>0]|0)|0;g=g+22|0;g=Rj(a[g>>0]|0,a[g+1>>0]|0)|0;if((f|l|g)<<16>>16<0){o=-1;l=34;break}if(f<<16>>16==0&g<<16>>16!=0|(g&65535)+(f&65535)<<1>>>0>(h+2|0)>>>0){o=-1;l=34;break}k=h+k|0;j=j+1|0;if((j|0)>=(n|0)){l=14;break}}if((l|0)==14){if((k|0)<5){c=-1;return c|0}j=i|12;f=m+2+j|0;if((f|0)>(e|0)){c=f-e|0;return c|0}f=b+j|0;h=0;i=0;do{k=f+h|0;k=Rj(a[k>>0]|0,a[k+1>>0]|0)|0;g=k&65535;if((k&65535)>1024|(g&7|0)!=0){o=-1;l=34;break}i=(g|0)>(i|0)?g:i;h=h+2|0}while((h|0)<(m|0));if((l|0)==34)return o|0;f=m+8+j+i|0;l=Rj(a[b+6>>0]|0,a[b+7>>0]|0)|0;m=l&65535;if((l&65535)<64){c=-1;return c|0}g=f+2+m|0;if((g|0)>(e|0)){c=g-e|0;return c|0}k=b+f|0;l=m+-3|0;f=0;a:while(1){h=k+f|0;g=a[h>>0]|0;if(g<<24>>24>-1){if((g&255)>73){o=-1;l=34;break}j=a[h+1>>0]|0;i=j&255;switch(j&15){case 10:{o=-1;l=34;break a}case 13:{if((d[h+2>>0]|0)>64){o=-1;l=34;break a}break}default:{}}if(((g&255)<<4&16|i>>>4)>>>0>n>>>0){o=-1;l=34;break}if((g|j)<<24>>24==0?(f|0)<(l|0)&(a[h+2>>0]|0)==0:0){o=-1;l=34;break}f=f+2|0}f=f+1|0;if((f|0)>=(m|0)){l=33;break}}if((l|0)==33){eg(0,c,0);c=0;return c|0}else if((l|0)==34)return o|0}else if((l|0)==34)return o|0;return 0}function Gg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=l;l=l+3200|0;t=w+2176|0;p=w+2048|0;u=w;h=p;i=h+128|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));gp(u|0,0,2048)|0;n=Pl(b)|0;n=(n&255)<<4&240|((Pl(b)|0)&255)>>>4;bg(e,20);s=Ul(b)|0;o=(s&65535)>>>1;if((s&65535)>257){v=-1;l=w;return v|0}Ul(b)|0;Ul(b)|0;if(n){h=t+6|0;m=t+1|0;j=t+14|0;k=t+12|0;i=t+7|0;f=0;g=0;do{cm(t,1,16,b)|0;bg(e,22);s=Rj(a[h>>0]|0,a[i>>0]|0)|0;Xj(e,s);g=((s&65535)<<1)+g|0;Wj(e,a[t>>0]|0);Wj(e,a[m>>0]|0);ko(j,2,1,e)|0;ko(k,2,1,e)|0;f=f+1|0}while((f|0)<(n|0));h=t;i=h+29|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));a[t+29>>0]=1;if((f|0)<31)v=7}else{h=t;i=h+29|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));a[t+29>>0]=1;f=0;g=0;v=7}if((v|0)==7)do{ko(t,30,1,e)|0;f=f+1|0}while((f|0)!=31);Wj(e,o&255);Wj(e,127);dm(b,2,1)|0;dm(b,2,1)|0;if(!o)s=0;else{h=0;f=0;do{s=((Ul(b)|0)&65535)>>>3;a[p+h>>0]=s;s=s&255;f=(s|0)>(f|0)?s:f;h=h+1|0}while((h|0)!=(o|0));s=f}ko(p,128,1,e)|0;Yj(e,1294879534);f=0;while(1){c[u+(f<<4)>>2]=(Ul(b)|0)&65535;c[u+(f<<4)+4>>2]=(Ul(b)|0)&65535;c[u+(f<<4)+8>>2]=(Ul(b)|0)&65535;c[u+(f<<4)+12>>2]=(Ul(b)|0)&65535;if((f|0)<(s|0))f=f+1|0;else break}p=em(b)|0;q=0;f=0;a:while(1){gp(t|0,0,1024)|0;r=0;do{dm(b,(c[u+(q<<4)+(3-r<<2)>>2]|0)+p|0,0)|0;o=r<<2;h=0;do{n=(h<<4)+o|0;k=Pl(b)|0;m=k&255;if(k<<24>>24>=0){i=Pl(b)|0;j=Pl(b)|0;k=(k&255)>>>1&255;a[t+n>>0]=d[35367+(k<<1)>>0]|0|m<<4&16;a[t+(n|1)>>0]=a[35367+(k<<1)+1>>0]|0;k=i&255;switch(i&15){case 8:{i=k&240;break}case 7:{i=(k&240|10)&255;v=21;break}case 5:case 6:{v=21;break}case 14:{j=1;break}case 11:{j=((j&255)+4|0)>>>1&255;break}default:{}}if((v|0)==21){v=0;m=j&255;j=((j&255)>128?256-m|0:m<<4)&255}a[t+(n|2)>>0]=i;a[t+(n|3)>>0]=j;if((i&15)==13)break}else h=h+255-m|0;h=h+1|0}while((h|0)<64);h=em(b)|0;if((h|0)<0){f=-1;v=30;break a}f=(h|0)>(f|0)?h:f;r=r+1|0}while((r|0)<4);ko(t,1024,1,e)|0;if((q|0)<(s|0))q=q+1|0;else break}if((v|0)==30){l=w;return f|0}dm(b,(f&1)+f|0,0)|0;ag(e,b,g);v=0;l=w;return v|0}function Hg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;j=a[b+2>>0]|0;h=j&255;if(j<<24>>24<1){b=-1;return b|0}p=a[b+3>>0]&63;q=p&255;if((p+-1&255)>30){b=-1;return b|0}else c=0;while(1){f=c*6|0;if((d[b+(f+7)>>0]|0)>64){l=-1;n=38;break}c=c+1|0;if((d[b+(f+6)>>0]|0)>15){l=-1;n=38;break}if((c|0)>=(q|0)){g=0;n=7;break}}if((n|0)==7){while(1){c=b+(g*6|0)|0;f=c+4|0;f=Rj(a[f>>0]|0,a[f+1>>0]|0)|0;if(f<<16>>16==0|(f+32767&65535)<32734){l=-1;n=38;break}n=c+8|0;n=Rj(a[n>>0]|0,a[n+1>>0]|0)|0;if(!(n<<16>>16==-1|(n&65535)<(f&65535))){l=-1;n=38;break}g=g+1|0;if((f&65535)>65503&(~f&65535)>>>0>q>>>0){l=-1;n=38;break}if((g|0)>=(q|0)){n=10;break}}if((n|0)==10){m=(Rj(a[b>>0]|0,a[b+1>>0]|0)|0)&65535;c=q*6|0;i=(h<<3|4)+c|0;if(m>>>0>>0){b=-1;return b|0}g=h<<2;a:do if(j<<24>>24){c=b+4+c|0;f=0;while(1){h=c+(f<<1)|0;f=f+1|0;if((i+((Rj(a[h>>0]|0,a[h+1>>0]|0)|0)&65535)|0)>>>0>m>>>0){l=-1;break}if((f|0)>=(g|0))break a}return l|0}while(0);if((i|0)>(e|0)){b=i-e|0;return b|0}c=a[b+i>>0]|0;if(c<<24>>24==-1){b=-1;return b|0}else f=0;do{if((c&255)>=(j&255)){l=-1;n=38;break}f=f+1|0;k=f+i|0;c=a[b+k>>0]|0}while((f|0)<128&c<<24>>24!=-1);if((n|0)==38)return l|0;if((k|0)>(m|0)|(f|128|0)==128){b=-1;return b|0}if((m|0)>=(e|0)){b=1-e+m|0;return b|0}c=(i|1)+f|0;if((c|0)>=(m|0)){b=0;return b|0}b:while(1){e=a[b+c>>0]|0;h=c+1|0;f=a[b+h>>0]|0;g=e&255;c:do switch(e<<24>>24){case -1:{switch((f&-64)<<24>>24){case 0:{o=h;break c}case 64:{o=c+2|0;break c}default:{}}if((f&255)>191)o=c+3|0;else n=29;break}case 127:{o=c;break}default:n=29}while(0);d:do if((n|0)==29){n=0;e:do switch(((g&240)+-96|0)>>>4&268435455|0){case 0:{o=h;break d}case 9:{o=(f&31)>(p&255);g=o?1:19;c=o?c:c+2|0;break}case 1:{o=(f&31)>(p&255);g=o?1:19;c=o?c:h;break}case 8:{o=c+2|0;break d}default:{f=(g<<4&16|(f&255)>>>4)>>>0>q>>>0;if(!(g&128)){g=f&1;c=f?c:c+2|0;break e}else{g=f?1:19;c=f?c:c+3|0;break e}}}while(0);switch(g&31){case 19:case 0:{o=c;break}default:{l=-1;n=38;break b}}}while(0);c=o+1|0;if((c|0)>=(m|0)){l=0;n=38;break}}if((n|0)==38)return l|0}else if((n|0)==38)return l|0}else if((n|0)==38)return l|0;return 0}function Ig(e,f){e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;L=l;l=l+134656|0;G=L+133624|0;F=L+2552|0;o=L+2424|0;m=L+2296|0;A=L+248|0;K=L+124|0;J=L;gp(A|0,0,2048)|0;gp(F|0,0,131072)|0;g=o;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));g=K;h=g+124|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));g=m;h=g+60|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));b[m+60>>1]=0;c[J>>2]=0;I=(Ul(e)|0)&65535;n=Pl(e)|0;D=n&255;if(n<<24>>24<0){K=-1;l=L;return K|0}E=(Pl(e)|0)&255;if(E&64|0){K=-1;l=L;return K|0}H=E&63;bg(f,20);C=(H|0)==0;if(!C){k=0;do{bg(f,22);z=Ul(e)|0;h=z&65535;g=m+(k<<2)|0;c[g>>2]=h;if((z&65535)>65280){i=h^65535;j=c[K+(i<<2)>>2]|0;c[K+(k<<2)>>2]=j;h=c[m+(i<<2)>>2]|0;c[g>>2]=h;g=c[J+(i<<2)>>2]|0;i=J}else{g=k+-1|0;if((k|0)>0)c[J+(k<<2)>>2]=(c[K+(g<<2)>>2]|0)+(c[J+(g<<2)>>2]|0);g=h<<1;j=g;i=K}c[i+(k<<2)>>2]=g;Xj(f,h&65535);Wj(f,(Pl(e)|0)&63);Wj(f,Pl(e)|0);g=Ul(e)|0;if(g<<16>>16==-1){Xj(f,0);Xj(f,1)}else{Xj(f,g);Xj(f,((j|0)/2|0)-(g&65535)&65535)}k=k+1|0}while((k|0)!=(H|0));g=G;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[G+29>>0]=1;if(H>>>0<31){g=H;B=16}}else{g=G;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[G+29>>0]=1;g=0;B=16}if((B|0)==16)while(1){B=0;ko(G,30,1,f)|0;g=g+1|0;if((g|0)==31)break;else B=16}i=n<<24>>24==0;if(i)g=0;else{g=0;do{c[A+(g<<4)>>2]=(Ul(e)|0)&65535;c[A+(g<<4)+4>>2]=(Ul(e)|0)&65535;c[A+(g<<4)+8>>2]=(Ul(e)|0)&65535;c[A+(g<<4)+12>>2]=(Ul(e)|0)&65535;g=g+1|0}while((g|0)!=(D|0));g=0}do{h=Pl(e)|0;if(h<<24>>24==-1)break;a[o+g>>0]=h;g=g+1|0}while((g|0)<128);Wj(f,g&255);Wj(f,127);ko(o,128,1,f)|0;Yj(f,1294879534);z=em(e)|0;if((z|0)<0){K=-1;l=L;return K|0}if(!i){w=0;a:while(1){y=w<<2;x=0;v=63;while(1){dm(e,(c[A+(w<<4)+(x<<2)>>2]|0)+z|0,0)|0;b:do if((v|0)<0)g=v;else{u=x+y|0;g=0;while(1){q=(g<<2)+(F+(u<<8))|0;n=Pl(e)|0;o=n&255;h=o&112;c:do if((h|0)==112){switch(n<<24>>24){case 127:case -1:{i=n<<24>>24==-1;B=42;break c}default:{}}n=(Pl(e)|0)&255;k=n>>>5|o<<3&120;m=(n&16|(d[35367+(k<<1)>>0]|0))&255;a[q>>0]=m;k=a[35367+(k<<1)+1>>0]|0;a[q+1>>0]=k;n=n<<4&255;a[q+2>>0]=n;if(o&128){t=Pl(e)|0;h=t&255;if(t<<24>>24>-1){g=h+g|0;break}h=h+128&255;if(h){i=g;j=0;do{i=i+1|0;t=(i<<2)+(F+(u<<8))|0;a[t>>0]=m;a[t+1>>0]=k;a[t+2>>0]=n;j=j+1|0}while((j|0)!=(h|0));g=g+h|0}}}else{i=n<<24>>24==-1;if(!(i|(h|0)!=96)){h=Pl(e)|0;i=((o&15|0)==8?o+248&255:n)&255;m=i&15;j=q+3|0;a[q+2>>0]=m;switch(n&15){case 10:case 6:case 5:{k=h&255;k=(h<<24>>24<0?256-k<<4:k)&255;break}default:k=h}a[j>>0]=k;switch(n&15){case 11:case 13:break b;default:{}}if(i&128){t=Pl(e)|0;h=t&255;if(t<<24>>24>-1){g=h+g|0;break}h=h+128&255;if(h){i=g;j=0;do{i=i+1|0;t=(i<<2)+(F+(u<<8))|0;a[t+2>>0]=m;a[t+3>>0]=k;j=j+1|0}while((j|0)!=(h|0));g=g+h|0}}}else B=42}while(0);d:do if((B|0)==42){B=0;h=(o&128|0)==0;if(!(h|i)){k=Pl(e)|0;i=Pl(e)|0;m=Pl(e)|0;j=o>>>1&63;p=(d[35367+(j<<1)>>0]|0|o<<4&16)&255;a[q>>0]=p;o=a[35367+(j<<1)+1>>0]|0;a[q+1>>0]=o;j=k&255;j=(j&15|0)==8?j+248&255:k;h=q+3|0;a[q+2>>0]=j;switch(k&15){case 10:case 6:case 5:{t=i&255;i=(i<<24>>24<0?256-t<<4:t)&255;break}default:{}}a[h>>0]=i;switch(k&15){case 11:case 13:break b;default:{}}h=m&255;if(m<<24>>24>-1){g=h+g|0;break}n=h+128&255;if(!n)break;else{h=i;k=g;m=0}do{k=k+1|0;s=(k<<2)+(F+(u<<8))|0;a[s>>0]=p;a[s+1>>0]=o;i=j&255;t=j;j=(i&15|0)==8?i+248&255:j;i=s+3|0;a[s+2>>0]=j;switch(t&15){case 10:case 6:case 5:{t=h&255;h=(h<<24>>24<0?256-t<<4:t)&255;break}default:{}}a[i>>0]=h;m=m+1|0}while((m|0)!=(n|0));g=g+n|0;break}if((o&127|0)!=127){j=Pl(e)|0;h=Pl(e)|0;t=(n&255)>>>1&255;a[q>>0]=d[35367+(t<<1)>>0]|0|o<<4&16;a[q+1>>0]=a[35367+(t<<1)+1>>0]|0;t=j&255;i=q+3|0;a[q+2>>0]=(t&15|0)==8?t+248&255:j;switch(j&15){case 10:case 6:case 5:{t=h&255;h=(h<<24>>24<0?256-t<<4:t)&255;break}default:{}}a[i>>0]=h;switch(j&15){case 11:case 13:break b;default:break d}}if(!h){t=Pl(e)|0;h=t&255;if((t&255)<64){g=h+g|0;break}i=h+192|0;j=(Pl(e)|0)&255;h=i&255;if(h>>>0>127){i=h+-128|0;h=(Pl(e)|0)&255|j<<8}else h=j;t=em(e)|0;if((t|0)<0){g=-1;B=115;break a}dm(e,0-h|0,1)|0;s=i&255;if((g|0)<=(v|0)){r=0;while(1){m=Pl(e)|0;q=(g<<2)+(F+(u<<8))|0;i=m&255;e:do if((i&112|0)==112){switch(m<<24>>24){case 127:case -1:{B=67;break e}default:{}}n=(Pl(e)|0)&255;k=n>>>5|i<<3&120;m=(n&16|(d[35367+(k<<1)>>0]|0))&255;a[q>>0]=m;k=a[35367+(k<<1)+1>>0]|0;a[q+1>>0]=k;n=n<<4&255;a[q+2>>0]=n;if(!(i&128)){h=g;break}q=Pl(e)|0;h=q&255;if(q<<24>>24>-1){h=h+g|0;break}i=h+128&255;if(!i){h=g;break}else{h=0;j=g}do{j=j+1|0;q=(j<<2)+(F+(u<<8))|0;a[q>>0]=m;a[q+1>>0]=k;a[q+2>>0]=n;h=h+1|0}while((h|0)!=(i|0));h=g+i|0}else B=67;while(0);f:do if((B|0)==67){B=0;g:do if((i&96|0)==96){switch(m<<24>>24){case 127:case -1:break g;default:{}}h=Pl(e)|0;i=((i&15|0)==8?i+248&255:m)&255;n=i&15;j=q+3|0;a[q+2>>0]=n;switch(m&15){case 10:case 6:case 5:{k=h&255;k=(h<<24>>24<0?256-k<<4:k)&255;break}default:k=h}a[j>>0]=k;switch(m&15){case 11:case 13:break b;default:{}}if(!(i&128)){h=g;break f}q=Pl(e)|0;h=q&255;if(q<<24>>24>-1){h=h+g|0;break f}i=h+128&255;if(!i){h=g;break f}else{h=0;j=g}do{j=j+1|0;q=(j<<2)+(F+(u<<8))|0;a[q+2>>0]=n;a[q+3>>0]=k;h=h+1|0}while((h|0)!=(i|0));h=g+i|0;break f}while(0);h=(i&128|0)==0;if((m&127)==127|h){if((i&127|0)==127){if(h){h=g;break}h=Pl(e)|0;h=((h&255)<64?h&255:0)+g|0;break}p=Pl(e)|0;h=Pl(e)|0;o=(m&255)>>>1&255;a[q>>0]=d[35367+(o<<1)>>0]|0|i<<4&16;a[q+1>>0]=a[35367+(o<<1)+1>>0]|0;o=p&255;i=q+3|0;a[q+2>>0]=(o&15|0)==8?o+248&255:p;switch(p&15){case 10:case 6:case 5:{q=h&255;h=(h<<24>>24<0?256-q<<4:q)&255;break}default:{}}a[i>>0]=h;h=g;break}m=Pl(e)|0;h=Pl(e)|0;n=Pl(e)|0;o=i>>>1&63;p=(d[35367+(o<<1)>>0]|0|i<<4&16)&255;a[q>>0]=p;o=a[35367+(o<<1)+1>>0]|0;a[q+1>>0]=o;j=m&255;j=(j&15|0)==8?j+248&255:m;i=q+3|0;a[q+2>>0]=j;switch(m&15){case 10:case 6:case 5:{k=h&255;k=(h<<24>>24<0?256-k<<4:k)&255;break}default:k=h}a[i>>0]=k;switch(m&15){case 11:case 13:break b;default:{}}h=n&255;if(n<<24>>24>-1){h=h+g|0;break}n=h+128&255;if(!n){h=g;break}else{m=0;h=k;k=g}do{k=k+1|0;M=(k<<2)+(F+(u<<8))|0;a[M>>0]=p;a[M+1>>0]=o;i=j&255;q=j;j=(i&15|0)==8?i+248&255:j;i=M+3|0;a[M+2>>0]=j;switch(q&15){case 10:case 6:case 5:{M=h&255;h=(h<<24>>24<0?256-M<<4:M)&255;break}default:{}}a[i>>0]=h;m=m+1|0}while((m|0)!=(n|0));h=g+n|0}while(0);g=h+1|0;if((h|0)<(v|0)&(r|0)<(s|0))r=r+1|0;else break}}dm(e,t,0)|0;g=g+-1|0}}while(0);if((g|0)<(v|0))g=g+1|0;else{g=v;break}}}while(0);x=x+1|0;if((x|0)>=4)break;else v=g}w=w+1|0;if((w|0)>=(D|0)){m=0;break}}if((B|0)==115){l=L;return g|0}do{gp(G|0,0,1024)|0;k=m<<2;g=k|1;h=k|2;i=k|3;j=0;do{M=j<<4;B=j<<2;A=G+M|0;z=F+(k<<8)+B|0;z=d[z>>0]|d[z+1>>0]<<8|d[z+2>>0]<<16|d[z+3>>0]<<24;a[A>>0]=z;a[A+1>>0]=z>>8;a[A+2>>0]=z>>16;a[A+3>>0]=z>>24;A=G+(M|4)|0;z=F+(g<<8)+B|0;z=d[z>>0]|d[z+1>>0]<<8|d[z+2>>0]<<16|d[z+3>>0]<<24;a[A>>0]=z;a[A+1>>0]=z>>8;a[A+2>>0]=z>>16;a[A+3>>0]=z>>24;A=G+(M|8)|0;z=F+(h<<8)+B|0;z=d[z>>0]|d[z+1>>0]<<8|d[z+2>>0]<<16|d[z+3>>0]<<24;a[A>>0]=z;a[A+1>>0]=z>>8;a[A+2>>0]=z>>16;a[A+3>>0]=z>>24;M=G+(M|12)|0;B=F+(i<<8)+B|0;B=d[B>>0]|d[B+1>>0]<<8|d[B+2>>0]<<16|d[B+3>>0]<<24;a[M>>0]=B;a[M+1>>0]=B>>8;a[M+2>>0]=B>>16;a[M+3>>0]=B>>24;j=j+1|0}while((j|0)!=64);ko(G,1024,1,f)|0;m=m+1|0}while((m|0)!=(D|0))}dm(e,I,0)|0;if(C){M=0;l=L;return M|0}j=(E&128|0)!=0;k=0;do{dm(e,(c[J+(k<<2)>>2]|0)+I|0,0)|0;g=c[K+(k<<2)>>2]|0;i=Vm(g)|0;gp(i|0,0,g|0)|0;cm(i,g,1,e)|0;if(j&(g|0)>1){h=0;m=1;do{M=i+m|0;h=(0-(d[M>>0]|0)&255)+(h&255)|0;a[M>>0]=h;m=m+1|0}while((m|0)!=(g|0))}ko(i,g,1,f)|0;Wm(i);k=k+1|0}while((k|0)!=(H|0));g=0;l=L;return g|0}function Jg(b,c,d){b=b|0;c=c|0;d=d|0;do if((d|0)>=22)if((nn(b,35709,16)|0)==0?(a[b+21>>0]|0)==-50:0){if((d|0)<4714){b=4714-d|0;break}if((((Rj(a[b+4712>>0]|0,a[b+4713>>0]|0)|0)&3)==0?(a[b+36>>0]|0)==16:0)?(a[b+37>>0]|0)==-4:0){eg(0,c,0);b=0}else b=-1}else b=-1;else b=22-d|0;while(0);return b|0}function Kg(e,f){e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;z=l;l=l+132912|0;t=z+132776|0;s=z+132648|0;q=z+1032|0;n=z+520|0;r=z+8|0;y=z+1576|0;w=z+1544|0;x=z;g=t;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));g=s;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));gp(y|0,0,131072)|0;g=w;h=g+31|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));c[x>>2]=0;gp(q|0,0,512)|0;gp(n|0,0,512)|0;g=0;do{c[r+(g<<2)>>2]=9999;g=g+1|0}while((g|0)!=128);bg(f,20);dm(e,4460,0)|0;g=0;v=0;do{bg(f,22);u=Ul(e)|0;Xj(f,u);v=((u&65535)<<1)+v|0;u=Pl(e)|0;a[w+g>>0]=u;Wj(f,u);Wj(f,Pl(e)|0);Xj(f,Ul(e)|0);Xj(f,Ul(e)|0);g=g+1|0}while((g|0)!=31);u=Ul(e)|0;k=(u&65535)>>>2;p=k&65535;if((u&65535)>515){y=-1;l=z;return y|0}Wj(f,k&255);Wj(f,127);g=0;do{c[q+(g<<2)>>2]=am(e)|0;g=g+1|0}while((g|0)!=128);if(!(k<<16>>16))u=0;else{j=0;i=0;while(1){if(j){a:do if((j|0)>0){h=c[q+(j<<2)>>2]|0;g=0;while(1){if((h|0)==(c[q+(g<<2)>>2]|0))break;g=g+1|0;if((g|0)>=(j|0))break a}a[t+j>>0]=a[t+g>>0]|0}else g=0;while(0);if((g|0)==(j|0)){a[t+j>>0]=i;u=i+1|0}else u=i}else{a[t>>0]=0;u=i+1|0}j=j+1|0;if((j|0)>=(p|0))break;else i=u}ep(n|0,q|0,k<<2&65535|0)|0;b:while(1){g=0;c:while(1){if((g|0)>0){m=n+(g<<2)|0;k=c[m>>2]|0;h=0;do{j=n+(h<<2)|0;i=c[j>>2]|0;if((k|0)<(i|0))break c;h=h+1|0}while((h|0)<(g|0))}g=g+1|0;if((g|0)>=(p|0)){j=0;g=0;break b}}B=t+h|0;A=a[B>>0]|0;h=t+g|0;a[B>>0]=a[h>>0]|0;a[h>>0]=A;c[j>>2]=k;c[m>>2]=i}do{i=c[n+(j<<2)>>2]|0;h=r+(g<<2)|0;if(j){if((i|0)!=(c[h>>2]|0)){g=g+1|0;h=r+(g<<2)|0;o=30}}else o=30;if((o|0)==30){o=0;c[h>>2]=i}j=j+1|0}while((j|0)<(p|0));k=0;g=0;do{j=c[q+(g<<2)>>2]|0;g=s+g|0;h=0;i=0;do{if((j|0)==(c[r+(i<<2)>>2]|0))a[g>>0]=h;h=h+1<<24>>24;i=h&255}while(i>>>0

>>0);k=k+1<<24>>24;g=k&255}while(g>>>0

>>0);ep(t|0,s|0,p|0)|0}ko(t,128,1,f)|0;Yj(f,1294879534);dm(e,4456,0)|0;g=am(e)|0;dm(e,5222,0)|0;if((g|0)>0){h=0;i=0;do{B=(Ul(e)|0)&65535;i=(B|0)>(i|0)?B:i;h=h+2|0}while((h|0)<(g|0));g=(i<<2)+4|0}else g=4;t=Vm(g)|0;cm(t,g,1,e)|0;dm(e,5222,0)|0;if((u|0)>0){r=0;do{g=0;q=0;do{s=q<<4;p=0;do{o=(p<<2)+s+(y+(r<<10))|0;i=t+(((Ul(e)|0)&65535)<<2)|0;i=d[i>>0]|d[i+1>>0]<<8|d[i+2>>0]<<16|d[i+3>>0]<<24;a[o>>0]=i;a[o+1>>0]=i>>8;a[o+2>>0]=i>>16;a[o+3>>0]=i>>24;m=i>>>16;n=i&255&-16;h=n&255|i>>>20&15;if(!h)h=a[x+p>>0]|0;else{h=h&255;a[x+p>>0]=h}k=o+1|0;j=i<<8&3840|i>>>8&255;B=a[w+((h&255)+-1)>>0]|0;i=B&255;d:do if(j|0?h<<24>>24!=0&B<<24>>24!=0:0){h=0;do{if((h|0)>=36)break d;B=h;h=h+1|0}while((b[22260+(i*72|0)+(B<<1)>>1]|0)!=(j|0));a[o>>0]=a[35367+(h<<1)>>0]|n;a[k>>0]=a[35367+(h<<1)+1>>0]|0}while(0);switch(m&15){case 11:case 13:{g=1;break}default:{}}p=p+1|0}while((p|0)!=4);q=q+1|0}while((g|0)!=1&(q|0)<64);ko(y+(r<<10)|0,1024,1,f)|0;r=r+1|0}while((r|0)!=(u|0))}Wm(t);dm(e,4452,0)|0;dm(e,(am(e)|0)+4456|0,0)|0;ag(f,e,v);B=0;l=z;return B|0}function Lg(b,c,d){b=b|0;c=c|0;d=d|0;do if((d|0)>=22)if((nn(b,35709,16)|0)==0?(a[b+21>>0]|0)==-46:0){if((d|0)<4714){b=4714-d|0;break}if((((Rj(a[b+4712>>0]|0,a[b+4713>>0]|0)|0)&3)==0?(a[b+36>>0]|0)==17:0)?(a[b+37>>0]|0)==0:0){eg(0,c,0);b=0}else b=-1}else b=-1;else b=22-d|0;while(0);return b|0}function Mg(e,f){e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;B=l;l=l+131760|0;m=B+131624|0;z=B+8|0;A=B+552|0;x=B+520|0;y=B;g=m;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));gp(A|0,0,131072)|0;g=x;h=g+31|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));c[y>>2]=0;gp(z|0,0,512)|0;bg(f,20);dm(e,4464,0)|0;g=0;w=0;do{bg(f,22);v=Ul(e)|0;Xj(f,v);w=((v&65535)<<1)+w|0;v=Pl(e)|0;a[x+g>>0]=v;Wj(f,v);Wj(f,Pl(e)|0);Xj(f,Ul(e)|0);Xj(f,Ul(e)|0);g=g+1|0}while((g|0)!=31);v=Ul(e)|0;g=(v&65535)>>>2;k=g&65535;if((v&65535)>515){A=-1;l=B;return A|0}Wj(f,g&255);Wj(f,127);h=0;do{c[z+(h<<2)>>2]=am(e)|0;h=h+1|0}while((h|0)!=128);if(!(g<<16>>16))k=0;else{j=0;g=0;while(1){if(j){a:do if((j|0)>0){i=c[z+(j<<2)>>2]|0;h=0;while(1){if((i|0)==(c[z+(h<<2)>>2]|0))break;h=h+1|0;if((h|0)>=(j|0))break a}a[m+j>>0]=a[m+h>>0]|0}else h=0;while(0);if((h|0)==(j|0)){a[m+j>>0]=g;g=g+1|0}}else{a[m>>0]=0;g=g+1|0}j=j+1|0;if((j|0)>=(k|0)){k=g;break}}}ko(m,128,1,f)|0;Yj(f,1294879534);dm(e,4460,0)|0;g=am(e)|0;dm(e,5226,0)|0;do if((g|0)>0){i=0;j=0;while(1){h=(Ul(e)|0)&65535;if(gm(e)|0){g=-1;h=42;break}j=(h|0)>(j|0)?h:j;i=i+2|0;if((i|0)>=(g|0)){h=20;break}}if((h|0)==20){g=(j<<2)+4|0;break}else if((h|0)==42){l=B;return g|0}}else g=4;while(0);v=Vm(g)|0;if(!v){A=-1;l=B;return A|0}cm(v,g,1,e)|0;dm(e,5226,0)|0;u=(k<<16)+-65536|0;r=u>>16;b:do if((u|0)>=0){t=0;c:while(1){dm(e,(c[z+(t<<2)>>2]|0)+5226|0,0)|0;g=0;s=0;do{u=s<<4;q=0;do{p=(q<<2)+u+(A+(t<<10))|0;i=v+(((Ul(e)|0)&65535)<<2)|0;i=d[i>>0]|d[i+1>>0]<<8|d[i+2>>0]<<16|d[i+3>>0]<<24;a[p>>0]=i;a[p+1>>0]=i>>8;a[p+2>>0]=i>>16;a[p+3>>0]=i>>24;n=i>>>16;o=i&255&-16;h=o&255|i>>>20&15;if(!h)j=a[y+q>>0]|0;else{j=h&255;a[y+q>>0]=j}m=p+1|0;k=i<<8&3840|i>>>8&255;if((j+-1&255)<31){h=a[x+((j&255)+-1)>>0]|0;if((h&255)>15)break c;else i=h&255}else i=0;d:do if(k|0?(i|0)!=0&j<<24>>24!=0:0){h=0;do{if((h|0)>=36)break d;j=h;h=h+1|0}while((b[22260+(i*72|0)+(j<<1)>>1]|0)!=(k|0));a[p>>0]=a[35367+(h<<1)>>0]|o;a[m>>0]=a[35367+(h<<1)+1>>0]|0}while(0);switch(n&15){case 11:case 13:{g=1;break}default:{}}q=q+1|0}while((q|0)<4);s=s+1|0}while((g|0)!=1&(s|0)<64);ko(A+(t<<10)|0,1024,1,f)|0;if((t|0)<(r|0))t=t+1|0;else break b}Wm(v);A=-1;l=B;return A|0}while(0);Wm(v);dm(e,4456,0)|0;dm(e,(am(e)|0)+4460|0,0)|0;ag(f,e,w);A=0;l=B;return A|0}function Ng(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0;if((e|0)<963){c=963-e|0;return c|0}if((a[b+10>>0]|0)!=3){c=-1;return c|0}if((a[b+11>>0]|0)==-64){f=0;h=0}else{c=-1;return c|0}while(1){e=b+(f*14|0)|0;h=(((Rj(a[e>>0]|0,a[e+1>>0]|0)|0)&65535)<<1)+h|0;if((d[e+3>>0]|0)>64){i=-1;g=14;break}g=e+4|0;if((((Rj(a[g>>0]|0,a[g+1>>0]|0)|0)&65535)<<1|0)>(h|0)){i=-1;g=14;break}f=f+1|0;if((Vj(e+8|0)|0)>>>0<=959){i=-1;g=14;break}if((f|0)>=31){g=9;break}}if((g|0)==9){if((h+-3|0)>>>0>2031582){c=-1;return c|0}e=b+448|0;f=0;do{if(((Vj(e+(f<<2)|0)|0)+-958|0)<(h|0)){i=-1;g=14;break}f=f+1|0}while((f|0)<128);if((g|0)==14)return i|0;eg(0,c,0);c=0;return c|0}else if((g|0)==14)return i|0;return 0}function Og(e,f){e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0;B=l;l=l+1824|0;s=B+1688|0;g=B+1560|0;z=B+1544|0;r=B+1032|0;q=B+520|0;p=B+8|0;y=B;gp(r|0,0,512)|0;gp(q|0,0,512)|0;gp(p|0,0,512)|0;h=s;i=h+128|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));h=g;i=h+128|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));h=z;i=h+16|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));h=y;c[h>>2]=0;c[h+4>>2]=0;bg(f,20);h=0;A=0;do{bg(f,22);v=Ul(e)|0;Xj(f,v);A=((v&65535)<<1)+A|0;Pl(e)|0;v=Pl(e)|0;w=Ul(e)|0;x=Ul(e)|0;am(e)|0;Pl(e)|0;t=Pl(e)|0;u=t&255;Wj(f,(t<<24>>24==0?u:u+11|0)&255);Wj(f,v);Xj(f,w);Xj(f,x);h=h+1|0}while((h|0)!=31);dm(e,14,1)|0;h=0;do{c[r+(h<<2)>>2]=am(e)|0;h=h+1|0}while((h|0)!=128);k=0;h=0;while(1){if(!k){a[s>>0]=0;k=1;h=h+1|0;continue}a:do if((k|0)>0){j=c[r+(k<<2)>>2]|0;i=0;while(1){if((j|0)==(c[r+(i<<2)>>2]|0))break;i=i+1|0;if((i|0)>=(k|0))break a}a[s+k>>0]=a[s+i>>0]|0}else i=0;while(0);if((i|0)==(k|0)){a[s+k>>0]=h;h=h+1|0}k=k+1|0;if((k|0)==128)break}ep(q|0,r|0,512)|0;b:while(1){h=0;c:while(1){if((h|0)>0){n=q+(h<<2)|0;m=c[n>>2]|0;i=0;do{k=q+(i<<2)|0;j=c[k>>2]|0;if((m|0)<(j|0))break c;i=i+1|0}while((i|0)<(h|0))}h=h+1|0;if((h|0)>=128){k=0;h=0;break b}}v=s+i|0;w=a[v>>0]|0;x=s+h|0;a[v>>0]=a[x>>0]|0;a[x>>0]=w;c[k>>2]=m;c[n>>2]=j}do{j=c[q+(k<<2)>>2]|0;i=p+(h<<2)|0;if(k){if((j|0)!=(c[i>>2]|0)){h=h+1|0;i=p+(h<<2)|0;o=27}}else o=27;if((o|0)==27){o=0;c[i>>2]=j}k=k+1|0}while((k|0)!=128);gp(q|0,0,512)|0;n=c[r>>2]|0;k=c[p>>2]|0;m=0;j=0;while(1){c[q+(j<<2)>>2]=k;h=j+1|0;m=m+1|0;i=k;k=c[p+(m<<2)>>2]|0;if((k-i|0)>1024){c[q+(h<<2)>>2]=i+1024;h=j+2|0}if((m|0)==120){k=n;h=0;break}else j=h}while(1){i=g+h|0;j=0;do{if((k|0)==(c[q+(j<<2)>>2]|0))a[i>>0]=j;j=j+1|0}while((j|0)!=128);h=h+1|0;if((h|0)==128)break;k=c[r+(h<<2)>>2]|0}h=s;i=h+128|0;do{a[h>>0]=a[g>>0]|0;h=h+1|0;g=g+1|0}while((h|0)<(i|0));j=(n|0)<999999?n:999999;g=1;do{x=c[r+(g<<2)>>2]|0;j=(x|0)<(j|0)?x:j;g=g+1|0}while((g|0)!=128);g=128;h=-128;while(1){if(a[s+(g+-1)>>0]|0)break;h=h+-1<<24>>24;g=h&255;if(!(h<<24>>24)){h=0;break}}Wj(f,h);if((g|0)>0){i=0;h=0;do{x=a[s+i>>0]|0;h=(x&255)>(h&255)?x:h;i=i+1|0}while((i|0)!=(g|0))}else h=0;Wj(f,127);g=0;do{Wj(f,a[s+g>>0]|0);g=g+1|0}while((g|0)!=128);Yj(f,1294879534);x=em(e)|0;dm(e,j,0)|0;w=(h&255)<<10;t=Vm(w)|0;u=cm(t,1,w,e)|0;w=w+1024&261120;v=Vm(w)|0;gp(v|0,0,w|0)|0;if((u|0)>0){r=0;s=0;g=n}else{ko(v,w,1,f)|0;Wm(t);Wm(v);dm(e,x,0)|0;ag(f,e,A);l=B;return 0}while(1){j=a[t+r>>0]|0;p=j&255;do if(j<<24>>24!=-1){q=(g|0)%4|0;o=y+(q<<1)|0;k=b[o>>1]|0;m=s+1|0;n=s+3|0;g=g+1|0;h=s+4|0;i=s+2|0;if(!(k<<16>>16)){C=a[t+(r+1)>>0]|0;k=a[t+(r+2)>>0]|0;r=r+3|0;o=a[t+r>>0]|0;a[z+(q<<2)>>0]=j;a[z+(q<<2)+1>>0]=C;a[z+(q<<2)+2>>0]=k;a[z+(q<<2)+3>>0]=o;q=(C&255)>>>1&255;a[v+s>>0]=d[35367+(q<<1)>>0]|p&240;a[v+m>>0]=a[35367+(q<<1)+1>>0]|0;a[v+i>>0]=k&255|p<<4;a[v+n>>0]=o;i=r;break}else{D=a[z+(q<<2)>>0]|0;j=a[z+(q<<2)+1>>0]|0;p=a[z+(q<<2)+2>>0]|0;C=a[z+(q<<2)+3>>0]|0;b[o>>1]=(k&65535)+65535;q=D&255;o=(j&255)>>>1&255;a[v+s>>0]=d[35367+(o<<1)>>0]|q&240;a[v+m>>0]=a[35367+(o<<1)+1>>0]|0;a[v+i>>0]=p&255|q<<4;a[v+n>>0]=C;i=r+-1|0;break}}else{i=r+1|0;b[y+(((g+3|0)%4|0)<<1)>>1]=~a[t+i>>0]&255;h=s}while(0);if((h|0)<(u|0)){r=i+1|0;s=h}else break}ko(v,w,1,f)|0;Wm(t);Wm(v);dm(e,x,0)|0;ag(f,e,A);l=B;return 0}function Pg(b,c,d){b=b|0;c=c|0;d=d|0;if((d|0)>=1084)if(((Vj(b+1080|0)|0)==1397642286?(a[b+951>>0]|0)==127:0)?(a[b+950>>0]|0)>=0:0){eg(b,c,20);b=0}else b=-1;else b=1084-d|0;return b|0}function Qg(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;q=l;l=l+2048|0;n=q;gp(n|0,0,2048)|0;cm(n,950,1,b)|0;ko(n,950,1,c)|0;e=0;o=0;do{m=n+(e*30|0)|0;o=(((Rj(a[m+42>>0]|0,a[m+43>>0]|0)|0)&65535)<<1)+o|0;e=e+1|0}while((e|0)!=31);Wj(c,Pl(b)|0);gp(n|0,0,2048)|0;cm(n,129,1,b)|0;ko(n,129,1,c)|0;Yj(c,1294879534);e=1;f=0;do{m=a[n+e>>0]|0;f=(m&255)>(f&255)?m:f;e=e+1|0}while((e|0)!=129);dm(b,1084,0)|0;j=f&255;f=n+1|0;g=n+2|0;h=n+3|0;k=0;a:while(1){m=0;do{a[n>>0]=Pl(b)|0;a[f>>0]=Pl(b)|0;a[g>>0]=Pl(b)|0;i=Pl(b)|0;a[h>>0]=i;e=a[f>>0]|0;if((e&255)>36){e=-1;p=11;break a}t=e&255;s=d[n>>0]|0;e=(s<<4|(d[g>>0]|0))&255;r=a[35367+(t<<1)+1>>0]|0;Wj(c,(d[35367+(t<<1)>>0]|0|s&240)&255);Wj(c,r);Wj(c,e);Wj(c,i);m=m+1|0}while((m|0)<256);if((k|0)<(j|0))k=k+1|0;else break}if((p|0)==11){l=q;return e|0}ag(c,b,o);t=0;l=q;return t|0}function Rg(a,b,c){a=a|0;b=b|0;c=c|0;var e=0,f=0,g=0;if((c|0)<260){g=260-c|0;return g|0}if((Vj(a)|0)==1397642273)c=0;else{g=-1;return g|0}while(1){if((d[a+((c<<3)+11)>>0]|0)>64){f=-1;g=9;break}c=c+1|0;if((c|0)>=31){e=0;break}}if((g|0)==9)return f|0;do{if((d[a+((e<<3)+10)>>0]|0)>15){f=-1;g=9;break}e=e+1|0}while((e|0)<31);if((g|0)==9)return f|0;eg(0,b,0);g=0;return g|0}function Sg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;x=l;l=l+32|0;v=x+8|0;u=x;c[v>>2]=0;c[v+4>>2]=0;c[v+8>>2]=0;c[v+12>>2]=0;bg(e,20);dm(b,8,0)|0;f=0;w=0;do{bg(e,22);t=Ul(b)|0;Xj(e,t);w=((t&65535)<<1)+w|0;Wj(e,Pl(b)|0);Wj(e,Pl(b)|0);Xj(e,Ul(b)|0);Xj(e,Ul(b)|0);f=f+1|0}while((f|0)!=31);Wj(e,Pl(b)|0);Wj(e,Pl(b)|0);f=0;g=0;do{t=Pl(b)|0;Wj(e,t);g=(t&255)>(g&255)?t:g;f=f+1|0}while((f|0)!=128);Yj(e,1294879534);dm(b,770,0)|0;s=g&255;q=u+1|0;r=u+2|0;o=u+3|0;m=v+4|0;n=v+8|0;p=v+12|0;g=0;h=0;f=0;t=0;a:while(1){k=0;while(1){c[u>>2]=0;i=Pl(b)|0;j=i&255;switch(i<<24>>24){case -128:{Yj(e,0);i=g;g=f;f=0;break}case -64:{ko(v,4,1,e)|0;f=c[v>>2]|0;c[u>>2]=f;h=c[m>>2]|0;i=c[n>>2]|0;g=c[p>>2]|0;break}default:{if((i&255)>73){f=13;break a}y=Pl(b)|0;i=Pl(b)|0;y=y&255;z=j>>>1;a[u>>0]=d[35367+(z<<1)>>0]|0|y>>>3&16;a[q>>0]=a[35367+(z<<1)+1>>0]|0;a[r>>0]=y&15|j<<4&16|y<<1&224;a[o>>0]=i;ko(u,1,4,e)|0;i=g;g=f;f=c[u>>2]|0}}c[v>>2]=h;c[m>>2]=i;c[n>>2]=g;c[p>>2]=f;k=k+1|0;if((k|0)>=256)break;else h=i}if((t|0)<(s|0)){h=i;t=t+1|0}else{f=15;break}}if((f|0)==13){z=-1;l=x;return z|0}else if((f|0)==15){ag(e,b,w);z=0;l=x;return z|0}return 0}function Tg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;if((e|0)<564){c=564-e|0;return c|0}else{j=0;l=0}while(1){m=b+(j*14|0)|0;f=Vj(m+130|0)|0;h=m+134|0;h=(Rj(a[h>>0]|0,a[h+1>>0]|0)|0)&65535;g=Vj(m+138|0)|0;i=m+142|0;i=(Rj(a[i>>0]|0,a[i+1>>0]|0)|0)&65535;if((g|0)<(f|0)|(d[m+137>>0]|0)>64){k=-1;i=25;break}if((f|0)<564|(g|0)<564){k=-1;i=25;break}m=g-f|0;if((m|0)>(h|0)|(i+m|0)>(h+2|0)){k=-1;i=25;break}l=h+l|0;j=j+1|0;if((j|0)>=31){i=7;break}}if((i|0)==7){if((l+-3|0)>>>0>2031582){m=-1;return m|0}j=a[b>>0]|0;if(j<<24>>24<1){m=-1;return m|0}else{g=0;h=0}do{m=a[b+(g+2)>>0]|0;f=m&255;if(m<<24>>24<0){k=-1;i=25;break}h=(f|0)>(h|0)?f:h;g=g+1|0}while((g|0)<128);if((i|0)==25)return k|0;i=(h<<10)+1024|0;f=(j&255)+2|0;a:do if(f>>>0<128){while(1){if(a[b+(f+2)>>0]|0){k=-1;break}f=f+1|0;if((f|0)>=128)break a}return k|0}while(0);g=l+564|0;f=i+g|0;if((f|0)>(e|0)){m=f-e|0;return m|0}b:do if((i|0)>0){f=b+g|0;h=0;c:while(1){g=f+h|0;if((d[g>>0]|0)>31){k=-1;i=25;break}m=a[g+1>>0]|0;if(!((m&255)<73&(m&1)==0)){k=-1;i=25;break}switch(a[g+2>>0]&15){case 11:{k=-1;i=25;break c}case 12:{if((d[g+3>>0]|0)>64){k=-1;i=25;break c}break}case 13:{if((d[g+3>>0]|0)>64){k=-1;i=25;break c}break}default:{}}h=h+4|0;if((h|0)>=(i|0))break b}if((i|0)==25)return k|0}while(0);eg(0,c,0);m=-1;return m|0}else if((i|0)==25)return k|0;return 0}function Ug(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;q=l;l=l+2304|0;m=q+1272|0;j=q+248|0;o=q+124|0;p=q;f=o;g=f+124|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));f=p;g=f+124|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));bg(e,1080);if((Ao(e,950,0)|0)<0){p=-1;l=q;return p|0}cm(m,130,1,b)|0;ko(m,130,1,e)|0;f=0;h=0;do{g=a[m+(f+2)>>0]|0;h=(g&255)>(h&255)?g:h;f=f+1|0}while((f|0)!=128);f=0;g=0;do{if((Ao(e,(f*30|0)+42|0,0)|0)<0){k=-1;i=16;break}r=am(b)|0;c[o+(f<<2)>>2]=r;t=Ul(b)|0;s=t&65535;Xj(e,t);g=s+g|0;c[p+(f<<2)>>2]=s;Wj(e,Pl(b)|0);Wj(e,Pl(b)|0);Xj(e,((am(b)|0)-r|0)>>>1&65535);Xj(e,Ul(b)|0);f=f+1|0}while((f|0)<31);if((i|0)==16){l=q;return k|0}if((dm(b,g,1)|0)<0){t=-1;l=q;return t|0}if((Ao(e,0,2)|0)<0){t=-1;l=q;return t|0}Yj(e,1294879534);f=h&255;g=0;while(1){gp(m|0,0,1024)|0;gp(j|0,0,1024)|0;if((cm(m,1,1024,b)|0)==1024)h=0;else{k=-1;i=16;break}do{t=h<<4;u=t|3;a[j+u>>0]=a[m+u>>0]|0;u=t|2;s=d[m+t>>0]|0;a[j+u>>0]=a[m+u>>0]&15|s<<4;u=t|1;i=(d[m+u>>0]|0)>>>1&255;a[j+t>>0]=s&240|a[35367+(i<<1)>>0];a[j+u>>0]=a[35367+(i<<1)+1>>0]|0;u=t|4;i=t|7;a[j+i>>0]=a[m+i>>0]|0;i=t|6;s=d[m+u>>0]|0;a[j+i>>0]=a[m+i>>0]&15|s<<4;i=t|5;r=(d[m+i>>0]|0)>>>1&255;a[j+u>>0]=s&240|a[35367+(r<<1)>>0];a[j+i>>0]=a[35367+(r<<1)+1>>0]|0;i=t|8;r=t|11;a[j+r>>0]=a[m+r>>0]|0;r=t|10;u=d[m+i>>0]|0;a[j+r>>0]=a[m+r>>0]&15|u<<4;r=t|9;s=(d[m+r>>0]|0)>>>1&255;a[j+i>>0]=u&240|a[35367+(s<<1)>>0];a[j+r>>0]=a[35367+(s<<1)+1>>0]|0;r=t|12;s=t|15;a[j+s>>0]=a[m+s>>0]|0;s=t|14;i=d[m+r>>0]|0;a[j+s>>0]=a[m+s>>0]&15|i<<4;t=t|13;s=(d[m+t>>0]|0)>>>1&255;a[j+r>>0]=i&240|a[35367+(s<<1)>>0];a[j+t>>0]=a[35367+(s<<1)+1>>0]|0;h=h+1|0}while((h|0)!=64);if((ko(j,1,1024,e)|0)!=1024){k=-1;i=16;break}if((g|0)<(f|0))g=g+1|0;else{n=0;i=13;break}}if((i|0)==13){do{f=c[p+(n<<2)>>2]|0;if(f|0){dm(b,c[o+(n<<2)>>2]|0,0)|0;ag(e,b,f)}n=n+1|0}while((n|0)!=31);k=0;l=q;return k|0}else if((i|0)==16){l=q;return k|0}return 0}function Vg(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;if((e|0)<1084){c=1084-e|0;return c|0}if((Vj(b+1080|0)|0)==1294879534){e=0;g=0}else{c=-1;return c|0}do{k=b+(e*30|0)|0;f=k+42|0;f=((Rj(a[f>>0]|0,a[f+1>>0]|0)|0)&65535)<<1;j=k+46|0;j=(Rj(a[j>>0]|0,a[j+1>>0]|0)|0)&65535;k=k+48|0;if((f+2|0)>>>0<((Rj(a[k>>0]|0,a[k+1>>0]|0)|0)&65535)+j<<1>>>0){i=-1;h=16;break}g=f+g|0;e=e+1|0}while((e|0)<31);if((h|0)==16)return i|0;if((g|0)<3){k=-1;return k|0}else f=0;while(1){e=b+(f*30|0)|0;if(((a[e+40>>0]|0)+8&255)>15){i=-1;h=16;break}if(a[e+44>>0]|0){i=-1;h=16;break}f=f+1|0;if((d[e+45>>0]|0)>64){i=-1;h=16;break}if((f|0)>=31){h=11;break}}if((h|0)==11){e=Xg(b)|0;if((e|0)<0){k=-1;return k|0}a:do if(e|0){f=0;while(1){if((d[b+((f*3|0)+1084)>>0]|0)>116){i=-1;break}f=f+1|0;if((f|0)>=(e|0))break a}return i|0}while(0);eg(b,c,20);k=0;return k|0}else if((h|0)==16)return i|0;return 0}function Wg(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0;p=l;l=l+1040|0;o=p;ag(c,b,20);g=0;n=0;do{ag(c,b,20);Wj(c,0);Wj(c,0);e=Pl(b)|0;f=(Pl(b)|0)&255;e=(e&255)<<8|f;do if(e)if(e>>>0<256){e=16-f&255;break}else{e=256-f&255;break}else e=0;while(0);f=Ul(b)|0;i=f&65535;Xj(c,f);n=(i<<1)+n|0;Pl(b)|0;Wj(c,e);Wj(c,Pl(b)|0);f=Ul(b)|0;k=f&65535;m=Ul(b)|0;j=k<<1;Xj(c,(f<<16>>16!=0&(j+(m&65535)|0)>>>0<=i>>>0?j:k)&65535);Xj(c,m);g=g+1|0}while((g|0)!=31);Wj(c,Pl(b)|0);Wj(c,127);Pl(b)|0;cm(o,128,1,b)|0;ko(o,128,1,c)|0;e=0;f=0;do{m=a[o+e>>0]|0;f=(m&255)>(f&255)?m:f;e=e+1|0}while((e|0)!=128);f=f+1<<24>>24;Yj(c,1294879534);dm(b,1080,0)|0;e=am(b)|0;a:do if((e|0)>=1294879534)if((e|0)<1431193923)switch(e|0){case 1294879534:break a;default:{h=10;break a}}else switch(e|0){case 1431193923:break a;default:{h=10;break a}}else switch(e|0){case 0:break;default:h=10}while(0);if((h|0)==10)dm(b,-4,1)|0;m=f&255;b:do if(f<<24>>24){j=0;c:while(1){k=0;do{e=Pl(b)|0;i=Pl(b)|0;g=Pl(b)|0;if(gm(b)|0){e=-1;h=20;break c}h=e&255;f=h&63;if(f>>>0>36){e=-1;h=20;break c}if((i&15)==13)e=((((g&255)/10|0)&255)<<4|((g&255)%10|0)&255)&255;else e=g;g=k<<2;a[o+g>>0]=d[35367+(f<<1)>>0]|0|h>>>2&16;a[o+(g|1)>>0]=a[35367+(f<<1)+1>>0]|0;a[o+(g|2)>>0]=i;a[o+(g|3)>>0]=e;k=k+1|0}while((k|0)<256);ko(o,1024,1,c)|0;j=j+1|0;if((j|0)>=(m|0))break b}if((h|0)==20){l=p;return e|0}}while(0);ag(c,b,n);o=0;l=p;return o|0}function Xg(b){b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0;g=a[b+950>>0]|0;e=g&255;if(g<<24>>24<1){b=-1;return b|0}else{c=0;g=0}do{i=a[b+(c+952)>>0]|0;f=i&255;if(i<<24>>24<0){d=-1;h=7;break}g=(f|0)>(g|0)?f:g;c=c+1|0}while((c|0)<(e|0));if((h|0)==7)return d|0;d=(g<<8)+256|0;if((c|0)==128){i=d;return i|0}while(1){if(a[b+(c+952)>>0]|0){d=-1;h=7;break}c=c+1|0;if((c|0)==128){h=7;break}}if((h|0)==7)return d|0;return 0}function Yg(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;if((d|0)<1084){c=1084-d|0;return c|0}if(!(Vj(b+1080|0)|0)){c=-1;return c|0}e=Zg(b)|0;if((e|0)<0){c=-1;return c|0}f=Xg(b)|0;if((f|0)<0){c=-1;return c|0}if((_g(b,d,f,e,1080)|0)<0){c=-1;return c|0}d=a[b>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+1>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+2>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+3>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+4>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+5>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+6>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+7>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+8>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+9>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+10>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+11>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+12>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+13>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+14>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+15>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+16>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+17>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+18>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}d=a[b+19>>0]|0;if((d&255)>180|(d+-1&255)<31){c=-1;return c|0}eg(b,c,20);c=0;return c|0}function Zg(b){b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;h=0;i=0;j=0;while(1){c=b+(h*30|0)|0;d=c+42|0;d=Rj(a[d>>0]|0,a[d+1>>0]|0)|0;e=(d&65535)<<1;f=c+46|0;f=Rj(a[f>>0]|0,a[f+1>>0]|0)|0;g=c+48|0;g=Rj(a[g>>0]|0,a[g+1>>0]|0)|0;j=e+j|0;if(g<<16>>16?(e+2|0)>>>0<(g&65535)+(f&65535)<<1>>>0:0){c=-1;d=10;break}if((f|d|g)<<16>>16<0){c=-1;d=10;break}e=a[c+45>>0]|0;if((e&255)>64){c=-1;d=10;break}k=c+40|0;k=Rj(a[k>>0]|0,a[k+1>>0]|0)|0;c=d<<16>>16==0;if(c&k<<16>>16!=0|(k+-9&65535)<238){c=-1;d=10;break}if(f<<16>>16!=0&(g&65535)<2|c&e<<24>>24!=0){c=-1;d=10;break}h=h+1|0;i=c?i:h;if((h|0)>=31){d=9;break}}if((d|0)==9){k=(j|0)<3?-1:i;return k|0}else if((d|0)==10)return c|0;return 0}function _g(b,c,d,e,f){b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0;g=(d*3|0)+2+f|0;if((g|0)>(c|0)){d=g-c|0;return d|0}if((d|0)<=0){d=0;return d|0}h=b+f|0;i=0;while(1){g=h+(i*3|0)|0;f=a[g>>0]|0;if((f&255)>116|(f&63)>36){g=-1;b=10;break}c=a[g+1>>0]&15;g=a[g+2>>0]|0;b=(g&255)>64;if(c<<24>>24==12&b){g=-1;b=10;break}if(c<<24>>24==11&g<<24>>24<0|c<<24>>24==13&b){g=-1;b=10;break}i=i+1|0;if(((g&255)>>>4|(f&255)>>>2&48|0)>(e|0)){g=-1;b=10;break}if((i|0)>=(d|0)){g=0;b=10;break}}if((b|0)==10)return g|0;return 0}function $g(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;if((c|0)>=1084)if((((Vj(a+1080|0)|0)==0?(d=Zg(a)|0,(d|0)>=0):0)?(e=Xg(a)|0,(e|0)>=0):0)?(_g(a,c,e,d,1084)|0)>=0:0){eg(a,b,20);d=0}else d=-1;else d=1084-c|0;return d|0}function ah(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;if((d|0)<1084){c=1084-d|0;return c|0}if(!(Vj(b+1080|0)|0)){c=-1;return c|0}else{i=0;l=0;j=0}while(1){g=b+(i*30|0)|0;h=g+22|0;h=Rj(a[h>>0]|0,a[h+1>>0]|0)|0;m=(h&65535)<<1;f=g+26|0;f=Rj(a[f>>0]|0,a[f+1>>0]|0)|0;e=g+28|0;e=Rj(a[e>>0]|0,a[e+1>>0]|0)|0;j=m+j|0;if((m+2|0)>>>0<(e&65535)+(f&65535)<<1>>>0){k=-1;i=26;break}if((f|h|e)<<16>>16<0){k=-1;i=26;break}f=a[g+25>>0]|0;if((f&255)>64){k=-1;i=26;break}m=g+20|0;e=h<<16>>16==0;if(e&((Rj(a[m>>0]|0,a[m+1>>0]|0)|0)<<16>>16!=0|f<<24>>24!=0)){k=-1;i=26;break}i=i+1|0;l=e?l:i;if((i|0)>=31){i=9;break}}if((i|0)==9){if((j|0)<3){m=-1;return m|0}m=a[b+930>>0]|0;f=m&255;if(m<<24>>24<1){m=-1;return m|0}else{g=0;h=0}while(1){m=a[b+(g+932)>>0]|0;e=m&255;if(m<<24>>24<0){k=-1;i=26;break}h=(e|0)>(h|0)?e:h;e=g+1|0;if((e|0)>=(f|0))break;else g=e}if((i|0)==26)return k|0;e=g+3|0;k=(h<<8)+256|0;a:do if((e|0)!=128){while(1){if(a[b+(e+932)>>0]|0){k=-1;break}e=e+1|0;if((e|0)==128)break a}return k|0}while(0);e=(k*3|0)+1062|0;if((e|0)>(d|0)){m=e-d|0;return m|0}b:do if((k|0)>0){i=b+1060|0;j=0;while(1){e=i+(j*3|0)|0;h=a[e>>0]|0;if((h&255)>116|(h&63)>36){k=-1;i=26;break}g=a[e+1>>0]&15;e=a[e+2>>0]|0;f=(e&255)>64;if(g<<24>>24==12&f){k=-1;i=26;break}if(g<<24>>24==11&e<<24>>24<0|g<<24>>24==13&f){k=-1;i=26;break}j=j+1|0;if(((e&255)>>>4|(h&255)>>>2&48|0)>(l|0)){k=-1;i=26;break}if((j|0)>=(k|0))break b}if((i|0)==26)return k|0}while(0);eg(0,c,0);m=0;return m|0}else if((i|0)==26)return k|0;return 0}function bh(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0;o=l;l=l+1040|0;n=o;bg(c,20);g=0;m=0;do{ag(c,b,20);Wj(c,0);Wj(c,0);e=Pl(b)|0;f=(Pl(b)|0)&255;e=(e&255)<<8|f;do if(e)if(e>>>0<256){e=16-f&255;break}else{e=256-f&255;break}else e=0;while(0);f=Ul(b)|0;h=f&65535;Xj(c,f);m=(h<<1)+m|0;Pl(b)|0;Wj(c,e);Wj(c,Pl(b)|0);f=Ul(b)|0;j=f&65535;k=Ul(b)|0;i=j<<1;Xj(c,(f<<16>>16!=0&(i+(k&65535)|0)>>>0<=h>>>0?i:j)&65535);Xj(c,k);g=g+1|0}while((g|0)!=31);Wj(c,Pl(b)|0);Wj(c,127);Pl(b)|0;cm(n,128,1,b)|0;ko(n,128,1,c)|0;e=0;f=0;do{k=a[n+e>>0]|0;f=(k&255)>(f&255)?k:f;e=e+1|0}while((e|0)!=128);k=f+1<<24>>24;Yj(c,1294879534);h=k&255;a:do if(k<<24>>24){j=0;b:while(1){k=0;do{i=Pl(b)|0;g=Pl(b)|0;e=Pl(b)|0;i=i&255;f=i&63;if(f>>>0>36){e=-1;break b}if((g&15)==13)e=((((e&255)/10|0)&255)<<4|((e&255)%10|0)&255)&255;p=k<<2;a[n+p>>0]=d[35367+(f<<1)>>0]|0|i>>>2&16;a[n+(p|1)>>0]=a[35367+(f<<1)+1>>0]|0;a[n+(p|2)>>0]=g;a[n+(p|3)>>0]=e;k=k+1|0}while((k|0)<256);ko(n,1024,1,c)|0;j=j+1|0;if((j|0)>=(h|0))break a}l=o;return e|0}while(0);ag(c,b,m);p=0;l=o;return p|0}function ch(b,c,d){b=b|0;c=c|0;d=d|0;if((d|0)>=1082)if((((a[b+1080>>0]|0)==87?(a[b+1081>>0]|0)==78:0)?(a[b+951>>0]|0)==127:0)?(a[b+950>>0]|0)>=0:0){eg(b,c,20);b=0}else b=-1;else b=1082-d|0;return b|0}function dh(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0;n=l;l=l+1024|0;g=n;ag(c,b,950);e=0;m=0;do{dm(b,(e*30|0)+42|0,0)|0;m=(((Ul(b)|0)&65535)<<1)+m|0;e=e+1|0}while((e|0)!=31);dm(b,950,0)|0;Wj(c,Pl(b)|0);cm(g,129,1,b)|0;ko(g,129,1,c)|0;Yj(c,1294879534);e=0;f=0;do{e=e+1|0;k=a[g+e>>0]|0;f=(k&255)>(f&255)?k:f}while((e|0)!=128);k=f+1<<24>>24;dm(b,1084,0)|0;i=k&255;a:do if(k<<24>>24){j=0;b:while(1){k=0;do{e=Pl(b)|0;f=Pl(b)|0;g=Pl(b)|0;h=Pl(b)|0;if((e&255)>73|(gm(b)|0)!=0){e=-1;break b}o=(e&255)>>>1&255;Wj(c,(d[35367+(o<<1)>>0]|0|(e&255)*240)&255);Wj(c,a[35367+(o<<1)+1>>0]|0);Wj(c,((f&255)<<4|g&255)&255);Wj(c,h);k=k+1|0}while((k|0)<256);j=j+1|0;if((j|0)>=(i|0))break a}l=n;return e|0}while(0);ag(c,b,m);o=0;l=n;return o|0}function eh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if((e|0)<505){c=505-e|0;return c|0}l=Vj(b)|0;if((l+-502|0)>>>0>2162688){c=-1;return c|0}else g=0;while(1){f=b+(g<<4)|0;if((d[f+9>>0]|0)>64){k=-1;j=15;break}j=f+6|0;g=g+1|0;if((((Rj(a[j>>0]|0,a[j+1>>0]|0)|0)&65535)%72|0)<<16>>16){k=-1;j=15;break}if((g|0)>=31){j=5;break}}if((j|0)==5){f=b+10|0;g=b+12|0;h=b+14|0;i=0;do{o=i<<4;m=f+o|0;m=Rj(a[m>>0]|0,a[m+1>>0]|0)|0;n=g+o|0;n=Rj(a[n>>0]|0,a[n+1>>0]|0)|0;i=i+1|0;if(!((Vj(h+o|0)|0)>=(l|0)&(n|m)<<16>>16>-1)){k=-1;j=15;break}}while((i|0)<31);if((j|0)==15)return k|0;f=a[b+5>>0]|0;if(f<<24>>24<1){o=-1;return o|0}g=(f&255)<<2;f=l+4+g|0;if((f|0)>(e|0)){o=f-e|0;return o|0}if((Vj(b+l+g|0)|0)!=-1){o=-1;return o|0}eg(0,c,0);o=0;return o|0}else if((j|0)==15)return k|0;return 0}function fh(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;t=l;l=l+2176|0;s=t+1152|0;q=t+1024|0;p=t+512|0;r=t;gp(p|0,0,512)|0;gp(r|0,0,512)|0;f=q;g=f+128|0;do{a[f>>0]=0;f=f+1|0}while((f|0)<(g|0));g=am(b)|0;f=Pl(b)|0;h=Pl(b)|0;k=h&255;if(h<<24>>24<0){s=-1;l=t;return s|0}o=f&255;if(f<<24>>24<0){s=-1;l=t;return s|0}bg(e,20);f=0;m=999999;n=0;do{bg(e,22);i=(((Ul(b)|0)&65535)/72|0)&255;Pl(b)|0;j=Pl(b)|0;u=Ul(b)|0;Xj(e,u);n=((u&65535)<<1)+n|0;Wj(e,i);Wj(e,j);j=Ul(b)|0;i=am(b)|0;m=(i|0)<(m|0)?i:m;Xj(e,((am(b)|0)-i|0)>>>1&65535);Xj(e,j);f=f+1|0}while((f|0)!=31);Wj(e,h);Wj(e,127);dm(b,g,0)|0;if(h<<24>>24){f=0;do{c[p+(f<<2)>>2]=am(b)|0;f=f+1|0}while((f|0)!=(k|0));i=c[p>>2]|0;f=0;j=0;do{if(j){a:do if((j|0)>0){h=c[p+(j<<2)>>2]|0;g=0;while(1){if((h|0)==(c[p+(g<<2)>>2]|0))break;g=g+1|0;if((g|0)>=(j|0))break a}a[q+j>>0]=a[q+g>>0]|0}else g=0;while(0);if((g|0)==(j|0)){c[r+((f&255)<<2)>>2]=c[p+(j<<2)>>2];a[q+j>>0]=f;f=f+1<<24>>24}}else{a[q>>0]=0;c[r>>2]=i;f=f+1<<24>>24}j=j+1|0}while((j|0)!=(k|0))}ko(q,128,1,e)|0;Yj(e,1294879534);f=0;while(1){gp(s|0,0,1024)|0;dm(b,c[r+(f<<2)>>2]|0,0)|0;do{u=Pl(b)|0;i=Pl(b)|0;k=Pl(b)|0;p=Pl(b)|0;i=i&255;j=i>>>1&63;u=u&255;q=s+(u<<2)|0;a[q>>0]=d[35367+(j<<1)>>0]|0|i<<4&16;a[q+1>>0]=a[35367+(j<<1)+1>>0]|0;a[q+2>>0]=k;a[q+3>>0]=p}while((u+1|0)>>>0<256);ko(s,1024,1,e)|0;if((f|0)==(o|0))break;else f=f+1|0}dm(b,m,0)|0;ag(e,b,n);u=0;l=t;return u|0}function gh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0;if((e|0)<1024){h=1024-e|0;return h|0}if(nn(b,35885,4)|0){h=-1;return h|0}f=Vj(b+4|0)|0;if((f+-794|0)>>>0>2128384){h=-1;return h|0}else c=0;while(1){e=b+(c<<3)+32|0;if((d[e>>0]|0)>15){h=-1;e=14;break}c=c+1|0;if((d[e+1>>0]|0)>=65){h=-1;e=14;break}if((c|0)>=31){e=8;break}}if((e|0)==8){g=Vj(b+28|0)|0;if((g|0)==0|(g|0)>(f|0)){h=-1;return h|0}else g=0;while(1){f=b+(g<<3)+32|0;e=f+2|0;e=Rj(a[e>>0]|0,a[e+1>>0]|0)|0;c=f+4|0;c=Rj(a[c>>0]|0,a[c+1>>0]|0)|0;f=f+6|0;f=Rj(a[f>>0]|0,a[f+1>>0]|0)|0;if((c|e|f)<<16>>16<0){h=-1;e=14;break}if((f&65535)+(c&65535)<<1>>>0>(((e&65535)<<1)+2|0)>>>0){h=-1;e=14;break}g=g+1|0;if(!(c<<16>>16==0|f<<16>>16!=0)){h=-1;e=14;break}if((g|0)>=31){e=13;break}}if((e|0)==13){h=(a[b+281>>0]|0)+-1<<24>>24<<24>>24>>7<<24>>24;return h|0}else if((e|0)==14)return h|0}else if((e|0)==14)return h|0;return 0}function hh(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;v=l;l=l+2176|0;q=v+2048|0;u=v+1024|0;o=v+512|0;t=v;gp(o|0,0,512)|0;gp(t|0,0,512)|0;f=q;g=f+128|0;do{a[f>>0]=0;f=f+1|0}while((f|0)<(g|0));am(b)|0;am(b)|0;ag(e,b,20);r=am(b)|0;f=0;s=0;do{bg(e,22);k=Pl(b)|0;m=Pl(b)|0;j=Ul(b)|0;Xj(e,j);s=((j&65535)<<1)+s|0;Wj(e,k);Wj(e,m);Xj(e,Ul(b)|0);Xj(e,Ul(b)|0);f=f+1|0}while((f|0)!=31);m=((Ul(b)|0)&65535)+1|0;Wj(e,m&255);Wj(e,127);m=m&255;if(m){h=0;f=999999;do{g=am(b)|0;c[o+(h<<2)>>2]=g;if(gm(b)|0){i=-1;p=29;break}f=(f|0)>(g|0)?g:f;h=h+1|0}while((h|0)<(m|0));if((p|0)==29){l=v;return i|0}k=c[o>>2]|0;a[q>>0]=0;c[t>>2]=k;if(m>>>0>1){k=1;g=1;do{h=c[o+(k<<2)>>2]|0;j=0;while(1){if((h|0)==(c[o+(j<<2)>>2]|0)){p=10;break}i=j+1|0;if((i|0)<(k|0))j=i;else{n=i;break}}if((p|0)==10){p=0;a[q+k>>0]=a[q+j>>0]|0;n=j}if((n|0)==(k|0)){c[t+((g&255)<<2)>>2]=h;a[q+k>>0]=g;g=g+1<<24>>24}k=k+1|0}while((k|0)!=(m|0))}else g=1}else{a[q>>0]=0;c[t>>2]=0;g=1;f=999999}ko(q,128,1,e)|0;Yj(e,1294879534);o=g&255;a:do if(g<<24>>24){k=794-f|0;m=0;b:while(1){if((dm(b,k+(c[t+(m<<2)>>2]|0)|0,0)|0)<0){i=-1;p=29;break}gp(u|0,0,1024)|0;n=0;do{j=u+(n<<2)|0;h=Pl(b)|0;i=h&255;if(h<<24>>24!=-64){if((i&192|0)==128){g=Pl(b)|0;f=i>>>2&15}else{f=Pl(b)|0;g=Pl(b)|0;if((h&255)>73){i=-1;p=29;break b}q=(h&255)>>>1&255;a[j>>0]=d[35367+(q<<1)>>0]|0|i<<4&16;a[j+1>>0]=a[35367+(q<<1)+1>>0]|0}a[j+2>>0]=f;a[j+3>>0]=g}n=n+1|0}while((n|0)<256);ko(u,1024,1,e)|0;m=m+1|0;if((m|0)>=(o|0))break a}if((p|0)==29){l=v;return i|0}}while(0);if((dm(b,r,0)|0)<0){u=-1;l=v;return u|0}ag(e,b,s);u=0;l=v;return u|0}function ih(a,b,c){a=a|0;b=b|0;c=c|0;return lh(a,b,c,35908)|0}function jh(a,b){a=a|0;b=b|0;return kh(a,b,3)|0}function kh(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;A=l;l=l+3264|0;n=A+3128|0;y=A+2104|0;m=A+2048|0;z=A;gp(z|0,0,2048)|0;i=n;j=i+128|0;do{a[i>>0]=0;i=i+1|0}while((i|0)<(j|0));dm(b,8,1)|0;ag(e,b,20);k=((Ul(b)|0)&65535)>>>3&255;g=k&65535;if(k<<16>>16){i=0;h=0;do{bg(e,22);w=Pl(b)|0;x=Pl(b)|0;v=Ul(b)|0;Xj(e,v);h=((v&65535)<<1)+h|0;Wj(e,w);Wj(e,x);Xj(e,Ul(b)|0);Xj(e,Ul(b)|0);i=i+1|0}while((i|0)<(g|0));i=m;j=i+29|0;do{a[i>>0]=0;i=i+1|0}while((i|0)<(j|0));a[m+29>>0]=1;if((k&65535)<31)o=5;else x=h}else{i=m;j=i+29|0;do{a[i>>0]=0;i=i+1|0}while((i|0)<(j|0));a[m+29>>0]=1;g=0;h=0;o=5}if((o|0)==5){do{ko(m,30,1,e)|0;g=g+1|0}while((g|0)!=31);x=h}Pl(b)|0;g=Pl(b)|0;Wj(e,g);i=g&255;if(g<<24>>24<0){f=-1;l=A;return f|0}Wj(e,127);if(!(g<<24>>24))g=0;else{h=0;g=0;do{v=((Ul(b)|0)&65535)>>>3;w=v&255;a[n+h>>0]=w;g=(v&255)>>>0>(g&255)>>>0?w:g;h=h+1|0}while((h|0)!=(i|0))}w=g&255;g=0;h=0;while(1){v=(Ul(b)|0)&65535;c[z+(g<<4)>>2]=v;v=(v|0)>(h|0)?v:h;u=(Ul(b)|0)&65535;c[z+(g<<4)+4>>2]=u;v=(u|0)>(v|0)?u:v;u=(Ul(b)|0)&65535;c[z+(g<<4)+8>>2]=u;v=(u|0)>(v|0)?u:v;u=(Ul(b)|0)&65535;c[z+(g<<4)+12>>2]=u;h=(u|0)>(v|0)?u:v;if((g|0)==(w|0))break;else g=g+1|0}ko(n,128,1,e)|0;Yj(e,1294879534);t=(em(b)|0)+2|0;u=(f|0)==2;s=u?2:1;v=0;g=h;a:while(1){gp(y|0,0,1024)|0;r=0;do{dm(b,t+(c[z+(v<<4)+(r<<2)>>2]|0)|0,0)|0;q=r<<2;h=0;b:while(1){p=y+(h<<4)+q|0;m=Pl(b)|0;k=m&255;j=k&192;do if((j|0)==192){i=25;h=h+255-k|0}else{i=Pl(b)|0;if((j|0)==128){o=k>>>s;m=o&15;k=m&255;c:do switch(o&15){case 10:case 6:case 5:{j=i&255;if((i&255)>128){i=256-j&255;break c}else{i=j<<4&255;break c}}default:{}}while(0);a[p+2>>0]=(m|0)==8?0:k;a[p+3>>0]=i;i=25;break}n=i&255;o=k>>>2;if(u){k=k>>>1;if((m&255)>73){i=1;break}j=n&15;if(!j){a[p>>0]=d[35367+(k<<1)>>0]|0|o&16;a[p+1>>0]=a[35367+(k<<1)+1>>0]|0;a[p+2>>0]=i;i=25;break}}else{k=(k&64|0)==0?k&63:127-k|0;i=k&255;if(i>>>0>36){i=1;break}j=n&15;if(!j){a[p>>0]=d[35367+(i<<1)>>0]|0|o&16;a[p+1>>0]=a[35367+(i<<1)+1>>0]|0;a[p+2>>0]=n&240;i=25;break}}j=j&255;i=Pl(b)|0;j=j<<24>>24==8?0:j;m=j&255;d:do switch(j&15){case 10:case 6:case 5:{j=i&255;if((i&255)>128){i=256-j&255;break d}else{i=j<<4&255;break d}}default:{}}while(0);k=k&255;a[p>>0]=d[35367+(k<<1)>>0]|0|o&16;a[p+1>>0]=a[35367+(k<<1)+1>>0]|0;a[p+2>>0]=m|n&240;a[p+3>>0]=i;i=0}while(0);switch(i&31){case 25:case 0:break;default:{o=38;break b}}h=h+1|0;if(h>>>0>=64){o=37;break}}if((o|0)==37){h=em(b)|0;if((h|0)<0){g=-1;o=42;break a}else g=(h|0)>(g|0)?h:g}else if((o|0)==38)if(i){g=-1;o=42;break a}r=r+1|0}while((r|0)<4);ko(y,1024,1,e)|0;if((v|0)<(w|0))v=v+1|0;else{o=41;break}}if((o|0)==41){dm(b,((f|0)>2&(g&1|0)!=0&1)+g|0,0)|0;ag(e,b,x);f=0;l=A;return f|0}else if((o|0)==42){l=A;return g|0}return 0}function lh(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0;if((e|0)<1024){c=1024-e|0;return c|0}if(nn(b,f,8)|0){c=-1;return c|0}h=Rj(a[b+28>>0]|0,a[b+29>>0]|0)|0;f=h&65535;if(!(h<<16>>16!=0&(f&7|0)==0)){c=-1;return c|0}h=f>>>3;if(!h){c=-1;return c|0}else e=0;while(1){f=b+(e<<3)|0;if((d[f+30>>0]|0)>15){j=-1;f=15;break}e=e+1|0;if((d[f+31>>0]|0)>=65){j=-1;f=15;break}if((e|0)>=(h|0)){i=0;k=0;f=9;break}}if((f|0)==9){while(1){e=b+(i<<3)|0;l=e+32|0;l=Rj(a[l>>0]|0,a[l+1>>0]|0)|0;g=(l&65535)<<1;f=e+34|0;f=Rj(a[f>>0]|0,a[f+1>>0]|0)|0;e=e+36|0;e=Rj(a[e>>0]|0,a[e+1>>0]|0)|0;if((f|l|e)<<16>>16<0){j=-1;f=15;break}if(f<<16>>16!=0&e<<16>>16==0|(e&65535)+(f&65535)<<1>>>0>(g+2|0)>>>0){j=-1;f=15;break}k=g+k|0;i=i+1|0;if((i|0)>=(h|0)){f=12;break}}if((f|0)==12){if((k|0)<5){l=-1;return l|0}if((a[b+((h<<3)+31)>>0]|0)+-1<<24>>24<<24>>24<0){l=-1;return l|0}eg(b+8|0,c,20);l=0;return l|0}else if((f|0)==15)return j|0}else if((f|0)==15)return j|0;return 0}function mh(a,b,c){a=a|0;b=b|0;c=c|0;return lh(a,b,c,35935)|0}function nh(a,b){a=a|0;b=b|0;return kh(a,b,2)|0}function oh(a,b,c){a=a|0;b=b|0;c=c|0;switch(Vj(a)|0){case 1345597505:case 1345597506:case 1345597761:{eg(0,b,0);a=0;break}default:a=-1}return a|0}function ph(d,f){d=d|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0;J=l;l=l+133376|0;D=J+132344|0;E=J+1272|0;z=J+248|0;F=J+124|0;G=J;gp(z|0,0,1024)|0;gp(E|0,0,131072)|0;h=F;i=h+124|0;do{c[h>>2]=0;h=h+4|0}while((h|0)<(i|0));h=G;i=h+124|0;do{c[h>>2]=0;h=h+4|0}while((h|0)<(i|0));h=am(d)|0;Pl(d)|0;g=Pl(d)|0;C=g&255;if(g<<24>>24<0){f=-1;l=J;return f|0}r=Pl(d)|0;I=r&255;if((r&255)>31){f=-1;l=J;return f|0}Pl(d)|0;t=am(d)|0;s=am(d)|0;H=am(d)|0;if(gm(d)|0){f=-1;l=J;return f|0}bg(f,20);B=r<<24>>24==0;if(!B){q=(h+-1345597505|0)>>>0<2;o=(h|0)==1345597761;p=0;do{i=am(d)|0;c[F+(p<<2)>>2]=i;j=Ul(d)|0;c[G+(p<<2)>>2]=(j&65535)<<1;k=am(d)|0;m=Ul(d)|0;if(q)h=Ul(d)|0;else h=0;Pl(d)|0;n=Pl(d)|0;if(o)h=Ul(d)|0;bg(f,22);Xj(f,j);Wj(f,((h<<16>>16)/74|0)&255);Wj(f,n);Xj(f,((k-i|0)/2|0)&65535);Xj(f,m);p=p+1|0}while((p|0)!=(I|0));h=D;i=h+29|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));a[D+29>>0]=1;if((r&255)<31){h=I;A=13}}else{h=D;i=h+29|0;do{a[h>>0]=0;h=h+1|0}while((h|0)<(i|0));a[D+29>>0]=1;h=0;A=13}if((A|0)==13)while(1){A=0;ko(D,30,1,f)|0;h=h+1|0;if((h|0)==31)break;else A=13}Wj(f,g);Wj(f,127);dm(d,s+4|0,0)|0;i=g<<24>>24==0;if(!i){h=0;do{Wj(f,h);h=h+1<<24>>24}while((h&255)<(g&255));if(g<<24>>24>-1)A=17}else{g=0;A=17}if((A|0)==17)while(1){A=0;Wj(f,0);g=g+1<<24>>24;if(g<<24>>24<=-1)break;else A=17}Yj(f,1294879534);y=t+4|0;if(i)dm(d,y,0)|0;else{g=0;do{b[z+(g<<3)>>1]=y+((Ul(d)|0)&65535);b[z+(g<<3)+2>>1]=y+((Ul(d)|0)&65535);b[z+(g<<3)+4>>1]=y+((Ul(d)|0)&65535);b[z+(g<<3)+6>>1]=y+((Ul(d)|0)&65535);g=g+1|0}while((g|0)!=(C|0));dm(d,y,0)|0;v=0;a:while(1){x=v<<2;w=0;do{u=w+x|0;dm(d,e[z+(v<<3)+(w<<1)>>1]|0,0)|0;q=0;do{t=Pl(d)|0;h=Pl(d)|0;j=Pl(d)|0;o=Pl(d)|0;g=t&255;if(t<<24>>24!=-128){i=g<<4&16;p=g>>>1&63;g=a[35367+(p<<1)>>0]|0;p=a[35367+(p<<1)+1>>0]|0;switch(h&15){case 8:{n=(h&255)+248&255;break}case 10:case 6:case 5:{if(j<<24>>24<0){n=h;j=(j&255)<<4&255}else n=h;break}default:n=h}m=q<<2;k=(g&15|i)&255;a[E+(u<<8)+m>>0]=k;a[(m|1)+(E+(u<<8))>>0]=p;a[(m|2)+(E+(u<<8))>>0]=n;a[(m|3)+(E+(u<<8))>>0]=j;m=o&255;h=o<<24>>24>0?m:0;g=h+q|0;if(o<<24>>24<0){i=h|256;h=256;do{g=g+1|0;t=g<<2;a[E+(u<<8)+t>>0]=k;a[(t|1)+(E+(u<<8))>>0]=p;a[(t|2)+(E+(u<<8))>>0]=n;a[(t|3)+(E+(u<<8))>>0]=j;h=h+-1|0}while((h|0)>(m|0));g=i+q-m|0}}else{t=em(d)|0;if((t|0)<0){g=-1;A=53;break a}dm(d,y+((j&255)<<8|o&255)|0,0)|0;s=h&255;r=0;while(1){p=Pl(d)|0;g=Pl(d)|0;h=Pl(d)|0;n=Pl(d)|0;p=p&255;j=p<<4&16;p=p>>>1&63;i=a[35367+(p<<1)>>0]|0;p=a[35367+(p<<1)+1>>0]|0;switch(g&15){case 8:{o=(g&255)+248&255;break}case 10:case 6:case 5:{if(h<<24>>24<0){o=g;h=(h&255)<<4&255}else o=g;break}default:o=g}k=(i&15|j)&255;m=q<<2;a[E+(u<<8)+m>>0]=k;a[(m|1)+(E+(u<<8))>>0]=p;a[(m|2)+(E+(u<<8))>>0]=o;a[(m|3)+(E+(u<<8))>>0]=h;m=n&255;i=n<<24>>24>0?m:0;g=i+q|0;if(n<<24>>24<0){j=i|256;i=256;do{g=g+1|0;n=g<<2;a[E+(u<<8)+n>>0]=k;a[(n|1)+(E+(u<<8))>>0]=p;a[(n|2)+(E+(u<<8))>>0]=o;a[(n|3)+(E+(u<<8))>>0]=h;i=i+-1|0}while((i|0)>(m|0));g=j+q-m|0}if((r|0)==(s|0))break;else{r=r+1|0;q=g+1|0}}dm(d,t,0)|0}q=g+1|0}while((q|0)<64);w=w+1|0}while((w|0)<4);v=v+1|0;if((v|0)>=(C|0)){m=0;break}}if((A|0)==53){l=J;return g|0}do{gp(D|0,0,1024)|0;k=m<<2;g=k|1;h=k|2;i=k|3;j=0;do{A=j<<4;w=j<<2;x=w|1;y=w|2;z=w|3;a[D+A>>0]=a[E+(k<<8)+w>>0]|0;a[D+(A|1)>>0]=a[E+(k<<8)+x>>0]|0;a[D+(A|2)>>0]=a[E+(k<<8)+y>>0]|0;a[D+(A|3)>>0]=a[E+(k<<8)+z>>0]|0;a[D+(A|4)>>0]=a[E+(g<<8)+w>>0]|0;a[D+(A|5)>>0]=a[E+(g<<8)+x>>0]|0;a[D+(A|6)>>0]=a[E+(g<<8)+y>>0]|0;a[D+(A|7)>>0]=a[E+(g<<8)+z>>0]|0;a[D+(A|8)>>0]=a[E+(h<<8)+w>>0]|0;a[D+(A|9)>>0]=a[E+(h<<8)+x>>0]|0;a[D+(A|10)>>0]=a[E+(h<<8)+y>>0]|0;a[D+(A|11)>>0]=a[E+(h<<8)+z>>0]|0;a[D+(A|12)>>0]=a[E+(i<<8)+w>>0]|0;a[D+(A|13)>>0]=a[E+(i<<8)+x>>0]|0;a[D+(A|14)>>0]=a[E+(i<<8)+y>>0]|0;a[D+(A|15)>>0]=a[E+(i<<8)+z>>0]|0;j=j+1|0}while((j|0)!=64);ko(D,1024,1,f)|0;m=m+1|0}while((m|0)!=(C|0))}if(B){f=0;l=J;return f|0}else g=0;do{dm(d,(c[F+(g<<2)>>2]|0)+H|0,0)|0;ag(f,d,c[G+(g<<2)>>2]|0);g=g+1|0}while((g|0)!=(I|0));g=0;l=J;return g|0}function qh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;if((e|0)<2048){i=2048-e|0;return i|0}if((a[b+3>>0]|0)==60)e=0;else{i=-1;return i|0}while(1){j=Vj(b+(e<<2)|0)|0;e=e+1|0;if(!(j>>>0<132157&(j&-4|0)==(j|0))){h=-1;i=14;break}if((e|0)>=128){f=0;break}}if((i|0)==14)return h|0;a:while(1){switch(a[b+(f<<2|3)>>0]|0){case 0:case 60:break;default:{h=-1;i=14;break a}}f=f+1|0;if((f|0)>=64){g=0;break}}if((i|0)==14)return h|0;do{if((d[b+((g<<4)+519)>>0]|0)>64){h=-1;i=14;break}g=g+1|0}while((g|0)<31);if((i|0)==14)return h|0;g=b+526|0;e=b+520|0;f=0;while(1){if((f|0)>=30)break;b=Vj(g+(f<<4)|0)|0;f=f+1|0;j=Vj(e+(f<<4)|0)|0;if(b>>>0>j>>>0|(b>>>0<2108|j>>>0<2108)){h=-1;i=14;break}}if((i|0)==14)return h|0;eg(0,c,0);j=0;return j|0}function rh(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0;q=l;l=l+1168|0;i=q+1032|0;p=q;e=i;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));gp(p|0,0,1025)|0;bg(c,20);dm(b,518,0)|0;e=0;o=0;do{bg(c,22);h=Pl(b)|0;j=Pl(b)|0;k=am(b)|0;n=Ul(b)|0;m=am(b)|0;g=Ul(b)|0;Xj(c,g);o=((g&65535)<<1)+o|0;Wj(c,h);Wj(c,j);Xj(c,((k-m|0)/2|0)&65535);Xj(c,n);Ul(b)|0;e=e+1|0}while((e|0)!=31);dm(b,0,0)|0;f=0;h=0;e=0;do{g=am(b)|0;if(!g){f=h&255;break}m=((g+-60|0)/1024|0)+255|0;n=m&255;a[i+h>>0]=n;e=(m&255)>>>0>(e&255)>>>0?n:e;h=h+1|0;f=f+1<<24>>24}while((h&255)<<24>>24>-1);n=e+1<<24>>24;Wj(c,f);Wj(c,127);ko(i,128,1,c)|0;Yj(c,1294879534);dm(b,1084,0)|0;i=n&255;a:do if(n<<24>>24){k=0;b:while(1){m=0;do{h=p+(m<<2)|0;n=((Pl(b)|0)&255)>>>3;f=Pl(b)|0;g=Pl(b)|0;e=Pl(b)|0;if(gm(b)|0){e=-1;f=39;break b}j=f&255;if((f&255)>73){e=-1;f=39;break b}g=g&255;do switch(g>>>2|g<<30|0){case 1:case 0:{f=0;break}case 2:{f=1;break}case 3:{f=2;break}case 4:{f=3;break}case 5:{f=3;break}case 6:{f=4;break}case 7:{f=4;break}case 9:{f=5;break}case 10:{e=((e&255)<<4|(e&255)>>>4&255)&255;f=6;break}case 11:{f=6;break}case 14:{f=9;break}case 15:{e=((e&255)<<4|(e&255)>>>4&255)&255;f=10;break}case 16:{f=10;break}case 17:{f=11;break}case 18:{f=12;break}case 19:{f=13;break}case 20:{f=15;break}case 22:{e=1;f=14;break}case 23:{e=e|16;f=14;break}case 24:{e=e|32;f=14;break}case 33:{e=e|-112;f=14;break}case 34:{e=e|-96;f=14;break}case 35:{e=e|-80;f=14;break}case 37:{e=e|-48;f=14;break}case 38:{e=e|-32;f=14;break}default:{e=0;f=0}}while(0);n=n&255;j=j>>>1;a[h>>0]=d[35367+(j<<1)>>0]|0|n&16;a[h+1>>0]=a[35367+(j<<1)+1>>0]|0;a[h+2>>0]=f|n<<4;a[h+3>>0]=e;m=m+1|0}while((m|0)<256);ko(p,1024,1,c)|0;k=k+1|0;if((k|0)>=(i|0))break a}if((f|0)==39){l=q;return e|0}}while(0);ag(c,b,o);c=0;l=q;return c|0}function sh(a,b,c){a=a|0;b=b|0;c=c|0;return xh(a,b,c,80)|0}function th(a,b){a=a|0;b=b|0;return uh(a,b,80)|0}function uh(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;A=l;l=l+3584|0;p=A+3448|0;k=A+2296|0;q=A+248|0;z=A+124|0;y=A;s=A+2424|0;t=Xm(512,256)|0;if(!t){z=-1;l=A;return z|0}gp(q|0,0,2048)|0;g=p;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));g=z;h=g+124|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));g=k;h=g+124|0;do{c[g>>2]=0;g=g+4|0}while((g|0)<(h|0));c[y>>2]=0;x=(Ul(b)|0)&65535;m=Pl(b)|0;v=m&255;if((m&255)>128){Wm(t);z=-1;l=A;return z|0}u=(Pl(b)|0)&255;o=(f|0)<96;if(!(o|(u&64|0)==0)){Wm(t);z=-1;l=A;return z|0}w=u&63;if(w>>>0>31){Wm(t);z=-1;l=A;return z|0}bg(e,20);r=(w|0)==0;if(!r){j=0;do{bg(e,22);i=Ul(b)|0;g=i&65535;f=k+(j<<2)|0;c[f>>2]=g;if((i&65535)>65280){h=g^65535;i=c[z+(h<<2)>>2]|0;c[z+(j<<2)>>2]=i;g=c[k+(h<<2)>>2]|0;c[f>>2]=g;f=c[y+(h<<2)>>2]|0;h=y}else{f=j+-1|0;if((j|0)>0)c[y+(j<<2)>>2]=(c[z+(f<<2)>>2]|0)+(c[y+(f<<2)>>2]|0);f=g<<1;i=f;h=z}c[h+(j<<2)>>2]=f;Xj(e,g&65535);Wj(e,(Pl(b)|0)&63);Wj(e,Pl(b)|0);f=Ul(b)|0;if(f<<16>>16==-1){Xj(e,0);Xj(e,1)}else{Xj(e,f);Xj(e,((i|0)/2|0)-(f&65535)&65535)}j=j+1|0}while((j|0)!=(w|0));g=s;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[s+29>>0]=1;if(w>>>0<31){f=w;n=21}}else{g=s;h=g+29|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));a[s+29>>0]=1;f=0;n=21}if((n|0)==21)while(1){ko(s,30,1,e)|0;f=f+1|0;if((f|0)==31)break;else n=21}i=m<<24>>24==0;if(!i){f=0;do{c[q+(f<<4)>>2]=(Ul(b)|0)&65535;c[q+(f<<4)+4>>2]=(Ul(b)|0)&65535;c[q+(f<<4)+8>>2]=(Ul(b)|0)&65535;c[q+(f<<4)+12>>2]=(Ul(b)|0)&65535;f=f+1|0}while((f|0)!=(v|0))}h=o&1;f=0;do{g=Pl(b)|0;if(g<<24>>24==-1)break;a[p+f>>0]=(g&255)>>>h;f=f+1|0}while((f|0)<128);Wj(e,f&255);Wj(e,127);ko(p,128,1,e)|0;Yj(e,1294879534);if((vh(b,v,t,q)|0)<0){Wm(t);z=-1;l=A;return z|0}if(!i){g=0;do{gp(s|0,0,1024)|0;i=g<<11;j=i|512;k=i|1024;f=i|1536;h=0;do{q=h<<4;p=h<<2;o=s+q|0;n=t+(i+p)|0;n=d[n>>0]|d[n+1>>0]<<8|d[n+2>>0]<<16|d[n+3>>0]<<24;a[o>>0]=n;a[o+1>>0]=n>>8;a[o+2>>0]=n>>16;a[o+3>>0]=n>>24;o=s+(q|4)|0;n=t+(j+p)|0;n=d[n>>0]|d[n+1>>0]<<8|d[n+2>>0]<<16|d[n+3>>0]<<24;a[o>>0]=n;a[o+1>>0]=n>>8;a[o+2>>0]=n>>16;a[o+3>>0]=n>>24;o=s+(q|8)|0;n=t+(k+p)|0;n=d[n>>0]|d[n+1>>0]<<8|d[n+2>>0]<<16|d[n+3>>0]<<24;a[o>>0]=n;a[o+1>>0]=n>>8;a[o+2>>0]=n>>16;a[o+3>>0]=n>>24;q=s+(q|12)|0;p=t+(f+p)|0;p=d[p>>0]|d[p+1>>0]<<8|d[p+2>>0]<<16|d[p+3>>0]<<24;a[q>>0]=p;a[q+1>>0]=p>>8;a[q+2>>0]=p>>16;a[q+3>>0]=p>>24;h=h+1|0}while((h|0)!=64);ko(s,1024,1,e)|0;g=g+1|0}while((g|0)!=(v|0))}Wm(t);if(r){z=0;l=A;return z|0}i=(u&128|0)!=0;j=0;do{dm(b,(c[y+(j<<2)>>2]|0)+x|0,0)|0;f=c[z+(j<<2)>>2]|0;h=Vm(f)|0;gp(h|0,0,f|0)|0;cm(h,f,1,b)|0;if(i&(f|0)>1){g=a[h>>0]|0;k=1;do{v=h+k|0;g=256-(d[v>>0]|0)+(g&255)&255;a[v>>0]=g;k=k+1|0}while((k|0)!=(f|0))}ko(h,f,1,e)|0;Wm(h);j=j+1|0}while((j|0)!=(w|0));f=0;l=A;return f|0}function vh(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;t=em(a)|0;if((t|0)<0){d=-1;return d|0}if((b|0)>0)u=0;else{d=0;return d|0}a:while(1){w=u<<2;v=0;g=63;while(1){dm(a,(c[e+(u<<4)+(v<<2)>>2]|0)+t|0,0)|0;b:do if((g|0)<0)f=g;else{s=v+w<<9;f=0;while(1){k=d+((f<<2)+s)|0;h=Pl(a)|0;m=Pl(a)|0;n=Pl(a)|0;j=h&255;i=h<<24>>24==-128;c:do if(!(i|(j&128|0)==0)){i=Pl(a)|0;l=(j^255)&255;switch((wh(k,l,m,n)|0)<<24>>24){case 11:case 13:break b;default:{}}h=i&255;if(i<<24>>24>-1){h=h+f|0;break}j=0-h&255;if(!j)h=f;else{i=0;while(1){h=f+1|0;if((f|0)>62)break c;wh(d+((h<<2)+s)|0,l,m,n)|0;i=i+1|0;if((i|0)>=(j|0))break;else f=h}}}else{if(!i)switch((wh(k,h,m,n)|0)<<24>>24){case 11:case 13:break b;default:{h=f;break c}}h=Pl(a)|0;q=em(a)|0;if((q|0)<0){f=-1;r=31;break a}p=m&255;dm(a,0-(h&255|(n&255)<<8)|0,1)|0;o=0;d:while(1){j=d+((f<<2)+s)|0;h=Pl(a)|0;m=Pl(a)|0;n=Pl(a)|0;i=h&255;e:do if(!(h<<24>>24==-128|(i&128|0)==0)){k=Pl(a)|0;l=(i^255)&255;if((f|0)<=63){switch((wh(j,l,m,n)|0)<<24>>24){case 11:case 13:{h=9999;break d}default:{}}h=k&255;if(k<<24>>24>-1){f=h+f|0;break}h=256-h&255;if(!(h<<24>>24)){h=l;r=24}else while(1){h=h+-1<<24>>24;i=f+1|0;if((f|0)>62){h=l;f=i;r=24;break e}wh(d+((i<<2)+s)|0,l,m,n)|0;if(!(h<<24>>24)){h=l;f=i;r=24;break}else f=i}}}else r=24;while(0);if((r|0)==24){r=0;wh(d+((f<<2)+s)|0,h,m,n)|0}if((o|0)<(p|0)){f=f+1|0;o=o+1|0}else{h=f;f=g;break}}dm(a,q,0)|0;g=f}while(0);if((h|0)<(g|0))f=h+1|0;else{f=g;break}}}while(0);v=v+1|0;if((v|0)>=4)break;else g=f}u=u+1|0;if((u|0)>=(b|0)){f=0;r=31;break}}if((r|0)==31)return f|0;return 0}function wh(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;var g=0,h=0,i=0;h=(c&255)>>>1&255;a[b>>0]=d[35367+(h<<1)>>0]|0|(c&255)<<4&16;a[b+1>>0]=a[35367+(h<<1)+1>>0]|0;h=e&255;i=h&15;c=i&255;g=b+3|0;a[b+2>>0]=(i|0)==8?h+248&255:e;switch(e&15){case 10:case 6:case 5:break;default:{i=f;a[g>>0]=i;return c|0}}i=f&255;i=(f<<24>>24<0?256-i<<4:i)&255;a[g>>0]=i;return c|0}function xh(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;m=a[b+2>>0]|0;l=m&255;if(m<<24>>24<1){c=-1;return c|0}q=a[b+3>>0]&63;r=q&255;if((q+-1&255)>30){c=-1;return c|0}else g=0;while(1){h=g*6|0;if((d[b+(h+7)>>0]|0)>64){p=-1;g=33;break}g=g+1|0;if((d[b+(h+6)>>0]|0)>15){p=-1;g=33;break}if((g|0)>=(r|0)){i=0;g=6;break}}if((g|0)==6){while(1){g=b+(i*6|0)|0;h=g+4|0;h=Rj(a[h>>0]|0,a[h+1>>0]|0)|0;if(h<<16>>16==0|(h+32767&65535)<32734){p=-1;g=33;break}q=g+8|0;q=Rj(a[q>>0]|0,a[q+1>>0]|0)|0;if(!(q<<16>>16==-1|(q&65535)<(h&65535))){p=-1;g=33;break}if((h&65535)>65503?(~h&65535)>>>0>r>>>0:0){p=-1;g=33;break}i=i+1|0;if((i|0)>=(r|0)){g=11;break}}if((g|0)==11){q=(Rj(a[b>>0]|0,a[b+1>>0]|0)|0)&65535;g=r*6|0;k=(l<<3|4)+g|0;if(q>>>0>>0){c=-1;return c|0}i=l<<2;a:do if(m<<24>>24){g=b+4+g|0;h=0;while(1){j=g+(h<<1)|0;h=h+1|0;if((k+((Rj(a[j>>0]|0,a[j+1>>0]|0)|0)&65535)|0)>>>0>q>>>0){p=-1;break}if((h|0)>=(i|0))break a}return p|0}while(0);if((k|0)>(e|0)){c=k-e|0;return c|0}g=a[b+k>>0]|0;if(g<<24>>24==-1){c=-1;return c|0}j=(f|0)>95;f=l<<1;h=g;g=g&255;i=0;while(1){if(j){if((h&255)>=(m&255)){p=-1;g=33;break}}else if(g>>>0>f>>>0|(g&1|0)!=0){p=-1;g=33;break}o=i+1|0;n=o+k|0;g=a[b+n>>0]|0;if((i|0)>126|g<<24>>24==-1){g=24;break}else{h=g;g=g&255;i=o}}if((g|0)==24){if((n|0)>(q|0)|(o|128|0)==128){c=-1;return c|0}if((q|0)>=(e|0)){c=1-e+q|0;return c|0}g=k+(i+2)|0;b:do if((g|0)<(q|0)){while(1){i=b+g|0;h=a[i>>0]|0;f=h&255;if(!(f&128)){if((h&255)>73){p=-1;g=33;break}if(((d[i+1>>0]|0)>>>4|f<<4&16)>>>0>r>>>0){p=-1;g=33;break}else h=2}else h=3;g=h+g+1|0;if((g|0)>=(q|0))break b}if((g|0)==33)return p|0}while(0);eg(0,c,0);c=0;return c|0}else if((g|0)==33)return p|0}else if((g|0)==33)return p|0}else if((g|0)==33)return p|0;return 0}function yh(a,b,c){a=a|0;b=b|0;c=c|0;return xh(a,b,c,96)|0}function zh(a,b){a=a|0;b=b|0;return uh(a,b,96)|0}function Ah(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;if((e|0)<1024){b=1024-e|0;return b|0}if((a[b+249>>0]|0)<0){b=-1;return b|0}else{i=0;l=0}while(1){c=b+(i<<3)|0;f=Rj(a[c>>0]|0,a[c+1>>0]|0)|0;j=(f&65535)<<1;h=c+4|0;h=Rj(a[h>>0]|0,a[h+1>>0]|0)|0;k=(h&65535)<<1;g=c+6|0;g=Rj(a[g>>0]|0,a[g+1>>0]|0)|0;l=j+l|0;if(!(g<<16>>16)){m=-1;c=18;break}if(h<<16>>16!=0&g<<16>>16==1){m=-1;c=18;break}if((((g&65535)<<1)+k|0)>>>0>(j+2|0)>>>0){m=-1;c=18;break}if((d[c+2>>0]|0)>15){m=-1;c=18;break}i=i+1|0;if(!(f<<16>>16>-1&((d[c+3>>0]|0)<65&k>>>0<=j>>>0))){m=-1;c=18;break}if((i|0)>=31){c=10;break}}if((c|0)==10){if((l|0)<3){b=-1;return b|0}if((a[b+248>>0]|0)<1){b=-1;return b|0}else{c=0;f=0}do{m=d[b+(c+250)>>0]|0;f=(m|0)>(f|0)?m:f;c=c+1|0}while((c|0)!=512);f=f<<6;c=f+762|0;if((c|0)>(e|0)){b=c-e|0;return b|0}f=f+64|0;if((f|0)>0)c=0;else{b=0;return b|0}while(1){if((d[b+((c<<2)+762)>>0]|0)>19){m=-1;c=18;break}c=c+1|0;if((c|0)>=(f|0)){m=0;c=18;break}}if((c|0)==18)return m|0}else if((c|0)==18)return m|0;return 0}function Bh(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0;n=l;l=l+1552|0;m=n+1032|0;i=n+1024|0;j=n;gp(m|0,0,512)|0;bg(c,20);f=i+4|0;g=i+5|0;e=i+1|0;h=0;k=0;while(1){if((cm(i,1,8,b)|0)!=8){e=-1;f=17;break}bg(c,22);k=(((Rj(a[i>>0]|0,a[e>>0]|0)|0)&65535)<<1)+k|0;if(!((a[f>>0]|a[g>>0])<<24>>24))a[g>>0]=1;h=h+1|0;if((ko(i,1,8,c)|0)!=8){e=-1;f=17;break}if((h|0)>=31){f=7;break}}if((f|0)==7){i=Pl(b)|0;Wj(c,i);Wj(c,Pl(b)|0);f=0;e=0;do{h=Pl(b)|0;a[m+f>>0]=h;h=h&255;e=(h|0)>(e|0)?h:e;f=f+1|0}while((f|0)!=128);f=0;do{h=Pl(b)|0;a[m+128+f>>0]=h;h=h&255;e=(h|0)>(e|0)?h:e;f=f+1|0}while((f|0)!=128);f=0;do{h=Pl(b)|0;a[m+256+f>>0]=h;h=h&255;e=(h|0)>(e|0)?h:e;f=f+1|0}while((f|0)!=128);f=0;h=e;do{g=Pl(b)|0;a[m+384+f>>0]=g;g=g&255;h=(g|0)>(h|0)?g:h;f=f+1|0}while((f|0)!=128);g=i&255;if(!(i<<24>>24)){bg(c,128);Yj(c,1294879534)}else{e=0;do{Wj(c,e&255);e=e+1|0}while((e|0)!=(g|0));bg(c,128-g|0);Yj(c,1294879534);f=0;do{gp(j|0,0,1024)|0;dm(b,((d[m+f>>0]|0)<<8)+762|0,0)|0;e=0;do{cm(j+(e<<4)|0,1,4,b)|0;e=e+1|0}while((e|0)!=64);dm(b,((d[m+128+f>>0]|0)<<8)+762|0,0)|0;e=0;do{cm(j+(e<<4)+4|0,1,4,b)|0;e=e+1|0}while((e|0)!=64);dm(b,((d[m+256+f>>0]|0)<<8)+762|0,0)|0;e=0;do{cm(j+(e<<4)+8|0,1,4,b)|0;e=e+1|0}while((e|0)!=64);dm(b,((d[m+384+f>>0]|0)<<8)+762|0,0)|0;e=0;do{cm(j+(e<<4)+12|0,1,4,b)|0;e=e+1|0}while((e|0)!=64);ko(j,1024,1,c)|0;f=f+1|0}while((f|0)!=(g|0))}if((dm(b,(h<<8)+1018|0,0)|0)<0){m=-1;l=n;return m|0}ag(c,b,k);m=0;l=n;return m|0}else if((f|0)==17){l=n;return e|0}return 0}function Ch(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;f=0;h=0;while(1){e=b+(f<<3)|0;g=((Rj(a[e>>0]|0,a[e+1>>0]|0)|0)&65535)<<1;if((d[e+2>>0]|0)>15){j=-1;e=14;break}k=e+4|0;h=g+h|0;k=((Rj(a[k>>0]|0,a[k+1>>0]|0)|0)&65535)<<1;f=f+1|0;if(k>>>0>g>>>0|(d[e+3>>0]|0)>64){j=-1;e=14;break}if((f|0)>=31){e=5;break}}if((e|0)==5){if((h|0)<3){k=-1;return k|0}if((a[b+248>>0]|0)<1){k=-1;return k|0}else{e=0;f=0}do{k=d[b+(e+250)>>0]|0;f=(k|0)>(f|0)?k:f;e=e+1|0}while((e|0)!=512);h=(f<<6)+64|0;do if((h|0)>0){f=0;g=0;while(1){k=b+(f<<1)+762|0;k=Rj(a[k>>0]|0,a[k+1>>0]|0)|0;e=k&65535;if((k&65535)>16384){j=-1;e=14;break}g=(e|0)>(g|0)?e:g;f=f+1|0;if((f|0)>=(h|0)){e=11;break}}if((e|0)==11){i=(g<<2)+4|0;break}else if((e|0)==14)return j|0}else i=4;while(0);if((Vj(b+(h<<1)+762|0)|0)!=(i|0)){k=-1;return k|0}eg(0,c,0);k=0;return k|0}else if((e|0)==14)return j|0;return 0}function Dh(a,b){a=a|0;b=b|0;return Eh(a,b,0)|0}function Eh(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;s=l;l=l+132608|0;r=s+132096|0;q=s;o=s+131072|0;gp(r|0,0,512)|0;gp(q|0,0,131072)|0;bg(e,20);g=0;p=0;do{bg(e,22);n=Ul(b)|0;Xj(e,n);p=((n&65535)<<1)+p|0;Wj(e,Pl(b)|0);Wj(e,Pl(b)|0);Xj(e,Ul(b)|0);Xj(e,Ul(b)|0);g=g+1|0}while((g|0)!=31);i=Pl(b)|0;n=i&255;if((i&255)>128){r=-1;l=s;return r|0}Wj(e,i);Wj(e,Pl(b)|0);h=0;g=0;do{m=Pl(b)|0;a[r+h>>0]=m;m=m&255;g=(m|0)>(g|0)?m:g;h=h+1|0}while((h|0)!=128);h=0;do{m=Pl(b)|0;a[r+128+h>>0]=m;m=m&255;g=(m|0)>(g|0)?m:g;h=h+1|0}while((h|0)!=128);h=0;do{m=Pl(b)|0;a[r+256+h>>0]=m;m=m&255;g=(m|0)>(g|0)?m:g;h=h+1|0}while((h|0)!=128);h=0;k=g;do{m=Pl(b)|0;a[r+384+h>>0]=m;m=m&255;k=(m|0)>(k|0)?m:k;h=h+1|0}while((h|0)!=128);j=i<<24>>24==0;if(j)g=0;else{g=0;do{Wj(e,g&255);g=g+1|0}while((g|0)!=(n|0));g=n}bg(e,128-g|0);Yj(e,1294879534);i=(f|0)==0;h=0;while(1){g=0;do{m=(Ul(b)|0)&65535;c[q+(h<<8)+(g<<2)>>2]=i?m:m>>>2;g=g+1|0}while((g|0)!=64);if((h|0)<(k|0))h=h+1|0;else break}g=am(b)|0;if(!g){r=-1;l=s;return r|0}m=Vm(g)|0;cm(m,g,1,b)|0;if(!j){g=0;do{gp(o|0,0,1024)|0;h=d[r+g>>0]|0;i=d[r+128+g>>0]|0;j=d[r+256+g>>0]|0;k=d[r+384+g>>0]|0;f=0;do{t=o+(f<<4)|0;u=m+(c[q+(h<<8)+(f<<2)>>2]<<2)|0;u=d[u>>0]|d[u+1>>0]<<8|d[u+2>>0]<<16|d[u+3>>0]<<24;a[t>>0]=u;a[t+1>>0]=u>>8;a[t+2>>0]=u>>16;a[t+3>>0]=u>>24;u=t+4|0;v=m+(c[q+(i<<8)+(f<<2)>>2]<<2)|0;v=d[v>>0]|d[v+1>>0]<<8|d[v+2>>0]<<16|d[v+3>>0]<<24;a[u>>0]=v;a[u+1>>0]=v>>8;a[u+2>>0]=v>>16;a[u+3>>0]=v>>24;u=t+8|0;v=m+(c[q+(j<<8)+(f<<2)>>2]<<2)|0;v=d[v>>0]|d[v+1>>0]<<8|d[v+2>>0]<<16|d[v+3>>0]<<24;a[u>>0]=v;a[u+1>>0]=v>>8;a[u+2>>0]=v>>16;a[u+3>>0]=v>>24;t=t+12|0;u=m+(c[q+(k<<8)+(f<<2)>>2]<<2)|0;u=d[u>>0]|d[u+1>>0]<<8|d[u+2>>0]<<16|d[u+3>>0]<<24;a[t>>0]=u;a[t+1>>0]=u>>8;a[t+2>>0]=u>>16;a[t+3>>0]=u>>24;f=f+1|0}while((f|0)!=64);ko(o,1024,1,e)|0;g=g+1|0}while((g|0)!=(n|0))}Wm(m);ag(e,b,p);v=0;l=s;return v|0}function Fh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;f=0;h=0;while(1){e=b+(f<<3)|0;g=((Rj(a[e>>0]|0,a[e+1>>0]|0)|0)&65535)<<1;if((d[e+2>>0]|0)>15){i=-1;e=21;break}j=e+4|0;h=g+h|0;j=((Rj(a[j>>0]|0,a[j+1>>0]|0)|0)&65535)<<1;f=f+1|0;if(j>>>0>g>>>0|(d[e+3>>0]|0)>64){i=-1;e=21;break}if((f|0)>=31){e=5;break}}if((e|0)==5){if((h|0)<3){c=-1;return c|0}if((a[b+248>>0]|0)<1){c=-1;return c|0}else{e=0;f=0}do{j=d[b+(e+250)>>0]|0;f=(j|0)>(f|0)?j:f;e=e+1|0}while((e|0)!=512);h=(f<<6)+64|0;do if((h|0)>0){f=0;g=0;while(1){e=b+(f<<1)+762|0;e=(Rj(a[e>>0]|0,a[e+1>>0]|0)|0)&65535;if(e&3|0){i=-1;e=21;break}g=(e|0)>(g|0)?e:g;f=f+1|0;if((f|0)>=(h|0)){e=11;break}}if((e|0)==11){k=g+4&-4;break}else if((e|0)==21)return i|0}else k=4;while(0);j=Vj(b+(h<<1)+762|0)|0;if(!((j|0)<65536&(j|0)==(k|0))){c=-1;return c|0}j=k>>2;a:do if((k|0)>0){g=b+h+766|0;i=0;while(1){h=g+(i<<2)|0;e=a[h+2>>0]&15;f=a[h+3>>0]|0;if(e<<24>>24==12&(f&255)>65){i=-1;e=21;break}if(e<<24>>24==13&(f&255)>64){i=-1;e=21;break}if(e<<24>>24==11&f<<24>>24<0){i=-1;e=21;break}i=i+1|0;if((a[h>>0]&-16&255)>=17){i=-1;e=21;break}if((i|0)>=(j|0))break a}if((e|0)==21)return i|0}while(0);eg(0,c,0);c=0;return c|0}else if((e|0)==21)return i|0;return 0}function Gh(a,b){a=a|0;b=b|0;return Eh(a,b,1)|0}function Hh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;f=Rj(a[b+268>>0]|0,a[b+269>>0]|0)|0;e=f&65535;if(e&3|0){c=-1;return c|0}h=e>>>2;if((f&65535)>511|(h|0)==0){c=-1;return c|0}f=b+784|0;if(!(a[f>>0]|0))e=0;else{c=-1;return c|0}while(1){m=b+(e<<3)|0;k=m+20|0;k=((Rj(a[k>>0]|0,a[k+1>>0]|0)|0)&65535)<<1;l=m+24|0;l=(Rj(a[l>>0]|0,a[l+1>>0]|0)|0)&65535;m=m+26|0;e=e+1|0;if(((Rj(a[m>>0]|0,a[m+1>>0]|0)|0)&65535)+l<<1>>>0>(k+2|0)>>>0){j=-1;i=24;break}if((e|0)>=31){g=0;break}}if((i|0)==24)return j|0;while(1){e=b+(g<<3)|0;if((d[e+22>>0]|0)>15){j=-1;i=24;break}g=g+1|0;if((d[e+23>>0]|0)>64){j=-1;i=24;break}if((g|0)>=31){i=9;break}}if((i|0)==9){f=Vj(f)|0;if((f|0)<788){m=-1;return m|0}else e=0;do{if((Vj(b+e+272|0)|0)>>>0>f>>>0){j=-1;i=24;break}e=e+4|0}while((e|0)<(h|0));if((i|0)==24)return j|0;e=e|2;a:do if((e|0)<128){while(1){if(Vj(b+(e<<2)+272|0)|0){j=-1;break}e=e+1|0;if((e|0)>=128)break a}return j|0}while(0);g=f+4|0;b:do if((g|0)>788){h=788;c:while(1){f=b+h|0;e=a[f>>0]|0;d:do if(e<<24>>24==-128)e=1;else{if((e&255)>128){j=-1;i=24;break c}if(!(Vj(f)|0)){j=-1;i=24;break c}switch((d[f+2>>0]|0)*15&4095){case 12:if((d[f+3>>0]|0)>64){j=-1;i=24;break c}else{e=4;break d}case 13:if((d[f+3>>0]|0)>64){j=-1;i=24;break c}else{e=4;break d}default:{e=4;break d}}}while(0);h=h+e|0;if((h|0)>=(g|0))break b}if((i|0)==24)return j|0}while(0);eg(b,c,20);m=0;return m|0}else if((i|0)==24)return j|0;return 0}function Ih(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;x=l;l=l+2816|0;u=x+2688|0;r=x+2560|0;v=x+1536|0;p=x+1024|0;q=x+512|0;m=x;e=u;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));e=r;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));gp(p|0,0,512)|0;gp(q|0,0,512)|0;gp(m|0,0,512)|0;ag(d,b,20);e=0;w=0;do{bg(d,22);t=Ul(b)|0;Xj(d,t);w=((t&65535)<<1)+w|0;Wj(d,Pl(b)|0);Wj(d,Pl(b)|0);Xj(d,Ul(b)|0);Xj(d,Ul(b)|0);e=e+1|0}while((e|0)!=31);k=Ul(b)|0;o=k&255;k=k&255;t=k&65535;if((k&65535)>127){w=-1;l=x;return w|0}dm(b,2,1)|0;e=0;do{c[p+(e<<2)>>2]=am(b)|0;e=e+1|0}while((e|0)!=128);n=k<<16>>16==0;a:do if(n){ep(q|0,p|0,512)|0;h=0;e=0}else{h=0;e=0;do{if(h){b:do if((h|0)>0){g=c[p+(h<<2)>>2]|0;f=0;while(1){if((g|0)==(c[p+(f<<2)>>2]|0))break;f=f+1|0;if((f|0)>=(h|0))break b}a[u+h>>0]=a[u+f>>0]|0}else f=0;while(0);if((f|0)==(h|0)){a[u+h>>0]=e;e=e+1|0}}else{a[u>>0]=0;e=e+1|0}h=h+1|0}while((h|0)!=(t|0));ep(q|0,p|0,512)|0;while(1){e=0;c:while(1){if((e|0)>0){j=q+(e<<2)|0;i=c[j>>2]|0;f=0;do{h=q+(f<<2)|0;g=c[h>>2]|0;if((i|0)<(g|0))break c;f=f+1|0}while((f|0)<(e|0))}e=e+1|0;if((e|0)>=(t|0)){h=0;e=0;break a}}z=u+f|0;y=a[z>>0]|0;f=u+e|0;a[z>>0]=a[f>>0]|0;a[f>>0]=y;c[h>>2]=i;c[j>>2]=g}}while(0);do{g=c[q+(h<<2)>>2]|0;f=m+(e<<2)|0;if(h){if((g|0)!=(c[f>>2]|0)){e=e+1|0;f=m+(e<<2)|0;s=31}}else s=31;if((s|0)==31){s=0;c[f>>2]=g}h=h+1|0}while((h|0)!=128);j=t+-1|0;if((k&65535)>1){h=c[m>>2]|0;i=0;g=0;while(1){c[q+(g<<2)>>2]=h;e=g+1|0;i=i+1|0;f=h;h=c[m+(i<<2)>>2]|0;if((h-f|0)>1024){c[q+(e<<2)>>2]=f+1024;e=g+2|0}if((i|0)==(j|0)){g=0;break}else g=e}}else g=0;do{f=c[p+(g<<2)>>2]|0;e=0;do{if((f|0)==(c[q+(e<<2)>>2]|0)){s=38;break}e=e+1|0}while((e|0)<128);if((s|0)==38){s=0;a[r+g>>0]=e}g=g+1|0}while((g|0)!=128);e=u;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));if(n){Wj(d,o);e=0}else{ep(u|0,r|0,t|0)|0;Wj(d,o);f=0;e=0;do{z=a[u+f>>0]|0;e=(z&255)>(e&255)?z:e;f=f+1|0}while((f|0)!=(t|0))}Wj(d,127);ko(u,128,1,d)|0;Yj(d,1294879534);dm(b,784,0)|0;j=(am(b)|0)+788|0;f=(e&255)+1&255;if(f|0){g=0;do{gp(v|0,0,1024)|0;h=0;do{i=h<<4;z=Pl(b)|0;e=z&255;if(z<<24>>24!=-128){u=Pl(b)|0;y=Pl(b)|0;z=Pl(b)|0;a[v+(i|1)>>0]=u;y=y&255;a[v+(i|3)>>0]=z;z=(y>>>4|e&240)>>>2;a[v+i>>0]=e&15|z&48;a[v+(i|2)>>0]=y&15|z<<4}z=Pl(b)|0;e=z&255;if(z<<24>>24!=-128){u=Pl(b)|0;y=Pl(b)|0;z=Pl(b)|0;a[v+(i|5)>>0]=u;y=y&255;a[v+(i|7)>>0]=z;z=(y>>>4|e&240)>>>2;a[v+(i|4)>>0]=e&15|z&48;a[v+(i|6)>>0]=y&15|z<<4}z=Pl(b)|0;e=z&255;if(z<<24>>24!=-128){u=Pl(b)|0;y=Pl(b)|0;z=Pl(b)|0;a[v+(i|9)>>0]=u;y=y&255;a[v+(i|11)>>0]=z;z=(y>>>4|e&240)>>>2;a[v+(i|8)>>0]=e&15|z&48;a[v+(i|10)>>0]=y&15|z<<4}z=Pl(b)|0;e=z&255;if(z<<24>>24!=-128){u=Pl(b)|0;y=Pl(b)|0;z=Pl(b)|0;a[v+(i|13)>>0]=u;y=y&255;a[v+(i|15)>>0]=z;z=(y>>>4|e&240)>>>2;a[v+(i|12)>>0]=e&15|z&48;a[v+(i|14)>>0]=y&15|z<<4}h=h+1|0}while((h|0)!=64);ko(v,1024,1,d)|0;g=g+1|0}while((g|0)!=(f|0))}dm(b,j,0)|0;ag(d,b,w);z=0;l=x;return z|0}function Jh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;if((e|0)<182){c=182-e|0;return c|0}else{i=0;j=0}while(1){e=b+(i*12|0)|0;if((d[e+7>>0]|0)>64){k=-1;g=15;break}if(a[e+6>>0]|0){k=-1;g=15;break}h=Vj(e)|0;if((h|0)!=0&(h|0)<180){k=-1;g=15;break}f=e+4|0;f=Rj(a[f>>0]|0,a[f+1>>0]|0)|0;h=f&65535;g=e+8|0;g=Rj(a[g>>0]|0,a[g+1>>0]|0)|0;e=e+10|0;e=Rj(a[e>>0]|0,a[e+1>>0]|0)|0;if((g&65535)>(f&65535)){k=-1;g=15;break}if(e<<16>>16==0|((f&65535)>32768|(e&65535)>>>0>(h+1|0)>>>0)){k=-1;g=15;break}if(f<<16>>16==0?g<<16>>16!=0|e<<16>>16!=1:0){k=-1;g=15;break}j=h+j|0;i=i+1|0;if((i|0)>=15){g=11;break}}if((g|0)==11){if((j|0)<2){c=-1;return c|0}else f=0;while(1){e=b+f+180|0;e=Rj(a[e>>0]|0,a[e+1>>0]|0)|0;if(e<<16>>16==-1)break;f=f+2|0;if(!((e&65535)>179&(f|0)<256)){k=-1;g=15;break}}if((g|0)==15)return k|0;eg(0,c,0);c=0;return c|0}else if((g|0)==15)return k|0;return 0}function Kh(d,f){d=d|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;s=l;l=l+2656|0;o=s+1632|0;n=s+1088|0;k=s+576|0;p=s+64|0;q=s;r=s+1600|0;gp(p|0,0,512)|0;gp(k|0,0,512)|0;gp(n|0,0,512)|0;bg(f,20);g=0;do{c[q+(g<<2)>>2]=am(d)|0;bg(f,22);m=Ul(d)|0;Xj(f,m);b[r+(g<<1)>>1]=(m&65535)<<1;Wj(f,Pl(d)|0);Wj(f,Pl(d)|0);Xj(f,Ul(d)|0);Xj(f,Ul(d)|0);g=g+1|0}while((g|0)!=15);g=15;do{bg(f,22);Xj(f,0);Wj(f,0);Wj(f,64);Xj(f,0);Xj(f,1);g=g+1|0}while((g|0)!=31);cm(o,2,128,d)|0;h=0;g=0;while(1){j=o+(h<<1)|0;i=a[j>>0]|0;if(i<<24>>24==-1){m=h;g=h&255;break}m=(Rj(i,a[j+1>>0]|0)|0)&65535;c[n+(h<<2)>>2]=m;c[k+(h<<2)>>2]=m;h=h+1|0;g=g+1<<24>>24;if((h&255)<<24>>24<=-1){m=h;break}}Wj(f,g);Wj(f,127);Wn(k,m);if((m|0)>0){i=c[k>>2]|0;g=0;j=0;while(1){c[p+(j<<2)>>2]=i;do{t=g;g=g+1|0;h=c[k+(g<<2)>>2]|0}while((t|0)<(m|0)&(h|0)==(i|0));if((g|0)<(m|0)){i=h;j=j+1|0}else break}g=o;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));j=0;g=0;do{h=c[n+(j<<2)>>2]|0;i=0;while(1)if((h|0)==(c[p+(i<<2)>>2]|0))break;else i=i+1|0;a[o+j>>0]=i;g=(i|0)>(g|0)?i:g;j=j+1|0}while((j|0)!=(m|0))}else{g=o;h=g+128|0;do{a[g>>0]=0;g=g+1|0}while((g|0)<(h|0));g=0}ko(o,128,1,f)|0;Yj(f,1294879534);if((g|0)<0)h=0;else{j=0;while(1){dm(d,c[p+(j<<2)>>2]|0,0)|0;gp(o|0,0,1024)|0;k=0;m=Pl(d)|0;do{h=(Pl(d)|0)&255;i=h&63;h=h>>>6<<2|k<<4;if(i>>>0<37){a[o+h>>0]=a[35367+(i<<1)>>0]|0;a[o+(h|1)>>0]=a[35367+(i<<1)+1>>0]|0}a[o+(h|2)>>0]=Pl(d)|0;a[o+(h|3)>>0]=Pl(d)|0;if(m<<24>>24<0)break;m=Pl(d)|0;k=(m&127)+k|0}while((k|0)<64);ko(o,1024,1,f)|0;if((j|0)==(g|0)){h=0;break}else j=j+1|0}}do{g=c[q+(h<<2)>>2]|0;if(g|0){dm(d,g,0)|0;ag(f,d,e[r+(h<<1)>>1]|0)}h=h+1|0}while((h|0)!=15);l=s;return 0}function Lh(a,b){a=a|0;b=b|0;a=c[a>>2]|0;b=c[b>>2]|0;return ((a|0)==(b|0)?0:(a|0)>(b|0)?1:-1)|0}function Mh(a,b,c){a=a|0;b=b|0;c=c|0;var e=0;if((c|0)<260){e=260-c|0;return e|0}else c=0;do{if((d[a+(c<<3|4)>>0]|0)>64){c=-1;e=7;break}c=c+1|0}while((c|0)<31);if((e|0)==7)return c|0;if((Vj(a+256|0)|0)!=1397446996){e=-1;return e|0}eg(0,b,0);e=0;return e|0}function Nh(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;p=l;l=l+3072|0;m=p+2048|0;o=p;gp(o|0,0,512)|0;bg(e,20);f=0;n=0;do{bg(e,22);k=Ul(b)|0;Xj(e,k);n=((k&65535)<<1)+n|0;Wj(e,Pl(b)|0);Wj(e,Pl(b)|0);Xj(e,Ul(b)|0);Xj(e,Ul(b)|0);f=f+1|0}while((f|0)!=31);am(b)|0;am(b)|0;am(b)|0;f=((Pl(b)|0)&255)+1|0;k=f&255;if(k>>>0>127){o=-1;l=p;return o|0}Wj(e,f&255);Wj(e,127);g=(k|0)==0;if(g)f=0;else{f=0;do{c[o+(f<<4)>>2]=(Ul(b)|0)&65535;c[o+(f<<4)+4>>2]=(Ul(b)|0)&65535;c[o+(f<<4)+8>>2]=(Ul(b)|0)&65535;c[o+(f<<4)+12>>2]=(Ul(b)|0)&65535;f=f+1|0}while((f|0)!=(k|0));f=0}do{Wj(e,(f|0)<(k|0)?f&255:0);f=f+1|0}while((f|0)!=128);Yj(e,1294879534);Pl(b)|0;f=em(b)|0;if(!g){j=f+-256|0;f=0;do{gp(m|0,0,1024)|0;g=0;do{dm(b,j+(c[o+(f<<4)+(g<<2)>>2]<<8)|0,0)|0;i=g<<2;h=0;do{q=(h<<4)+i|0;u=Pl(b)|0;t=Pl(b)|0;s=Pl(b)|0;r=Pl(b)|0;t=t&255;u=u&255;a[m+q>>0]=d[35367+(u<<1)>>0]|0|t&240;a[m+(q|1)>>0]=a[35367+(u<<1)+1>>0]|0;a[m+(q|2)>>0]=t<<4|s&255;a[m+(q|3)>>0]=r;h=h+1|0}while((h|0)!=64);g=g+1|0}while((g|0)!=4);ko(m,1024,1,e)|0;f=f+1|0}while((f|0)!=(k|0))}ag(e,b,n);u=0;l=p;return u|0}function Oh(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0;if((d|0)<64){c=64-d|0;return c|0}if((Vj(b)|0)!=1297040469){c=-1;return c|0}f=(Rj(a[b+20>>0]|0,a[b+21>>0]|0)|0)&65535;e=f+4|0;g=((Rj(a[b+28>>0]|0,a[b+29>>0]|0)|0)&65535)+e|0;f=f+8|0;if((f|0)>(d|0)){c=f-d|0;return c|0}if((Vj(b+e|0)|0)!=1112491097){c=-1;return c|0}e=g+8|0;if((e|0)>(d|0)){c=e-d|0;return c|0}if((Vj(b+(g+4)|0)|0)!=1396788560){c=-1;return c|0}eg(b+4|0,c,16);c=0;return c|0}function Ph(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0;q=l;l=l+1536|0;o=q+512|0;p=q;am(b)|0;ag(d,b,16);Yj(d,0);m=(Ul(b)|0)&65535;k=Ul(b)|0;i=Ul(b)|0;j=Ul(b)|0;m=(m<<16)+262144>>16;n=((Ul(b)|0)&65535)+m|0;gp(o|0,0,930)|0;g=k<<16>>16;if(k<<16>>16>0){h=0;e=0;do{f=Pl(b)|0;if((f&255)>30)dm(b,7,1)|0;else{f=(f&255)*30|0;a[o+(f+25)>>0]=Pl(b)|0;k=Ul(b)|0;a[o+(f+22)>>0]=(k&65535)>>>8;a[o+(f+23)>>0]=k;a[o+(f+26)>>0]=Pl(b)|0;a[o+(f+27)>>0]=Pl(b)|0;a[o+(f+28)>>0]=Pl(b)|0;a[o+(f+29)>>0]=Pl(b)|0;e=((k&65535)<<1)+e|0}h=h+1|0}while((h|0)!=(g|0));k=e}else k=0;ko(o,930,1,d)|0;Wj(d,i&255);Wj(d,127);e=o;f=e+128|0;do{a[e>>0]=0;e=e+1|0}while((e|0)<(f|0));f=i<<16>>16;if(i<<16>>16>0){e=0;do{a[o+e>>0]=Ul(b)|0;e=e+1|0}while((e|0)!=(f|0))}ko(o,128,1,d)|0;gp(p|0,0,256)|0;i=j<<16>>16;if(j<<16>>16>0)e=0;else{Yj(d,1294879534);p=n<<16;p=p+262144|0;p=p>>16;dm(b,p,0)|0;ag(d,b,k);l=q;return 0}do{c[p+(e<<2)>>2]=(Ul(b)|0)&65535;e=e+1|0}while((e|0)!=(i|0));Yj(d,1294879534);e=m+4|0;g=0;do{dm(b,e+(c[p+(g<<2)>>2]|0)|0,0)|0;gp(o|0,0,1024)|0;h=0;do{f=(Ul(b)|0)&65535;if(f&1|0)cm(o+(h<<4)|0,1,4,b)|0;if(f&2|0)cm(o+(h<<4)+4|0,1,4,b)|0;if(f&4|0)cm(o+(h<<4)+8|0,1,4,b)|0;if(f&8|0)cm(o+(h<<4)+12|0,1,4,b)|0;h=h+1|0}while((h|0)!=64);ko(o,1024,1,d)|0;g=g+1|0}while((g|0)!=(i|0));p=n<<16;p=p+262144|0;p=p>>16;dm(b,p,0)|0;ag(d,b,k);l=q;return 0}function Qh(a,b,c){a=a|0;b=b|0;c=c|0;var e=0,f=0;if((c|0)<1084){b=1084-c|0;return b|0}if((Vj(a+1080|0)|0)!=1213355041){b=-1;return b|0}c=a+20|0;f=0;while(1){e=c+(f*30|0)|0;if((d[e+24>>0]|0)>15){c=-1;e=9;break}f=f+1|0;if((d[e+25>>0]|0)>=65){c=-1;e=9;break}if((f|0)>=31){e=8;break}}if((e|0)==8){eg(a,b,20);b=0;return b|0}else if((e|0)==9)return c|0;return 0}function Rh(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;s=l;l=l+1024|0;q=s;gp(q|0,0,950)|0;cm(q,950,1,b)|0;c[q+38>>2]=0;c[q+68>>2]=0;c[q+98>>2]=0;c[q+128>>2]=0;c[q+158>>2]=0;c[q+188>>2]=0;c[q+218>>2]=0;c[q+248>>2]=0;c[q+278>>2]=0;c[q+308>>2]=0;c[q+338>>2]=0;c[q+368>>2]=0;c[q+398>>2]=0;c[q+428>>2]=0;c[q+458>>2]=0;c[q+488>>2]=0;c[q+518>>2]=0;c[q+548>>2]=0;c[q+578>>2]=0;c[q+608>>2]=0;c[q+638>>2]=0;c[q+668>>2]=0;c[q+698>>2]=0;c[q+728>>2]=0;c[q+758>>2]=0;c[q+788>>2]=0;c[q+818>>2]=0;c[q+848>>2]=0;c[q+878>>2]=0;c[q+908>>2]=0;c[q+938>>2]=0;ko(q,950,1,e)|0;f=q+42|0;g=0;r=0;do{p=f+(g*30|0)|0;r=(((Rj(a[p>>0]|0,a[p+1>>0]|0)|0)&65535)<<1)+r|0;g=g+1|0}while((g|0)!=31);Wj(e,Pl(b)|0);Wj(e,Pl(b)|0);cm(q,1,128,b)|0;f=0;p=0;do{o=d[q+f>>0]|0;p=(o|0)>(p|0)?o:p;f=f+1|0}while((f|0)!=128);Yj(e,1294879534);dm(b,1084,0)|0;h=q+1|0;i=q+2|0;j=q+3|0;n=0;while(1){o=0;do{a[q>>0]=Pl(b)|0;a[h>>0]=Pl(b)|0;a[i>>0]=Pl(b)|0;k=Pl(b)|0;a[j>>0]=k;m=(d[q>>0]|0)>>>1;a[q>>0]=m;f=m&112;t=a[h>>0]|0;g=(t&255)>>>1&255;if(!(t<<24>>24))g=0;else{f=a[35367+(g<<1)>>0]|f;g=a[35367+(g<<1)+1>>0]|0}t=((m&255)<<4|(d[i>>0]|0))&255;Wj(e,f);Wj(e,g);Wj(e,t);Wj(e,k);o=o+1|0}while((o|0)!=256);if((n|0)<(p|0))n=n+1|0;else break}ag(e,b,r);l=s;return 0}function Sh(b,c,e){b=b|0;c=c|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;if((e|0)<1500){c=1500-e|0;return c|0}if((Vj(b+1080|0)|0)!=1294879534){c=-1;return c|0}e=b+6|0;f=0;g=0;do{h=e+(f<<4)|0;g=(((Rj(a[h>>0]|0,a[h+1>>0]|0)|0)&65535)<<1)+g|0;f=f+1|0}while((f|0)!=31);if(!g){c=-1;return c|0}else e=0;do{if((d[b+(e<<4|1)>>0]|0)>64){i=-1;j=22;break}e=e+1|0}while((e|0)<31);if((j|0)==22)return i|0;h=a[b+950>>0]|0;f=h&255;if(h<<24>>24<1){c=-1;return c|0}else{e=0;h=0}do{k=a[b+(e+952)>>0]|0;g=k&255;if(k<<24>>24<=-1){i=-1;j=22;break}h=(g|0)>(h|0)?g:h;e=e+1|0}while((e|0)<(f|0));if((j|0)==22)return i|0;h=(h<<8)+256|0;a:do if((e|0)!=128){while(1){if(a[b+(e+952)>>0]|0){i=-1;break}e=e+1|0;if((e|0)==128)break a}return i|0}while(0);b:do if((h|0)>0){e=b+1084|0;g=0;while(1){f=e+(g<<2)|0;if((d[f+2>>0]|0)>72){i=-1;j=22;break}if(a[f+3>>0]&7){i=-1;j=22;break}g=g+1|0;if(a[f>>0]&3){i=-1;j=22;break}if((g|0)>=(h|0))break b}if((j|0)==22)return i|0}while(0);eg(0,c,0);k=0;return k|0}function Th(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;t=l;l=l+2192|0;s=t+1160|0;k=t+1032|0;q=t;bg(c,20);j=0;r=0;do{bg(c,22);Pl(b)|0;f=Pl(b)|0;g=am(b)|0;h=Ul(b)|0;Xj(c,h);r=((h&65535)<<1)+r|0;h=am(b)|0;i=Ul(b)|0;do switch((Ul(b)|0)<<16>>16){case -1080:{e=15;break}case -72:{e=1;break}case -144:{e=2;break}case -216:{e=3;break}case -288:{e=4;break}case -360:{e=5;break}case -432:{e=6;break}case -504:{e=7;break}case -576:{e=8;break}case -648:{e=9;break}case -720:{e=10;break}case -792:{e=11;break}case -864:{e=12;break}case -936:{e=13;break}case -1008:{e=14;break}default:e=0}while(0);Wj(c,e);Wj(c,f);Xj(c,((h-g|0)/2|0)&65535);Xj(c,i);j=j+1|0}while((j|0)!=31);dm(b,950,0)|0;Wj(c,Pl(b)|0);Wj(c,Pl(b)|0);cm(k,128,1,b)|0;ko(k,128,1,c)|0;e=0;p=0;do{o=d[k+e>>0]|0;p=(o|0)>(p|0)?o:p;e=e+1|0}while((e|0)!=128);Yj(c,1294879534);dm(b,1084,0)|0;k=0;while(1){gp(q|0,0,1025)|0;cm(s,1024,1,b)|0;m=0;do{n=m<<2;h=n|3;o=(d[s+h>>0]|0)>>>3;i=n|2;f=a[s+i>>0]|0;e=a[s+n>>0]|0;j=n|1;g=a[s+j>>0]|0;switch(e<<24>>24){case 0:{e=3;break}case 12:{e=0;break}default:e=(e&255)>>>2}o=o&255;f=(f&255)>>>1&255;a[q+n>>0]=d[35367+(f<<1)>>0]|0|o&16;a[q+j>>0]=a[35367+(f<<1)+1>>0]|0;a[q+i>>0]=e|o<<4;a[q+h>>0]=g;m=m+1|0}while((m|0)!=256);ko(q,1024,1,c)|0;if((k|0)<(p|0))k=k+1|0;else break}ag(c,b,r);l=t;return 0}function Uh(b){b=b|0;var d=0,e=0,f=0,g=0,h=0;h=l;l=l+4096|0;d=h;Vh(d);e=d+(fo(d)|0)|0;f=36135;g=e+11|0;do{a[e>>0]=a[f>>0]|0;e=e+1|0;f=f+1|0}while((e|0)<(g|0));d=oo(d)|0;c[b>>2]=d;if(!d){b=0;l=h;return b|0}d=To(d)|0;do if((d|0)>=0){e=ro(d,36146)|0;if(!e){Sn(d);break}else{b=e;l=h;return b|0}}while(0);Wm(c[b>>2]|0);b=0;l=h;return b|0}function Vh(a){a=a|0;var b=0,d=0,e=0;e=l;l=l+16|0;d=e;b=ua(36150)|0;if(!b){Ho(a,36161,4096)|0;l=e;return}else{c[d>>2]=b;io(a,4096,36157,d);l=e;return}}function Wh(a){a=a|0;if(!a)return;Go(a);Wm(a);return}function Xh(a,d){a=a|0;d=d|0;var e=0.0;b[d>>1]=0;c[d+4>>2]=0;e=3546895.0/+(a|0);h[d+528>>3]=e;h[d+520>>3]=e;return}function Yh(b,d,e,f,g,i,j,k,l){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0.0,n=0.0,o=0,p=0,q=0,r=0;r=c[b+84>>2]|0;m=+h[b+32>>3];q=f<<8;if(!e)return;p=b+88|0;g=c[p>>2]|0;n=+h[g+520>>3];j=~~((m-+(~~m|0))*65536.0);l=~~m>>>0;while(1){f=~~(n*.0625);b=(i|0)/(f|0)|0;o=f+-1|0;Zh(g,a[r+l>>0]|0);k=c[p>>2]|0;if((f|0)>1){g=0;do{_h(k,16);j=j+b|0;l=(j>>16)+l|0;j=j&65535;g=g+1|0;Zh(c[p>>2]|0,a[r+l>>0]|0);k=c[p>>2]|0}while((g|0)!=(o|0))}g=k+520|0;n=+h[g>>3]-+(f<<4|0);h[g>>3]=n;_h(k,~~n);k=c[p>>2]|0;f=($h(k,0)|0)<<16>>16;_h(k,16-~~+h[k+520>>3]|0);k=j+(i-(O(o,b)|0))|0;g=c[p>>2]|0;o=g+520|0;n=+h[g+528>>3]+ +h[o>>3];h[o>>3]=n;o=O(q,f)|0;c[d>>2]=(c[d>>2]|0)+o;e=e+-1|0;if(!e)break;else{d=d+4|0;j=k&65535;l=(k>>16)+l|0}}return}function Zh(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0;f=b[a>>1]|0;if(f<<16>>16==d<<16>>16)return;g=a+4|0;e=c[g>>2]|0;if(e>>>0>127){ko(36167,37,1,21640)|0;c[g>>2]=127;e=127;f=b[a>>1]|0}h=a+8|0;fp(a+12|0,h|0,e<<2|0)|0;c[g>>2]=e+1;b[a+10>>1]=0;b[h>>1]=(d&65535)-(f&65535);b[a>>1]=d;return}function _h(a,d){a=a|0;d=d|0;var f=0,g=0,h=0,i=0,j=0;if(!d)return;g=a+4|0;if(!(c[g>>2]|0))return;else f=0;while(1){j=a+8+(f<<2)+2|0;i=(e[j>>1]|0)+d|0;b[j>>1]=i;if((i<<16|0)>134152192)break;f=f+1|0;if(f>>>0>=(c[g>>2]|0)>>>0){h=6;break}}if((h|0)==6)return;c[g>>2]=f;return}function $h(a,d){a=a|0;d=d|0;var f=0,g=0,h=0;f=e[a>>1]<<17;g=c[a+4>>2]|0;if(!g){d=f;d=d>>17;d=d&65535;return d|0}else h=0;do{f=f-(O(c[3524+(d<<13)+(b[a+8+(h<<2)+2>>1]<<2)>>2]|0,b[a+8+(h<<2)>>1]|0)|0)|0;h=h+1|0}while((h|0)!=(g|0));d=f>>17;d=d&65535;return d|0}function ai(b,d,e,f,g,i,j,k,l){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0.0,n=0.0,o=0,p=0,q=0,r=0;r=c[b+84>>2]|0;m=+h[b+32>>3];q=f<<8;if(!e)return;p=b+88|0;g=c[p>>2]|0;n=+h[g+520>>3];j=~~((m-+(~~m|0))*65536.0);l=~~m>>>0;while(1){f=~~(n*.0625);b=(i|0)/(f|0)|0;o=f+-1|0;Zh(g,a[r+l>>0]|0);k=c[p>>2]|0;if((f|0)>1){g=0;do{_h(k,16);j=j+b|0;l=(j>>16)+l|0;j=j&65535;g=g+1|0;Zh(c[p>>2]|0,a[r+l>>0]|0);k=c[p>>2]|0}while((g|0)!=(o|0))}g=k+520|0;n=+h[g>>3]-+(f<<4|0);h[g>>3]=n;_h(k,~~n);k=c[p>>2]|0;f=($h(k,1)|0)<<16>>16;_h(k,16-~~+h[k+520>>3]|0);k=j+(i-(O(o,b)|0))|0;g=c[p>>2]|0;o=g+520|0;n=+h[g+528>>3]+ +h[o>>3];h[o>>3]=n;o=O(q,f)|0;c[d>>2]=(c[d>>2]|0)+o;e=e+-1|0;if(!e)break;else{d=d+4|0;j=k&65535;l=(k>>16)+l|0}}return}function bi(b,d,e,f,g,i,j,k,l){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0.0,n=0.0,o=0,p=0,q=0,r=0,s=0;s=c[b+84>>2]|0;m=+h[b+32>>3];r=f<<8;q=g<<8;if(!e)return;p=b+88|0;f=c[p>>2]|0;n=+h[f+520>>3];j=~~((m-+(~~m|0))*65536.0);l=~~m>>>0;while(1){g=~~(n*.0625);b=(i|0)/(g|0)|0;o=g+-1|0;Zh(f,a[s+l>>0]|0);k=c[p>>2]|0;if((g|0)>1){f=0;do{_h(k,16);j=j+b|0;l=(j>>16)+l|0;j=j&65535;f=f+1|0;Zh(c[p>>2]|0,a[s+l>>0]|0);k=c[p>>2]|0}while((f|0)!=(o|0))}f=k+520|0;n=+h[f>>3]-+(g<<4|0);h[f>>3]=n;_h(k,~~n);k=c[p>>2]|0;g=($h(k,0)|0)<<16>>16;_h(k,16-~~+h[k+520>>3]|0);k=j+(i-(O(o,b)|0))|0;f=c[p>>2]|0;b=f+520|0;n=+h[f+528>>3]+ +h[b>>3];h[b>>3]=n;b=O(q,g)|0;o=d+4|0;c[d>>2]=(c[d>>2]|0)+b;b=O(r,g)|0;c[o>>2]=(c[o>>2]|0)+b;e=e+-1|0;if(!e)break;else{d=d+8|0;j=k&65535;l=(k>>16)+l|0}}return}function ci(b,d,e,f,g,i,j,k,l){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0.0,n=0.0,o=0,p=0,q=0,r=0,s=0;s=c[b+84>>2]|0;m=+h[b+32>>3];r=f<<8;q=g<<8;if(!e)return;p=b+88|0;f=c[p>>2]|0;n=+h[f+520>>3];j=~~((m-+(~~m|0))*65536.0);l=~~m>>>0;while(1){g=~~(n*.0625);b=(i|0)/(g|0)|0;o=g+-1|0;Zh(f,a[s+l>>0]|0);k=c[p>>2]|0;if((g|0)>1){f=0;do{_h(k,16);j=j+b|0;l=(j>>16)+l|0;j=j&65535;f=f+1|0;Zh(c[p>>2]|0,a[s+l>>0]|0);k=c[p>>2]|0}while((f|0)!=(o|0))}f=k+520|0;n=+h[f>>3]-+(g<<4|0);h[f>>3]=n;_h(k,~~n);k=c[p>>2]|0;g=($h(k,1)|0)<<16>>16;_h(k,16-~~+h[k+520>>3]|0);k=j+(i-(O(o,b)|0))|0;f=c[p>>2]|0;b=f+520|0;n=+h[f+528>>3]+ +h[b>>3];h[b>>3]=n;b=O(q,g)|0;o=d+4|0;c[d>>2]=(c[d>>2]|0)+b;b=O(r,g)|0;c[o>>2]=(c[o>>2]|0)+b;e=e+-1|0;if(!e)break;else{d=d+8|0;j=k&65535;l=(k>>16)+l|0}}return}function di(a,b){a=a|0;b=b|0;b=c[(c[a+968>>2]|0)+(b<<3)+4>>2]|0;if((b|0)<0){a=-1;return a|0}a=c[(c[a+972>>2]|0)+(b<<7)+4>>2]|0;return a|0}function ei(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;e=c[a+972>>2]|0;g=e+(b<<7)|0;if((c[a+964>>2]|0)>>>0<=b>>>0)return;if(d|0)Vk(e,b,0);d=a+960|0;c[d>>2]=(c[d>>2]|0)+-1;d=c[a+968>>2]|0;f=e+(b<<7)+4|0;a=d+(c[f>>2]<<3)|0;c[a>>2]=(c[a>>2]|0)+-1;c[d+(c[g>>2]<<3)+4>>2]=-1;d=e+(b<<7)+88|0;a=c[d>>2]|0;e=g;b=e+128|0;do{c[e>>2]=0;e=e+4|0}while((e|0)<(b|0));c[d>>2]=a;c[f>>2]=-1;c[g>>2]=-1;return}function fi(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;c[a+952>>2]=b;e=c[a+1544>>2]|0;d=Zk(e,-1)|0;i=a+956|0;c[i>>2]=b;if(!(c[a+2852>>2]&32768))d=(d|0)>(b|0)?b:d;else c[i>>2]=d+b;d=Zk(e,d)|0;h=a+964|0;c[h>>2]=d;f=Xm(d,128)|0;j=a+972|0;c[j>>2]=f;if(!f){a=-1;return a|0}e=(d|0)>0;if(e){b=0;do{c[f+(b<<7)>>2]=-1;c[f+(b<<7)+4>>2]=-1;b=b+1|0}while((b|0)!=(d|0))}g=a+2856|0;a:do if((c[g>>2]|0)==0?!((c[a+2860>>2]|0)!=1|e^1):0){b=Xm(1,536)|0;c[f+88>>2]=b;if(b){f=a+1512|0;e=0;do{Xh(c[f>>2]|0,b);e=e+1|0;d=c[h>>2]|0;if((e|0)>=(d|0)){k=13;break a}l=c[j>>2]|0;b=Xm(1,536)|0;c[l+(e<<7)+88>>2]=b}while((b|0)!=0)}}else k=13;while(0);if((k|0)==13){b=c[i>>2]|0;e=Vm(b<<3)|0;c[a+968>>2]=e;if(e){if((b|0)>0){d=0;do{c[e+(d<<3)+4>>2]=-1;c[e+(d<<3)>>2]=0;d=d+1|0}while((d|0)!=(b|0))}c[a+960>>2]=0;l=0;return l|0}}if((c[g>>2]|0)==0?((d|0)>0?(c[a+2860>>2]|0)==1:0):0){d=0;do{Wm(c[(c[j>>2]|0)+(d<<7)+88>>2]|0);d=d+1|0}while((d|0)<(c[h>>2]|0))}Wm(c[j>>2]|0);l=-1;return l|0}function gi(a){a=a|0;var b=0,d=0,e=0;if(((c[a+2856>>2]|0)==0?(c[a+2860>>2]|0)==1:0)?(d=a+964|0,(c[d>>2]|0)>0):0){e=a+972|0;b=0;do{Wm(c[(c[e>>2]|0)+(b<<7)+88>>2]|0);b=b+1|0}while((b|0)<(c[d>>2]|0))}e=a+952|0;c[e>>2]=0;c[e+4>>2]=0;c[e+8>>2]=0;c[e+12>>2]=0;Wm(c[a+972>>2]|0);Wm(c[a+968>>2]|0);return}function hi(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;l=a+956|0;b=c[l>>2]|0;if((b|0)<1)return;k=a+964|0;if((c[k>>2]|0)>0){h=a+972|0;f=0;do{b=c[h>>2]|0;e=b+(f<<7)|0;g=b+(f<<7)+88|0;d=c[g>>2]|0;i=e;j=i+128|0;do{c[i>>2]=0;i=i+4|0}while((i|0)<(j|0));c[g>>2]=d;c[e>>2]=-1;c[b+(f<<7)+4>>2]=-1;f=f+1|0}while((f|0)<(c[k>>2]|0));b=c[l>>2]|0;if((b|0)>0)m=5}else m=5;if((m|0)==5){d=c[a+968>>2]|0;e=0;do{c[d+(e<<3)+4>>2]=-1;c[d+(e<<3)>>2]=0;e=e+1|0}while((e|0)<(b|0))}c[a+960>>2]=0;return}function ii(a,b){a=a|0;b=b|0;return ji(a,b)|0}function ji(a,b){a=a|0;b=b|0;if((c[a+956>>2]|0)>>>0<=b>>>0){a=-1;return a|0}b=c[(c[a+968>>2]|0)+(b<<3)+4>>2]|0;a=b>>>0<(c[a+964>>2]|0)>>>0?b:-1;return a|0}function ki(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=ji(a,b)|0;if((d|0)<0)return;g=a+972|0;Vk(c[g>>2]|0,d,0);f=a+960|0;c[f>>2]=(c[f>>2]|0)+-1;f=c[a+968>>2]|0;a=c[g>>2]|0;g=a+(d<<7)+4|0;e=f+(c[g>>2]<<3)|0;c[e>>2]=(c[e>>2]|0)+-1;c[f+(b<<3)+4>>2]=-1;f=a+(d<<7)|0;b=a+(d<<7)+88|0;a=c[b>>2]|0;d=f;e=d+128|0;do{c[d>>2]=0;d=d+4|0}while((d|0)<(e|0));c[b>>2]=a;c[g>>2]=-1;c[f>>2]=-1;return}function li(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;g=ji(b,d)|0;if((g|0)<0)return;f=c[b+972>>2]|0;i=c[f+(g<<7)+4>>2]|0;if((i|0)<64?(a[b+888+i>>0]|0)!=0:0)Vk(f,g,0);else h=5;if((h|0)==5?(Vk(f,g,e),e|0):0)return;if((c[b+952>>2]|0)>(d|0))return;ei(b,g,1);return}function mi(a,b,d){a=a|0;b=b|0;d=d|0;b=ji(a,b)|0;if((b|0)<0)return;Wk(c[a+972>>2]|0,b,d);return}function ni(a,b,d){a=a|0;b=b|0;d=d|0;b=ji(a,b)|0;if((b|0)<0)return;Yk(c[a+972>>2]|0,b,d);return}function oi(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;b=ji(a,b)|0;if((b|0)<0)return;Xk(c[a+972>>2]|0,b,d,e);return}function pi(a,b){a=a|0;b=b|0;var c=0.0;b=ji(a,b)|0;if((b|0)<0){c=-1.0;return +c}c=+Rk(a,b);return +c}function qi(a,b,d){a=a|0;b=b|0;d=d|0;var e=0.0;b=ji(a,b)|0;if((b|0)<0)return;if((c[(c[a+972>>2]|0)+(b<<7)+52>>2]|0)==(d|0))return;e=+Rk(a,b);Sk(a,b,d,0);Pk(a,b,e,0);return}function ri(a,b,d){a=a|0;b=b|0;d=d|0;b=ji(a,b)|0;if((b|0)<0)return;c[(c[a+972>>2]|0)+(b<<7)+60>>2]=d;return}function si(a,b,d){a=a|0;b=b|0;d=d|0;b=ji(a,b)|0;if((b|0)<0)return;Tk(c[a+972>>2]|0,b,d);return}function ti(a,b,d,e,f,g,h,i){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0;if((c[a+956>>2]|0)>>>0<=b>>>0){f=-1;return f|0}l=(d|0)<0?-1:e;if(h|0?(j=a+964|0,(c[j>>2]|0)>0):0){e=0;do{ui(a,e,b,d,l,f,h,i);e=e+1|0}while((e|0)<(c[j>>2]|0))}i=a+968|0;e=c[(c[i>>2]|0)+(b<<3)+4>>2]|0;if((e|0)>-1){k=a+972|0;if(c[(c[k>>2]|0)+(e<<7)+60>>2]|0){j=vi(a,b)|0;if((j|0)<0){f=-1;return f|0}i=c[i>>2]|0;b=c[a+952>>2]|0;while(1){h=i+(b<<3)+4|0;if((c[h>>2]|0)>-1)b=b+1|0;else break}c[(c[k>>2]|0)+(e<<7)>>2]=b;c[h>>2]=e;e=j}}else{e=vi(a,b)|0;if((e|0)<0){f=-1;return f|0}}if((l|0)<0){ei(a,e,1);f=b;return f|0}else{Sk(a,e,l,1);a=a+972|0;Tk(c[a>>2]|0,e,f);f=c[a>>2]|0;c[f+(e<<7)+48>>2]=d;c[f+(e<<7)+60>>2]=g;f=b;return f|0}return 0}function ui(a,b,d,e,f,g,h,i){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0;j=c[a+972>>2]|0;k=c[(c[a+968>>2]|0)+(d<<3)+4>>2]|0;if((c[j+(b<<7)+4>>2]|0)!=(d|0))return;if((c[j+(b<<7)+48>>2]|0)!=(e|0))return;switch(h|0){case 3:break;case 2:{if((c[j+(b<<7)+52>>2]|0)!=(f|0))return;break}case 1:{if((c[j+(b<<7)+8>>2]|0)!=(g|0))return;break}default:return}if(!i){ei(a,b,1);return}j=j+(b<<7)+60|0;if((k|0)==(b|0)?(c[j>>2]|0)==0:0)return;c[j>>2]=i;return}function vi(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=c[a+964>>2]|0;a:do if((f|0)>0){e=c[a+972>>2]|0;d=0;do{if((c[e+(d<<7)>>2]|0)==-1)break a;d=d+1|0}while((d|0)<(f|0))}else d=0;while(0);if((d|0)==(f|0))d=wi(a)|0;if((d|0)<=-1)return d|0;f=c[a+968>>2]|0;e=f+(b<<3)|0;c[e>>2]=(c[e>>2]|0)+1;e=a+960|0;c[e>>2]=(c[e>>2]|0)+1;a=c[a+972>>2]|0;c[a+(d<<7)>>2]=b;c[a+(d<<7)+4>>2]=b;c[f+(b<<3)+4>>2]=d;return d|0}function wi(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;e=c[a+964>>2]|0;if((e|0)<=0){h=-1;return h|0}f=c[a+972>>2]|0;g=c[a+952>>2]|0;h=0;b=-1;d=2147483647;do{if((c[f+(h<<7)>>2]|0)>=(g|0)){i=c[f+(h<<7)+16>>2]|0;j=(i|0)<(d|0);b=j?h:b;d=j?i:d}h=h+1|0}while((h|0)!=(e|0));if((b|0)<=-1){j=b;return j|0}j=c[a+968>>2]|0;c[j+(c[f+(b<<7)>>2]<<3)+4>>2]=-1;j=j+(c[f+(b<<7)+4>>2]<<3)|0;c[j>>2]=(c[j>>2]|0)+-1;j=a+960|0;c[j>>2]=(c[j>>2]|0)+-1;j=b;return j|0}function xi(a,b,d){a=a|0;b=b|0;d=+d;b=ji(a,b)|0;if((b|0)<0)return;Uk(c[a+972>>2]|0,b,d);return}function yi(a,b,c){a=a|0;b=b|0;c=+c;b=ji(a,b)|0;if((b|0)<0)return;Pk(a,b,c,1);return}function zi(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;e=c[a+952>>2]|0;h=a+956|0;if((e|0)>=(c[h>>2]|0))return;i=a+972|0;g=a+628|0;do{f=ji(a,e)|0;a:do if((f|0)>=0?(c[(c[i>>2]|0)+(f<<7)+4>>2]|0)==(b|0):0)switch(d|0){case 0:{ei(a,f,1);break a}case 2:{Hi(c[g>>2]|0,e);break a}case 3:{Ii(c[g>>2]|0,e);break a}default:break a}while(0);e=e+1|0}while((e|0)<(c[h>>2]|0));return}function Ai(a,b){a=a|0;b=b|0;var d=0;d=ji(a,b)|0;if((d|0)<0){a=-1;return a|0}if((c[a+952>>2]|0)>(b|0)){a=256;return a|0}a=c[(c[a+972>>2]|0)+(d<<7)+60>>2]|0;return a|0}function Bi(a,b,d,e){a=a|0;b=b|0;d=d|0;e=+e;var f=0.0,g=0.0;if((c[a+32>>2]&8|0?(c[a+2856>>2]|0)==0:0)?(c[a+2860>>2]|0)==1:0){e=+(Ci(b,d)|0);return +e}g=+(d|0);f=+(b|0)+g*.0078125;switch(c[a+2860>>2]|0){case 2:{f=(240.0-f)*16.0;break}case 3:{f=g+ +jo((b|0)/12|0)*8363.0*.03125;break}default:f=13696.0/+wa(+(f/12.0))}e=e>.1?f*e:f;return +e}function Ci(a,b){a=a|0;b=b|0;var c=0;c=a+-48|0;if(c>>>0>35){c=-1;return c|0}a=b>>4;if((a+8|0)>>>0>15){c=0;return c|0}c=e[22260+(((a|0)<0?a+16|0:a)*72|0)+(c<<1)>>1]|0;return c|0}function Di(a,b){a=a|0;b=b|0;return +(13696.0/+wa(+((+(a|0)+ +(b|0)/12800.0)/12.0)))}function Ei(a){a=a|0;if((a|0)<1){a=0;return a|0}a=~~(+hp(+(+M(+(13696.0/+(a|0)))*12.0/.6931471805599453))+1.0);return a|0}function Fi(a,b,d,e){a=a|0;b=+b;d=d|0;e=+e;if(!d){d=0;return d|0}switch(c[a+2860>>2]|0){case 2:{d=~~((+(240-d<<4|0)-b)*8.0*100.0);return d|0}case 3:{d=~~+hp(+(+M(+(b/+Bi(a,d,0,e)))*221597.9582805448));return d|0}default:{d=~~+hp(+(+M(+(+Bi(a,d,0,e)/b))*221597.9582805448));return d|0}}return 0}function Gi(a,b,d){a=a|0;b=b|0;d=d|0;if(!a){c[d>>2]=0;c[b>>2]=0;return}else{a=~~(+M(+(+(a|0)/8363.0))*1536.0/.6931471805599453);c[b>>2]=(a|0)/128|0;c[d>>2]=(a|0)%128|0;return}}function Hi(a,b){a=a|0;b=b|0;a=a+(b*464|0)+8|0;c[a>>2]=c[a>>2]|2;return}function Ii(a,b){a=a|0;b=b|0;a=a+(b*464|0)+8|0;c[a>>2]=c[a>>2]|1;return}function Ji(b,e){b=b|0;e=e|0;var f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;o=b+9168|0;n=b+332|0;if((e+-4e3|0)>>>0>45170)return;q=b+9188|0;g=c[q>>2]|0;if((g|0)<1)return;if((g|0)!=1)Ki(b);if((_k(b,e)|0)<0)return;c[b+324>>2]=100;c[b+320>>2]=100;c[b+328>>2]=c[b+2836>>2];c[b>>2]=0;c[b+4>>2]=0;c[b+12>>2]=-1;m=b+8|0;c[m>>2]=0;h[b+40>>3]=0.0;c[b+56>>2]=0;c[b+60>>2]=0;g=b+888|0;e=b+632|0;i=0;do{a[g+i>>0]=0;c[e+(i<<2)>>2]=100;i=i+1|0}while((i|0)!=64);g=c[b>>2]|0;k=b+1724|0;j=c[k>>2]|0;a:do if((g|0)<(j|0)){l=b+2520|0;i=c[b+1696>>2]|0;while(1){e=d[l+g>>0]|0;if((e|0)<(i|0))break;g=g+1|0;c[b>>2]=g;if((g|0)>=(j|0)){p=12;break a}}if((j|0)!=0?(f=b+1704|0,(c[f>>2]|0)!=0):0){c[b+356>>2]=c[c[(c[b+1736>>2]|0)+(e<<2)>>2]>>2];g=c[b+384>>2]|0;e=360}else p=15}else p=12;while(0);if((p|0)==12){c[k>>2]=0;p=15}if((p|0)==15){c[b+376>>2]=0;c[b>>2]=0;c[b+380>>2]=0;c[m>>2]=0;c[b+360>>2]=0;f=b+1704|0;g=0;e=356}c[b+e>>2]=g;Li(b);if(fi(b,(c[o>>2]|0)+(c[f>>2]|0)|0)|0)return;c[b+340>>2]=0;c[b+344>>2]=0;c[b+336>>2]=-1;c[n>>2]=0;c[b+368>>2]=0;j=b+956|0;g=c[j>>2]|0;f=Xm(g,8)|0;i=b+352|0;c[i>>2]=f;if(!f)return;e=Xm(g,464)|0;k=b+628|0;c[k>>2]=e;b:do if(e){c:do if((g|0)>0){g=b+9152|0;if((wm(c[g>>2]|0,e)|0)>=0){f=1;while(1){if((f|0)>=(c[j>>2]|0))break c;if((wm(c[g>>2]|0,(c[k>>2]|0)+(f*464|0)|0)|0)<0)break;else f=f+1|0}}Wm(c[k>>2]|0);f=c[i>>2]|0;break b}while(0);Mi(b);c[q>>2]=2;return}while(0);Wm(f);return}function Ki(a){a=a|0;var b=0,d=0,e=0,f=0;b=a+9188|0;if((c[b>>2]|0)<2)return;c[b>>2]=1;e=a+956|0;f=a+628|0;if((c[e>>2]|0)>0){b=a+9152|0;d=0;do{xm(c[b>>2]|0,(c[f>>2]|0)+(d*464|0)|0);d=d+1|0}while((d|0)<(c[e>>2]|0))}gi(a);Wm(c[f>>2]|0);e=a+352|0;Wm(c[e>>2]|0);c[f>>2]=0;c[e>>2]=0;$k(a);return}function Li(a){a=a|0;var b=0,d=0;b=c[a>>2]|0;d=c[a+2872+(b*24|0)>>2]|0;if(d|0)c[a+16>>2]=d;d=c[a+2872+(b*24|0)+4>>2]|0;c[a+20>>2]=d;c[a+328>>2]=c[a+2872+(b*24|0)+8>>2];h[a+40>>3]=+(c[a+2872+(b*24|0)+12>>2]|0);h[a+48>>3]=+h[a+2824>>3]*+h[a+2816>>3]/+(d|0);c[a+1500>>2]=c[a+2872+(b*24|0)+20>>2];return}function Mi(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;f=b+956|0;if((c[f>>2]|0)>0){h=b+628|0;g=b+2836|0;d=b+9152|0;e=0;do{m=c[h>>2]|0;l=m+(e*464|0)|0;k=m+(e*464|0)+424|0;j=c[k>>2]|0;gp(l|0,0,464)|0;c[k>>2]=j;ym(c[d>>2]|0,l);c[m+(e*464|0)+44>>2]=-1;c[m+(e*464|0)+48>>2]=1;c[m+(e*464|0)+16>>2]=-1;c[m+(e*464|0)+76>>2]=c[g>>2];e=e+1|0}while((e|0)<(c[f>>2]|0))}i=c[b+952>>2]|0;if((i|0)<=0)return;j=c[b+628>>2]|0;k=c[b+1704>>2]|0;l=b+9168|0;m=0;do{if((m|0)>=(k|0)?(m|0)<((c[l>>2]|0)+k|0):0){c[j+(m*464|0)+56>>2]=64;d=128}else{c[j+(m*464|0)+56>>2]=c[b+1752+(m*12|0)+4>>2];d=c[b+1752+(m*12|0)>>2]|0}c[j+(m*464|0)+360>>2]=d;c[j+(m*464|0)+396>>2]=255;d=c[b+1752+(m*12|0)+8>>2]|0;if(d&4){e=(d>>>4&3)+1&255;a[j+(m*464|0)+92>>0]=e;if((m|0)>0){h=j+(m*464|0)+93|0;f=m&255;g=0;do{if(c[b+1752+(g*12|0)+8>>2]&4|0?(a[j+(g*464|0)+92>>0]|0)==e<<24>>24:0){a[j+(g*464|0)+93>>0]=f;a[h>>0]=g}g=g+1|0}while((g|0)!=(m|0))}}else a[j+(m*464|0)+92>>0]=0;if(d&16|0)c[j+(m*464|0)+376>>2]=1;m=m+1|0}while((m|0)!=(i|0));return}function Ni(b){b=b|0;var e=0,f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0.0;i=b+332|0;if((c[b+9188>>2]|0)<2){b=-8;return b|0}if((c[b+1724>>2]|0)<1){b=-1;return b|0}g=c[b+2852>>2]|0;f=c[b>>2]|0;if(g&134217728|0?(a[b+2520+f>>0]|0)==-1:0){b=-1;return b|0}j=b+4|0;e=c[j>>2]|0;if((f|0)==(e|0)){e=b+12|0;k=(c[e>>2]|0)+1|0;c[e>>2]=k;e=c[b+340>>2]|0;if((k|0)>=(O(e+1|0,c[b+16>>2]|0)|0)){if(!((g&4|0)==0|(e|0)==0)?c[i>>2]|0:0){Pi(b);Qi(b)}Pi(b)}}else{g=c[b+60>>2]|0;i=c[b+9020+(g<<3)>>2]|0;switch(e|0){case -1:{c[j>>2]=i;e=i;k=10;break}case -2:{b=-1;return b|0}default:if((e|0)==(i|0))k=10;else f=b+372|0}if((k|0)==10){f=b+372|0;c[b+360>>2]=c[f+(g<<4)+12>>2]}if((e|0)>(c[f+(g<<4)+4>>2]|0))c[b+360>>2]=0;c[b+344>>2]=0;c[b+336>>2]=-1;c[b>>2]=((e|0)>(i|0)?e:i)+-1;Oi(b);Li(b);hi(b);Mi(b)}e=c[b+1704>>2]|0;if((e|0)>0){f=c[b+628>>2]|0;g=0;do{k=f+(g*464|0)|0;c[k>>2]=c[k>>2]&-67108865;g=g+1|0}while((g|0)!=(e|0))}if((c[b+12>>2]|0)==0?(Qi(b),Ri(b,d[b+2520+(c[b>>2]|0)>>0]|0,c[b+8>>2]|0),m=b+1500|0,l=c[m>>2]|0,l|0):0){c[b+16>>2]=((l&65536|0)==0?l:l>>>8)&255;c[m>>2]=l^65536}Si(b);f=b+956|0;if((c[f>>2]|0)>0){e=0;do{Ti(b,e);e=e+1|0}while((e|0)<(c[f>>2]|0))}n=+h[b+2824>>3]*+h[b+2816>>3]/+(c[b+20>>2]|0);h[b+48>>3]=n;m=b+40|0;h[m>>3]=+h[m>>3]+n;Ik(b);b=0;return b|0}function Oi(b){b=b|0;var e=0,f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;l=b+1724|0;n=b+1728|0;o=b+60|0;k=b+328|0;m=b+1696|0;p=c[b+2852>>2]|0;e=c[b>>2]|0;while(1){g=e+1|0;c[b>>2]=g;if(!(p&134217728))e=0;else e=(a[b+2520+g>>0]|0)==-1;f=c[l>>2]|0;if(e|(g|0)>=(f|0)){e=c[n>>2]|0;if(((e|0)<=(f|0)?(d[b+2520+e>>0]|0)<(c[m>>2]|0):0)?(i=c[o>>2]|0,j=b+9020+(i<<3)|0,(g|0)>=(c[j>>2]|0)):0){e=(mk(b,e)|0)==(i|0);e=e?n:j}else e=b+9020+(c[o>>2]<<3)|0;g=c[e>>2]|0;c[b>>2]=g;c[k>>2]=c[b+2872+(g*24|0)+8>>2]}e=b+2520+g|0;if((d[e>>0]|0)<(c[m>>2]|0))break;else e=g}h[b+40>>3]=+(c[b+2872+(g*24|0)+12>>2]|0);o=c[c[(c[b+1736>>2]|0)+(d[e>>0]<<2)>>2]>>2]|0;c[b+356>>2]=o;f=b+344|0;e=c[f>>2]|0;if((e|0)>=(o|0)){c[f>>2]=0;e=0}c[b+8>>2]=e;c[f>>2]=0;c[b+4>>2]=g;c[b+12>>2]=0;if(!(p&256))return;g=c[b+1704>>2]|0;if((g|0)<=0)return;e=c[b+628>>2]|0;f=0;do{c[e+(f*464|0)+4>>2]=0;f=f+1|0}while((f|0)!=(g|0));return}function Pi(a){a=a|0;var b=0,d=0;c[a+12>>2]=0;c[a+340>>2]=0;b=a+332|0;if(c[b>>2]|0){c[b>>2]=0;d=a+336|0;b=c[d>>2]|0;if((b|0)!=-1){c[a>>2]=b+-1;c[d>>2]=-1}Oi(a);return}d=a+348|0;b=c[d>>2]|0;if(b|0){c[a+8>>2]=(c[(c[a+352>>2]|0)+(b+-1<<3)>>2]|0)+-1;c[d>>2]=0}d=a+364|0;b=c[d>>2]|0;if(!b){d=a+8|0;b=(c[d>>2]|0)+1|0;c[d>>2]=b;c[a+368>>2]=0}else{c[d>>2]=b+-1;b=c[a+8>>2]|0}if((b|0)<(c[a+356>>2]|0))return;Oi(a);return}function Qi(a){a=a|0;var b=0,d=0,e=0;d=c[a+60>>2]|0;if((c[a>>2]|0)!=(c[a+372+(d<<4)+4>>2]|0))return;if((c[a+8>>2]|0)!=(c[a+372+(d<<4)+8>>2]|0))return;e=a+360|0;b=c[e>>2]|0;if(!b){b=a+56|0;c[b>>2]=(c[b>>2]|0)+1;b=c[a+372+(d<<4)+12>>2]|0;c[e>>2]=b}c[e>>2]=b+-1;return}function Ri(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;A=l;l=l+16|0;p=A;o=b+1704|0;if((c[o>>2]|0)<=0){l=A;return}z=b+1740|0;y=b+1736|0;s=b+1708|0;x=b+1744|0;r=p+3|0;q=p+4|0;v=b+368|0;u=b+364|0;t=b+2856|0;w=b+628|0;n=0;do{g=c[(c[z>>2]|0)+(c[(c[(c[y>>2]|0)+(e<<2)>>2]|0)+4+(n<<2)>>2]<<2)>>2]|0;if((c[g>>2]|0)>(f|0)){i=g+4+(f<<3)|0;h=i;i=i+4|0;h=d[h>>0]|d[h+1>>0]<<8|d[h+2>>0]<<16|d[h+3>>0]<<24;i=d[i>>0]|d[i+1>>0]<<8|d[i+2>>0]<<16|d[i+3>>0]<<24}else{h=0;i=0}g=p;c[g>>2]=h;c[g+4>>2]=i;g=bp(h|0,i|0,8)|0;j=g&255;if((h&255)<<24>>24==-127){g=(g&255)+-1|0;if(g>>>0<(c[s>>2]|0)>>>0?(k=c[x>>2]|0,(c[k+(g*764|0)+36>>2]|0)>0):0)g=c[k+(g*764|0)+44>>2]&1;else g=0;if(((h&-16777216|0)==234881024&0==0?!(j<<24>>24==0|(i&240|0)!=208):0)?(m=i&15,m|g|0):0){if(m|0)a[p>>0]=0;a[r>>0]=0;a[q>>0]=0}}do if(kj(b,p,n)|0){if((c[t>>2]|0)==3)c[(c[w>>2]|0)+(n*464|0)>>2]=0}else{if(c[v>>2]|0?(c[u>>2]|0)<=0:0)break;nj(b,p,n);Dk(b,e,n,f)}while(0);n=n+1|0}while((n|0)<(c[o>>2]|0));l=A;return}function Si(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0;h=b+1704|0;e=c[h>>2]|0;i=b+9168|0;d=c[i>>2]|0;if((d+e|0)>0)g=0;else return;do{f=b+976+(g<<3)+7|0;if(a[f>>0]|0){nj(b,b+976+(g<<3)|0,g);a[f>>0]=0;e=c[h>>2]|0;d=c[i>>2]|0}g=g+1|0}while((g|0)<(d+e|0));return} +function Ti(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;m=c[a+628>>2]|0;l=m+(b*464|0)|0;c[m+(b*464|0)+452>>2]=0;do if((Ui(a)|0)==0?c[l>>2]&2097152|0:0){e=a+20|0;d=(c[e>>2]|0)+(c[m+(b*464|0)+392>>2]|0)|0;c[e>>2]=d;if((d|0)<32){c[e>>2]=32;break}if((d|0)>255)c[e>>2]=255}while(0);e=m+(b*464|0)+60|0;d=c[e>>2]|0;if((d|0)>0?(k=d+-1|0,c[e>>2]=k,(k|0)==0):0)nj(a,m+(b*464|0)+428|0,b);h=Ai(a,b)|0;if((h|0)==-1){Vi(a,b);return}j=m+(b*464|0)+44|0;d=c[j>>2]|0;k=a+1708|0;e=c[k>>2]|0;do if((h|0)!=256&(c[a+12>>2]|0)==0){if(d>>>0>>0?(c[(c[a+1744>>2]|0)+(d*764|0)+36>>2]|0)>0:0){if(h|0)break}else g=15;if(((g|0)==15?(f=c[a+9172>>2]|0,(f|0)>0):0)?!((h|0)==0|d>>>0>=(e+f|0)>>>0):0)break;ki(a,b);return}while(0);if(!(d>>>0>>0?(c[(c[a+1744>>2]|0)+(d*764|0)+36>>2]|0)>0:0))g=21;if((g|0)==21?(g=c[a+9172>>2]|0,!((g|0)>0&d>>>0<(e+g|0)>>>0)):0)return;zm(a,l,b);if(c[l>>2]&262144|0?(e=(c[a+2852>>2]&16777216|0)!=0,i=m+(b*464|0)+236|0,f=c[i>>2]|0,g=f+-1|0,c[i>>2]=g,e?(f|0)<2:(g|0)==0):0){e=m+(b*464|0)+240|0;d=c[e>>2]|0;if((d|0)<16){yi(a,b,0.0);d=c[e>>2]|0}else{g=m+(b*464|0)+8|0;c[g>>2]=c[g>>2]|4}g=m+(b*464|0)+76|0;f=O(c[20124+(d*12|0)+4>>2]|0,(c[g>>2]|0)+(c[20124+(d*12|0)>>2]|0)|0)|0;c[g>>2]=(f|0)/(c[20124+(d*12|0)+8>>2]|0)|0;c[i>>2]=c[m+(b*464|0)+232>>2]&15}e=m+(b*464|0)+64|0;d=c[e>>2]|0;if(d){i=d+-1|0;c[e>>2]=i;d=m+(b*464|0)+8|0;if(!i){c[d>>2]=c[d>>2]|2;e=d}else e=d}else e=m+(b*464|0)+8|0;mi(a,b,(c[e>>2]|0)>>>1&1);Wi(a,b,h);Xi(a,b,h);Yi(a,b,h);Vi(a,b);Zi(a,b);_i(a,b);if(c[a+2852>>2]&4|0?(c[j>>2]|0)<(c[k>>2]|0):0)$i(c[a+1748>>2]|0,l);d=c[e>>2]|0;if(d&128|0)c[e>>2]=d|2;c[m+(b*464|0)+448>>2]=~~+pi(a,b);return}function Ui(a){a=a|0;var b=0;b=c[a+12>>2]|0;if((c[a+2856>>2]&-2|0)!=2){a=b;a=(a|0)==0;a=a&1;return a|0}a=(b|0)%(c[a+16>>2]|0)|0;a=(a|0)==0;a=a&1;return a|0}function Vi(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;l=c[b+628>>2]|0;f=l+(e*464|0)|0;k=((c[b+12>>2]|0)%(c[b+16>>2]|0)|0|0)==0;if(k?(c[b+2852>>2]&64|0)==0:0){i=c[f>>2]|0;h=l+(e*464|0)+76|0;m=20}else{i=c[f>>2]|0;f=b+328|0;if(i&1048576|0)c[f>>2]=(c[f>>2]|0)+(c[l+(e*464|0)+280>>2]|0);j=l+(e*464|0)+4|0;h=c[j>>2]|0;if((i|h)&1|0){f=l+(e*464|0)+76|0;c[f>>2]=(c[f>>2]|0)+(c[l+(e*464|0)+248>>2]|0)}do if(h&1|0){f=c[l+(e*464|0)+248>>2]|0;if((f|0)>0){g=l+(e*464|0)+76|0;f=c[b+2836>>2]|0;if((c[g>>2]|0)<=(f|0))break;c[g>>2]=f;c[j>>2]=h&-2;break}if((f|0)<0?(g=l+(e*464|0)+76|0,(c[g>>2]|0)<0):0){c[g>>2]=0;c[j>>2]=h&-2}}while(0);h=l+(e*464|0)+76|0;if(i&8192|0)c[h>>2]=(c[h>>2]|0)+(c[l+(e*464|0)+256>>2]|0);f=l+(e*464|0)+56|0;if(i&512|0)c[f>>2]=(c[f>>2]|0)+(c[l+(e*464|0)+292>>2]|0);if(k)m=20}if((m|0)==20){if(i&64|0)c[h>>2]=(c[h>>2]|0)+(c[l+(e*464|0)+252>>2]|0);g=b+368|0;f=c[g>>2]|0;if(i&33554432|0?!((f|0)!=0&(f&2|0)==0):0)c[h>>2]=(c[h>>2]|0)+(c[l+(e*464|0)+264>>2]|0);c[g>>2]=f&-3;f=l+(e*464|0)+56|0;if(i&1024|0)c[f>>2]=(c[f>>2]|0)+(c[l+(e*464|0)+296>>2]|0);f=b+328|0;if(i&1048576)c[f>>2]=(c[f>>2]|0)+(c[l+(e*464|0)+284>>2]|0)}g=c[h>>2]|0;if((g|0)>=0){f=c[b+2836>>2]|0;if((g|0)>(f|0))m=31;else f=g}else{f=0;m=31}if((m|0)==31)c[h>>2]=f;i=b+328|0;h=c[i>>2]|0;if((h|0)>=0){g=c[b+2840>>2]|0;if((h|0)>(g|0))m=34}else{g=0;m=34}if((m|0)==34)c[i>>2]=g;i=l+(e*464|0)+56|0;h=c[i>>2]|0;if((h|0)>=0){g=c[b+2836>>2]|0;if((h|0)>(g|0))m=37}else{g=0;m=37}if((m|0)==37)c[i>>2]=g;if(!(a[l+(e*464|0)+92>>0]|0))return;c[l+((d[l+(e*464|0)+93>>0]|0)*464|0)+76>>2]=f;return}function Wi(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;p=b+628|0;q=c[p>>2]|0;l=q+(e*464|0)|0;n=Em(b,c[q+(e*464|0)+44>>2]|0)|0;o=b+2852|0;k=c[o>>2]|0;if(k&262144){h=q+(e*464|0)+8|0;g=c[h>>2]|0;if((f|0)==2|(g&2|0)!=0){j=(c[n+44>>2]&5|0)!=1;m=h}else{j=0;m=h}}else{i=q+(e*464|0)+8|0;g=c[i>>2]|0;h=(g&2|0)!=0;if(!((c[n+44>>2]&1|0)!=0|h^1))c[q+(e*464|0)+68>>2]=0;j=(f|0)==2|h;m=i}do if(!((f|0)!=3&(g&1|0)==0&(j^1))){j=q+(e*464|0)+68|0;h=c[j>>2]|0;i=c[q+(e*464|0)+72>>2]|0;if((h|0)>(i|0)){c[j>>2]=h-i;break}else{c[j>>2]=0;g=g|4;c[m>>2]=g;break}}while(0);j=n+44|0;i=q+(e*464|0)+96|0;h=c[i>>2]|0;switch(fj(j,h)|0){case -1:{g=g|4;c[m>>2]=g;break}case 0:break;default:if(k&2){g=g|1;c[m>>2]=g}}if(!(c[q+(e*464|0)+4>>2]&4194304)){h=aj(j,h,g>>>1&1|(f|0)==2,(c[l>>2]|0)>>>26&1,(c[b+2856>>2]|0)==3&1)|0;c[i>>2]=h}f=bj(j,h,64)|0;if(gj(j,h)|0){if(!(f&65535)){g=g|4;c[m>>2]=g}g=g|16;c[m>>2]=g}if(g&4|0?(c[b+952>>2]|0)<=(e|0):0){ki(b,e);return}g=Am(b,l)|0;j=b+2856|0;h=c[j>>2]|0;if((h|0)==3)g=(O(100-(c[q+(e*464|0)+84>>2]|0)|0,c[q+(e*464|0)+76>>2]|0)|0)/100|0;do if(c[l>>2]&32){if((Ui(b)|0)==0|(k&4|0)==0)g=((ck(h,q+(e*464|0)+132|0,0)|0)/64|0)+g|0;if(Ui(b)|0?(c[o>>2]&1048576|0)==0:0)break;hk(q+(e*464|0)+132|0)}while(0);i=c[b+2836>>2]|0;h=(O(c[q+(e*464|0)+68>>2]|0,(g|0)<0?0:(g|0)>(i|0)?i:g)|0)>>6;g=O(c[b+328>>2]|0,f&65535)|0;g=O(g,c[q+(e*464|0)+56>>2]|0)|0;g=(O((h<<6|0)/(i|0)|0,(g|0)/(c[b+2840>>2]|0)|0)|0)>>>18;g=(O(g,hj(b,e)|0)|0)/100|0;h=c[b+2848>>2]|0;if(h){l=(i|0)==255?2:4;g=c[h+(g>>l<<2)>>2]<>2]&16384){g=O(c[n+32>>2]|0,g)|0;g=(O(g,c[q+(e*464|0)+80>>2]|0)|0)>>12}if((c[j>>2]|0)==1)g=ij(b,e,g)|0;else g=jj(c[p>>2]|0,e,g)|0;g=(O(c[((c[b+1704>>2]|0)>(e|0)?b+324|0:b+320|0)>>2]|0,g)|0)/100|0;c[q+(e*464|0)+452>>2]=c[m>>2]&32|0?0:g;li(b,e,g);if(!(a[q+(e*464|0)+92>>0]|0))return;li(b,d[q+(e*464|0)+93>>0]|0,g);return}function Xi(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0.0,i=0,j=0.0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;z=l;l=l+16|0;w=z+8|0;x=z+4|0;y=z;v=c[b+628>>2]|0;s=v+(d*464|0)|0;u=Em(b,c[v+(d*464|0)+44>>2]|0)|0;m=v+(d*464|0)+4|0;if(!(c[m>>2]&16777216)){f=u+356|0;t=v+(d*464|0)+104|0;i=c[s>>2]|0;e=aj(f,c[t>>2]|0,(c[v+(d*464|0)+8>>2]|0)>>>1&1|(e|0)==2,i>>>26&1,(c[b+2856>>2]|0)==3&1)|0;c[t>>2]=e;r=s}else{t=v+(d*464|0)+104|0;e=c[t>>2]|0;i=c[s>>2]|0;f=u+356|0;r=s}e=bj(f,e,0)|0;if(i&16384|0){k=v+(d*464|0)+420|0;f=c[k>>2]|0;if(!f){i=v+(d*464|0)+12|0;f=(c[i>>2]|0)+(c[v+(d*464|0)+408>>2]|0)|0;c[i>>2]=f;h[v+(d*464|0)+24>>3]=+Bi(b,f,c[v+(d*464|0)+40>>2]|0,+h[v+(d*464|0)+32>>3]);f=c[v+(d*464|0)+416>>2]|0;c[k>>2]=f}else i=v+(d*464|0)+12|0;c[k>>2]=f+-1;si(b,d,c[i>>2]|0)}p=v+(d*464|0)+200|0;i=b+2856|0;g=+(ck(c[i>>2]|0,p,1)|0);q=v+(d*464|0)+216|0;g=g/+((c[q>>2]<<12)+4096|0);hk(p);p=c[q>>2]|0;c[q>>2]=(p|0)>1?p+-2|0:0;if((c[r>>2]&16|0)==0?(c[m>>2]&16|0)==0:0)k=b+2852|0;else{q=(Ui(b)|0)==0;k=b+2852|0;f=c[k>>2]|0;if(q|(f&4|0)==0){f=(ck(c[i>>2]|0,v+(d*464|0)+112|0,1)|0)/(512<<(f>>>19&1)|0)|0;q=c[k>>2]|0;j=+(f|0);f=q;g=g+((q&2097152|0)==0?j:-j)}if(!((Ui(b)|0)!=0&(f&1048576|0)==0))hk(v+(d*464|0)+112|0)}j=+h[v+(d*464|0)+24>>3];j=j+ +(Bm(s)|0);j=j<.1?.1:j;o=c[k>>2]|0;m=o&67108864;if(!m)n=a[(c[v+(d*464|0)+192>>2]|0)+(v+(d*464|0)+172)>>0]|0;else n=ej(b,s)|0;q=v+(d*464|0)+12|0;p=c[q>>2]|0;f=Fi(b,g+(j<16.23927&(o&16|0)!=0?16.23927:j),p,+h[v+(d*464|0)+32>>3])|0;do if((c[v+(d*464|0)+8>>2]&512|0)!=0?(c[r>>2]&4|0)!=0:0){if((f|0)>0){f=f+6400|0;f=f-((f|0)%12800|0)|0;break}i=f+-6400|0;if((f|0)<0)f=i-((i|0)%12800|0)|0;else f=0}while(0);if((n|0)!=0&(m|0)!=0){f=((c[v+(d*464|0)+40>>2]|0)*100|0)+(f-((f|0)%12800|0))|0;if((p+n|0)>107)i=(c[b+16>>2]|0)>-1?108-p|0:n;else i=n}else i=n;if((c[t>>2]|0)>-1)f=((c[u+356>>2]&8|0)==0?e<<7:0)+f|0;do if(i){f=f+(i*12800|0)|0;if(o&4){i=p+i|0;if((i|0)>84){f=f+-460800|0;break}if((i|0)==84)li(b,d,0)}}while(0);f=(Cm(b,s)|0)+f|0;j=+Di(c[q>>2]|0,f);xi(b,d,j);c[v+(d*464|0)+444>>2]=f>>7;f=~~(j*4096.0);i=v+(d*464|0)+440|0;c[i>>2]=f;do if((c[b+2860>>2]|0)==1){j=+(f|0);f=c[v+(d*464|0)+40>>2]|0;g=+Bi(b,83,f,0.0)*4096.0;if(j>2]=~~g;break}g=+Bi(b,48,f,0.0)*4096.0;if(j>g)c[i>>2]=~~g}else if((f|0)<4096)c[i>>2]=4096;while(0);if(!(c[k>>2]&65536)){l=z;return}if((c[t>>2]|0)>-1?(c[u+356>>2]&8|0)!=0:0){f=v+(d*464|0)+404|0;if((e|0)<254)c[f>>2]=e;else e=c[f>>2]|0;e=(O(e,c[v+(d*464|0)+396>>2]|0)|0)>>8}else e=c[v+(d*464|0)+396>>2]|0;f=c[v+(d*464|0)+400>>2]|0;if((e|0)>254)e=255;else{Ek(c[b+1512>>2]|0,e,f,w,x,y);oi(b,d,176,c[w>>2]|0);oi(b,d,177,c[x>>2]|0);oi(b,d,178,c[y>>2]|0);oi(b,d,3,f)}oi(b,d,2,e);l=z;return}function Yi(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;h=c[a+628>>2]|0;e=h+(b*464|0)|0;g=Em(a,c[h+(b*464|0)+44>>2]|0)|0;if(!(c[h+(b*464|0)+4>>2]&8388608)){g=g+200|0;i=h+(b*464|0)+100|0;e=c[e>>2]|0;f=aj(g,c[i>>2]|0,(c[h+(b*464|0)+8>>2]|0)>>>1&1|(d|0)==2,e>>>26&1,(c[a+2856>>2]|0)==3&1)|0;c[i>>2]=f;d=g}else{f=c[h+(b*464|0)+100>>2]|0;e=c[e>>2]|0;d=g+200|0}g=bj(d,f,32)|0;if(e&524288){e=h+(b*464|0)+152|0;f=a+2856|0;d=(ck(c[f>>2]|0,e,0)|0)/512|0;if(!(Ui(a)|0))e=f;else{hk(e);e=f}}else{d=0;e=a+2856|0}i=c[h+(b*464|0)+360>>2]|0;f=i+-128|0;d=i+d+((O(128-((f|0)>-1?f:128-i|0)|0,g+-32|0)|0)/32|0)|0;if((c[e>>2]|0)==3)e=(c[h+(b*464|0)+88>>2]<<2)+d|0;else e=d;d=c[h+(b*464|0)+376>>2]|0;do if(!(c[a+1516>>2]&4))if(!d){d=(O(c[a+1524>>2]|0,(e|0)<0?-128:((e|0)<255?e:255)+-128|0)|0)/100|0;c[h+(b*464|0)+456>>2]=d+128;e=16;break}else{c[h+(b*464|0)+456>>2]=128;e=15;break}else{c[h+(b*464|0)+456>>2]=128;if(!d){d=0;e=16}else e=15}while(0);if((e|0)==15){ni(a,b,32768);return}else if((e|0)==16){ni(a,b,d);return}}function Zi(a,b){a=a|0;b=b|0;var d=0,e=0.0,f=0,g=0.0,i=0.0,j=0,k=0,l=0,m=0;m=c[a+628>>2]|0;l=m+(b*464|0)|0;if(!((Ui(a)|0)!=0?!(c[a+2852>>2]&128|0):0))d=3;do if((d|0)==3){k=c[l>>2]|0;if(!((k&8|0)==0?!(c[m+(b*464|0)+4>>2]&8|0):0))d=5;if((d|0)==5?(j=m+(b*464|0)+24|0,e=+h[j>>3]+ +(c[m+(b*464|0)+304>>2]|0),h[j>>3]=e,c[a+2852>>2]&4|0):0)h[m+(b*464|0)+328>>3]=e;if((k&4|0)==0?(c[m+(b*464|0)+4>>2]&4|0)==0:0)break;j=m+(b*464|0)+328|0;g=+h[j>>3];if(g>0.0){d=m+(b*464|0)+336|0;i=+(c[m+(b*464|0)+340>>2]|0);f=m+(b*464|0)+24|0;e=+h[f>>3];if((c[d>>2]|0)>0){i=e+i;h[f>>3]=i;if(!(i>=g))break}else{i=e-i;h[f>>3]=i;if(!(i<=g))break}h[f>>3]=g;c[d>>2]=0;c[l>>2]=k&-5;k=m+(b*464|0)+4|0;c[k>>2]=c[k>>2]&-5;if(c[a+2852>>2]&4|0)h[j>>3]=-1.0}}while(0);if(Ui(a)|0){d=c[l>>2]|0;f=m+(b*464|0)+24|0;if(d&128|0)h[f>>3]=+h[m+(b*464|0)+312>>3]+ +h[f>>3];if(d&32768|0){k=m+(b*464|0)+12|0;l=(c[k>>2]|0)+(c[m+(b*464|0)+412>>2]|0)|0;c[k>>2]=l;h[f>>3]=+Bi(a,l,c[m+(b*464|0)+40>>2]|0,+h[m+(b*464|0)+32>>3])}}a:do switch(c[a+2860>>2]|0){case 2:{d=m+(b*464|0)+24|0;e=+h[d>>3];if(e<0.0){h[d>>3]=0.0;break a}if(e>7680.0)h[d>>3]=7680.0;break}case 1:{d=m+(b*464|0)+24|0;g=+h[d>>3];f=c[m+(b*464|0)+40>>2]|0;e=+Bi(a,83,f,0.0);if(g>3]=e;break a}e=+Bi(a,48,f,0.0);if(g>e)h[d>>3]=e;break}default:d=m+(b*464|0)+24|0}while(0);l=m+(b*464|0)+192|0;c[l>>2]=((c[l>>2]|0)+1|0)%(c[m+(b*464|0)+188>>2]|0)|0;if(!(+h[d>>3]<.25))return;li(a,b,0);return}function _i(a,b){a=a|0;b=b|0;var d=0,e=0;d=c[a+628>>2]|0;if(!(c[d+(b*464|0)>>2]&2))return;a=(Ui(a)|0)==0;e=d+(b*464|0)+360|0;a=(c[e>>2]|0)+(c[(a?d+(b*464|0)+364|0:d+(b*464|0)+368|0)>>2]|0)|0;c[e>>2]=a;if((a|0)<0){c[e>>2]=0;return}if((a|0)<=255)return;c[e>>2]=255;return}function $i(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0;g=c[d+52>>2]|0;e=d+384|0;f=(c[e>>2]|0)+(c[20328+(c[d+380>>2]<<2)>>2]|0)|0;c[e>>2]=f;h=c[b+(g*52|0)+44>>2]|0;if(!((f|0)>127&(h&2|0)!=0))return;c[e>>2]=0;f=c[b+(g*52|0)+36>>2]|0;d=d+388|0;e=c[d>>2]|0;e=(e|0)<((c[b+(g*52|0)+40>>2]|0)-f|0)?e+1|0:0;c[d>>2]=e;if(h&1|0)return;b=(c[b+(g*52|0)+48>>2]|0)+(e+f)|0;a[b>>0]=~a[b>>0];return}function aj(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;b=((b|0)<65535&1)+b|0;do if((b|0)>=0){if((c[a>>2]&1|0)!=0?(c[a+4>>2]|0)>=1:0)if(!f){b=dj(a,b,d)|0;break}else{b=cj(a,b,d,e)|0;break}}else b=-1;while(0);return b|0}function bj(a,d,e){a=a|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;if((d|0)<0){d=e;return d|0}if(!(c[a>>2]&1)){d=e;return d|0}f=c[a+4>>2]|0;if((f|0)<1){d=e;return d|0}e=f<<1;f=e+-2|0;if((f|0)==0?1:(b[a+28+(f<<1)>>1]|0)<=(d|0)){d=b[a+28+(e+-1<<1)>>1]|0;return d|0}while(1){e=f+-2|0;h=b[a+28+(e<<1)>>1]|0;i=h<<16>>16;if((f|0)>2&(i|0)>(d|0))f=e;else break}g=b[a+28+(f+-1<<1)>>1]|0;e=b[a+28+(f<<1)>>1]|0;f=b[a+28+((f|1)<<1)>>1]|0;if(e<<16>>16==h<<16>>16){d=f;return d|0}d=((O(f-g|0,d-i|0)|0)/((e<<16>>16)-i|0)|0)+g|0;return d|0}function cj(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0;h=c[a>>2]|0;g=h&4;h=h&2;i=c[a+20>>2]<<1;k=c[a+24>>2]<<1;l=c[a+12>>2]<<1;j=c[a+16>>2]<<1;if((f|0)!=0&(h|0)!=0?((b[a+28+(j<<1)>>1]|0)+1|0)==(d|0):0){d=b[a+28+(l<<1)>>1]|0;return d|0}if(!((e|0)!=0|(h|0)==0)){if(((b[a+28+(j<<1)>>1]|0)+1|0)!=(d|0))return d|0;d=b[a+28+(l<<1)>>1]|0;return d|0}if(!g)return d|0;if((b[a+28+(k<<1)>>1]|0)>=(d|0))return d|0;d=b[a+28+(i<<1)>>1]|0;return d|0}function dj(a,d,e){a=a|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;m=c[a>>2]|0;g=m&2;h=c[a+20>>2]<<1;i=c[a+24>>2]<<1;j=c[a+12>>2]<<1;k=(m&4|0)!=0;f=(e|0)!=0;g=(m&6|0)==6?(f|(j|0)!=(i|0)?g:0):g;if(k?((b[a+28+(i<<1)>>1]|0)+1|0)<(d|0):0){e=1;l=4}else if(g){e=b[a+28+(j<<1)>>1]|0;if(f|(e+1|0)<(d|0)){f=1;e=d}else{f=0;e=(e|0)>(d|0)?d:e}}else l=4;if((l|0)==4){f=(e|0)!=0;e=d}if(!k){m=e;return m|0}if((e|0)<(b[a+28+(i<<1)>>1]|0)){m=e;return m|0}if((j|0)==(i|0)&((g|0)!=0&f)){m=e;return m|0}m=b[a+28+(h<<1)>>1]|0;return m|0}function ej(b,d){b=b|0;d=d|0;var e=0;if((a[d+173>>0]|0)==0?(a[d+174>>0]|0)==0:0){d=0;return d|0}e=c[b+12>>2]|0;if(!e){d=0;return d|0}b=c[b+16>>2]|0;e=b-((e|0)%(b|0)|0)|0;if((e|0)==16){d=0;return d|0}if((e|0)>16){d=a[d+174>>0]|0;return d|0}else{d=a[((e|0)%3|0)+(d+172)>>0]|0;return d|0}return 0}function fj(a,d){a=a|0;d=d|0;var e=0;if(!(c[a>>2]&1)){d=0;return d|0}e=c[a+4>>2]<<1;if((b[a+28+(e+-2<<1)>>1]|0)>=(d|0)){d=0;return d|0}d=(b[a+28+(e+-1<<1)>>1]|0)==0?-1:1;return d|0}function gj(a,d){a=a|0;d=d|0;var e=0,f=0;f=~c[a>>2];if(f&1|0)return 0;e=c[a+4>>2]|0;if((e|0)<1)return 0;else{e=(e<<1)+-2|0;return (((f&4|0)==0|(e|0?(b[a+28+(e<<1)>>1]|0)>(d|0):0))^1)&1|0}return 0}function hj(a,b){a=a|0;b=b|0;if((c[a+952>>2]|0)>(b|0)){a=c[a+632+(b<<2)>>2]|0;return a|0}if((c[a+956>>2]|0)<=(b|0)){a=0;return a|0}b=di(a,b)|0;if((b|0)<0){a=0;return a|0}a=c[a+632+(b<<2)>>2]|0;return a|0}function ij(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;h=c[b+628>>2]|0;i=h+(d*464|0)+246|0;f=a[i>>0]|0;g=f&255;if(!(g&128))return e|0;a:do if((c[h+(d*464|0)>>2]&134217728|0)!=0?(c[b+12>>2]|0)!=0:0){f=g&223;a[i>>0]=f;switch(f<<24>>24){case -128:{f=a[h+(d*464|0)+244>>0]|-64;a[i>>0]=f;break a}case -64:{f=a[h+(d*464|0)+245>>0]|-128;a[i>>0]=f;break a}default:{f=f+-1<<24>>24;a[i>>0]=f;break a}}}while(0);return ((f&-32)<<24>>24==-128?0:e)|0}function jj(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;if(!(c[b+(d*464|0)>>2]&134217728))return e|0;g=b+(d*464|0)+246|0;f=a[g>>0]|0;switch(f<<24>>24){case 0:{f=a[b+(d*464|0)+244>>0]|-128;h=5;break}case -128:{f=a[b+(d*464|0)+245>>0]|0;h=5;break}default:{}}if((h|0)==5)a[g>>0]=f;h=f+-1<<24>>24;a[g>>0]=h;return (h<<24>>24>-1?0:e)|0}function kj(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;o=c[b+628>>2]|0;j=a[e+3>>0]|0;switch(j<<24>>24){case 15:{h=a[e+4>>0]|0;if((h&255)<32){i=h;m=4}break}case -93:{i=a[e+4>>0]|0;m=4;break}default:{}}if((m|0)==4?i<<24>>24:0)c[b+16>>2]=i&255;n=e+5|0;h=a[n>>0]|0;switch(h<<24>>24){case 15:{i=a[e+6>>0]|0;if((i&255)<32){k=i;m=9}break}case -93:{k=a[e+6>>0]|0;m=9;break}default:{}}if((m|0)==9?k<<24>>24:0)c[b+16>>2]=k&255;if(!((j<<24>>24==14?(l=d[e+4>>0]|0,(l&240|0)==208):0)?(g=l&15,(g|0)!=0):0)){if(h<<24>>24!=14){e=0;return e|0}g=d[e+6>>0]|0;if((g&240|0)!=208){e=0;return e|0}g=g&15;if(!g){e=0;return e|0}}c[o+(f*464|0)+60>>2]=g+1;h=o+(f*464|0)+428|0;i=e;l=i;l=d[l>>0]|d[l+1>>0]<<8|d[l+2>>0]<<16|d[l+3>>0]<<24;i=i+4|0;i=d[i>>0]|d[i+1>>0]<<8|d[i+2>>0]<<16|d[i+3>>0]<<24;g=h;m=g;a[m>>0]=l;a[m+1>>0]=l>>8;a[m+2>>0]=l>>16;a[m+3>>0]=l>>24;g=g+4|0;a[g>>0]=i;a[g+1>>0]=i>>8;a[g+2>>0]=i>>16;a[g+3>>0]=i>>24;g=a[e+1>>0]|0;i=g<<24>>24==0;if(!i)c[o+(f*464|0)+436>>2]=g&255;if(!(c[b+2852>>2]&33554432)){e=1;return e|0}if(((a[e+2>>0]|0)==0?!((a[n>>0]|0)!=0|i^1):0)?(a[e>>0]|0)!=-127:0)a[o+(f*464|0)+430>>0]=(c[o+(f*464|0)+76>>2]|0)+1;if(!(a[e>>0]|0))a[h>>0]=(c[o+(f*464|0)+16>>2]|0)+1;if(!i){e=1;return e|0}a[o+(f*464|0)+429>>0]=c[o+(f*464|0)+48>>2];e=1;return e|0}function lj(e){e=e|0;var f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;if((c[e+9188>>2]|0)<1)return;p=c[e+1704>>2]|0;f=c[e+4>>2]|0;if(!((f|0)>-1?(f|0)<(c[e+1724>>2]|0):0))f=0;c[9746]=f;o=d[e+2520+f>>0]|0;c[9747]=o;n=(o|0)<(c[e+1696>>2]|0);if(n)m=c[c[(c[e+1736>>2]|0)+(o<<2)>>2]>>2]|0;else m=0;c[9749]=m;l=c[e+8>>2]|0;c[9748]=l;c[9750]=c[e+12>>2];c[9751]=c[e+16>>2];c[9752]=c[e+20>>2];f=c[e+60>>2]|0;c[9754]=c[e+372+(f<<4)>>2];c[9755]=~~(+h[e+48>>3]*1.0e3);c[9753]=~~+h[e+40>>3];c[9756]=c[e+1536>>2];c[9758]=24585;g=c[e+1548>>2]|0;c[9757]=g;i=~c[e+1516>>2];if(i&5|0)c[9757]=g<<(i>>>2&1)<<(i&1);c[9759]=c[e+328>>2];c[9760]=c[e+56>>2];c[9761]=c[e+956>>2];c[9762]=c[e+960>>2];c[9763]=f;j=c[e+628>>2]|0;if(!((j|0)!=0&(p|0)>0))return;k=e+1736|0;i=e+1740|0;g=0;do{a[39056+(g*24|0)+10>>0]=c[j+(g*464|0)+16>>2];b[39056+(g*24|0)+8>>1]=c[j+(g*464|0)+444>>2];c[39056+(g*24|0)>>2]=c[j+(g*464|0)+440>>2];c[39056+(g*24|0)+4>>2]=c[j+(g*464|0)+448>>2];a[39056+(g*24|0)+11>>0]=c[j+(g*464|0)+44>>2];a[39056+(g*24|0)+12>>0]=c[j+(g*464|0)+52>>2];a[39056+(g*24|0)+13>>0]=(c[j+(g*464|0)+452>>2]|0)>>>4;a[39056+(g*24|0)+14>>0]=c[j+(g*464|0)+456>>2];a[39056+(g*24|0)+15>>0]=0;f=39056+(g*24|0)+16|0;e=f;c[e>>2]=0;c[e+4>>2]=0;if(!((l|0)>=(m|0)|n^1)?(q=c[(c[i>>2]|0)+(c[(c[(c[k>>2]|0)+(o<<2)>>2]|0)+4+(g<<2)>>2]<<2)>>2]|0,(l|0)<(c[q>>2]|0)):0){r=q+4+(l<<3)|0;s=r;r=r+4|0;r=d[r>>0]|d[r+1>>0]<<8|d[r+2>>0]<<16|d[r+3>>0]<<24;e=f;c[e>>2]=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;c[e+4>>2]=r}g=g+1|0}while((g|0)!=(p|0));return}function mj(a){a=a|0;var b=0;if((c[a+9188>>2]|0)<1)return;b=a+2792|0;c[10148]=c[b>>2];c[10149]=c[b+4>>2];c[10150]=c[b+8>>2];c[10151]=c[b+12>>2];c[10153]=a+1568;c[10154]=c[a+2788>>2];c[10155]=c[a+9016>>2];c[10156]=a+9020;c[10152]=c[a+2836>>2];return}function nj(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0;f=c[b+628>>2]|0;g=a[d+1>>0]|0;if(g<<24>>24)c[f+(e*464|0)+48>>2]=g&255;g=f+(e*464|0)+8|0;f=c[g>>2]|0;if(f&32|0)c[g>>2]=f|4;if((c[b+1704>>2]|0)<=(e|0)){oj(b,d,e);return}switch(c[b+2856>>2]|0){case 0:{pj(b,d,e);return}case 1:{qj(b,d,e);return}case 2:{rj(b,d,e);return}case 3:{sj(b,d,e)|0;return}case 4:{tj(b,d,e);return}default:{pj(b,d,e);return}}}function oj(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;o=c[b+628>>2]|0;p=o+(f*464|0)|0;c[p>>2]=0;q=e+1|0;g=a[q>>0]|0;if(!(g<<24>>24))return;l=g&255;m=l+-1|0;c[p>>2]=2048;c[o+(f*464|0)+68>>2]=65536;c[o+(f*464|0)+4>>2]=0;n=o+(f*464|0)+220|0;c[n>>2]=0;k=o+(f*464|0)+8|0;h=c[k>>2]|0;c[k>>2]=h&-3;c[o+(f*464|0)+44>>2]=m;i=c[b+1708>>2]|0;if((l|0)>(i|0)?(l|0)<=((c[b+9172>>2]|0)+i|0):0){c[o+(f*464|0)+72>>2]=c[(c[b+9180>>2]|0)+((m-i|0)*764|0)+40>>2];j=1}else j=0;c[p>>2]=67584;g=a[e>>0]|0;if(g<<24>>24==-127){c[k>>2]=h|2;return}l=(g&255)+-1|0;c[o+(f*464|0)+16>>2]=l;c[k>>2]=h&-7;if(!j){g=uj(b,m,l)|0;if(!g)return;i=(c[g+12>>2]|0)+l+(a[(c[b+1744>>2]|0)+(m*764|0)+512+(l<<1)+1>>0]|0)|0;h=c[g+40>>2]|0;h=(c[(c[b+1748>>2]|0)+(h*52|0)+32>>2]|0)==0?-1:h;if((h|0)>-1?(h|0)<(c[b+1712>>2]|0):0){ti(b,f,m,h,i,0,0,0)|0;c[o+(f*464|0)+52>>2]=h}}else{g=c[(c[b+9180>>2]|0)+((m-i|0)*764|0)+756>>2]|0;if(!g)return;i=(c[g+12>>2]|0)+l|0;h=c[g+40>>2]|0;h=(c[(c[b+9184>>2]|0)+(h*52|0)+32>>2]|0)==0?-1:h;if((h|0)>-1?(h|0)<(c[b+9176>>2]|0):0){l=(c[b+1712>>2]|0)+h|0;ti(b,f,m,l,i,0,0,0)|0;c[o+(f*464|0)+52>>2]=l}}vj(b,i,g,p);xj(b,i,g,p,0);if(a[q>>0]|0)wj(b,p);c[o+(f*464|0)+76>>2]=(d[e+2>>0]|0)+-1;c[o+(f*464|0)+12>>2]=i;yi(b,f,+(c[n>>2]|0));return}function pj(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=c[b+628>>2]|0;p=q+(f*464|0)|0;c[p>>2]=0;n=e+3|0;switch(a[n>>0]|0){case 122:case 5:case 3:{g=3;break}default:switch(a[e+5>>0]|0){case 122:case 5:case 3:{g=3;break}default:o=0}}if((g|0)==3)o=1;m=e+1|0;g=a[m>>0]|0;do if(!(g<<24>>24)){i=0;k=0}else{j=(g&255)+-1|0;c[p>>2]=2048;c[q+(f*464|0)+68>>2]=65536;c[q+(f*464|0)+4>>2]=0;c[q+(f*464|0)+220>>2]=0;l=q+(f*464|0)+8|0;c[l>>2]=c[l>>2]&-4;if(j>>>0<(c[b+1708>>2]|0)>>>0?(k=c[b+1744>>2]|0,(c[k+(j*764|0)+36>>2]|0)>0):0){g=uj(b,j,(d[e>>0]|0)+-1|0)|0;i=(g|0)!=0;if(!o){c[q+(f*464|0)+44>>2]=j;c[q+(f*464|0)+72>>2]=c[k+(j*764|0)+40>>2];if(!i){i=0;k=1;break}if(!(c[b+2852>>2]&4)){i=0;k=1;break}c[q+(f*464|0)+40>>2]=c[g+16>>2];i=0;k=1;break}else{if(!i){i=0;k=1;break}if(a[q+(f*464|0)+92>>0]|0){i=0;k=0;break}c[q+(f*464|0)+76>>2]=c[g>>2];i=0;k=0;break}}ki(b,f);i=1;k=1}while(0);g=a[e>>0]|0;do if(g<<24>>24){c[p>>2]=c[p>>2]|65536;if(g<<24>>24==-127){i=q+(f*464|0)+8|0;c[i>>2]=c[i>>2]|2;i=-1;k=0;break}if(!o){g=(g&255)+-1|0;c[q+(f*464|0)+16>>2]=g;l=q+(f*464|0)+8|0;c[l>>2]=c[l>>2]&-5;l=c[q+(f*464|0)+44>>2]|0;j=uj(b,l,g)|0;if(!((i|0)==0&(j|0)!=0)){c[p>>2]=0;i=-1;k=0;break}i=(c[j+12>>2]|0)+g+(a[(c[b+1744>>2]|0)+(l*764|0)+512+(g<<1)+1>>0]|0)|0;g=c[j+40>>2]|0;g=(c[(c[b+1748>>2]|0)+(g*52|0)+32>>2]|0)==0?-1:g;if((g|0)>-1?(g|0)<(c[b+1712>>2]|0):0){ti(b,f,l,g,i,0,0,0)|0;c[q+(f*464|0)+52>>2]=g}}else i=-1}else i=-1;while(0);j=uj(b,c[q+(f*464|0)+44>>2]|0,c[q+(f*464|0)+16>>2]|0)|0;vj(b,i,j,p);if((j|0)!=0&(a[m>>0]|0)!=0)wj(b,p);g=a[e+2>>0]|0;if(g<<24>>24){c[q+(f*464|0)+76>>2]=(g&255)+-1;c[p>>2]=c[p>>2]|4096}Fk(b,p,f,e,1);Fk(b,p,f,e,0);if((a[n>>0]&-2)<<24>>24==-72)h[q+(f*464|0)+24>>3]=+Bi(b,i,c[q+(f*464|0)+40>>2]|0,+h[q+(f*464|0)+32>>3]);else xj(b,i,j,p,o);if(!j)return;if((i|0)>-1){c[q+(f*464|0)+12>>2]=i;yi(b,f,+(c[q+(f*464|0)+220>>2]|0))}g=c[p>>2]|0;if(g&256){if(!((c[b+2852>>2]&4|0)==0?!(c[b+32>>2]&2|0):0)){b=q+(f*464|0)+220|0;c[b>>2]=(c[b>>2]|0)+(c[q+(f*464|0)+224>>2]|0)}g=g&-257;c[p>>2]=g}if(!((k|0)!=0&(g&4096|0)==0))return;if(a[q+(f*464|0)+92>>0]|0)return;c[q+(f*464|0)+76>>2]=c[j>>2];return}function qj(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0;K=l;l=l+16|0;H=K;I=c[b+628>>2]|0;J=I+(f*464|0)|0;if((c[b+12>>2]|0)>=(c[b+16>>2]|0)){l=K;return}y=e;g=y;g=d[g>>0]|d[g+1>>0]<<8|d[g+2>>0]<<16|d[g+3>>0]<<24;y=y+4|0;y=d[y>>0]|d[y+1>>0]<<8|d[y+2>>0]<<16|d[y+3>>0]<<24;u=H;c[u>>2]=g;c[u+4>>2]=y;u=I+(f*464|0)+246|0;i=bp(g|0,y|0,8)|0;j=z;w=i&255;e=bp(g|0,y|0,24)|0;e=e&255;k=bp(g|0,y|0,40)|0;m=z;q=k&255;D=bp(g|0,y|0,16)|0;E=D&255;v=y&255;if(!((g&16711680|0)==0&0==0))a[u>>0]=a[u>>0]&127;c[J>>2]=0;h=g&255;g=i&255;n=H+3|0;switch(e<<24>>24){case 20:{if(0==0&(y&255|0)==0)if(((D|i|k)&255)<<24>>24){e=c[I+(f*464|0)+44>>2]|0;if((e>>>0<(c[b+1708>>2]|0)>>>0?(o=c[b+1744>>2]|0,(c[o+(e*764|0)+36>>2]|0)>0):0)?(p=I+(f*464|0)+8|0,(c[o+(e*764|0)+44>>2]&1|0)==0):0){c[p>>2]=c[p>>2]|1;a[n>>0]=0;e=0;i=1;h=0;A=11}else{e=20;i=1;h=0;A=11}}else{e=20;C=0;B=1;h=0}else{e=20;i=0;A=11}break}case 122:case 5:case 3:{i=0;A=12;break}default:{i=0;A=11}}if((A|0)==11)switch(q<<24>>24){case 122:case 5:case 3:{A=12;break}default:{C=0;B=i}}if((A|0)==12){C=1;B=i}q=w<<24>>24==0;if(!q){i=g+-1|0;k=c[b+1708>>2]|0;if(i>>>0>>0?(r=c[b+1744>>2]|0,(c[r+(i*764|0)+36>>2]|0)>0):0)if((h+-1|0)>>>0>127?(s=c[I+(f*464|0)+44>>2]|0,t=uj(b,s,c[I+(f*464|0)+16>>2]|0)|0,(t|0)!=0):0){i=c[b+1752+(f*12|0)>>2]|0;j=i+-128|0;c[I+(f*464|0)+76>>2]=c[t>>2];if(!(c[b+2852>>2]&4096))c[I+(f*464|0)+360>>2]=((O((c[t+8>>2]|0)+-128|0,128-((j|0)>-1?j:128-i|0)|0)|0)/128|0)+i;c[I+(f*464|0)+72>>2]=c[r+(s*764|0)+40>>2];c[J>>2]=4096;i=6144;o=1}else{i=2048;o=1}else{i=2048;g=0;o=0}c[J>>2]=i;c[I+(f*464|0)+68>>2]=65536;c[I+(f*464|0)+4>>2]=0;t=I+(f*464|0)+8|0;c[t>>2]=c[t>>2]&((B|0)==0?-132:-131);g=g+-1|0;if(g>>>0>>0?(c[(c[b+1744>>2]|0)+(g*764|0)+36>>2]|0)>0:0)if(!C){c[I+(f*464|0)+44>>2]=g;m=i;n=h;g=0}else{m=i;n=h;g=0}else{c[J>>2]=0;m=0;n=(C|0)==0?h:0;g=1}a[u>>0]=32;h=n+-1|0;if(o&h>>>0<128){k=c[I+(f*464|0)+44>>2]|0;i=uj(b,k,h)|0;if(!i)c[I+(f*464|0)+76>>2]=0;else{h=c[b+1752+(f*12|0)>>2]|0;j=h+-128|0;c[I+(f*464|0)+76>>2]=c[i>>2];if(!(c[b+2852>>2]&4096))c[I+(f*464|0)+360>>2]=((O((c[i+8>>2]|0)+-128|0,128-((j|0)>-1?j:128-h|0)|0)|0)/128|0)+h;c[I+(f*464|0)+72>>2]=c[(c[b+1744>>2]|0)+(k*764|0)+40>>2]}j=m|4096;c[J>>2]=j;i=n;p=1;h=1}else{j=m;i=n;p=o;h=1}}else{j=0;i=h;g=0;p=0;h=0}do if(!i){e=0;o=h}else{c[J>>2]=j|65536;a:do switch(i|0){case 129:{j=E<<24>>24!=0|e<<24>>24==12;k=e<<24>>24==14;i=k&v<<24>>24==-48;e=c[I+(f*464|0)+44>>2]|0;if(e>>>0<(c[b+1708>>2]|0)>>>0?(v=c[b+1744>>2]|0,x=v+(e*764|0)+44|0,(c[v+(e*764|0)+36>>2]|0)>0):0)if(!(c[x>>2]&1)){e=x;A=38}else{e=x;i=1}else{e=0;A=38}if((A|0)==38)if(j|i&w<<24>>24!=0){e=I+(f*464|0)+8|0;c[e>>2]=c[e>>2]|1;e=129;break a}else i=0;x=(Dj(e,c[I+(f*464|0)+96>>2]|0)|0)!=0;h=I+(f*464|0)+8|0;e=c[h>>2]|0;c[h>>2]=(x?128:2)|e;if(i&k?!((y&240|0)!=208|(y&15|0)==0):0){c[h>>2]=e&-131;e=129;h=0}else{e=129;h=0}break}case 131:{e=I+(f*464|0)+8|0;c[e>>2]=c[e>>2]|1;e=131;break}default:e=(C|0)==0?i:0}while(0);if(q){y=(c[I+(f*464|0)+48>>2]|0)+-1|0;if(y>>>0<(c[b+1708>>2]|0)>>>0?(c[(c[b+1744>>2]|0)+(y*764|0)+36>>2]|0)>0:0)A=48;else g=1}else A=48;if((A|0)==48)if(!g){g=0;o=h;break}ki(b,f);o=h}while(0);h=e+-1|0;if(yj(h)|0){A=c[I+(f*464|0)+44>>2]|0;i=uj(b,A,h)|0;if((g|0)==0&(i|0)!=0?(e+-13+(c[i+12>>2]|0)+(a[(c[b+1744>>2]|0)+(A*764|0)+512+(h<<1)+1>>0]|0)|0)>>>0>118:0){c[J>>2]=c[J>>2]&-65537;e=0}}else i=0;k=e+-1|0;n=I+(f*464|0)+16|0;do if(!(yj(k)|0)){h=-1;i=o}else{c[n>>2]=k;c[I+(f*464|0)+68>>2]=65536;j=I+(f*464|0)+8|0;e=c[j>>2]|0;c[j>>2]=e&-5;if(i|0){h=c[b+1744>>2]|0;m=c[I+(f*464|0)+44>>2]|0;if(!(c[h+(m*764|0)+44>>2]&1))c[j>>2]=e&-8;if(!g){g=(c[i+12>>2]|0)+k+(a[h+(m*764|0)+512+(k<<1)+1>>0]|0)|0;e=c[i+40>>2]|0;e=(c[(c[b+1748>>2]|0)+(e*52|0)+32>>2]|0)==0?-1:e;if((e|0)<=-1){h=g;i=o;break}if((e|0)>=(c[b+1712>>2]|0)){h=g;i=o;break}ti(b,f,m,e,g,0,0,0)|0;c[I+(f*464|0)+52>>2]=e;h=g;i=o;break}}c[J>>2]=0;h=-1;i=0}while(0);g=uj(b,c[I+(f*464|0)+44>>2]|0,c[n>>2]|0)|0;vj(b,h,g,J);if(!((B|0)!=0|p&(g|0)!=0^1))wj(b,J);if(E<<24>>24?(c[I+(f*464|0)+76>>2]=(D&255)+-1,c[J>>2]=c[J>>2]|4096,G=I+(f*464|0)+8|0,F=c[G>>2]|0,F&4|0):0){c[I+(f*464|0)+68>>2]=65536;c[G>>2]=F&-4}e=I+(f*464|0)+220|0;c[e>>2]=0;Fk(b,J,f,H,1);Fk(b,J,f,H,0);Hj(b,h,g,J,C);if(!g){l=K;return}do if((h|0)>-1){c[I+(f*464|0)+12>>2]=h;e=c[e>>2]|0;if(c[b+2852>>2]&67108864|0?(e|0)>=(c[(c[b+1748>>2]|0)+((c[g+40>>2]|0)*52|0)+32>>2]|0):0){ki(b,f);break}yi(b,f,+(e|0))}while(0);if(!i){l=K;return}if(c[J>>2]&4096|0){l=K;return}c[I+(f*464|0)+76>>2]=c[g>>2];l=K;return}function rj(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;n=c[b+628>>2]|0;o=n+(f*464|0)|0;c[o>>2]=0;switch(a[e+3>>0]|0){case 122:case 5:case 3:{g=3;break}default:switch(a[e+5>>0]|0){case 122:case 5:case 3:{g=3;break}default:h=0}}if((g|0)==3)h=1;l=(ii(b,f)|0)<0;m=e+1|0;g=a[m>>0]|0;if(l)h=(c[n+(f*464|0)+44>>2]|0)==((g&255)+-1|0)?h:0;do if(!(g<<24>>24)){g=65536;k=0;j=0}else{i=(g&255)+-1|0;c[o>>2]=2048;c[n+(f*464|0)+68>>2]=65536;c[n+(f*464|0)+4>>2]=0;c[n+(f*464|0)+220>>2]=0;l=n+(f*464|0)+8|0;c[l>>2]=c[l>>2]&-4;if(i>>>0<(c[b+1708>>2]|0)>>>0?(j=c[b+1744>>2]|0,(c[j+(i*764|0)+36>>2]|0)>0):0){g=n+(f*464|0)+44|0;if((c[g>>2]|0)==(i|0)){g=67584;k=0;j=1;break}if(!h){c[g>>2]=i;c[n+(f*464|0)+72>>2]=c[j+(i*764|0)+40>>2];g=67584;k=1;j=1;break}g=uj(b,i,(d[e>>0]|0)+-1|0)|0;if(!g){g=67584;k=1;j=1;break}c[n+(f*464|0)+76>>2]=c[g>>2];g=67584;k=1;j=0;break}c[o>>2]=0;g=65536;k=0;j=0}while(0);i=a[e>>0]|0;do if(i<<24>>24){c[o>>2]=g;g=i&255;if(i<<24>>24==-127){k=n+(f*464|0)+8|0;c[k>>2]=c[k>>2]|2;k=-1;j=0;break}if(h|0){if(!k){k=-1;break}c[n+(f*464|0)+220>>2]=0;k=-1;break}g=g+-1|0;c[n+(f*464|0)+16>>2]=g;l=n+(f*464|0)+8|0;c[l>>2]=c[l>>2]&-5;l=c[n+(f*464|0)+44>>2]|0;k=uj(b,l,g)|0;if(!k){c[o>>2]=0;k=-1;j=0;break}i=(c[k+12>>2]|0)+g+(a[(c[b+1744>>2]|0)+(l*764|0)+512+(g<<1)+1>>0]|0)|0;g=c[k+40>>2]|0;g=(c[(c[b+1748>>2]|0)+(g*52|0)+32>>2]|0)==0?-1:g;if((g|0)>-1?(g|0)<(c[b+1712>>2]|0):0){ti(b,f,l,g,i,0,0,0)|0;c[n+(f*464|0)+52>>2]=g;k=i}else k=i}else k=-1;while(0);i=uj(b,c[n+(f*464|0)+44>>2]|0,c[n+(f*464|0)+16>>2]|0)|0;vj(b,k,i,o);if((i|0)!=0&(a[m>>0]|0)!=0)wj(b,o);g=a[e+2>>0]|0;if(g<<24>>24){c[n+(f*464|0)+76>>2]=(g&255)+-1;c[o>>2]=c[o>>2]|4096}Fk(b,o,f,e,1);Fk(b,o,f,e,0);xj(b,k,i,o,h);if(!i)return;if((k|0)>-1){c[n+(f*464|0)+12>>2]=k;yi(b,f,+(c[n+(f*464|0)+220>>2]|0))}if(j|0?(c[o>>2]&4096|0)==0:0)c[n+(f*464|0)+76>>2]=c[i>>2];if(!(c[b+2852>>2]&16))return;if(!(c[o>>2]&4096))return;e=n+(f*464|0)+76|0;f=O(c[b+328>>2]|0,c[e>>2]|0)|0;c[e>>2]=(f|0)/(c[b+2836>>2]|0)|0;return}function sj(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0;P=l;l=l+16|0;O=P;J=b+628|0;M=c[J>>2]|0;N=M+(f*464|0)|0;p=e;j=p;j=d[j>>0]|d[j+1>>0]<<8|d[j+2>>0]<<16|d[j+3>>0]<<24;p=p+4|0;p=d[p>>0]|d[p+1>>0]<<8|d[p+2>>0]<<16|d[p+3>>0]<<24;g=O;c[g>>2]=j;c[g+4>>2]=p;g=O+1|0;e=bp(j|0,p|0,8)|0;e=e&255;s=j&255;q=bp(j|0,p|0,24)|0;q=q&255;o=bp(j|0,p|0,40)|0;o=o&255;p=bp(j|0,p|0,16)|0;p=p&255;if(!(e<<24>>24))if(s<<24>>24!=0?(k=M+(f*464|0)+436|0,i=c[k>>2]|0,(i|0)!=0):0){e=i&255;a[g>>0]=e;c[k>>2]=0}else e=0;else c[M+(f*464|0)+436>>2]=0;c[N>>2]=0;w=j&255;I=M+(f*464|0)+44|0;j=c[I>>2]|0;H=b+2852|0;r=c[H>>2]|0;u=(r&32768|0)==0;if(s<<24>>24==-127&(r&8388608|0)!=0?(m=(e&255)+-1|0,m>>>0<(c[b+1708>>2]|0)>>>0):0)G=(c[(c[b+1744>>2]|0)+(m*764|0)+36>>2]|0)>0&1;else G=0;if(!(e<<24>>24))if(zj(s)|0){g=(c[M+(f*464|0)+48>>2]|0)+-1|0;if(g>>>0<(c[b+1708>>2]|0)>>>0?(c[(c[b+1744>>2]|0)+(g*764|0)+36>>2]|0)>0:0)if(!(Aj(b,g,w+-1|0)|0)){g=0;B=18}else{e=j;B=17}else{g=1;B=18}}else{g=0;B=18}else{g=e&255;if(((g|0)<=(c[b+1708>>2]|0)?(zj(s)|0)!=0:0)?(n=g+-1|0,(Aj(b,n,w+-1|0)|0)!=0):0){e=n;B=17}else{g=0;B=18}}a:do if((B|0)==17){p=O;c[p>>2]=0;c[p+4>>2]=0;p=0;i=0;F=0;D=0;k=0;v=0}else if((B|0)==18){switch(q<<24>>24){case 122:case 5:case 3:break;default:switch(o<<24>>24){case 122:case 5:case 3:break;default:{i=q;F=e;D=s;e=j;k=0;v=g;break a}}}i=q;F=e;D=s;e=j;k=1;v=g}while(0);E=M+(f*464|0)+8|0;g=c[E>>2]|0;m=(g&3|0)==0;A=M+(f*464|0)+24|0;if(!(+h[A>>3]<=0.0)&(g&4|0)==0)if((k|0)!=0&i<<24>>24==9)if(!(r&4194304)){g=g&-17;c[E>>2]=g;z=1;k=0;C=1}else{z=1;k=0;C=0}else{z=0;C=0}else{z=0;k=0;C=0}x=F<<24>>24==0;do if(x){s=k;g=w;r=0;o=0;q=0;i=0;B=56}else{t=(F&255)+-1|0;n=s<<24>>24!=0;i=(k|0)==0;do if(n|m)if(i){i=0;g=0;j=0;B=35}else{i=r&4194304;B=33}else{if(i){Bj(b,N);i=0;g=0;j=0;B=35;break}i=r&4194304;if(!(i|g&64))B=33;else{Bj(b,N);i=0;g=0;j=0;B=35}}while(0);if((B|0)==33)if((j|0)==(t|0)&(i|0)==0){g=(Cj(b,f,j,w+-1|0)|0)==0;if(m|g){i=1;g=g&1;j=1;B=35}else{m=1;o=0;q=0;k=1}}else{i=1;g=0;j=1;B=35}if((B|0)==35){c[N>>2]=c[N>>2]|2048;m=i;o=g;q=1;k=j}c[M+(f*464|0)+4>>2]=0;if(t>>>0<(c[b+1708>>2]|0)>>>0?(c[(c[b+1744>>2]|0)+(t*764|0)+36>>2]|0)>0:0){if(!n?(y=c[E>>2]|0,(y&256|0)==0):0){if(!((y&4|0)==0|u^1))yi(b,f,0.0);if((c[I>>2]|0)==(t|0)){c[N>>2]=c[N>>2]|2048;g=w;i=1}else{g=(c[M+(f*464|0)+16>>2]|0)+1|0;i=q}c[E>>2]=c[E>>2]&-65}else{g=w;i=q}j=c[I>>2]|0;if((j|0)==(t|0)){j=t;s=m;r=o;B=56;break}if(k?c[H>>2]&4194304|0:0){s=m;r=o;B=56;break}if(Cj(b,f,t,g+-1|0)|0){e=t;s=m;r=o;B=56;break}if(!k){e=t;s=m;r=1;B=56;break}e=uj(b,t,g)|0;if(!e){e=t;s=m;r=1;B=56;break}c[M+(f*464|0)+76>>2]=c[e>>2];e=t;s=m;r=1;i=0;B=56;break}if(u)c[M+(f*464|0)+76>>2]=0;c[N>>2]=0;t=e;s=m;g=w;r=o;j=q;e=1;i=0}while(0);b:do if((B|0)==56){k=(v|0)!=0;if(k|(g|0)==0){t=e;j=q;e=k}else{m=c[N>>2]|0;c[N>>2]=m|65536;k=c[E>>2]|0;n=k|64;c[E>>2]=n;switch(g|0){case 131:{c[E>>2]=k|65;t=e;g=131;j=0;e=0;i=0;break b}case 130:{c[E>>2]=k|332;h[A>>3]=0.0;ki(b,f);t=e;g=130;j=q;e=0;break b}case 129:{if(j>>>0<(c[b+1708>>2]|0)>>>0){g=c[b+1744>>2]|0;g=(c[g+(j*764|0)+36>>2]|0)>0?g+(j*764|0)+44|0:0}else g=0;t=(Dj(g,c[M+(f*464|0)+96>>2]|0)|0)!=0;c[E>>2]=(t?128:2)|n;c[N>>2]=m|67174400;t=e;g=129;j=0;e=0;i=0;break b}default:{A=(s|0)!=0;j=(z|0)!=0|A&x?q:1;if(!A){t=e;s=0;e=0;break b}if(k&4|r|0){c[N>>2]=m|67584;c[E>>2]=n&-132;t=e;e=0;break b}g=g+-1|0;if(!(yj(g)|0)){t=e;g=0;r=0;e=0;break b}c[M+(f*464|0)+108>>2]=g;t=e;g=0;r=0;e=0;break b}}}}while(0);m=g+-1|0;do if(!(e|(yj(m)|0)==0)){g=c[E>>2]|0;k=(g&8|0)==0?i:1;c[M+(f*464|0)+16>>2]=m;c[E>>2]=g&-5;g=uj(b,t,m)|0;if(!g){c[N>>2]=0;n=-1;k=0;break}n=(c[g+12>>2]|0)+m+(a[(c[b+1744>>2]|0)+(t*764|0)+512+(m<<1)+1>>0]|0)|0;e=c[g+40>>2]|0;if((e|0)<(c[b+1712>>2]|0)?(c[(c[b+1748>>2]|0)+(e*52|0)+32>>2]|0)!=0:0)q=e;else q=-1;if(o|0){Ej(b,f,g);ki(b,f)}o=ti(b,f,t,q,n,c[g+44>>2]|0,c[g+48>>2]|0,c[g+52>>2]|0)|0;i=g+36|0;e=c[i>>2]|0;g=e&255;if(!g)g=0;else{g=(Jo()|0)%((g>>>0<100?g:100)+1|0)|0;e=c[i>>2]|0}c[M+(f*464|0)+84>>2]=g;A=e>>>8&255;e=A>>>0<64?A:64;if(!A)e=0;else e=((Jo()|0)%(e+1|0)|0)-(e>>>1)|0;c[M+(f*464|0)+88>>2]=e;if((o|0)<0){O=-1;l=P;return O|0}if((o|0)!=(f|0)){Fj(b,o,f);c[(c[J>>2]|0)+(o*464|0)>>2]=0}if((q|0)>-1)c[M+(f*464|0)+52>>2]=q}else{m=g;n=-1;k=i}while(0);g=(G|0)!=0;if(s|G|0?!((c[H>>2]&4194304|0)==0|F<<24>>24==0):0)Bj(b,N);if(t>>>0<(c[b+1708>>2]|0)>>>0?(L=b+1744|0,K=c[L>>2]|0,(c[K+(t*764|0)+36>>2]|0)>0):0){if((c[I>>2]|0)==(t|0))e=K;else{wj(b,N);e=c[L>>2]|0}c[I>>2]=t;c[M+(f*464|0)+72>>2]=c[e+(t*764|0)+40>>2]}if(F<<24>>24!=0?(c[E>>2]&16|0)!=0:0){if(Gj(b,N,t)|0){wj(b,N);B=97}}else B=97;if((B|0)==97?j|0:0){if(D<<24>>24)c[E>>2]=c[E>>2]&-132;c[M+(f*464|0)+68>>2]=65536}if(g&(r|0)!=0){c[N>>2]=c[N>>2]|2048;yi(b,f,0.0);c[M+(f*464|0)+68>>2]=65536;c[E>>2]=c[E>>2]&-132}i=uj(b,c[I>>2]|0,c[M+(f*464|0)+16>>2]|0)|0;vj(b,n,i,N);j=(n|0)>-1;if(j&(i|0)!=0){e=c[i+8>>2]|0;if((e|0)>-1){c[M+(f*464|0)+360>>2]=e;c[M+(f*464|0)+376>>2]=0}if(!(c[E>>2]&8)){if(!C)Bj(b,N)}else wj(b,N);c[E>>2]=c[E>>2]&-9}g=p&255;do if(p<<24>>24){e=(m|0)!=129;if(!(c[E>>2]&8)){if(!e)break}else if(!(e&F<<24>>24!=0))break;c[M+(f*464|0)+76>>2]=g+-1;c[N>>2]=c[N>>2]|4096}while(0);e=M+(f*464|0)+220|0;c[e>>2]=c[e>>2]&-65536;Fk(b,N,f,O,0);Fk(b,N,f,O,1);xj(b,n,i,N,s);if(!i){O=0;l=P;return O|0}if(j){c[M+(f*464|0)+12>>2]=n;yi(b,f,+(c[e>>2]|0))}if(!k){O=0;l=P;return O|0}if(c[N>>2]&4096|0){O=0;l=P;return O|0}c[M+(f*464|0)+76>>2]=c[i>>2];O=0;l=P;return O|0}function tj(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;p=c[b+628>>2]|0;q=p+(e*464|0)|0;c[q>>2]=0;switch(a[d+3>>0]|0){case 5:case 3:{r=1;break}default:r=0}o=d+1|0;m=a[o>>0]|0;f=m&255;if(m<<24>>24){m=a[d>>0]|0;i=m&255;if(!(m<<24>>24)){g=-1;k=1}else{f=f+-1|0;c[q>>2]=2048;c[p+(e*464|0)+68>>2]=65536;c[p+(e*464|0)+220>>2]=0;m=p+(e*464|0)+8|0;c[m>>2]=c[m>>2]&-4;do if(f>>>0<(c[b+1708>>2]|0)>>>0?(g=c[b+1744>>2]|0,(c[g+(f*764|0)+36>>2]|0)>0):0){if(!r){c[p+(e*464|0)+44>>2]=f;c[p+(e*464|0)+72>>2]=c[g+(f*764|0)+40>>2];f=0;g=1;break}f=uj(b,f,i+-1|0)|0;if(!f){f=0;g=1}else{c[p+(e*464|0)+76>>2]=c[f>>2];f=0;g=0}}else j=11;while(0);if((j|0)==11){ki(b,e);f=1;g=1}k=c[p+(e*464|0)+424>>2]|0;c[k+48>>2]=0;c[k+52>>2]=0;k=g;j=13}}else{f=0;k=0;j=13}a:do if((j|0)==13){g=a[d>>0]|0;if(!(g<<24>>24))g=-1;else{c[q>>2]=c[q>>2]|65536;switch(g<<24>>24){case -127:{g=p+(e*464|0)+8|0;c[g>>2]=c[g>>2]|2;g=-1;k=0;break a}case -126:{g=p+(e*464|0)+8|0;c[g>>2]=c[g>>2]|4;h[p+(e*464|0)+24>>3]=0.0;ki(b,e);g=-1;break a}default:{if(r|0){g=-1;break a}m=c[p+(e*464|0)+44>>2]|0;if(m>>>0>=(c[b+1708>>2]|0)>>>0){g=-1;break a}l=c[b+1744>>2]|0;i=c[l+(m*764|0)+36>>2]|0;if((i|0)<=0){g=-1;break a}j=(g&255)+-1|0;c[p+(e*464|0)+16>>2]=j;g=p+(e*464|0)+8|0;c[g>>2]=c[g>>2]&-5;g=p+(e*464|0)+32|0;h[g>>3]=0.0;if(((((i|0)!=1?(n=c[l+(m*764|0)+760>>2]|0,n|0):0)?(c[n>>2]|0)==133303461:0)?(c[n+4>>2]|0)==0:0)?(c[n+8>>2]|0)==0:0)h[g>>3]=2.0;i=uj(b,m,j)|0;if(!((f|0)==0&(i|0)!=0)){c[q>>2]=0;g=-1;k=0;break a}g=(c[i+12>>2]|0)+j+(a[l+(m*764|0)+512+(j<<1)+1>>0]|0)|0;f=c[i+40>>2]|0;f=(c[(c[b+1748>>2]|0)+(f*52|0)+32>>2]|0)==0?-1:f;if((f|0)<=-1)break a;if((f|0)>=(c[b+1712>>2]|0))break a;ti(b,e,m,f,g,0,0,0)|0;c[p+(e*464|0)+52>>2]=f;break a}}}}while(0);j=uj(b,c[p+(e*464|0)+44>>2]|0,c[p+(e*464|0)+16>>2]|0)|0;i=p+(e*464|0)+40|0;f=c[i>>2]|0;vj(b,g,j,q);if(a[o>>0]|0){if(j|0)wj(b,q)}else c[i>>2]=f;f=a[d+2>>0]|0;if(f<<24>>24){c[p+(e*464|0)+76>>2]=(f&255)+-1;c[q>>2]=c[q>>2]|4096}Fk(b,q,e,d,1);Fk(b,q,e,d,0);xj(b,g,j,q,r);if(!j)return;if((g|0)>-1){c[p+(e*464|0)+12>>2]=g;yi(b,e,+(c[p+(e*464|0)+220>>2]|0))}if(!k)return;if(c[q>>2]&4096|0)return;c[p+(e*464|0)+76>>2]=c[j>>2];return}function uj(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0;if((c[b+1708>>2]|0)>>>0<=d>>>0){d=0;return d|0}f=c[b+1744>>2]|0;g=c[f+(d*764|0)+36>>2]|0;if((g|0)<=0){d=0;return d|0}if(!(yj(e)|0)){d=c[f+(d*764|0)+756>>2]|0;return d|0}e=a[f+(d*764|0)+512+(e<<1)>>0]|0;b=e&255;if(!(e<<24>>24!=-1&(b|0)<(g|0))){d=0;return d|0}d=(c[f+(d*764|0)+756>>2]|0)+(b<<6)|0;return d|0}function vj(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0;if(!((d|0)>-1&(e|0)!=0)){e=f+60|0;c[e>>2]=0;e=f+245|0;a[e>>0]=0;e=f+244|0;a[e>>0]=0;e=f+172|0;a[e>>0]=0;e=f+192|0;c[e>>2]=0;f=f+188|0;c[f>>2]=1;return}d=c[f+44>>2]|0;g=c[b+1708>>2]|0;if((d|0)<(g|0))g=(c[b+1744>>2]|0)+(d*764|0)|0;else g=(c[b+9180>>2]|0)+((d-g|0)*764|0)|0;if(!(c[b+2852>>2]&4))c[f+40>>2]=c[e+16>>2];c[f+80>>2]=c[e+4>>2];d=c[e+56>>2]|0;if(!(d&128)){if(!(c[g+356>>2]&8)){d=255;h=10}}else{d=(d<<1)+-256|0;h=10}if((h|0)==10)c[f+396>>2]=d;c[f+404>>2]=256;d=c[e+60>>2]|0;if(d&128|0)c[f+400>>2]=(d<<1)+-256;h=f+200|0;jk(h,c[e+24>>2]|0);kk(h,c[e+28>>2]>>2);lk(h,c[e+20>>2]|0);c[f+216>>2]=c[e+32>>2];ik(f+112|0);ik(f+132|0);e=f+60|0;c[e>>2]=0;e=f+245|0;a[e>>0]=0;e=f+244|0;a[e>>0]=0;e=f+172|0;a[e>>0]=0;e=f+192|0;c[e>>2]=0;f=f+188|0;c[f>>2]=1;return}function wj(a,b){a=a|0;b=b|0;var d=0;d=c[b+44>>2]|0;if(d>>>0>=(c[a+1708>>2]|0)>>>0)return;if((c[(c[a+1744>>2]|0)+(d*764|0)+36>>2]|0)<=0)return;a=b+8|0;c[a>>2]=c[a>>2]&-17;c[b+96>>2]=-1;c[b+100>>2]=-1;c[b+104>>2]=-1;return}function xj(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0.0;if(!((b|0)>-1&(d|0)!=0))return;g=+Bi(a,b,c[e+40>>2]|0,+h[e+32>>3]);f=(f|0)!=0;if((b|0)>0&f|(c[a+2852>>2]&4|0)==0)h[e+328>>3]=g;d=e+24|0;if(f&!(+h[d>>3]<1.0))return;h[d>>3]=g;return}function yj(a){a=a|0;return a>>>0<121|0}function zj(a){a=a|0;return (a+-1&255)<121|0}function Aj(b,d,e){b=b|0;d=d|0;e=e|0;if((c[b+1708>>2]|0)<=(d|0)){b=0;return b|0}d=a[(c[b+1744>>2]|0)+(d*764|0)+512+(e<<1)>>0]|0;if(d<<24>>24==-1){b=1;return b|0}else return (d&255|0)>=(c[b+1712>>2]|0)|0;return 0}function Bj(a,b){a=a|0;b=b|0;var d=0,e=0;d=c[b+44>>2]|0;if(d>>>0>=(c[a+1708>>2]|0)>>>0)return;if((c[(c[a+1744>>2]|0)+(d*764|0)+36>>2]|0)<=0)return;e=b+8|0;c[e>>2]=c[e>>2]&-17;d=Em(a,d)|0;if(!(c[d+44>>2]&32))c[b+96>>2]=-1;if(!(c[d+200>>2]&32))c[b+100>>2]=-1;if(c[d+356>>2]&32|0)return;c[b+104>>2]=-1;return}function Cj(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=c[a+628>>2]|0;e=uj(a,d,e)|0;d=uj(a,c[f+(b*464|0)+44>>2]|0,c[f+(b*464|0)+16>>2]|0)|0;if(!((e|0)!=0&(d|0)!=0)){f=0;f=f&1;return f|0}f=(c[e+40>>2]|0)==(c[d+40>>2]|0);f=f&1;return f|0}function Dj(a,d){a=a|0;d=d|0;if((a|0)!=0?(c[a>>2]&5|0)==1:0)a=(b[a+28+(c[a+12>>2]<<1<<1)>>1]|0)==(d|0);else a=0;return a&1|0}function Ej(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0;if((c[e+44>>2]|0)!=1)return;f=c[b+628>>2]|0;g=Em(b,c[f+(d*464|0)+44>>2]|0)|0;h[f+(d*464|0)+24>>3]=+Bi(b,(c[e+12>>2]|0)+(c[f+(d*464|0)+16>>2]|0)+(a[g+512+(c[f+(d*464|0)+108>>2]<<1)+1>>0]|0)|0,c[f+(d*464|0)+40>>2]|0,+h[f+(d*464|0)+32>>3]);return}function Fj(a,b,d){a=a|0;b=b|0;d=d|0;if((b|0)<1|(b|0)==(d|0))return;a=c[a+628>>2]|0;ep(a+(b*464|0)|0,a+(d*464|0)|0,464)|0;return}function Gj(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;a=Em(a,d)|0;if(!a){b=1;return b|0}if((c[a+44>>2]&33|0)==33?(e=c[b+72>>2]|0,(e|0)!=0):0)a=(c[b+68>>2]|0)<=(e|0);else a=1;b=a&1;return b|0}function Hj(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0;g=(f|0)!=0;if((b|0)>0&g)h[e+328>>3]=+Bi(a,b,c[e+40>>2]|0,+h[e+32>>3]);if(!((b|0)>-1&(d|0)!=0))return;f=e+24|0;if(g&!(+h[f>>3]<1.0))return;h[f>>3]=+Bi(a,b,c[e+40>>2]|0,+h[e+32>>3]);return}function Ij(a,b){a=a|0;b=b|0;var d=0,e=0;d=Ko(a)|0;e=(b|0)!=0;if((d|0)<0){if(!e){a=-1;return a|0}a=(zo(a)|0)==0;c[b>>2]=a?-1:c[10299]|0;a=-1;return a|0}else{if(e)c[b>>2]=0;a=d&255;return a|0}return 0}function Jj(a,b){a=a|0;b=b|0;var d=0,e=0;d=Ko(a)|0;e=(b|0)!=0;if((d|0)<0){if(!e){a=0;return a|0}a=(zo(a)|0)==0;c[b>>2]=a?-1:c[10299]|0;a=0;return a|0}else{if(e)c[b>>2]=0;a=d&255;return a|0}return 0}function Kj(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=Ko(a)|0;f=(b|0)!=0;if((d|0)>=0?(e=Ko(a)|0,(e|0)>=0):0){if(f)c[b>>2]=0;a=(e<<8|d)&65535;return a|0}if(!f){a=-1;return a|0}a=(zo(a)|0)==0;c[b>>2]=a?-1:c[10299]|0;a=-1;return a|0}function Lj(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=Ko(a)|0;f=(b|0)!=0;if((d|0)>=0?(e=Ko(a)|0,(e|0)>=0):0){if(f)c[b>>2]=0;a=(e|d<<8)&65535;return a|0}if(!f){a=-1;return a|0}a=(zo(a)|0)==0;c[b>>2]=a?-1:c[10299]|0;a=-1;return a|0}function Mj(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=Ko(a)|0;if(((d|0)>=0?(e=Ko(a)|0,(e|0)>=0):0)?(f=Ko(a)|0,(f|0)>=0):0){if(b|0)c[b>>2]=0;a=e<<8|d|f<<16;return a|0}if(!b){a=16777215;return a|0}a=(zo(a)|0)==0;c[b>>2]=a?-1:c[10299]|0;a=16777215;return a|0}function Nj(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=Ko(a)|0;if(((d|0)>=0?(e=Ko(a)|0,(e|0)>=0):0)?(f=Ko(a)|0,(f|0)>=0):0){if(b|0)c[b>>2]=0;a=e<<8|d<<16|f;return a|0}if(!b){a=16777215;return a|0}a=(zo(a)|0)==0;c[b>>2]=a?-1:c[10299]|0;a=16777215;return a|0}function Oj(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=Ko(a)|0;if((((d|0)>=0?(f=Ko(a)|0,(f|0)>=0):0)?(g=Ko(a)|0,(g|0)>=0):0)?(e=Ko(a)|0,(e|0)>=0):0){if(b|0)c[b>>2]=0;a=f<<8|d|g<<16|e<<24;return a|0}if(!b){a=-1;return a|0}a=(zo(a)|0)==0;c[b>>2]=a?-1:c[10299]|0;a=-1;return a|0}function Pj(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=Ko(a)|0;if((((d|0)>=0?(f=Ko(a)|0,(f|0)>=0):0)?(g=Ko(a)|0,(g|0)>=0):0)?(e=Ko(a)|0,(e|0)>=0):0){if(b|0)c[b>>2]=0;a=f<<16|d<<24|g<<8|e;return a|0}if(!b){a=-1;return a|0}a=(zo(a)|0)==0;c[b>>2]=a?-1:c[10299]|0;a=-1;return a|0}function Qj(a,b){a=a|0;b=b|0;return ((b&255)<<8|a&255)&65535|0}function Rj(a,b){a=a|0;b=b|0;return ((a&255)<<8|b&255)&65535|0}function Sj(a,b,c){a=a|0;b=b|0;c=c|0;return (b&255)<<8|a&255|(c&255)<<16|0}function Tj(a,b,c){a=a|0;b=b|0;c=c|0;return (b&255)<<8|(a&255)<<16|c&255|0}function Uj(a){a=a|0;return (d[a+1>>0]|0)<<8|(d[a>>0]|0)|(d[a+2>>0]|0)<<16|(d[a+3>>0]|0)<<24|0}function Vj(a){a=a|0;return (d[a+1>>0]|0)<<16|(d[a>>0]|0)<<24|(d[a+2>>0]|0)<<8|(d[a+3>>0]|0)|0}function Wj(a,b){a=a|0;b=b|0;No(b&255,a);return}function Xj(a,b){a=a|0;b=b|0;Wj(a,(b&65535)>>>8&255);Wj(a,b&255);return}function Yj(a,b){a=a|0;b=b|0;Wj(a,b>>>24&255);Wj(a,b>>>16&255);Wj(a,b>>>8&255);Wj(a,b&255);return}function Zj(a){a=a|0;var b=0;b=a+16|0;c[b>>2]=0;c[b+4>>2]=0;c[a>>2]=1732584193;c[a+4>>2]=-271733879;c[a+8>>2]=-1732584194;c[a+12>>2]=271733878;return}function _j(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0;h=a+16|0;i=h;j=c[i>>2]|0;i=c[i+4>>2]|0;e=bp(j|0,i|0,3)|0;e=e&63;f=64-e|0;g=cp(d|0,0,3)|0;g=Xo(j|0,i|0,g|0,z|0)|0;c[h>>2]=g;c[h+4>>2]=z;if(f>>>0<=d>>>0){if(e){ep(a+24+e|0,b|0,f|0)|0;$j(a,a+24|0);b=b+f|0;d=d-f|0}if(d>>>0>63){g=d+-64|0;h=g&-64;f=h+64|0;e=b;while(1){$j(a,e);d=d+-64|0;if(d>>>0<=63)break;else e=e+64|0}e=0;b=b+f|0;d=g-h|0}else e=0}if(!d)return;ep(a+24+e|0,b|0,d|0)|0;return}function $j(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;A=d[b>>0]|d[b+1>>0]<<8|d[b+2>>0]<<16|d[b+3>>0]<<24;t=b+4|0;t=d[t>>0]|d[t+1>>0]<<8|d[t+2>>0]<<16|d[t+3>>0]<<24;m=b+8|0;m=d[m>>0]|d[m+1>>0]<<8|d[m+2>>0]<<16|d[m+3>>0]<<24;v=b+12|0;v=d[v>>0]|d[v+1>>0]<<8|d[v+2>>0]<<16|d[v+3>>0]<<24;o=b+16|0;o=d[o>>0]|d[o+1>>0]<<8|d[o+2>>0]<<16|d[o+3>>0]<<24;x=b+20|0;x=d[x>>0]|d[x+1>>0]<<8|d[x+2>>0]<<16|d[x+3>>0]<<24;q=b+24|0;q=d[q>>0]|d[q+1>>0]<<8|d[q+2>>0]<<16|d[q+3>>0]<<24;z=b+28|0;z=d[z>>0]|d[z+1>>0]<<8|d[z+2>>0]<<16|d[z+3>>0]<<24;s=b+32|0;s=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;l=b+36|0;l=d[l>>0]|d[l+1>>0]<<8|d[l+2>>0]<<16|d[l+3>>0]<<24;u=b+40|0;u=d[u>>0]|d[u+1>>0]<<8|d[u+2>>0]<<16|d[u+3>>0]<<24;n=b+44|0;n=d[n>>0]|d[n+1>>0]<<8|d[n+2>>0]<<16|d[n+3>>0]<<24;w=b+48|0;w=d[w>>0]|d[w+1>>0]<<8|d[w+2>>0]<<16|d[w+3>>0]<<24;p=b+52|0;p=d[p>>0]|d[p+1>>0]<<8|d[p+2>>0]<<16|d[p+3>>0]<<24;y=b+56|0;y=d[y>>0]|d[y+1>>0]<<8|d[y+2>>0]<<16|d[y+3>>0]<<24;r=b+60|0;r=d[r>>0]|d[r+1>>0]<<8|d[r+2>>0]<<16|d[r+3>>0]<<24;j=c[a>>2]|0;h=a+4|0;i=c[h>>2]|0;f=a+8|0;g=c[f>>2]|0;b=a+12|0;e=c[b>>2]|0;B=A+-680876936+j+((e^g)&i^e)|0;B=(B<<7|B>>>25)+i|0;e=t+-389564586+e+(B&(g^i)^g)|0;e=(e<<12|e>>>20)+B|0;g=m+606105819+g+(e&(B^i)^i)|0;g=(g<<17|g>>>15)+e|0;i=v+-1044525330+i+(g&(e^B)^B)|0;i=(i<<22|i>>>10)+g|0;B=o+-176418897+B+(i&(g^e)^e)|0;B=(B<<7|B>>>25)+i|0;e=x+1200080426+e+(B&(i^g)^g)|0;e=(e<<12|e>>>20)+B|0;g=q+-1473231341+g+(e&(B^i)^i)|0;g=(g<<17|g>>>15)+e|0;i=z+-45705983+i+(g&(e^B)^B)|0;i=(i<<22|i>>>10)+g|0;B=s+1770035416+B+(i&(g^e)^e)|0;B=(B<<7|B>>>25)+i|0;e=l+-1958414417+e+(B&(i^g)^g)|0;e=(e<<12|e>>>20)+B|0;g=u+-42063+g+(e&(B^i)^i)|0;g=(g<<17|g>>>15)+e|0;i=n+-1990404162+i+(g&(e^B)^B)|0;i=(i<<22|i>>>10)+g|0;B=w+1804603682+B+(i&(g^e)^e)|0;B=(B<<7|B>>>25)+i|0;e=p+-40341101+e+(B&(i^g)^g)|0;e=(e<<12|e>>>20)+B|0;g=y+-1502002290+g+(e&(B^i)^i)|0;g=(g<<17|g>>>15)+e|0;i=r+1236535329+i+(g&(e^B)^B)|0;i=(i<<22|i>>>10)+g|0;B=t+-165796510+B+((i^g)&e^g)|0;B=(B<<5|B>>>27)+i|0;e=q+-1069501632+e+((B^i)&g^i)|0;e=(e<<9|e>>>23)+B|0;g=n+643717713+g+((e^B)&i^B)|0;g=(g<<14|g>>>18)+e|0;i=A+-373897302+i+((g^e)&B^e)|0;i=(i<<20|i>>>12)+g|0;B=x+-701558691+B+((i^g)&e^g)|0;B=(B<<5|B>>>27)+i|0;e=u+38016083+e+((B^i)&g^i)|0;e=(e<<9|e>>>23)+B|0;g=r+-660478335+g+((e^B)&i^B)|0;g=(g<<14|g>>>18)+e|0;i=o+-405537848+i+((g^e)&B^e)|0;i=(i<<20|i>>>12)+g|0;B=l+568446438+B+((i^g)&e^g)|0;B=(B<<5|B>>>27)+i|0;e=y+-1019803690+e+((B^i)&g^i)|0;e=(e<<9|e>>>23)+B|0;g=v+-187363961+g+((e^B)&i^B)|0;g=(g<<14|g>>>18)+e|0;i=s+1163531501+i+((g^e)&B^e)|0;i=(i<<20|i>>>12)+g|0;B=p+-1444681467+B+((i^g)&e^g)|0;B=(B<<5|B>>>27)+i|0;e=m+-51403784+e+((B^i)&g^i)|0;e=(e<<9|e>>>23)+B|0;g=z+1735328473+g+((e^B)&i^B)|0;g=(g<<14|g>>>18)+e|0;k=g^e;i=w+-1926607734+i+(k&B^e)|0;i=(i<<20|i>>>12)+g|0;k=x+-378558+B+(k^i)|0;k=(k<<4|k>>>28)+i|0;e=s+-2022574463+e+(i^g^k)|0;e=(e<<11|e>>>21)+k|0;g=n+1839030562+g+(k^i^e)|0;g=(g<<16|g>>>16)+e|0;i=y+-35309556+i+(e^k^g)|0;i=(i<<23|i>>>9)+g|0;k=t+-1530992060+k+(g^e^i)|0;k=(k<<4|k>>>28)+i|0;e=o+1272893353+e+(i^g^k)|0;e=(e<<11|e>>>21)+k|0;g=z+-155497632+g+(k^i^e)|0;g=(g<<16|g>>>16)+e|0;i=u+-1094730640+i+(e^k^g)|0;i=(i<<23|i>>>9)+g|0;k=p+681279174+k+(g^e^i)|0;k=(k<<4|k>>>28)+i|0;e=A+-358537222+e+(i^g^k)|0;e=(e<<11|e>>>21)+k|0;g=v+-722521979+g+(k^i^e)|0;g=(g<<16|g>>>16)+e|0;i=q+76029189+i+(e^k^g)|0;i=(i<<23|i>>>9)+g|0;k=l+-640364487+k+(g^e^i)|0;k=(k<<4|k>>>28)+i|0;e=w+-421815835+e+(i^g^k)|0;e=(e<<11|e>>>21)+k|0;g=r+530742520+g+(k^i^e)|0;g=(g<<16|g>>>16)+e|0;i=m+-995338651+i+(e^k^g)|0;i=(i<<23|i>>>9)+g|0;k=A+-198630844+k+((i|~e)^g)|0;k=(k<<6|k>>>26)+i|0;e=z+1126891415+e+((k|~g)^i)|0;e=(e<<10|e>>>22)+k|0;g=y+-1416354905+g+((e|~i)^k)|0;g=(g<<15|g>>>17)+e|0;i=x+-57434055+i+((g|~k)^e)|0;i=(i<<21|i>>>11)+g|0;k=w+1700485571+k+((i|~e)^g)|0;k=(k<<6|k>>>26)+i|0;e=v+-1894986606+e+((k|~g)^i)|0;e=(e<<10|e>>>22)+k|0;g=u+-1051523+g+((e|~i)^k)|0;g=(g<<15|g>>>17)+e|0;i=t+-2054922799+i+((g|~k)^e)|0;i=(i<<21|i>>>11)+g|0;k=s+1873313359+k+((i|~e)^g)|0;k=(k<<6|k>>>26)+i|0;e=r+-30611744+e+((k|~g)^i)|0;e=(e<<10|e>>>22)+k|0;g=q+-1560198380+g+((e|~i)^k)|0;g=(g<<15|g>>>17)+e|0;i=p+1309151649+i+((g|~k)^e)|0;i=(i<<21|i>>>11)+g|0;k=o+-145523070+k+((i|~e)^g)|0;k=(k<<6|k>>>26)+i|0;e=n+-1120210379+e+((k|~g)^i)|0;e=(e<<10|e>>>22)+k|0;g=m+718787259+g+((e|~i)^k)|0;g=(g<<15|g>>>17)+e|0;i=l+-343485551+i+((g|~k)^e)|0;c[a>>2]=k+j;c[h>>2]=g+(c[h>>2]|0)+(i<<21|i>>>11);c[f>>2]=g+(c[f>>2]|0);c[b>>2]=e+(c[b>>2]|0);return}function ak(b,d){b=b|0;d=d|0;var e=0;bk(d);if(!b)return;a[b+3>>0]=(c[d>>2]|0)>>>24;a[b+2>>0]=(c[d>>2]|0)>>>16;a[b+1>>0]=(c[d>>2]|0)>>>8;a[b>>0]=c[d>>2];e=d+4|0;a[b+7>>0]=(c[e>>2]|0)>>>24;a[b+6>>0]=(c[e>>2]|0)>>>16;a[b+5>>0]=(c[e>>2]|0)>>>8;a[b+4>>0]=c[e>>2];e=d+8|0;a[b+11>>0]=(c[e>>2]|0)>>>24;a[b+10>>0]=(c[e>>2]|0)>>>16;a[b+9>>0]=(c[e>>2]|0)>>>8;a[b+8>>0]=c[e>>2];e=d+12|0;a[b+15>>0]=(c[e>>2]|0)>>>24;a[b+14>>0]=(c[e>>2]|0)>>>16;a[b+13>>0]=(c[e>>2]|0)>>>8;a[b+12>>0]=c[e>>2];b=d+88|0;do{c[d>>2]=0;d=d+4|0}while((d|0)<(b|0));return}function bk(b){b=b|0;var d=0,e=0,f=0,g=0,h=0;d=l;l=l+16|0;e=d;f=b+16|0;g=c[f>>2]|0;f=c[f+4>>2]|0;h=bp(g|0,f|0,56)|0;a[e+7>>0]=h;h=bp(g|0,f|0,48)|0;a[e+6>>0]=h;h=bp(g|0,f|0,40)|0;a[e+5>>0]=h;a[e+4>>0]=f;h=bp(g|0,f|0,24)|0;a[e+3>>0]=h;h=bp(g|0,f|0,16)|0;a[e+2>>0]=h;h=bp(g|0,f|0,8)|0;a[e+1>>0]=h;a[e>>0]=g;f=bp(g|0,f|0,3)|0;f=Yo(64,0,f&63|0,0)|0;_j(b,36205,(f>>>0<9?f+64|0:f)+-8|0);_j(b,e,8);l=d;return}function ck(a,b,c){a=a|0;b=b|0;c=c|0;a:do switch(a|0){case 2:{a=dk(b)|0;break}case 1:if(!c){a=fk(b)|0;break a}else{a=ek(b)|0;break a}case 3:{a=gk(b)|0;break}default:a=fk(b)|0}while(0);return a|0}function dk(a){a=a|0;if(!(c[a+4>>2]|0)){a=0;return a|0}if((c[a>>2]|0)==2){a=O((c[a+12>>2]|0)<32?255:0,c[a+8>>2]|0)|0;return a|0}else{a=fk(a)|0;return a|0}return 0}function ek(a){a=a|0;if(!(c[a+4>>2]|0)){a=0;return a|0}if((c[a>>2]|0)==1){a=O(((((c[a+12>>2]|0)+32|0)%64|0)<<3)+-255|0,c[a+8>>2]|0)|0;return a|0}else{a=fk(a)|0;return a|0}return 0}function fk(a){a=a|0;var b=0;if(!(c[a+4>>2]|0)){b=0;return b|0}switch(c[a>>2]|0){case 0:{b=c[20392+(c[a+12>>2]<<2)>>2]|0;break}case 1:{b=255-(c[a+12>>2]<<3)|0;break}case 2:{b=(c[a+12>>2]|0)<32?255:-255;break}case 3:{b=((Jo()|0)&511)+-256|0;break}case 669:{b=c[a+12>>2]&1;break}default:{b=0;return b|0}}b=O(c[a+8>>2]|0,b)|0;return b|0}function gk(a){a=a|0;if(!(c[a+4>>2]|0)){a=0;return a|0}a=dk(a)|0;return a|0}function hk(a){a=a|0;var b=0;b=a+12|0;c[b>>2]=((c[b>>2]|0)+(c[a+4>>2]|0)|0)%64|0;return}function ik(a){a=a|0;c[a+12>>2]=0;return}function jk(a,b){a=a|0;b=b|0;c[a+8>>2]=b;return}function kk(a,b){a=a|0;b=b|0;c[a+4>>2]=b;return}function lk(a,b){a=a|0;b=b|0;c[a>>2]=b;return}function mk(a,b){a=a|0;b=b|0;return d[a+64+b>>0]|0|0}function nk(b){b=b|0;var e=0,f=0,g=0,h=0,i=0,j=0;j=l;l=l+256|0;i=j;e=0;do{c[b+2872+(e*24|0)+8>>2]=-1;e=e+1|0}while((e|0)!=256);gp(b+64|0,-1,256)|0;a[i>>0]=0;c[b+372>>2]=ok(b,0,0)|0;g=b+1724|0;h=1;while(1){f=c[g>>2]|0;a:do if((f|0)>0){e=0;do{if((a[b+64+e>>0]|0)==-1)break a;e=e+1|0}while((e|0)<(f|0))}else e=0;while(0);if(!((h|0)<16&(e|0)!=(f|0)))break;a[i+h>>0]=e;f=ok(b,e,h)|0;c[b+372+(h<<4)>>2]=f;h=((f|0)>0&1)+h|0}f=b+9016|0;c[f>>2]=h;if((h|0)>0)e=0;else{l=j;return}do{c[b+9020+(e<<3)>>2]=d[i+e>>0];c[b+9020+(e<<3)+4>>2]=c[b+372+(e<<4)>>2];e=e+1|0}while((e|0)<(c[f>>2]|0));l=j;return}function ok(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,i=0,j=0,k=0,m=0,n=0.0,o=0.0,p=0,q=0,r=0,s=0,t=0.0,u=0,v=0,w=0,x=0.0,y=0,z=0,A=0,B=0,C=0,D=0.0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0.0,ja=0,ka=0,la=0,ma=0;ma=l;l=l+512|0;ea=ma+256|0;fa=ma;da=b+1724|0;g=c[da>>2]|0;if(!g){b=0;l=ma;return b|0}if((g|0)>0){k=b+9156|0;j=b+1696|0;m=b+1736|0;i=0;do{g=d[b+2520+i>>0]|0;if((g|0)<(c[j>>2]|0)){g=c[c[(c[m>>2]|0)+(g<<2)>>2]>>2]|0;g=(g|0)==0?1:g}else g=1;gp(c[(c[k>>2]|0)+(i<<2)>>2]|0,0,g|0)|0;i=i+1|0}while((i|0)<(c[da>>2]|0))}ba=b+1704|0;g=c[ba>>2]|0;if((g|0)>0){ka=g<<2;gp(ea|0,0,ka|0)|0;gp(fa|0,-1,ka|0)|0}Y=b+2852|0;U=(e|0)==0;V=f&255;ga=b+1696|0;$=(c[Y>>2]&134217728|0)!=0;_=b+1728|0;ha=b+1736|0;ja=b+9156|0;ka=b+2824|0;ia=+(~~+h[b+2816>>3]|0);aa=b+1740|0;X=b+2840|0;W=b+32|0;Z=b+2856|0;p=c[b+1720>>2]|0;g=0;m=0;A=c[b+1732>>2]|0;z=0;y=0;s=-1;v=0;k=e+-1|0;w=-1;r=0;i=c[b+1716>>2]|0;C=0;o=0.0;n=0.0;a:while(1){while(1){k=k+1|0;q=c[da>>2]|0;if(k>>>0>=q>>>0){j=c[_>>2]|0;if((j|0)<=(q|0)?(d[b+2520+j>>0]|0)<(c[ga>>2]|0):0){k=(mk(b,j)|0)==(f|0);k=k?j:e}else k=e;j=a[b+2520+k>>0]|0;if($&j<<24>>24==-1){j=0;break a}}else j=a[b+2520+k>>0]|0;T=j&255;q=b+64+k|0;if(!U?(a[q>>0]|0)!=-1:0){j=0;break a}a[q>>0]=V;if((T|0)<(c[ga>>2]|0))break;if(!($&j<<24>>24==-1))continue;k=c[da>>2]|0}S=b+2520+k|0;g=(g|0)<(c[c[(c[ha>>2]|0)+(T<<2)>>2]>>2]|0)?g:0;j=(y|0)!=0;if(!(j|(a[(c[(c[ja>>2]|0)+(k<<2)>>2]|0)+g>>0]|0)==0)){j=0;break}if(!j?(ca=b+2872+(k*24|0)+8|0,(c[ca>>2]|0)<0):0){c[ca>>2]=A;c[b+2872+(k*24|0)+4>>2]=p;c[b+2872+(k*24|0)>>2]=i;c[b+2872+(k*24|0)+12>>2]=~~(n+ia*(+(m|0)*+h[ka>>3])/+(p|0));c[b+2872+(k*24|0)+20>>2]=C}j=b+2872+(k*24|0)+16|0;if((k|0)!=0&(c[j>>2]|0)==0){if((k|0)==(e|0))o=n+ia*(+(m|0)*+h[ka>>3])/+(p|0);c[j>>2]=g}j=c[c[(c[ha>>2]|0)+(T<<2)>>2]>>2]|0;if((g|0)<(j|0)){u=0;B=j;j=0;while(1){p=(p|0)>20?p:20;if((j|0)>512)break a;r=(c[(c[ja>>2]|0)+(k<<2)>>2]|0)+g|0;q=a[r>>0]|0;if(!v)if(!(q<<24>>24))q=0;else{la=34;break a}a[r>>0]=q+1<<24>>24;if((c[ba>>2]|0)>0){R=g+-1|0;Q=0;M=B;P=s;N=0;I=C;while(1){q=c[aa>>2]|0;r=c[ha>>2]|0;b:do if((g|0)<(c[c[q+(c[(c[r+(T<<2)>>2]|0)+4+(Q<<2)>>2]<<2)>>2]>>2]|0)){J=c[q+(c[(c[r+(d[S>>0]<<2)>>2]|0)+4+(Q<<2)>>2]<<2)>>2]|0;E=a[J+4+(g<<3)+3>>0]|0;F=E&255;C=a[J+4+(g<<3)+4>>0]|0;K=C&255;G=a[J+4+(g<<3)+5>>0]|0;H=G&255;J=a[J+4+(g<<3)+6>>0]|0;L=J&255;B=E<<24>>24==16;q=B?K:L;if(B|G<<24>>24==16){A=c[X>>2]|0;A=(q|0)>(A|0)?A:q}q=E<<24>>24==17;c:do if(q|G<<24>>24==17){r=(z|0)==0;B=q?K:L;while(1){if(B|0)break;if(r){z=0;break c}else B=z}r=B>>>4&15;q=B&15;s=c[Y>>2]|0;if(!(s&32)){q=r-q|0;if(!(s&64)){A=(O(q,i+-1|0)|0)+A|0;z=B;break}else{A=(O(q,i)|0)+A|0;z=B;break}}if((q|0)==15&(r|0)!=0){A=r+A|0;z=B;break}if((q|0)!=0&(r|0)==15){A=A-q|0;z=B;break}q=r-q|0;if(!(s&64)){A=(O(q,i+-1|0)|0)+A|0;z=B;break}else{A=(O(q,i)|0)+A|0;z=B;break}}while(0);q=E<<24>>24==15;B=C<<24>>24!=0;if(!(q&B)?!(G<<24>>24==15&J<<24>>24!=0):0){s=p;r=I}else la=57;do if((la|0)==57){r=q?K:L;q=m+(O(i,j)|0)|0;if(!r){s=p;m=q;j=0;r=I;break}if(c[Y>>2]&268435456|0){s=p;m=q;j=0;i=r;r=0;break}if(r>>>0<32|(c[W>>2]&1|0)!=0){s=p;m=q;j=0;i=r;r=0;break}s=r;m=0;j=0;r=I;n=n+ia*(+(q|0)*+h[ka>>3])/+(p|0)}while(0);E=E<<24>>24==126?163:F;C=G<<24>>24==126?163:H;if(!(B&(E|0)==162)){p=(E|0)==163;if(B&p){p=r;la=66}else la=64}else{r=K&15;la=K>>>4;p=0;r=(r|0)==0?la:la<<8|r;la=64}do if((la|0)==64){la=0;if(!(J<<24>>24!=0&(C|0)==163)){F=r;break}if(p){p=r;la=66}else{q=L;p=r;la=67}}while(0);if((la|0)==66){q=K;la=67}if((la|0)==67){la=0;F=(q|0)==0;I=O(i,j)|0;m=(F?0:I)+m|0;j=F?j:0;i=F?i:q;F=F?p:0}p=(E|0)==171;if(!(B&p)?!(J<<24>>24!=0&(C|0)==171):0)p=s;else la=70;do if((la|0)==70){la=0;p=p?K:L;if(p>>>0<=31){p=s;break}I=m+(O(i,j)|0)|0;m=0;j=0;n=n+ia*(+(I|0)*+h[ka>>3])/+(s|0)}while(0);q=(E|0)==135;if(!(!(B&q)?!(J<<24>>24!=0&(C|0)==135):0))la=74;d:do if((la|0)==74){la=0;q=q?K:L;J=m+(O(j,i)|0)|0;D=+h[ka>>3];t=+(p|0);n=n+ia*(+(J|0)*D)/t;switch(q>>>4&15){case 0:{x=ia*D;n=x/t+n;if((i|0)>1){m=q&15;j=1;do{p=p-m|0;p=(p|0)>32?p:32;n=n+x/+(p|0);j=j+1|0}while((j|0)!=(i|0));q=p}else q=p;p=q;m=0;j=0;n=n-ia*(+(i|0)*D)/+(q|0);break d}case 1:{x=ia*D;n=x/t+n;if((i|0)>1){m=q&15;j=1;do{p=p+m|0;p=(p|0)<255?p:255;n=n+x/+(p|0);j=j+1|0}while((j|0)!=(i|0));q=p}else q=p;p=q;m=0;j=0;n=n-ia*(+(i|0)*D)/+(q|0);break d}default:{p=q;m=0;j=0;break d}}}while(0);if((E|0)==136){J=K&15;I=(c[(c[ja>>2]|0)+(k<<2)>>2]|0)+g|0;a[I>>0]=(d[I>>0]|0)+J;m=m+(O(i,J)|0)|0}q=(E|0)==142;I=(E|0)==11;J=I|(C|0)==11;w=J?(I?K:L):w;y=J?0:y;I=(E|0)==13;H=I|(C|0)==13;I=I?K:L;B=H|(q|J)?0:M;u=H?((I>>>4)*10|0)+(I&15)|0:J?0:q?K:u;q=(E|0)==14;if(!(q|(C|0)==14)){s=P;r=N;q=F;break}q=q?K:L;switch(q>>>4&15){case 14:{M=(N|0)!=0&(c[Z>>2]|0)==2;r=q&15;s=O(i,r)|0;m=(M?0:s)+m|0;s=P;r=M?N:r;q=F;break b}case 6:break;default:{s=P;r=N;q=F;break b}}r=q&15;if(!r){c[fa+(Q<<2)>>2]=R;u=(c[Y>>2]&67108864|0)==0?u:g;y=1;s=P;r=N;q=F;break}s=ea+(Q<<2)|0;q=c[s>>2]|0;if(!q){c[s>>2]=r;s=Q;v=v+1|0;r=N;q=F;break}M=q+-1|0;c[s>>2]=M;if(M|0){s=Q;r=N;q=F;break}q=v+-1|0;if(!(c[Y>>2]&1)){y=0;s=P;v=q;r=N;q=F;break}c[fa+(Q<<2)>>2]=g;y=0;s=P;v=q;r=N;q=F}else{B=M;s=P;r=N;q=I}while(0);Q=Q+1|0;if((Q|0)>=(c[ba>>2]|0))break;else{M=B;P=s;N=r;I=q}}}else{r=0;q=C}if((s|0)>-1){C=-1;g=c[fa+(s<<2)>>2]|0}else C=s;if(!q)q=0;else{m=m+(O(i,j)|0)|0;j=0;i=((q&65536|0)==0?q:q>>>8)&255;q=q^65536}g=g+1|0;j=j+1|0;if((g|0)<(B|0)){s=C;C=q}else{s=C;break}}}else{u=0;j=0;q=C}C=(w|0)>-1;g=((u|0)!=0&(r|0)!=0&1)+u|0;m=m+(O(i,j)|0)|0;k=C?w+-1|0:k;w=C?-1:w;C=q}if((la|0)==34)j=j+-1|0;la=d[b+2520+k>>0]|0;if(!((la|0)<(c[ga>>2]|0)?(g|0)<(c[c[(c[ha>>2]|0)+(la<<2)>>2]>>2]|0):0))g=0;c[b+372+(f<<4)+12>>2]=a[(c[(c[ja>>2]|0)+(k<<2)>>2]|0)+g>>0];c[b+372+(f<<4)+8>>2]=g;c[b+372+(f<<4)+4>>2]=k;b=m+(O(i,j)|0)|0;b=~~(n-o+ia*(+(b|0)*+h[ka>>3])/+(p|0));l=ma;return b|0}function pk(){var a=0;a=Xm(1,9192)|0;if(!a){a=0;return a|0}c[a+2868>>2]=100;c[a+1544>>2]=128;return a|0}function qk(a){a=a|0;if((c[a+9188>>2]|0)<=0){Wm(a);return}Bl(a);Wm(a);return}function rk(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0;h=mk(b,d)|0;if((h|0)==255)return;e=c[b+2852>>2]&134217728;if((h|0)<=-1)return;c[b+60>>2]=h;if((d|0)>-1){g=(e|0)!=0;e=a[b+2520+d>>0]|0;f=e&255;if(g&e<<24>>24==-2){do{d=d+1|0;f=a[b+2520+d>>0]|0}while(f<<24>>24==-2);e=f;f=f&255}if((f|0)<(c[b+1696>>2]|0)){if(g&e<<24>>24==-1)return;if((d|0)>(c[b+372+(h<<4)+4>>2]|0))e=b+360|0;else{c[b+356>>2]=c[c[(c[b+1736>>2]|0)+(f<<2)>>2]>>2];c[b+360>>2]=c[b+372+(h<<4)+12>>2];e=b+344|0}c[e>>2]=0}}if((d|0)>=(c[b+1724>>2]|0))return;c[b+4>>2]=(d|0)==0?-1:d;return}function sk(a,b){a=a|0;b=b|0;if((c[a+9188>>2]|0)<2)return;if((c[a+1724>>2]|0)<=(b|0))return;rk(a,b);return}function tk(a){a=a|0;var b=0,d=0,e=0;e=c[a+424>>2]|0;b=e+68|0;d=c[b>>2]|0;a=(O(c[e+60>>2]|0,c[20648+(d>>5<<2)>>2]|0)|0)>>10;c[b>>2]=((c[e+64>>2]|0)+d|0)%1024|0;return a|0}function uk(b,e){b=b|0;e=e|0;var f=0,g=0,h=0;f=c[e+424>>2]|0;h=c[f+48>>2]|0;if(!h){h=0;return h|0}b=c[(c[(c[b+9152>>2]|0)+8>>2]|0)+(c[e+44>>2]<<2)>>2]|0;g=b+h|0;if((a[g>>0]|0)==-3){h=0;return h|0}e=f+52|0;f=c[e>>2]|0;c[e>>2]=f+1;b=a[b+f>>0]|0;if(b<<24>>24==-3){c[e>>2]=h+1;b=d[g>>0]|0}else b=b&255;h=b*12800|0;return h|0}function vk(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;j=c[b+9152>>2]|0;if(!j)return;if((c[j>>2]|0)!=133303461)return;w=c[e+424>>2]|0;u=b+1744|0;v=c[e+44>>2]|0;l=c[(c[u>>2]|0)+(v*764|0)+760>>2]|0;g=w+84|0;if(!(c[g>>2]|0)){o=c[l+12>>2]|0;if((o|0?(c[b+12>>2]|0)>=(o|0):0)?(c[w+80>>2]|0)==0:0){o=e+8|0;c[o>>2]=c[o>>2]|1}}else if((c[w+80>>2]|0)==0?(c[b+12>>2]|0)>=(c[l+12>>2]|0):0){o=e+8|0;c[o>>2]=c[o>>2]|1;c[g>>2]=0}g=c[b+12>>2]|0;if((g|0)==((c[b+16>>2]|0)+-1|0)?(i=w+80|0,(c[i>>2]|0)!=2):0)c[i>>2]=0;o=c[(c[j+4>>2]|0)+(v<<2)>>2]|0;if(o|0?(t=c[(c[j+8>>2]|0)+(v<<2)>>2]|0,t|0):0){if(((g|0)==0?(k=c[e>>2]|0,k&65536|0):0)?(c[w+44>>2]=~~+h[e+24>>3],k&2048|0):0){c[w+52>>2]=0;c[w+48>>2]=0;c[w+20>>2]=0;c[w+16>>2]=0;c[w+4>>2]=0;c[w+40>>2]=0;c[w+36>>2]=0;c[w+24>>2]=0;c[w+88>>2]=-1;c[w+92>>2]=0;n=w+96|0;c[n>>2]=c[n>>2]&-2;c[w+8>>2]=0;c[w+28>>2]=0;c[w+12>>2]=c[l+4>>2];c[w+32>>2]=c[l+8>>2]}n=w+12|0;g=c[n>>2]|0;if((g|0)<=0)return;i=w+16|0;m=c[i>>2]|0;c[i>>2]=m+-1;if(m|0)return;c[i>>2]=g+-1;m=w+20|0;g=c[m>>2]|0;a:do if((g|0)<=0){l=w+4|0;g=c[l>>2]|0;k=0;b:while(1){j=g+1|0;c[l>>2]=j;i=a[o+g>>0]|0;switch(i<<24>>24){case -5:case -1:{s=27;break b}case -6:{s=30;break b}case -11:{s=31;break b}case -12:{s=32;break b}case -13:{s=33;break b}case -14:{s=34;break b}case -15:{s=35;break b}case -16:{s=36;break b}case -2:break;default:{s=37;break b}}if(k|0){n=0;break a}c[l>>2]=g+2;k=d[o+j>>0]|0;c[l>>2]=k;g=k;k=1}if((s|0)==27){c[l>>2]=g;n=0;break}else if((s|0)==30){c[l>>2]=g+2;n=d[o+j>>0]|0;break}else if((s|0)==31){c[l>>2]=g+2;c[w+88>>2]=d[o+j>>0];n=w+96|0;c[n>>2]=c[n>>2]|1;n=0;break}else if((s|0)==32){c[l>>2]=g+2;c[w+88>>2]=d[o+j>>0];n=0;break}else if((s|0)==33){c[l>>2]=g+2;c[w+8>>2]=d[o+j>>0];n=0;break}else if((s|0)==34){c[l>>2]=g+2;c[w+8>>2]=0-(d[o+j>>0]|0);n=0;break}else if((s|0)==35){c[l>>2]=g+2;c[m>>2]=d[o+j>>0];n=0;break}else if((s|0)==36){c[l>>2]=g+2;c[n>>2]=d[o+j>>0];n=0;break}else if((s|0)==37){if((i&255)>=65){n=0;break}c[w+76>>2]=i&255;n=0;break}}else{c[m>>2]=g+-1;n=0}while(0);i=w+88|0;g=c[i>>2]|0;if(((g|0)>-1?(p=c[(c[(c[u>>2]|0)+(v*764|0)+756>>2]|0)+(g<<6)+40>>2]|0,q=c[b+1748>>2]|0,(c[q+(p*52|0)+32>>2]|0)==128):0)?(r=w+92|0,o=c[r>>2]|0,c[w+76>>2]=(a[(c[q+(p*52|0)+48>>2]|0)+o>>0]|0)+128>>2,c[r>>2]=o+1,(o|0)>126):0){if(!(c[w+96>>2]&1))c[i>>2]=-1;c[r>>2]=0}i=w+76|0;g=(c[i>>2]|0)+(c[w+8>>2]|0)|0;c[i>>2]=g;if((g|0)>=0){if((g|0)>64){g=64;s=47}}else{g=0;s=47}if((s|0)==47)c[i>>2]=g;m=w+40|0;g=c[m>>2]|0;c:do if((g|0)>0){c[m>>2]=g+-1;g=0}else{l=w+24|0;i=c[l>>2]|0;g=0;d:while(1){k=i+1|0;c[l>>2]=k;j=a[t+i>>0]|0;switch(j<<24>>24){case -3:{g=0;break c}case -5:case -1:{s=52;break d}case -4:{s=57;break d}case -6:{s=59;break d}case -9:{s=60;break d}case -10:{s=61;break d}case -11:{s=62;break d}case -12:{s=63;break d}case -13:{s=64;break d}case -14:{s=65;break d}case -15:{s=66;break d}case -16:{s=67;break d}case -2:break;default:{s=68;break d}}if(g|0){g=0;break c}c[l>>2]=i+2;g=a[t+k>>0]|0;if(g<<24>>24==-1){s=55;break}i=g&255;c[l>>2]=i;g=1}switch(s|0){case 52:{c[l>>2]=i;g=0;break c}case 55:{c[l>>2]=k;g=0;break c}case 57:{g=i+2|0;c[l>>2]=g;c[w+52>>2]=k;c[w+48>>2]=k;do{b=g;g=g+1|0;c[l>>2]=g}while((a[t+b>>0]|0)!=-3);g=0;break}case 59:{c[l>>2]=i+2;g=d[t+k>>0]|0;break c}case 60:{c[l>>2]=i+2;c[w+56>>2]=d[t+k>>0];g=0;break c}case 61:{h[e+24>>3]=+(c[w+44>>2]|0);g=0;break c}case 62:{c[l>>2]=i+2;c[w+64>>2]=d[t+k>>0];g=0;break c}case 63:{c[l>>2]=i+2;c[w+60>>2]=d[t+k>>0];g=0;break c}case 64:{c[l>>2]=i+2;c[w+28>>2]=0-(d[t+k>>0]|0);g=0;break c}case 65:{c[l>>2]=i+2;c[w+28>>2]=d[t+k>>0];g=0;break c}case 66:{c[l>>2]=i+2;c[m>>2]=d[t+k>>0];g=0;break c}case 67:{c[l>>2]=i+2;c[w+32>>2]=d[t+k>>0];g=0;break c}case 68:{i=j&255;g=c[u>>2]|0;if((i|0)>=(c[g+(v*764|0)+36>>2]|0)){g=0;break c}g=c[(c[g+(v*764|0)+756>>2]|0)+(i<<6)+40>>2]|0;i=e+52|0;if((g|0)==(c[i>>2]|0)){g=0;break c}c[i>>2]=g;qi(b,f,g);g=0;break c}}}while(0);e=e+24|0;h[e>>3]=+h[e>>3]+ +(c[w+28>>2]|0);if(n|0)c[w+24>>2]=n;if(!g)return;c[w+4>>2]=g;return}c[w+76>>2]=64;return}function wk(a){a=a|0;var b=0;b=Xm(1,16)|0;c[a+760>>2]=b;if(!b){a=-1;return a|0}c[b>>2]=133303461;a=0;return a|0}function xk(a){a=a|0;var b=0;b=Xm(1,100)|0;c[a+424>>2]=b;if(!b){a=-1;return a|0}c[b>>2]=133303461;a=0;return a|0}function yk(b){b=b|0;var c=0;b=b+4|0;c=b+96|0;do{a[b>>0]=0;b=b+1|0}while((b|0)<(c|0));return}function zk(a){a=a|0;Wm(a);return}function Ak(a){a=a|0;var b=0,d=0;b=Xm(1,12)|0;c[a+7584>>2]=b;if(!b){b=-1;return b|0}c[b>>2]=133303461;a=c[a+140>>2]|0;d=Xm(4,a)|0;c[b+4>>2]=d;if(!d){d=-1;return d|0}d=Xm(4,a)|0;c[b+8>>2]=d;d=((d|0)==0)<<31>>31;return d|0}function Bk(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;h=a+7584|0;g=c[h>>2]|0;f=g+4|0;b=c[f>>2]|0;if(b|0){e=a+140|0;if((c[e>>2]|0)>0){d=0;do{Wm(c[b+(d<<2)>>2]|0);d=d+1|0;b=c[f>>2]|0}while((d|0)<(c[e>>2]|0))}Wm(b)}f=g+8|0;b=c[f>>2]|0;if(!b){h=c[h>>2]|0;Wm(h);return}e=a+140|0;if((c[e>>2]|0)>0){d=0;do{Wm(c[b+(d<<2)>>2]|0);d=d+1|0;b=c[f>>2]|0}while((d|0)<(c[e>>2]|0))}Wm(b);h=c[h>>2]|0;Wm(h);return}function Ck(a,b){a=a|0;b=b|0;if(b<<24>>24!=-79)return;a=c[a+424>>2]|0;b=a+84|0;c[b>>2]=(c[b>>2]|0)+1;c[a+80>>2]=1;return}function Dk(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0;g=c[(c[b+1740>>2]|0)+(c[(c[(c[b+1736>>2]|0)+(d<<2)>>2]|0)+4+(e<<2)>>2]<<2)>>2]|0;d=f+1|0;if((d|0)>=(c[g>>2]|0))return;if((a[g+4+(d<<3)+5>>0]|0)!=-79)return;c[(c[(c[b+628>>2]|0)+(e*464|0)+424>>2]|0)+80>>2]=2;return}function Ek(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var i=0.0,j=0.0,k=0.0;i=+(a|0);j=+va(+((b|0)<0?.25:+(((b|0)<255?b:255)|0)*.02083333395421505+.25))*110.0;k=i*.5;j=i/((j>k?k:j)*6.2831854820251465);k=+g[20776+(((d|0)<0?0:((d|0)<255?d:255)>>1)<<2)>>2]*(j+1.0)+-1.0;j=j*j;i=j+(k+1.0);c[e>>2]=~~(1.0/i*65536.0);c[f>>2]=~~((j+(j+k))/i*65536.0);c[h>>2]=~~(-j/i*65536.0);return}function Fk(b,e,f,g,i){b=b|0;e=e|0;f=f|0;g=g|0;i=i|0;var j=0,k=0.0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;m=b+332|0;q=c[b+2856>>2]|0;if((q|0)!=3)c[e+108>>2]=c[e+16>>2];s=a[g>>0]|0;r=(i|0)==0;p=g+3|0;o=g+4|0;i=a[(r?o:g+6|0)>>0]|0;n=a[(r?p:g+5|0)>>0]|0;a:do switch(n<<24>>24){case 0:{l=c[b+2852>>2]|0;t=8;break}case -76:{l=c[b+2852>>2]|0;n=i&255;m=i<<24>>24==0;if(!(l&16)){j=e+196|0;if(m){i=c[j>>2]&255;t=8;break a}}else{j=e+260|0;if(m){i=c[j>>2]&255;t=8;break a}}c[j>>2]=n;t=10;break}case 112:{j=i&255;if(!(i<<24>>24))return;a[e+172>>0]=0-(j>>>4);a[e+173>>0]=0;a[e+174>>0]=j&15;c[e+188>>2]=3;return}case 113:{j=i&255;if(!(i<<24>>24))return;a[e+172>>0]=0;a[e+173>>0]=j&15;a[e+174>>0]=0;a[e+175>>0]=0-(j>>>4);c[e+188>>2]=4;return}case 114:{j=i&15;if(!(i<<24>>24))return;a[e+172>>0]=j;a[e+173>>0]=j;a[e+174>>0]=0;c[e+188>>2]=3;return}case 1:{n=c[b+2852>>2]|0;m=i&255;l=i<<24>>24==0;do if(!(n&16)){j=e+320|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}else{j=e+260|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}while(0);b:do if(n&32|0?r|(n&2048|0)==0:0){j=i&255;switch((i&255)>>>4&15){case 15:{i=j&15;t=210;break a}case 14:{i=(j&15|16)&255;t=318;break a}default:break b}}while(0);c[e>>2]=c[e>>2]|8;j=i&255;if(!(i<<24>>24)){j=e+304|0;i=c[j>>2]|0;if((i|0)<=0)return;c[j>>2]=0-i;return}else{c[e+304>>2]=0-j;if(!(n&1024))return;c[e+344>>2]=j;return}}case 2:{n=c[b+2852>>2]|0;m=i&255;l=i<<24>>24==0;do if(!(n&16)){j=e+320|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}else{j=e+260|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}while(0);c:do if(n&32|0?r|(n&2048|0)==0:0){j=i&255;switch((i&255)>>>4&15){case 15:{i=j&15;t=213;break a}case 14:{i=(j&15|32)&255;t=318;break a}default:break c}}while(0);c[e>>2]=c[e>>2]|8;j=i&255;l=e+304|0;if(!(i<<24>>24)){i=c[l>>2]|0;if((i|0)>=0)return;c[l>>2]=0-i;return}else{c[l>>2]=j;if(!(n&1024))return;c[e+344>>2]=j;return}}case 3:{if(!(i<<24>>24))i=c[e+344>>2]&255;else c[e+344>>2]=i&255;j=c[b+2852>>2]|0;l=i&255;i=i<<24>>24!=0;if(!((j&16|0)==0|i^1))c[e+260>>2]=l;if(i){if(j&1024|0)c[e+320>>2]=l;c[e+340>>2]=l}if(s<<24>>24==0&(j&131072|0)!=0?(c[e+336>>2]|0)==0:0)return;i=c[e+44>>2]|0;if(i>>>0>=(c[b+1708>>2]|0)>>>0)return;if((c[(c[b+1744>>2]|0)+(i*764|0)+36>>2]|0)<=0)return;Gk(b,e,s&255);c[e>>2]=c[e>>2]|4;return}case 4:{if(!(i<<24>>24))i=c[e+128>>2]&255;else c[e+128>>2]=i&255;j=i&255;if(!(i<<24>>24==0?1:(c[b+2852>>2]&16|0)==0))c[e+260>>2]=j;c[e>>2]=c[e>>2]|16;i=j<<2&60;if(i|0)jk(e+112|0,i);i=j>>>4;if(!i)return;kk(e+112|0,i);return}case -84:{if(!(i<<24>>24))i=c[e+128>>2]&255;else c[e+128>>2]=i&255;j=i&255;if(!(i<<24>>24==0?1:(c[b+2852>>2]&16|0)==0))c[e+260>>2]=j;c[e>>2]=c[e>>2]|16;i=j&15;if(i|0)jk(e+112|0,i);i=j>>>4;if(!i)return;kk(e+112|0,i);return}case 5:{j=c[e+44>>2]|0;if(j>>>0>=(c[b+1708>>2]|0)>>>0)return;if((c[(c[b+1744>>2]|0)+(j*764|0)+36>>2]|0)>0){Gk(b,e,s&255);j=4;t=6;break a}else return}case 6:{j=16;t=6;break}case 7:{m=i&255;l=i<<24>>24==0;do if(!(c[b+2852>>2]&16)){j=e+148|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}else{j=e+260|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}while(0);c[e>>2]=c[e>>2]|32;j=i&255;i=j&15;if(i|0)jk(e+132|0,i);i=j>>>4;if(!i)return;kk(e+132|0,i);return}case 8:{j=c[b+2852>>2]|0;if(!(j&4))t=103;else return;break}case 9:{m=i&255;l=i<<24>>24==0;do if(!(c[b+2852>>2]&16)){j=e+228|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}else{j=e+260|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}while(0);c[e>>2]=c[e>>2]|256;if(s<<24>>24){t=e+220|0;b=(i&255)<<8;c[t>>2]=c[t>>2]&-65536|b;c[e+224>>2]=b}if(!(a[g+1>>0]|0))return;c[e+224>>2]=(i&255)<<8;return}case 10:{t=7;break}case -92:{c[e>>2]=c[e>>2]|8192;j=i&255;l=j>>>4;if(!(i<<24>>24))return;c[e+256>>2]=l|0?l:0-(j&15)|0;return}case 11:{c[m>>2]=1;c[b+336>>2]=i&255;c[b+344>>2]=0;return}case 12:{c[e>>2]=c[e>>2]|4096;i=i&255;c[e+76>>2]=i;if(!(a[e+92>>0]|0))return;c[(c[b+628>>2]|0)+((d[e+93>>0]|0)*464|0)+76>>2]=i;return}case 13:{c[m>>2]=1;e=i&255;c[b+344>>2]=((e>>>4)*10|0)+(e&15);return}case 14:{j=c[b+2852>>2]|0;m=(j&16|0)==0;do if(!m)if(!(i<<24>>24)){i=c[e+260>>2]&255;break}else{c[e+260>>2]=i&255;break}while(0);g=i&15;do switch((i&255)>>>4&15){case 14:{i=g;t=215;break a}case 0:{if(q|0)return;if((c[b+2860>>2]|0)!=1)return;c[b+1504>>2]=(i&1^1)&255;return}case 1:{i=g&255;l=g<<24>>24==0;if(m){j=e+352|0;if(l){i=c[j>>2]&255;t=210;break a}else{c[j>>2]=i;t=211;break a}}else{j=e+260|0;if(l){i=c[j>>2]&255;t=210;break a}else{c[j>>2]=i;t=211;break a}}}case 2:{l=g&255;j=g<<24>>24==0;if(m){i=e+356|0;if(j){i=c[i>>2]&255;t=213;break a}}else{i=e+260|0;if(j){i=c[i>>2]&255;t=213;break a}}c[i>>2]=l;i=g;t=214;break a}case 3:{e=e+8|0;b=c[e>>2]|0;c[e>>2]=g<<24>>24?b|512:b&-513;return}case 4:{lk(e+112|0,i&3);return}case 5:{if(s<<24>>24==0&(j&67108864|0)!=0)return;c[e+40>>2]=(i<<4&255)<<24>>24;return}case 6:{m=g&255;n=c[b+352>>2]|0;if(!(g<<24>>24)){i=c[b+8>>2]|0;c[n+(f<<3)>>2]=i;if(!(j&67108864))return;c[b+344>>2]=i;return}l=n+(f<<3)+4|0;i=c[l>>2]|0;if(!i){c[l>>2]=m;c[b+348>>2]=f+1;return}e=i+-1|0;c[l>>2]=e;if(e|0){c[b+348>>2]=f+1;return}if(!(j&1))return;c[n+(f<<3)>>2]=(c[b+8>>2]|0)+1;return}case 7:{lk(e+132|0,i&3);return}case 8:{i=i<<4&255;t=103;break a}case 9:{c[e>>2]=c[e>>2]|262144;b=g&255;c[e+232>>2]=b;c[e+236>>2]=b+1;c[e+240>>2]=0;return}case 10:{l=g&255;j=g<<24>>24==0;if(m){i=e+272|0;if(j){i=c[i>>2]&255;t=201;break a}else{c[i>>2]=l;i=g;t=201;break a}}else{i=e+260|0;if(j){i=c[i>>2]&255;t=201;break a}else{c[i>>2]=l;i=g;t=201;break a}}}case 11:{l=g&255;j=g<<24>>24==0;if(m){i=e+276|0;if(j){i=c[i>>2]&255;t=209;break a}else{c[i>>2]=l;i=g;t=209;break a}}else{i=e+260|0;if(j){i=c[i>>2]&255;t=209;break a}else{c[i>>2]=l;i=g;t=209;break a}}}case 12:{c[e>>2]=c[e>>2]|262144;b=e+8|0;c[b>>2]=c[b>>2]|8;b=g+1&255;c[e+232>>2]=b;c[e+236>>2]=b;c[e+240>>2]=16;return}case 15:{c[e+380>>2]=g&255;return}default:return}while(0)}case 15:{if((c[b+2852>>2]&268435456|0)==0?!((i&255)<32?1:(c[b+32>>2]&1|0)!=0):0)t=224;else t=222;break}case -90:{c[e+40>>2]=((i&255)<<16)+-8388608>>16;return}case -83:{m=i&255;l=i<<24>>24==0;if(!(c[b+2852>>2]&16)){j=e+272|0;if(l){i=c[j>>2]&255;t=201;break a}else{c[j>>2]=m;t=201;break a}}else{j=e+260|0;if(l){i=c[j>>2]&255;t=201;break a}else{c[j>>2]=m;t=201;break a}}}case -82:{m=i&255;l=i<<24>>24==0;if(!(c[b+2852>>2]&16)){j=e+272|0;if(l){i=c[j>>2]&255;t=209;break a}else{c[j>>2]=m;t=209;break a}}else{j=e+260|0;if(l){i=c[j>>2]&255;t=209;break a}else{c[j>>2]=m;t=209;break a}}}case -81:{t=210;break}case -80:{t=213;break}case -77:{t=215;break}case -93:{if(c[b+2852>>2]&16)if(!(i<<24>>24)){i=c[e+260>>2]&255;t=222;break a}else{i=i&255;c[e+260>>2]=i;t=223;break a}else t=222;break}case -85:{t=224;break}case -121:{j=i&255;switch((i&255)>>>4&15){case 0:{c[e>>2]=c[e>>2]|2097152;c[e+392>>2]=0-(j&15);break}case 1:{c[e>>2]=c[e>>2]|2097152;c[e+392>>2]=j&15;break}default:c[b+20>>2]=((i&255)>20?i:20)&255}h[b+48>>3]=+h[b+2824>>3]*+h[b+2816>>3]/+(c[b+20>>2]|0);return}case -120:{j=b+368|0;if(c[j>>2]|0)return;c[b+364>>2]=i&255;c[j>>2]=3;return}case -64:{m=i&255;l=i<<24>>24==0;do if(!(c[b+2852>>2]&16)){j=e+268|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}else{j=e+260|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}while(0);c[e>>2]=c[e>>2]|8192;c[e+256>>2]=i&255;return}case -63:{m=i&255;l=i<<24>>24==0;do if(!(c[b+2852>>2]&16)){j=e+268|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}else{j=e+260|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}while(0);c[e>>2]=c[e>>2]|8192;c[e+256>>2]=0-(i&255);return}case -62:{m=i&255;l=i<<24>>24==0;do if(!(c[b+2852>>2]&16)){j=e+268|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}else{j=e+260|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}while(0);c[e>>2]=c[e>>2]|33554432;c[e+264>>2]=i&255;return}case -61:{m=i&255;l=i<<24>>24==0;do if(!(c[b+2852>>2]&16)){j=e+268|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}else{j=e+260|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}while(0);c[e>>2]=c[e>>2]|33554432;c[e+264>>2]=0-(i&255);return}case -114:{c[m>>2]=1;c[b+344>>2]=i&255;return}case 16:{e=i&255;t=c[b+2840>>2]|0;c[b+328>>2]=(e|0)>(t|0)?t:e;return}case 17:{j=e+288|0;while(1){if(i<<24>>24)break;i=c[j>>2]|0;if(!(i&255)){t=430;break}else i=i&255}if((t|0)==430)return;c[e>>2]=c[e>>2]|1048576;i=i&255;c[j>>2]=i;l=i>>>4;i=i&15;j=(l|0)!=0;if(!(c[b+2852>>2]&32)){j=j?l:0-i|0;i=0}else{t=(i|0)==15&j;b=(l|0)==15&(i|0)!=0;i=0-i|0;j=t|b?0:j?l:i;i=t?l:b?i:0}c[e+280>>2]=j;c[e+284>>2]=i;return}case 20:{c[e+64>>2]=(i&255)+1;return}case 21:{if(c[b+2852>>2]&67108864){b=Em(b,c[e+44>>2]|0)|0;if(b|0?c[b+44>>2]&2|0:0)c[e+100>>2]=i&255}else c[e+100>>2]=i&255;b=i&255;c[e+96>>2]=b;c[e+104>>2]=b;return}case 25:{m=i&255;l=i<<24>>24==0;do if(!(c[b+2852>>2]&16)){j=e+372|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}else{j=e+260|0;if(l){i=c[j>>2]&255;break}else{c[j>>2]=m;break}}while(0);c[e>>2]=c[e>>2]|2;b=i&255;c[e+364>>2]=(b&15)-(b>>>4);return}case -75:{c[e>>2]=c[e>>2]|2;b=i&255;c[e+364>>2]=(b&15)-(b>>>4);return}case -119:{c[e>>2]=c[e>>2]|2;if(!(i<<24>>24))return;i=i&255;j=i>>>4;i=i&15;do if((j|0)!=15)if((i|0)==15){c[e+364>>2]=0;i=0-j|0;break}else{c[e+364>>2]=i-j;i=0;break}else c[e+364>>2]=0;while(0);c[e+368>>2]=i;return}case 27:{do if(c[b+2852>>2]&16)if(!(i<<24>>24)){i=c[e+260>>2]&255;t=299;break}else{i=i&255;c[e+260>>2]=i;t=300;break}else t=299;while(0);if((t|0)==299?i<<24>>24:0){i=i&255;t=300}if((t|0)==300)c[e+232>>2]=i;if(s<<24>>24){b=c[e+232>>2]|0;c[e+236>>2]=(b&15)+1;c[e+240>>2]=b>>>4&15}c[e>>2]=c[e>>2]|262144;return}case 29:{l=i&255;m=i<<24>>24==0;do if(!(c[b+2852>>2]&16)){j=e+247|0;if(m){i=a[j>>0]|0;break}else{a[j>>0]=i;break}}else{j=e+260|0;if(m){i=c[j>>2]&255;break}else{c[j>>2]=l;break}}while(0);l=(i&255)>>>4;m=e+244|0;a[m>>0]=l;i=i&15;j=e+245|0;a[j>>0]=i;if((q|0)!=1){if(!(l<<24>>24))a[m>>0]=1;if(!(i<<24>>24))a[j>>0]=1}else{b=e+246|0;a[b>>0]=a[b>>0]|-128}c[e>>2]=c[e>>2]|134217728;return}case 33:{t=318;break}case -115:{c[e+376>>2]=i&255;return}case -128:{i=i&255;if((i|0)>(c[b+2836>>2]|0))return;c[e+56>>2]=i;return}case -127:{if(!(i<<24>>24)){i=c[e+300>>2]|0;if(!(i&255))return;else i=i&255}j=c[b+2852>>2]|0;do if(j&32|0){n=i&255;m=n>>>4;l=n&15;if(!((m|0)==15&(l|0)!=0))if((l|0)==15&(m|0)!=0)i=n&240;else break;else i=l;c[e+300>>2]=n;i=i&255;t=332;break a}while(0);c[e>>2]=c[e>>2]|512;if(!(i<<24>>24))return;t=i&255;b=t>>>4;s=t&15;c[e+300>>2]=t;t=0-s|0;c[e+292>>2]=(j&512|0)==0?(b|0?b:t):s|0?t:b;return}case -126:{t=332;break}case -125:do switch(i<<24>>24){case 0:{zi(b,f,0);return}case 1:{zi(b,f,2);return}case 2:{zi(b,f,3);return}case 3:{ri(b,f,0);return}case 4:{ri(b,f,1);return}case 5:{ri(b,f,2);return}case 6:{ri(b,f,3);return}case 7:{e=e+4|0;c[e>>2]=c[e>>2]|4194304;return}case 8:{e=e+4|0;c[e>>2]=c[e>>2]&-4194305;return}case 9:{e=e+4|0;c[e>>2]=c[e>>2]|8388608;return}case 10:{e=e+4|0;c[e>>2]=c[e>>2]&-8388609;return}case 11:{e=e+4|0;c[e>>2]=c[e>>2]|16777216;return}case 12:{e=e+4|0;c[e>>2]=c[e>>2]&-16777217;return}default:return}while(0);case -124:{j=i&255;if((i&255)>=254?(c[e+400>>2]|0)<=0:0)return;c[e+396>>2]=j;return}case -123:{c[e+400>>2]=i&255;return}case -118:{c[e>>2]=c[e>>2]|524288;i=i&255;j=i<<4&240;if(j|0)jk(e+152|0,j);i=i>>>4;if(!i)return;kk(e+152|0,i);return}case -117:{lk(e+152|0,i&3);return}case -116:{e=e+220|0;c[e>>2]=c[e>>2]&65535|(i&255)<<16;return}case -74:{j=c[e+44>>2]|0;if(j>>>0>=(c[b+1708>>2]|0)>>>0)return;l=c[b+1744>>2]|0;if((c[l+(j*764|0)+36>>2]|0)>0){c[e>>2]=c[e>>2]|4096;t=(c[c[l+(j*764|0)+756>>2]>>2]|0)+(i&255)|0;e=e+76|0;c[e>>2]=t;b=c[b+2836>>2]|0;c[e>>2]=(t|0)>(b|0)?b:t;return}else return}case -73:{l=c[e+44>>2]|0;if(l>>>0>=(c[b+1708>>2]|0)>>>0)return;j=c[b+1744>>2]|0;if((c[j+(l*764|0)+36>>2]|0)<=0)return;c[e>>2]=c[e>>2]|4096;b=(c[c[j+(l*764|0)+756>>2]>>2]|0)-(i&255)|0;c[e+76>>2]=(b|0)>0?b:0;return}case -72:{t=e+4|0;c[t>>2]=c[t>>2]|4;h[e+328>>3]=+(i&255)+ +Bi(b,(s&255)+-1|0,c[e+40>>2]|0,0.0);c[e+340>>2]=2;c[e+336>>2]=1;return}case -71:{t=e+4|0;c[t>>2]=c[t>>2]|4;h[e+328>>3]=+Bi(b,(s&255)+-1|0,c[e+40>>2]|0,0.0)-+(i&255);c[e+340>>2]=2;c[e+336>>2]=-1;return}case -94:{l=i&255;j=l&15;l=l>>>4;if(!(i<<24>>24))return;c[b+1500>>2]=(j|0)==0?l:l<<8|j;return}case -96:{if(c[b+2852>>2]&32|0?(b=i&255,j=b&15,(b&240|0)==240&(j|0)!=0):0){i=j&255;t=201;break a}if(i<<24>>24)c[e+248>>2]=i&255;c[e>>2]=c[e>>2]|1;return}case -95:{if(c[b+2852>>2]&32|0?(b=i&255,l=b&15,(b&240|0)==240&(l|0)!=0):0){i=l&255;t=209;break a}if(i<<24>>24)c[e+248>>2]=0-(i&255);c[e>>2]=c[e>>2]|1;return}case -91:{c[e>>2]=c[e>>2]|64;j=i&255;l=j>>>4;if(!(i<<24>>24))return;c[e+252>>2]=l|0?l:0-(j&15)|0;return}case -98:case -97:case -99:case -100:{j=i&255;l=n&-2;if(i<<24>>24){i=j>>>4;if(l<<24>>24==-98){c[e+232>>2]=i;c[e+236>>2]=i+1;c[e+240>>2]=0}b=j&15;c[e+408>>2]=(n+99&255)<2?b:0-b|0;c[e+416>>2]=i;c[e+420>>2]=i}i=c[e>>2]|0;if(l<<24>>24==-98){i=i|262144;c[e>>2]=i}c[e>>2]=i|16384;return}case 115:{c[e>>2]=c[e>>2]|16384;c[e+408>>2]=0-(i&255);c[e+416>>2]=1;c[e+420>>2]=1;return}case 116:{c[e>>2]=c[e>>2]|16384;c[e+408>>2]=i&255;c[e+416>>2]=1;c[e+420>>2]=1;return}case 117:{c[e>>2]=c[e>>2]|32768;c[e+412>>2]=0-(i&255);return}case 118:{c[e>>2]=c[e>>2]|32768;c[e+412>>2]=i&255;return}case 123:{j=i&255;i=j&15;b=e+4|0;t=c[b>>2]|0;c[b>>2]=i|0?t|16:t&-17;if(i|0)jk(e+112|0,i<<2);i=j>>>4;if(!i)return;kk(e+112|0,i);return}case 121:{l=e+4|0;j=c[l>>2]|0;c[l>>2]=j|8;b=i&255;c[e+304>>2]=0-b;c[e+320>>2]=b;if(i<<24>>24)return;c[l>>2]=j&-9;return}case 120:{l=e+4|0;j=c[l>>2]|0;c[l>>2]=j|8;b=i&255;c[e+304>>2]=b;c[e+320>>2]=b;if(i<<24>>24)return;c[l>>2]=j&-9;return}case 122:{j=c[e+44>>2]|0;if(j>>>0>=(c[b+1708>>2]|0)>>>0)return;if((c[(c[b+1744>>2]|0)+(j*764|0)+36>>2]|0)<=0)return;j=e+4|0;c[j>>2]=c[j>>2]|4;Gk(b,e,s&255);c[e+340>>2]=i&255;if(i<<24>>24)return;c[j>>2]=c[j>>2]&-5;return}case 124:{l=e+4|0;j=c[l>>2]|0;c[l>>2]=j|1;c[e+248>>2]=i&255;if(i<<24>>24)return;c[l>>2]=j&-2;return}case 125:{l=e+4|0;j=c[l>>2]|0;c[l>>2]=j|1;c[e+248>>2]=0-(i&255);if(i<<24>>24)return;c[l>>2]=j&-2;return}case -110:{c[e>>2]=c[e>>2]|16;i=i&255;j=i<<3&120;if(j|0)jk(e+112|0,j);i=i>>>4;if(!i)return;kk(e+112|0,i);return}case 126:{if(!(i<<24>>24))t=415;else{c[b+16>>2]=i&255;c[b+1500>>2]=0;t=415}break}case 127:{t=415;break}case 96:{l=e+4|0;j=c[l>>2]|0;c[l>>2]=j|8;b=i&255;c[e+304>>2]=b*80;c[e+320>>2]=b;if(i<<24>>24)return;c[l>>2]=j&-9;return}case 97:{l=e+4|0;j=c[l>>2]|0;c[l>>2]=j|8;b=i&255;c[e+304>>2]=O(b,-80)|0;c[e+320>>2]=b;if(i<<24>>24)return;c[l>>2]=j&-9;return}case 98:{j=c[e+44>>2]|0;if(j>>>0>=(c[b+1708>>2]|0)>>>0)return;if((c[(c[b+1744>>2]|0)+(j*764|0)+36>>2]|0)<=0)return;j=e+4|0;c[j>>2]=c[j>>2]|4;Gk(b,e,s&255);c[e+340>>2]=(i&255)*40;if(i<<24>>24)return;c[j>>2]=c[j>>2]&-5;return}case 99:{c[e+40>>2]=(i<<24>>24)*80;return}case 100:{if(!(i&15)){i=e+4|0;c[i>>2]=c[i>>2]&-17;i=e+112|0}else{i=e+112|0;lk(i,669);e=e+4|0;c[e>>2]=c[e>>2]|16}jk(i,669);kk(i,1);return}default:{Dm(e,n,i);return}}while(0);switch(t|0){case 6:{c[e>>2]=c[e>>2]|j;t=7;break}case 8:{if(i<<24>>24==0&(l&536870912|0)!=0)return;else t=10;break}case 103:{if((s<<24>>24==-127&((r|(j&67108864|0)==0)^1)?(a[p>>0]|0)==14:0)?(a[o>>0]&-16)<<24>>24==-48:0)i=e+376|0;else{c[e+360>>2]=i&255;i=e+376|0;c[i>>2]=0}c[e+88>>2]=0;c[i>>2]=0;return}case 210:{if(!(i<<24>>24))return;else{i=i&255;t=211}break}case 213:{if(!(i<<24>>24))return;else t=214;break}case 215:{j=b+340|0;if((q|0)==2?c[j>>2]|0:0)return;c[j>>2]=i&255;return}case 222:{if(!(i<<24>>24))return;else{i=i&255;t=223}break}case 224:{k=+h[b+2824>>3];e=~~(k*20.0/10.0+.5);e=(i&255|0)<(e|0)?e&255:i;c[b+20>>2]=e&255;h[b+48>>3]=k*+h[b+2816>>3]/+(e&255);return}case 318:{c[e>>2]=c[e>>2]|128;switch((i&255)>>>4&15){case 1:{k=-.25;break}case 2:{k=.25;break}default:return}h[e+312>>3]=+(i&15)*k;return}case 332:{c[e>>2]=c[e>>2]|1024;j=i&255;if(!(i<<24>>24))return;c[e+296>>2]=(j>>>4)-(j&15);return}case 415:{c[e+4>>2]=0;return}}do if((t|0)==7){n=c[b+2852>>2]|0;o=(n&32|0)==0;g=e+260|0;while(1){m=i&255;if(!o){j=m>>>4;l=m&15;if((l|0)==15&(j|0)!=0){t=122;break}if((j|0)==15&(l|0)!=0){t=124;break}}if(i<<24>>24){t=126;break}l=c[g>>2]|0;i=l&255;if(!(l&255)){t=128;break}}if((t|0)==122){c[g>>2]=m;i=(i&255)>>>4;t=201;break}else if((t|0)==124){c[g>>2]=m;i=l&255;t=209;break}else if((t|0)==126){j=c[e>>2]|1;c[e>>2]=j;m=e;t=129}else if((t|0)==128){j=c[e>>2]|1;c[e>>2]=j;if(!(i<<24>>24))i=e;else{m=e;t=129}}if((t|0)==129){l=i&255;c[g>>2]=l;i=l>>>4;t=l&15;b=0-t|0;c[e+248>>2]=(n&512|0)==0?(i|0?i:b):t|0?b:i;i=m}if(o)return;if(!((l&240|0)==240|(l&15|0)==15))return;c[i>>2]=j|64;c[e+252>>2]=c[e+248>>2];return}else if((t|0)==10){a[e+172>>0]=0;a[e+173>>0]=(i&255)>>>4;a[e+174>>0]=i&15;c[e+188>>2]=3;return}else if((t|0)==211){c[e>>2]=c[e>>2]|128;h[e+312>>3]=+(0-i|0);return}else if((t|0)==214){c[e>>2]=c[e>>2]|128;h[e+312>>3]=+(i&255);return}else if((t|0)==223){c[b+16>>2]=i;c[b+1500>>2]=0;return}while(0);if((t|0)==201){c[e>>2]=c[e>>2]|64;c[e+252>>2]=i&255;return}else if((t|0)==209){c[e>>2]=c[e>>2]|64;c[e+252>>2]=0-(i&255);return}}function Gk(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,i=0,j=0,k=0;g=c[b+1744>>2]|0;i=c[e+44>>2]|0;k=d[g+(i*764|0)+512+(c[e+16>>2]<<1)>>0]|0;k=(k|0)<(c[g+(i*764|0)+36>>2]|0)?k:0;j=c[g+(i*764|0)+756>>2]|0;f=f+-1|0;if(f>>>0<128?i>>>0<(c[b+1708>>2]|0)>>>0:0)h[e+328>>3]=+Bi(b,(c[j+(k<<6)+12>>2]|0)+f+(a[g+(i*764|0)+512+(c[e+108>>2]<<1)+1>>0]|0)|0,c[e+40>>2]|0,+h[e+32>>3]);c[e+336>>2]=+h[e+24>>3]<+h[e+328>>3]?1:-1;return}function Hk(a){a=a|0;var b=0;b=~~(+(c[a+1512>>2]|0)*+h[a+2824>>3]*+h[a+2816>>3]/+(c[a+20>>2]|0)/1.0e3);c[a+1548>>2]=b;gp(c[a+1540>>2]|0,0,b<<((c[a+1516>>2]|0)>>>2&1^3)|0)|0;return}function Ik(b){b=b|0;var e=0,f=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0.0,p=0.0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,P=0,Q=0,R=0,S=0.0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0.0,ma=0,na=0,oa=0,pa=0;oa=b+1528|0;switch(c[oa>>2]|0){case 0:{e=21352;break}case 1:{e=21288;break}case 2:{e=21320;break}default:e=21288}na=b+32|0;if(((c[na>>2]&8|0)!=0?(c[b+2856>>2]|0)==0:0)?(c[b+2860>>2]|0)==1:0)$=(c[b+1504>>2]|0)==0?21384:21416;else $=e;Hk(b);_=b+964|0;if((c[_>>2]|0)>0){da=b+972|0;k=b+1540|0;ba=b+1712|0;ha=b+1748|0;ga=b+9160|0;Z=b+1512|0;e=b+1548|0;ea=b+628|0;f=b+1516|0;aa=b+2856|0;fa=b+9164|0;ia=b+9184|0;Y=b+2832|0;g=0;ca=0;do{q=c[da>>2]|0;X=q+(ca<<7)|0;j=q+(ca<<7)+80|0;i=c[j>>2]|0;if(i&2){if((c[oa>>2]|0)>0){Jk(b,ca,0,0);i=c[j>>2]|0}i=i&-3;c[j>>2]=i}do if((c[X>>2]|0)>=0){o=+h[q+(ca<<7)+24>>3];if(o<1.0){ei(b,ca,1);break}U=q+(ca<<7)+32|0;p=+h[U>>3];c[q+(ca<<7)+40>>2]=~~p;r=c[k>>2]|0;j=c[q+(ca<<7)+12>>2]|0;V=q+(ca<<7)+16|0;l=c[V>>2]|0;if((j|0)==32768){W=0-l<<7;T=l<<7}else{W=O(l,j+128|0)|0;T=O(l,128-j|0)|0}m=c[q+(ca<<7)+52>>2]|0;j=c[ba>>2]|0;n=(m|0)<(j|0);if(n){l=~~+h[(c[ga>>2]|0)+(m<<3)>>3];j=(c[ha>>2]|0)+(m*52|0)|0}else{l=c[Y>>2]|0;j=(c[ia>>2]|0)+((m-j|0)*52|0)|0}S=+(l|0)*428.0/+(c[Z>>2]|0)/o;if(!(S<.001)){if(n&(c[j+44>>2]&32|0)!=0&(i&1|0)==0?(ja=c[fa>>2]|0,p<+(c[ja+(m*52|0)+40>>2]|0)):0)j=ja+(m*52|0)|0;Kk(X,j);K=j+44|0;if(c[K>>2]&4|0?(ma=q+(ca<<7)+56|0,ka=(c[j+40>>2]|0)-(c[j+36>>2]>>((c[na>>2]|0)>>>2&1))+(c[ma>>2]|0)|0,c[ma>>2]=ka,(c[aa>>2]|0)==3):0)c[ma>>2]=ka+-1;l=c[e>>2]|0;i=l>>3;Q=q+(ca<<7)+64|0;G=(W-(c[Q>>2]|0)|0)/(i|0)|0;R=q+(ca<<7)+68|0;H=(T-(c[R>>2]|0)|0)/(i|0)|0;do if((l|0)>0){I=q+(ca<<7)+56|0;J=q+(ca<<7)+44|0;F=q+(ca<<7)+120|0;L=q+(ca<<7)+124|0;M=q+(ca<<7)+84|0;P=q+(ca<<7)+76|0;D=q+(ca<<7)+72|0;A=~~(S*65536.0);C=T>>8;B=W>>8;z=(H|G|0)==0;E=j+36|0;y=j+40|0;j=0;while(1){x=(a[(c[ea>>2]|0)+((c[X>>2]|0)*464|0)+92>>0]|0)!=0;p=+h[U>>3];o=+(c[I>>2]|0);if(!(p>=o)){w=~~+N(+((o-p)/S));w=(w|0)>(l|0)?l:w;v=w;w=(w|0)>0?0:j}else{v=0;w=1}do if(!(c[V>>2]|0))o=p;else{q=c[J>>2]|0;j=q&7;m=c[f>>2]|0;n=m&4;u=v<<(n>>>2^1);s=(v|0)>0;if(s){if(!n)g=c[r+(u+-2<<2)>>2]|0;t=c[r+(u+-1<<2)>>2]|0}else{t=0;g=0}if((c[F>>2]|0)>253)j=(c[L>>2]|0)==0?q&3:j;j=$+(j<<2)|0;j=d[j>>0]|d[j+1>>0]<<8|d[j+2>>0]<<16|d[j+3>>0]<<24;if(!s){o=p;break}if(!(c[M>>2]|0)){o=p;break}n=(i|0)>(v|0);if(j){Fa[j&31](X,r,v,B,C,A,z?v:n?0:v-i|0,G,H);m=c[f>>2]|0}j=r+(u<<2)|0;u=O(v,G)|0;c[Q>>2]=(c[Q>>2]|0)+u;u=O(v,H)|0;c[R>>2]=(c[R>>2]|0)+u;if(!(m&4))c[P>>2]=(c[j+-8>>2]|0)-g;c[D>>2]=(c[j+-4>>2]|0)-t;o=+h[U>>3];r=j;i=n?i-v|0:0}while(0);o=S*+(v|0)+o;h[U>>3]=o;l=l-w-v|0;j=c[K>>2]|0;m=(j&2|0)==0;if((l|0)<1)break;if(x|m){pa=56;break}Lk(b,X,c[E>>2]|0,c[y>>2]|0,j);j=w}if((pa|0)==56){pa=0;Jk(b,ca,r,l);Mk(b,ca,1);break}if(!m?(la=S+o,la>+(c[I>>2]|0)):0){h[U>>3]=la;Lk(b,X,c[E>>2]|0,c[y>>2]|0,j)}}while(0);c[Q>>2]=W;c[R>>2]=T}}while(0);ca=ca+1|0}while((ca|0)<(c[_>>2]|0))}else{k=b+1540|0;f=b+1516|0;e=b+1548|0}pa=c[f>>2]|0;j=c[e>>2]<<(pa>>>2&1^1);j=(j|0)<24585?j:24585;g=c[b+1536>>2]|0;i=pa&2;e=c[k>>2]|0;f=c[b+1520>>2]|0;if(!(pa&1)){Ok(g,e,j,f,i<<14);pa=b+1556|0;c[pa>>2]=0;b=b+1552|0;c[b>>2]=0;return}else{Nk(g,e,j,f,i<<6);pa=b+1556|0;c[pa>>2]=0;b=b+1552|0;c[b>>2]=0;return}}function Jk(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;h=c[a+972>>2]|0;f=c[a+1548>>2]>>3;i=h+(b<<7)+76|0;g=c[i>>2]|0;h=h+(b<<7)+72|0;b=c[h>>2]|0;c[h>>2]=0;c[i>>2]=0;if(!(b|g))return;if(!d){d=c[a+1540>>2]|0;e=f}else e=(f|0)<(e|0)?f:e;if((e|0)<1)return;i=O(e,e)|0;h=a+1516|0;a=g>>10;f=b>>10;while(1){e=e+-1|0;if(!(c[h>>2]&4)){b=e<<10;g=O(b,(O(e,a)|0)/(i|0)|0)|0;c[d>>2]=g+(c[d>>2]|0);d=d+4|0}else b=e<<10;g=O(b,(O(e,f)|0)/(i|0)|0)|0;c[d>>2]=g+(c[d>>2]|0);if(!e)break;else d=d+4|0}return}function Kk(a,b){a=a|0;b=b|0;var d=0;d=c[b+44>>2]|0;do if(!(d&2))d=b+32|0;else{if(d&16|0?(c[a+80>>2]&4|0)==0:0){d=b+32|0;break}d=b+40|0}while(0);c[a+56>>2]=c[d>>2];return}function Lk(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0.0,i=0.0,j=0,k=0;d=e-d|0;g=+(d|0);k=b+32|0;i=+h[k>>3]-g;h[k>>3]=i;j=b+56|0;c[j>>2]=e;b=b+80|0;c[b>>2]=c[b>>2]|4;if(!(f&4))return;d=d+e|0;c[j>>2]=d;g=i-g;h[k>>3]=g;if((c[a+2856>>2]|0)!=3)return;c[j>>2]=d+-1;h[k>>3]=g+1.0;return}function Mk(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;if((c[a+964>>2]|0)>>>0<=b>>>0)return;f=(c[a+628>>2]|0)+((c[(c[a+972>>2]|0)+(b<<7)>>2]|0)*464|0)+8|0;e=c[f>>2]|0;if(!d){c[f>>2]=e&-33;return}c[f>>2]=e|32;if(!(c[a+2852>>2]&1073741824))return;ei(a,b,0);return}function Nk(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0;h=20-f|0;if(!e)return;i=(g|0)==0;while(1){e=e+-1|0;f=c[d>>2]>>h;f=(f|0)>127?127:((f|0)>-128?f:-128)&255;if(!i)f=(f&255)+g&255;a[b>>0]=f;if(!e)break;else{b=b+1|0;d=d+4|0}}return}function Ok(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0;h=12-f|0;if(!e)return;i=(g|0)==0;while(1){e=e+-1|0;f=c[d>>2]>>h;f=(f|0)>32767?32767:((f|0)>-32768?f:-32768)&65535;if(!i)f=(f&65535)+g&65535;b[a>>1]=f;if(!e)break;else{a=a+2|0;d=d+4|0}}return}function Pk(a,b,d,e){a=a|0;b=b|0;d=+d;e=e|0;var f=0,g=0,i=0,j=0,k=0,l=0,m=0;i=c[a+972>>2]|0;m=i+(b<<7)|0;f=c[i+(b<<7)+52>>2]|0;g=c[a+1712>>2]|0;if((f|0)<(g|0))k=(c[a+1748>>2]|0)+(f*52|0)|0;else k=(c[a+9184>>2]|0)+((f-g|0)*52|0)|0;f=k+44|0;if(c[f>>2]&32768|0)return;j=i+(b<<7)+32|0;h[j>>3]=d;Kk(m,k);i=i+(b<<7)+56|0;g=c[i>>2]|0;f=c[f>>2]|0;if(+h[j>>3]>=+(g|0))h[j>>3]=+(c[((f&2|0)==0?k+32|0:k+36|0)>>2]|0);if(f&4|0?(l=(c[k+40>>2]|0)-(c[k+36>>2]>>((c[a+32>>2]|0)>>>2&1))+g|0,c[i>>2]=l,(c[a+2856>>2]|0)==3):0)c[i>>2]=l+-1;if(!e)return;Qk(m);return}function Qk(a){a=a|0;var b=0;b=a+80|0;c[b>>2]=c[b>>2]|2;c[a+64>>2]=0;c[a+68>>2]=0;return}function Rk(a,b){a=a|0;b=b|0;var d=0.0,e=0.0,f=0,g=0;f=c[a+972>>2]|0;g=Fm(a,c[f+(b<<7)+52>>2]|0)|0;a=c[g+44>>2]|0;if(a&32768|0){e=0.0;return +e}e=+h[f+(b<<7)+32>>3];if(!(a&4))return +e;d=+(c[g+40>>2]|0);if(!(e>=d))return +e;e=d-(e-d)+-1.0;return +e}function Sk(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;f=c[a+972>>2]|0;h=Fm(a,d)|0;c[f+(b<<7)+52>>2]=d;c[f+(b<<7)+16>>2]=0;c[f+(b<<7)+12>>2]=0;g=f+(b<<7)+80|0;c[g>>2]=c[g>>2]&-5;g=f+(b<<7)+44|0;c[g>>2]=0;c[g>>2]=(c[a+1516>>2]|0)>>>1&2^2;Mk(a,b,0);c[f+(b<<7)+84>>2]=c[h+48>>2];f=c[g>>2]|0;d=f|16;c[g>>2]=d;if((c[a+2852>>2]&65536|0)!=0?(c[a+1532>>2]&1|0)!=0:0){d=f|20;c[g>>2]=d}if(!(c[h+44>>2]&1)){Pk(a,b,0.0,e);return}c[g>>2]=d|1;Pk(a,b,0.0,e);return}function Tk(a,b,d){a=a|0;b=b|0;d=d|0;d=(d|0)<149?d:149;c[a+(b<<7)+8>>2]=d;h[a+(b<<7)+24>>3]=+Di(d,0);Qk(a+(b<<7)|0);return}function Uk(a,b,c){a=a|0;b=b|0;c=+c;h[a+(b<<7)+24>>3]=c;return}function Vk(a,b,d){a=a|0;b=b|0;d=d|0;if(!d)Qk(a+(b<<7)|0);c[a+(b<<7)+16>>2]=d;return}function Wk(a,b,d){a=a|0;b=b|0;d=d|0;b=a+(b<<7)+80|0;a=c[b>>2]|0;c[b>>2]=d|0?a|1:a&-2;return}function Xk(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;switch(d|0){case 2:{a=a+(b<<7)+120|0;break}case 3:{a=a+(b<<7)+124|0;break}case 176:{a=a+(b<<7)+108|0;break}case 177:{a=a+(b<<7)+112|0;break}case 178:{a=a+(b<<7)+116|0;break}default:return}c[a>>2]=e;return}function Yk(a,b,d){a=a|0;b=b|0;d=d|0;c[a+(b<<7)+12>>2]=d;return}function Zk(a,b){a=a|0;b=b|0;return ((b|0)<0|(a|0)<(b|0)?a:b)|0}function _k(a,b){a=a|0;b=b|0;var d=0,e=0;d=Xm(2,24585)|0;c[a+1536>>2]=d;if(!d){b=-1;return b|0}e=Xm(4,24585)|0;c[a+1540>>2]=e;if(!e){Wm(d);e=-1;return e|0}else{c[a+1512>>2]=b;c[a+1516>>2]=0;c[a+1520>>2]=1;c[a+1524>>2]=100;c[a+1528>>2]=1;c[a+1532>>2]=1;c[a+1556>>2]=0;c[a+1552>>2]=0;e=0;return e|0}return 0}function $k(a){a=a|0;var b=0;b=a+1536|0;Wm(c[b>>2]|0);a=a+1540|0;Wm(c[a>>2]|0);c[a>>2]=0;c[b>>2]=0;return}function al(b,d,e,f,g,i,j,k,l){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0.0,n=0;n=c[b+84>>2]|0;m=+h[b+32>>3];if(!e)return;b=f<<8;g=d;j=~~((m-+(~~m|0))*65536.0);l=~~m>>>0;while(1){k=O(b,a[n+l>>0]|0)|0;c[g>>2]=k+(c[g>>2]|0);k=j+i|0;e=e+-1|0;if(!e)break;else{g=g+4|0;j=k&65535;l=(k>>16)+l|0}}return}function bl(a,d,e,f,g,i,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0.0,n=0;n=c[a+84>>2]|0;m=+h[a+32>>3];if(!e)return;g=d;j=~~((m-+(~~m|0))*65536.0);l=~~m>>>0;while(1){k=O(b[n+(l<<1)>>1]|0,f)|0;c[g>>2]=k+(c[g>>2]|0);k=j+i|0;e=e+-1|0;if(!e)break;else{g=g+4|0;j=k&65535;l=(k>>16)+l|0}}return}function cl(b,d,e,f,g,i,j,k,l){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0.0,n=0,o=0;n=c[b+84>>2]|0;m=+h[b+32>>3];if(!e)return;j=e;b=~~((m-+(~~m|0))*65536.0);l=~~m>>>0;while(1){e=a[n+l>>0]<<8;o=O(e,g)|0;k=d+4|0;c[d>>2]=o+(c[d>>2]|0);e=O(e,f)|0;c[k>>2]=(c[k>>2]|0)+e;k=b+i|0;j=j+-1|0;if(!j)break;else{d=d+8|0;b=k&65535;l=(k>>16)+l|0}}return}function dl(a,d,e,f,g,i,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0.0,n=0,o=0;n=c[a+84>>2]|0;m=+h[a+32>>3];if(!e)return;j=e;a=~~((m-+(~~m|0))*65536.0);l=~~m>>>0;while(1){e=b[n+(l<<1)>>1]|0;o=O(e,g)|0;k=d+4|0;c[d>>2]=o+(c[d>>2]|0);e=O(e,f)|0;c[k>>2]=(c[k>>2]|0)+e;k=a+i|0;j=j+-1|0;if(!j)break;else{d=d+8|0;a=k&65535;l=(k>>16)+l|0}}return}function el(b,d,e,f,g,i,j,k,l){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0.0;p=c[b+84>>2]|0;q=+h[b+32>>3];g=~~q>>>0;m=~~((q-+(~~q|0))*65536.0);if((e|0)>(j|0)){n=d;o=e;l=c[b+64>>2]|0;while(1){b=a[p+g>>0]<<8;b=O(((O((a[p+(g+1)>>0]<<8)-b|0,m>>1)|0)>>15)+b|0,l>>8)|0;c[n>>2]=b+(c[n>>2]|0);b=m+i|0;g=(b>>16)+g|0;m=b&65535;o=o+-1|0;if((o|0)<=(j|0))break;else{n=n+4|0;l=l+k|0}}d=d+(e-j<<2)|0;e=j}if(!e)return;while(1){l=a[p+g>>0]<<8;l=O(((O((a[p+(g+1)>>0]<<8)-l|0,m>>1)|0)>>15)+l|0,f)|0;c[d>>2]=l+(c[d>>2]|0);l=m+i|0;e=e+-1|0;if(!e)break;else{d=d+4|0;m=l&65535;g=(l>>16)+g|0}}return}function fl(a,d,e,f,g,i,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0.0;p=c[a+84>>2]|0;q=+h[a+32>>3];g=~~q>>>0;m=~~((q-+(~~q|0))*65536.0);if((e|0)>(j|0)){n=d;o=e;l=c[a+64>>2]|0;while(1){a=b[p+(g<<1)>>1]|0;a=O(((O((b[p+(g+1<<1)>>1]|0)-a|0,m>>1)|0)>>15)+a|0,l>>8)|0;c[n>>2]=a+(c[n>>2]|0);a=m+i|0;g=(a>>16)+g|0;m=a&65535;o=o+-1|0;if((o|0)<=(j|0))break;else{n=n+4|0;l=l+k|0}}d=d+(e-j<<2)|0;e=j}if(!e)return;while(1){l=b[p+(g<<1)>>1]|0;l=O(((O((b[p+(g+1<<1)>>1]|0)-l|0,m>>1)|0)>>15)+l|0,f)|0;c[d>>2]=l+(c[d>>2]|0);l=m+i|0;e=e+-1|0;if(!e)break;else{d=d+4|0;m=l&65535;g=(l>>16)+g|0}}return}function gl(b,d,e,f,g,i,j,k,l){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0.0,t=0,u=0,v=0;r=c[b+84>>2]|0;s=+h[b+32>>3];m=~~s>>>0;n=~~((s-+(~~s|0))*65536.0);if((e|0)>(j|0)){p=e-j|0;q=d;o=c[b+64>>2]|0;b=c[b+68>>2]|0;while(1){u=a[r+m>>0]<<8;u=((O((a[r+(m+1)>>0]<<8)-u|0,n>>1)|0)>>15)+u|0;v=O(u,b>>8)|0;t=q+4|0;c[q>>2]=v+(c[q>>2]|0);u=O(u,o>>8)|0;c[t>>2]=u+(c[t>>2]|0);t=n+i|0;m=(t>>16)+m|0;n=t&65535;e=e+-1|0;if((e|0)<=(j|0))break;else{q=q+8|0;o=o+k|0;b=b+l|0}}d=d+(p<<1<<2)|0;e=j}if(!e)return;while(1){v=a[r+m>>0]<<8;v=((O((a[r+(m+1)>>0]<<8)-v|0,n>>1)|0)>>15)+v|0;u=O(v,g)|0;b=d+4|0;c[d>>2]=u+(c[d>>2]|0);v=O(v,f)|0;c[b>>2]=v+(c[b>>2]|0);b=n+i|0;e=e+-1|0;if(!e)break;else{d=d+8|0;n=b&65535;m=(b>>16)+m|0}}return}function hl(a,d,e,f,g,i,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0.0,t=0,u=0,v=0;r=c[a+84>>2]|0;s=+h[a+32>>3];m=~~s>>>0;n=~~((s-+(~~s|0))*65536.0);if((e|0)>(j|0)){p=e-j|0;q=d;o=c[a+64>>2]|0;a=c[a+68>>2]|0;while(1){u=b[r+(m<<1)>>1]|0;u=((O((b[r+(m+1<<1)>>1]|0)-u|0,n>>1)|0)>>15)+u|0;v=O(u,a>>8)|0;t=q+4|0;c[q>>2]=v+(c[q>>2]|0);u=O(u,o>>8)|0;c[t>>2]=u+(c[t>>2]|0);t=n+i|0;m=(t>>16)+m|0;n=t&65535;e=e+-1|0;if((e|0)<=(j|0))break;else{q=q+8|0;o=o+k|0;a=a+l|0}}d=d+(p<<1<<2)|0;e=j}if(!e)return;while(1){v=b[r+(m<<1)>>1]|0;v=((O((b[r+(m+1<<1)>>1]|0)-v|0,n>>1)|0)>>15)+v|0;u=O(v,g)|0;a=d+4|0;c[d>>2]=u+(c[d>>2]|0);v=O(v,f)|0;c[a>>2]=v+(c[a>>2]|0);a=n+i|0;e=e+-1|0;if(!e)break;else{d=d+8|0;n=a&65535;m=(a>>16)+m|0}}return}function il(b,d,e,f,g,i,j,k,l){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0.0,C=0,D=0,E=0;t=c[b+84>>2]|0;B=+h[b+32>>3];m=~~B>>>0;n=~~((B-+(~~B|0))*65536.0);y=b+100|0;l=c[y>>2]|0;A=b+104|0;g=c[A>>2]|0;r=c[b+108>>2]|0;s=((r|0)<0)<<31>>31;w=c[b+112>>2]|0;x=((w|0)<0)<<31>>31;u=c[b+116>>2]|0;v=((u|0)<0)<<31>>31;if((e|0)>(j|0)){o=d;p=e;q=l;b=c[b+64>>2]|0;while(1){C=a[t+m>>0]<<8;C=((O((a[t+(m+1)>>0]<<8)-C|0,n>>1)|0)>>15)+C|0;l=b>>8;l=Wo(l|0,((l|0)<0)<<31>>31|0,r|0,s|0)|0;C=Wo(l|0,z|0,C|0,((C|0)<0)<<31>>31|0)|0;l=z;E=Wo(q|0,((q|0)<0)<<31>>31|0,w|0,x|0)|0;D=z;g=Wo(g|0,((g|0)<0)<<31>>31|0,u|0,v|0)|0;g=Xo(g|0,z|0,E|0,D|0)|0;l=Xo(g|0,z|0,C|0,l|0)|0;l=bp(l|0,z|0,16)|0;c[o>>2]=l+(c[o>>2]|0);g=n+i|0;m=m+(g>>16)|0;n=g&65535;p=p+-1|0;if((p|0)<=(j|0))break;else{g=q;o=o+4|0;q=l;b=b+k|0}}d=d+(e-j<<2)|0;e=j;g=q}if(!e){D=l;E=g;c[y>>2]=D;c[A>>2]=E;return}o=Wo(r|0,s|0,f|0,((f|0)<0)<<31>>31|0)|0;p=z;while(1){E=a[t+m>>0]<<8;E=((O((a[t+(m+1)>>0]<<8)-E|0,n>>1)|0)>>15)+E|0;E=Wo(o|0,p|0,E|0,((E|0)<0)<<31>>31|0)|0;b=z;C=Wo(l|0,((l|0)<0)<<31>>31|0,w|0,x|0)|0;D=z;g=Wo(g|0,((g|0)<0)<<31>>31|0,u|0,v|0)|0;g=Xo(g|0,z|0,C|0,D|0)|0;g=Xo(g|0,z|0,E|0,b|0)|0;g=bp(g|0,z|0,16)|0;c[d>>2]=g+(c[d>>2]|0);b=n+i|0;e=e+-1|0;if(!e)break;else{E=l;d=d+4|0;l=g;n=b&65535;m=m+(b>>16)|0;g=E}}c[y>>2]=g;c[A>>2]=l;return}function jl(a,d,e,f,g,i,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0.0,C=0,D=0,E=0;t=c[a+84>>2]|0;B=+h[a+32>>3];m=~~B>>>0;n=~~((B-+(~~B|0))*65536.0);y=a+100|0;l=c[y>>2]|0;A=a+104|0;g=c[A>>2]|0;r=c[a+108>>2]|0;s=((r|0)<0)<<31>>31;w=c[a+112>>2]|0;x=((w|0)<0)<<31>>31;u=c[a+116>>2]|0;v=((u|0)<0)<<31>>31;if((e|0)>(j|0)){o=d;p=e;q=l;a=c[a+64>>2]|0;while(1){C=b[t+(m<<1)>>1]|0;C=((O((b[t+(m+1<<1)>>1]|0)-C|0,n>>1)|0)>>15)+C|0;l=a>>8;l=Wo(l|0,((l|0)<0)<<31>>31|0,r|0,s|0)|0;C=Wo(l|0,z|0,C|0,((C|0)<0)<<31>>31|0)|0;l=z;E=Wo(q|0,((q|0)<0)<<31>>31|0,w|0,x|0)|0;D=z;g=Wo(g|0,((g|0)<0)<<31>>31|0,u|0,v|0)|0;g=Xo(g|0,z|0,E|0,D|0)|0;l=Xo(g|0,z|0,C|0,l|0)|0;l=bp(l|0,z|0,16)|0;c[o>>2]=l+(c[o>>2]|0);g=n+i|0;m=m+(g>>16)|0;n=g&65535;p=p+-1|0;if((p|0)<=(j|0))break;else{g=q;o=o+4|0;q=l;a=a+k|0}}d=d+(e-j<<2)|0;e=j;g=q}if(!e){D=l;E=g;c[y>>2]=D;c[A>>2]=E;return}o=Wo(r|0,s|0,f|0,((f|0)<0)<<31>>31|0)|0;p=z;while(1){E=b[t+(m<<1)>>1]|0;E=((O((b[t+(m+1<<1)>>1]|0)-E|0,n>>1)|0)>>15)+E|0;E=Wo(o|0,p|0,E|0,((E|0)<0)<<31>>31|0)|0;a=z;C=Wo(l|0,((l|0)<0)<<31>>31|0,w|0,x|0)|0;D=z;g=Wo(g|0,((g|0)<0)<<31>>31|0,u|0,v|0)|0;g=Xo(g|0,z|0,C|0,D|0)|0;g=Xo(g|0,z|0,E|0,a|0)|0;g=bp(g|0,z|0,16)|0;c[d>>2]=g+(c[d>>2]|0);a=n+i|0;e=e+-1|0;if(!e)break;else{E=l;d=d+4|0;l=g;n=a&65535;m=m+(a>>16)|0;g=E}}c[y>>2]=g;c[A>>2]=l;return}function kl(b,d,e,f,g,i,j,k,l){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0.0,K=0,L=0,M=0,N=0,P=0;x=c[b+84>>2]|0;J=+h[b+32>>3];q=~~J>>>0;r=~~((J-+(~~J|0))*65536.0);F=b+100|0;o=c[F>>2]|0;G=b+104|0;p=c[G>>2]|0;B=c[b+108>>2]|0;C=((B|0)<0)<<31>>31;D=c[b+112>>2]|0;E=((D|0)<0)<<31>>31;y=c[b+116>>2]|0;A=((y|0)<0)<<31>>31;H=b+92|0;m=c[H>>2]|0;I=b+96|0;n=c[I>>2]|0;if((e|0)>(j|0)){t=e-j|0;u=d;v=o;o=p;w=m;s=c[b+64>>2]|0;p=c[b+68>>2]|0;while(1){K=a[x+q>>0]<<8;K=((O((a[x+(q+1)>>0]<<8)-K|0,r>>1)|0)>>15)+K|0;M=p>>8;b=s>>8;K=Wo(K|0,((K|0)<0)<<31>>31|0,B|0,C|0)|0;L=z;M=Wo(K|0,L|0,M|0,((M|0)<0)<<31>>31|0)|0;m=z;P=Wo(w|0,((w|0)<0)<<31>>31|0,D|0,E|0)|0;N=z;n=Wo(n|0,((n|0)<0)<<31>>31|0,y|0,A|0)|0;n=Xo(n|0,z|0,P|0,N|0)|0;m=Xo(n|0,z|0,M|0,m|0)|0;m=bp(m|0,z|0,16)|0;n=Wo(K|0,L|0,b|0,((b|0)<0)<<31>>31|0)|0;b=z;L=Wo(v|0,((v|0)<0)<<31>>31|0,D|0,E|0)|0;K=z;o=Wo(o|0,((o|0)<0)<<31>>31|0,y|0,A|0)|0;o=Xo(o|0,z|0,L|0,K|0)|0;o=Xo(o|0,z|0,n|0,b|0)|0;o=bp(o|0,z|0,16)|0;b=u+4|0;c[u>>2]=m+(c[u>>2]|0);c[b>>2]=o+(c[b>>2]|0);b=r+i|0;q=(b>>16)+q|0;r=b&65535;e=e+-1|0;if((e|0)<=(j|0))break;else{n=w;P=v;u=u+8|0;v=o;w=m;s=s+k|0;p=p+l|0;o=P}}d=d+(t<<1<<2)|0;e=j;p=v;n=w}if(!e){L=o;M=p;N=m;P=n;c[F>>2]=L;c[G>>2]=M;c[H>>2]=N;c[I>>2]=P;return}b=((g|0)<0)<<31>>31;t=((f|0)<0)<<31>>31;s=e;e=p;while(1){p=a[x+q>>0]<<8;p=((O((a[x+(q+1)>>0]<<8)-p|0,r>>1)|0)>>15)+p|0;p=Wo(p|0,((p|0)<0)<<31>>31|0,B|0,C|0)|0;P=z;N=Wo(p|0,P|0,g|0,b|0)|0;M=z;K=Wo(m|0,((m|0)<0)<<31>>31|0,D|0,E|0)|0;L=z;n=Wo(n|0,((n|0)<0)<<31>>31|0,y|0,A|0)|0;n=Xo(n|0,z|0,K|0,L|0)|0;n=Xo(n|0,z|0,N|0,M|0)|0;n=bp(n|0,z|0,16)|0;P=Wo(p|0,P|0,f|0,t|0)|0;p=z;M=Wo(o|0,((o|0)<0)<<31>>31|0,D|0,E|0)|0;N=z;e=Wo(e|0,((e|0)<0)<<31>>31|0,y|0,A|0)|0;e=Xo(e|0,z|0,M|0,N|0)|0;e=Xo(e|0,z|0,P|0,p|0)|0;e=bp(e|0,z|0,16)|0;p=d+4|0;c[d>>2]=n+(c[d>>2]|0);c[p>>2]=e+(c[p>>2]|0);p=r+i|0;s=s+-1|0;if(!s)break;else{N=m;P=o;d=d+8|0;o=e;m=n;r=p&65535;q=(p>>16)+q|0;n=N;e=P}}c[F>>2]=e;c[G>>2]=o;c[H>>2]=n;c[I>>2]=m;return} +function ll(a,d,e,f,g,i,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0.0,K=0,L=0,M=0,N=0,P=0;x=c[a+84>>2]|0;J=+h[a+32>>3];q=~~J>>>0;r=~~((J-+(~~J|0))*65536.0);F=a+100|0;o=c[F>>2]|0;G=a+104|0;p=c[G>>2]|0;B=c[a+108>>2]|0;C=((B|0)<0)<<31>>31;D=c[a+112>>2]|0;E=((D|0)<0)<<31>>31;y=c[a+116>>2]|0;A=((y|0)<0)<<31>>31;H=a+92|0;m=c[H>>2]|0;I=a+96|0;n=c[I>>2]|0;if((e|0)>(j|0)){t=e-j|0;u=d;v=o;o=p;w=m;s=c[a+64>>2]|0;p=c[a+68>>2]|0;while(1){K=b[x+(q<<1)>>1]|0;K=((O((b[x+(q+1<<1)>>1]|0)-K|0,r>>1)|0)>>15)+K|0;M=p>>8;a=s>>8;K=Wo(K|0,((K|0)<0)<<31>>31|0,B|0,C|0)|0;L=z;M=Wo(K|0,L|0,M|0,((M|0)<0)<<31>>31|0)|0;m=z;P=Wo(w|0,((w|0)<0)<<31>>31|0,D|0,E|0)|0;N=z;n=Wo(n|0,((n|0)<0)<<31>>31|0,y|0,A|0)|0;n=Xo(n|0,z|0,P|0,N|0)|0;m=Xo(n|0,z|0,M|0,m|0)|0;m=bp(m|0,z|0,16)|0;n=Wo(K|0,L|0,a|0,((a|0)<0)<<31>>31|0)|0;a=z;L=Wo(v|0,((v|0)<0)<<31>>31|0,D|0,E|0)|0;K=z;o=Wo(o|0,((o|0)<0)<<31>>31|0,y|0,A|0)|0;o=Xo(o|0,z|0,L|0,K|0)|0;o=Xo(o|0,z|0,n|0,a|0)|0;o=bp(o|0,z|0,16)|0;a=u+4|0;c[u>>2]=m+(c[u>>2]|0);c[a>>2]=o+(c[a>>2]|0);a=r+i|0;q=(a>>16)+q|0;r=a&65535;e=e+-1|0;if((e|0)<=(j|0))break;else{n=w;P=v;u=u+8|0;v=o;w=m;s=s+k|0;p=p+l|0;o=P}}d=d+(t<<1<<2)|0;e=j;p=v;n=w}if(!e){L=o;M=p;N=m;P=n;c[F>>2]=L;c[G>>2]=M;c[H>>2]=N;c[I>>2]=P;return}a=((g|0)<0)<<31>>31;t=((f|0)<0)<<31>>31;s=e;e=p;while(1){p=b[x+(q<<1)>>1]|0;p=((O((b[x+(q+1<<1)>>1]|0)-p|0,r>>1)|0)>>15)+p|0;p=Wo(p|0,((p|0)<0)<<31>>31|0,B|0,C|0)|0;P=z;N=Wo(p|0,P|0,g|0,a|0)|0;M=z;K=Wo(m|0,((m|0)<0)<<31>>31|0,D|0,E|0)|0;L=z;n=Wo(n|0,((n|0)<0)<<31>>31|0,y|0,A|0)|0;n=Xo(n|0,z|0,K|0,L|0)|0;n=Xo(n|0,z|0,N|0,M|0)|0;n=bp(n|0,z|0,16)|0;P=Wo(p|0,P|0,f|0,t|0)|0;p=z;M=Wo(o|0,((o|0)<0)<<31>>31|0,D|0,E|0)|0;N=z;e=Wo(e|0,((e|0)<0)<<31>>31|0,y|0,A|0)|0;e=Xo(e|0,z|0,M|0,N|0)|0;e=Xo(e|0,z|0,P|0,p|0)|0;e=bp(e|0,z|0,16)|0;p=d+4|0;c[d>>2]=n+(c[d>>2]|0);c[p>>2]=e+(c[p>>2]|0);p=r+i|0;s=s+-1|0;if(!s)break;else{N=m;P=o;d=d+8|0;o=e;m=n;r=p&65535;q=(p>>16)+q|0;n=N;e=P}}c[F>>2]=e;c[G>>2]=o;c[H>>2]=n;c[I>>2]=m;return}function ml(d,e,f,g,i,j,k,l,m){d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0.0,s=0;q=c[d+84>>2]|0;r=+h[d+32>>3];i=~~r>>>0;n=~~((r-+(~~r|0))*65536.0);if((f|0)>(k|0)){o=e;p=f;m=c[d+64>>2]|0;while(1){d=n>>6;s=O(a[q+(i+-1)>>0]|0,b[23412+(d<<1)>>1]|0)|0;s=(O(a[q+i>>0]|0,b[25460+(d<<1)>>1]|0)|0)+s|0;s=s+(O(a[q+(i+2)>>0]|0,b[27508+(d<<1)>>1]|0)|0)|0;d=O(s+(O(a[q+(i+1)>>0]|0,b[29556+(d<<1)>>1]|0)|0)>>6,m>>8)|0;c[o>>2]=d+(c[o>>2]|0);d=n+j|0;i=(d>>16)+i|0;n=d&65535;p=p+-1|0;if((p|0)<=(k|0))break;else{o=o+4|0;m=m+l|0}}e=e+(f-k<<2)|0;f=k}if(!f)return;while(1){m=n>>6;s=O(a[q+(i+-1)>>0]|0,b[23412+(m<<1)>>1]|0)|0;s=(O(a[q+i>>0]|0,b[25460+(m<<1)>>1]|0)|0)+s|0;s=s+(O(a[q+(i+2)>>0]|0,b[27508+(m<<1)>>1]|0)|0)|0;m=O(s+(O(a[q+(i+1)>>0]|0,b[29556+(m<<1)>>1]|0)|0)>>6,g)|0;c[e>>2]=m+(c[e>>2]|0);m=n+j|0;f=f+-1|0;if(!f)break;else{e=e+4|0;n=m&65535;i=(m>>16)+i|0}}return}function nl(a,d,e,f,g,i,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0.0,r=0;p=c[a+84>>2]|0;q=+h[a+32>>3];g=~~q>>>0;m=~~((q-+(~~q|0))*65536.0);if((e|0)>(j|0)){n=d;o=e;l=c[a+64>>2]|0;while(1){a=m>>6;r=O(b[p+(g+-1<<1)>>1]|0,b[23412+(a<<1)>>1]|0)|0;r=(O(b[p+(g<<1)>>1]|0,b[25460+(a<<1)>>1]|0)|0)+r|0;r=r+(O(b[p+(g+2<<1)>>1]|0,b[27508+(a<<1)>>1]|0)|0)|0;a=O(r+(O(b[p+(g+1<<1)>>1]|0,b[29556+(a<<1)>>1]|0)|0)>>14,l>>8)|0;c[n>>2]=a+(c[n>>2]|0);a=m+i|0;g=(a>>16)+g|0;m=a&65535;o=o+-1|0;if((o|0)<=(j|0))break;else{n=n+4|0;l=l+k|0}}d=d+(e-j<<2)|0;e=j}if(!e)return;while(1){l=m>>6;r=O(b[p+(g+-1<<1)>>1]|0,b[23412+(l<<1)>>1]|0)|0;r=(O(b[p+(g<<1)>>1]|0,b[25460+(l<<1)>>1]|0)|0)+r|0;r=r+(O(b[p+(g+2<<1)>>1]|0,b[27508+(l<<1)>>1]|0)|0)|0;l=O(r+(O(b[p+(g+1<<1)>>1]|0,b[29556+(l<<1)>>1]|0)|0)>>14,f)|0;c[d>>2]=l+(c[d>>2]|0);l=m+i|0;e=e+-1|0;if(!e)break;else{d=d+4|0;m=l&65535;g=(l>>16)+g|0}}return}function ol(d,e,f,g,i,j,k,l,m){d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0.0,u=0,v=0,w=0;s=c[d+84>>2]|0;t=+h[d+32>>3];n=~~t>>>0;o=~~((t-+(~~t|0))*65536.0);if((f|0)>(k|0)){q=f-k|0;r=e;p=c[d+64>>2]|0;d=c[d+68>>2]|0;while(1){v=o>>6;w=O(a[s+(n+-1)>>0]|0,b[23412+(v<<1)>>1]|0)|0;w=(O(a[s+n>>0]|0,b[25460+(v<<1)>>1]|0)|0)+w|0;w=w+(O(a[s+(n+2)>>0]|0,b[27508+(v<<1)>>1]|0)|0)|0;v=w+(O(a[s+(n+1)>>0]|0,b[29556+(v<<1)>>1]|0)|0)>>6;w=O(v,d>>8)|0;u=r+4|0;c[r>>2]=w+(c[r>>2]|0);v=O(v,p>>8)|0;c[u>>2]=v+(c[u>>2]|0);u=o+j|0;n=(u>>16)+n|0;o=u&65535;f=f+-1|0;if((f|0)<=(k|0))break;else{r=r+8|0;p=p+l|0;d=d+m|0}}e=e+(q<<1<<2)|0;f=k}if(!f)return;while(1){w=o>>6;v=O(a[s+(n+-1)>>0]|0,b[23412+(w<<1)>>1]|0)|0;v=(O(a[s+n>>0]|0,b[25460+(w<<1)>>1]|0)|0)+v|0;v=v+(O(a[s+(n+2)>>0]|0,b[27508+(w<<1)>>1]|0)|0)|0;w=v+(O(a[s+(n+1)>>0]|0,b[29556+(w<<1)>>1]|0)|0)>>6;v=O(w,i)|0;d=e+4|0;c[e>>2]=v+(c[e>>2]|0);w=O(w,g)|0;c[d>>2]=w+(c[d>>2]|0);d=o+j|0;f=f+-1|0;if(!f)break;else{e=e+8|0;o=d&65535;n=(d>>16)+n|0}}return}function pl(a,d,e,f,g,i,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0.0,t=0,u=0,v=0;r=c[a+84>>2]|0;s=+h[a+32>>3];m=~~s>>>0;n=~~((s-+(~~s|0))*65536.0);if((e|0)>(j|0)){p=e-j|0;q=d;o=c[a+64>>2]|0;a=c[a+68>>2]|0;while(1){u=n>>6;v=O(b[r+(m+-1<<1)>>1]|0,b[23412+(u<<1)>>1]|0)|0;v=(O(b[r+(m<<1)>>1]|0,b[25460+(u<<1)>>1]|0)|0)+v|0;v=v+(O(b[r+(m+2<<1)>>1]|0,b[27508+(u<<1)>>1]|0)|0)|0;u=v+(O(b[r+(m+1<<1)>>1]|0,b[29556+(u<<1)>>1]|0)|0)>>14;v=O(u,a>>8)|0;t=q+4|0;c[q>>2]=v+(c[q>>2]|0);u=O(u,o>>8)|0;c[t>>2]=u+(c[t>>2]|0);t=n+i|0;m=(t>>16)+m|0;n=t&65535;e=e+-1|0;if((e|0)<=(j|0))break;else{q=q+8|0;o=o+k|0;a=a+l|0}}d=d+(p<<1<<2)|0;e=j}if(!e)return;while(1){v=n>>6;u=O(b[r+(m+-1<<1)>>1]|0,b[23412+(v<<1)>>1]|0)|0;u=(O(b[r+(m<<1)>>1]|0,b[25460+(v<<1)>>1]|0)|0)+u|0;u=u+(O(b[r+(m+2<<1)>>1]|0,b[27508+(v<<1)>>1]|0)|0)|0;v=u+(O(b[r+(m+1<<1)>>1]|0,b[29556+(v<<1)>>1]|0)|0)>>14;u=O(v,g)|0;a=d+4|0;c[d>>2]=u+(c[d>>2]|0);v=O(v,f)|0;c[a>>2]=v+(c[a>>2]|0);a=n+i|0;e=e+-1|0;if(!e)break;else{d=d+8|0;n=a&65535;m=(a>>16)+m|0}}return}function ql(d,e,f,g,i,j,k,l,m){d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0.0,D=0,E=0,F=0;u=c[d+84>>2]|0;C=+h[d+32>>3];n=~~C>>>0;o=~~((C-+(~~C|0))*65536.0);A=d+100|0;m=c[A>>2]|0;B=d+104|0;i=c[B>>2]|0;s=c[d+108>>2]|0;t=((s|0)<0)<<31>>31;x=c[d+112>>2]|0;y=((x|0)<0)<<31>>31;v=c[d+116>>2]|0;w=((v|0)<0)<<31>>31;if((f|0)>(k|0)){p=e;q=f;r=m;d=c[d+64>>2]|0;while(1){D=o>>6;m=O(a[u+(n+-1)>>0]|0,b[23412+(D<<1)>>1]|0)|0;m=(O(a[u+n>>0]|0,b[25460+(D<<1)>>1]|0)|0)+m|0;m=m+(O(a[u+(n+2)>>0]|0,b[27508+(D<<1)>>1]|0)|0)|0;D=m+(O(a[u+(n+1)>>0]|0,b[29556+(D<<1)>>1]|0)|0)>>6;m=d>>8;m=Wo(m|0,((m|0)<0)<<31>>31|0,s|0,t|0)|0;D=Wo(m|0,z|0,D|0,((D|0)<0)<<31>>31|0)|0;m=z;F=Wo(r|0,((r|0)<0)<<31>>31|0,x|0,y|0)|0;E=z;i=Wo(i|0,((i|0)<0)<<31>>31|0,v|0,w|0)|0;i=Xo(i|0,z|0,F|0,E|0)|0;m=Xo(i|0,z|0,D|0,m|0)|0;m=bp(m|0,z|0,16)|0;c[p>>2]=m+(c[p>>2]|0);i=o+j|0;n=(i>>16)+n|0;o=i&65535;q=q+-1|0;if((q|0)<=(k|0))break;else{i=r;p=p+4|0;r=m;d=d+l|0}}e=e+(f-k<<2)|0;f=k;i=r}if(!f){E=m;F=i;c[A>>2]=E;c[B>>2]=F;return}p=Wo(s|0,t|0,g|0,((g|0)<0)<<31>>31|0)|0;q=z;while(1){F=o>>6;d=O(a[u+(n+-1)>>0]|0,b[23412+(F<<1)>>1]|0)|0;d=(O(a[u+n>>0]|0,b[25460+(F<<1)>>1]|0)|0)+d|0;d=d+(O(a[u+(n+2)>>0]|0,b[27508+(F<<1)>>1]|0)|0)|0;F=d+(O(a[u+(n+1)>>0]|0,b[29556+(F<<1)>>1]|0)|0)>>6;F=Wo(p|0,q|0,F|0,((F|0)<0)<<31>>31|0)|0;d=z;D=Wo(m|0,((m|0)<0)<<31>>31|0,x|0,y|0)|0;E=z;i=Wo(i|0,((i|0)<0)<<31>>31|0,v|0,w|0)|0;i=Xo(i|0,z|0,D|0,E|0)|0;i=Xo(i|0,z|0,F|0,d|0)|0;i=bp(i|0,z|0,16)|0;c[e>>2]=i+(c[e>>2]|0);d=o+j|0;f=f+-1|0;if(!f)break;else{F=m;e=e+4|0;m=i;o=d&65535;n=(d>>16)+n|0;i=F}}c[A>>2]=i;c[B>>2]=m;return}function rl(a,d,e,f,g,i,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0.0,C=0,D=0,E=0;t=c[a+84>>2]|0;B=+h[a+32>>3];m=~~B>>>0;n=~~((B-+(~~B|0))*65536.0);y=a+100|0;l=c[y>>2]|0;A=a+104|0;g=c[A>>2]|0;r=c[a+108>>2]|0;s=((r|0)<0)<<31>>31;w=c[a+112>>2]|0;x=((w|0)<0)<<31>>31;u=c[a+116>>2]|0;v=((u|0)<0)<<31>>31;if((e|0)>(j|0)){o=d;p=e;q=l;a=c[a+64>>2]|0;while(1){C=n>>6;l=O(b[t+(m+-1<<1)>>1]|0,b[23412+(C<<1)>>1]|0)|0;l=(O(b[t+(m<<1)>>1]|0,b[25460+(C<<1)>>1]|0)|0)+l|0;l=l+(O(b[t+(m+2<<1)>>1]|0,b[27508+(C<<1)>>1]|0)|0)|0;C=l+(O(b[t+(m+1<<1)>>1]|0,b[29556+(C<<1)>>1]|0)|0)>>14;l=a>>8;l=Wo(l|0,((l|0)<0)<<31>>31|0,r|0,s|0)|0;C=Wo(l|0,z|0,C|0,((C|0)<0)<<31>>31|0)|0;l=z;E=Wo(q|0,((q|0)<0)<<31>>31|0,w|0,x|0)|0;D=z;g=Wo(g|0,((g|0)<0)<<31>>31|0,u|0,v|0)|0;g=Xo(g|0,z|0,E|0,D|0)|0;l=Xo(g|0,z|0,C|0,l|0)|0;l=bp(l|0,z|0,16)|0;c[o>>2]=l+(c[o>>2]|0);g=n+i|0;m=(g>>16)+m|0;n=g&65535;p=p+-1|0;if((p|0)<=(j|0))break;else{g=q;o=o+4|0;q=l;a=a+k|0}}d=d+(e-j<<2)|0;e=j;g=q}if(!e){D=l;E=g;c[y>>2]=D;c[A>>2]=E;return}o=Wo(r|0,s|0,f|0,((f|0)<0)<<31>>31|0)|0;p=z;while(1){E=n>>6;a=O(b[t+(m+-1<<1)>>1]|0,b[23412+(E<<1)>>1]|0)|0;a=(O(b[t+(m<<1)>>1]|0,b[25460+(E<<1)>>1]|0)|0)+a|0;a=a+(O(b[t+(m+2<<1)>>1]|0,b[27508+(E<<1)>>1]|0)|0)|0;E=a+(O(b[t+(m+1<<1)>>1]|0,b[29556+(E<<1)>>1]|0)|0)>>14;E=Wo(o|0,p|0,E|0,((E|0)<0)<<31>>31|0)|0;a=z;C=Wo(l|0,((l|0)<0)<<31>>31|0,w|0,x|0)|0;D=z;g=Wo(g|0,((g|0)<0)<<31>>31|0,u|0,v|0)|0;g=Xo(g|0,z|0,C|0,D|0)|0;g=Xo(g|0,z|0,E|0,a|0)|0;g=bp(g|0,z|0,16)|0;c[d>>2]=g+(c[d>>2]|0);a=n+i|0;e=e+-1|0;if(!e)break;else{E=l;d=d+4|0;l=g;n=a&65535;m=(a>>16)+m|0;g=E}}c[y>>2]=g;c[A>>2]=l;return}function sl(d,e,f,g,i,j,k,l,m){d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0.0,L=0,M=0,N=0,P=0,Q=0;y=c[d+84>>2]|0;K=+h[d+32>>3];r=~~K>>>0;s=~~((K-+(~~K|0))*65536.0);G=d+100|0;p=c[G>>2]|0;H=d+104|0;q=c[H>>2]|0;C=c[d+108>>2]|0;D=((C|0)<0)<<31>>31;E=c[d+112>>2]|0;F=((E|0)<0)<<31>>31;A=c[d+116>>2]|0;B=((A|0)<0)<<31>>31;I=d+92|0;n=c[I>>2]|0;J=d+96|0;o=c[J>>2]|0;if((f|0)>(k|0)){u=f-k|0;v=e;w=p;p=q;x=n;t=c[d+64>>2]|0;q=c[d+68>>2]|0;while(1){L=s>>6;N=O(a[y+(r+-1)>>0]|0,b[23412+(L<<1)>>1]|0)|0;N=(O(a[y+r>>0]|0,b[25460+(L<<1)>>1]|0)|0)+N|0;N=N+(O(a[y+(r+2)>>0]|0,b[27508+(L<<1)>>1]|0)|0)|0;L=N+(O(a[y+(r+1)>>0]|0,b[29556+(L<<1)>>1]|0)|0)>>6;N=q>>8;d=t>>8;L=Wo(L|0,((L|0)<0)<<31>>31|0,C|0,D|0)|0;M=z;N=Wo(L|0,M|0,N|0,((N|0)<0)<<31>>31|0)|0;n=z;Q=Wo(x|0,((x|0)<0)<<31>>31|0,E|0,F|0)|0;P=z;o=Wo(o|0,((o|0)<0)<<31>>31|0,A|0,B|0)|0;o=Xo(o|0,z|0,Q|0,P|0)|0;n=Xo(o|0,z|0,N|0,n|0)|0;n=bp(n|0,z|0,16)|0;o=Wo(L|0,M|0,d|0,((d|0)<0)<<31>>31|0)|0;d=z;M=Wo(w|0,((w|0)<0)<<31>>31|0,E|0,F|0)|0;L=z;p=Wo(p|0,((p|0)<0)<<31>>31|0,A|0,B|0)|0;p=Xo(p|0,z|0,M|0,L|0)|0;p=Xo(p|0,z|0,o|0,d|0)|0;p=bp(p|0,z|0,16)|0;d=v+4|0;c[v>>2]=n+(c[v>>2]|0);c[d>>2]=p+(c[d>>2]|0);d=s+j|0;r=(d>>16)+r|0;s=d&65535;f=f+-1|0;if((f|0)<=(k|0))break;else{o=x;Q=w;v=v+8|0;w=p;x=n;t=t+l|0;q=q+m|0;p=Q}}e=e+(u<<1<<2)|0;f=k;q=w;o=x}if(!f){M=p;N=q;P=n;Q=o;c[G>>2]=M;c[H>>2]=N;c[I>>2]=P;c[J>>2]=Q;return}d=((i|0)<0)<<31>>31;u=((g|0)<0)<<31>>31;t=f;f=q;while(1){q=s>>6;Q=O(a[y+(r+-1)>>0]|0,b[23412+(q<<1)>>1]|0)|0;Q=(O(a[y+r>>0]|0,b[25460+(q<<1)>>1]|0)|0)+Q|0;Q=Q+(O(a[y+(r+2)>>0]|0,b[27508+(q<<1)>>1]|0)|0)|0;q=Q+(O(a[y+(r+1)>>0]|0,b[29556+(q<<1)>>1]|0)|0)>>6;q=Wo(q|0,((q|0)<0)<<31>>31|0,C|0,D|0)|0;Q=z;P=Wo(q|0,Q|0,i|0,d|0)|0;N=z;L=Wo(n|0,((n|0)<0)<<31>>31|0,E|0,F|0)|0;M=z;o=Wo(o|0,((o|0)<0)<<31>>31|0,A|0,B|0)|0;o=Xo(o|0,z|0,L|0,M|0)|0;o=Xo(o|0,z|0,P|0,N|0)|0;o=bp(o|0,z|0,16)|0;Q=Wo(q|0,Q|0,g|0,u|0)|0;q=z;N=Wo(p|0,((p|0)<0)<<31>>31|0,E|0,F|0)|0;P=z;f=Wo(f|0,((f|0)<0)<<31>>31|0,A|0,B|0)|0;f=Xo(f|0,z|0,N|0,P|0)|0;f=Xo(f|0,z|0,Q|0,q|0)|0;f=bp(f|0,z|0,16)|0;q=e+4|0;c[e>>2]=o+(c[e>>2]|0);c[q>>2]=f+(c[q>>2]|0);q=s+j|0;t=t+-1|0;if(!t)break;else{P=n;Q=p;e=e+8|0;p=f;n=o;s=q&65535;r=(q>>16)+r|0;o=P;f=Q}}c[G>>2]=f;c[H>>2]=p;c[I>>2]=o;c[J>>2]=n;return}function tl(a,d,e,f,g,i,j,k,l){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0.0,K=0,L=0,M=0,N=0,P=0;x=c[a+84>>2]|0;J=+h[a+32>>3];q=~~J>>>0;r=~~((J-+(~~J|0))*65536.0);F=a+100|0;o=c[F>>2]|0;G=a+104|0;p=c[G>>2]|0;B=c[a+108>>2]|0;C=((B|0)<0)<<31>>31;D=c[a+112>>2]|0;E=((D|0)<0)<<31>>31;y=c[a+116>>2]|0;A=((y|0)<0)<<31>>31;H=a+92|0;m=c[H>>2]|0;I=a+96|0;n=c[I>>2]|0;if((e|0)>(j|0)){t=e-j|0;u=d;v=o;o=p;w=m;s=c[a+64>>2]|0;p=c[a+68>>2]|0;while(1){K=r>>6;M=O(b[x+(q+-1<<1)>>1]|0,b[23412+(K<<1)>>1]|0)|0;M=(O(b[x+(q<<1)>>1]|0,b[25460+(K<<1)>>1]|0)|0)+M|0;M=M+(O(b[x+(q+2<<1)>>1]|0,b[27508+(K<<1)>>1]|0)|0)|0;K=M+(O(b[x+(q+1<<1)>>1]|0,b[29556+(K<<1)>>1]|0)|0)>>14;M=p>>8;a=s>>8;K=Wo(K|0,((K|0)<0)<<31>>31|0,B|0,C|0)|0;L=z;M=Wo(K|0,L|0,M|0,((M|0)<0)<<31>>31|0)|0;m=z;P=Wo(w|0,((w|0)<0)<<31>>31|0,D|0,E|0)|0;N=z;n=Wo(n|0,((n|0)<0)<<31>>31|0,y|0,A|0)|0;n=Xo(n|0,z|0,P|0,N|0)|0;m=Xo(n|0,z|0,M|0,m|0)|0;m=bp(m|0,z|0,16)|0;n=Wo(K|0,L|0,a|0,((a|0)<0)<<31>>31|0)|0;a=z;L=Wo(v|0,((v|0)<0)<<31>>31|0,D|0,E|0)|0;K=z;o=Wo(o|0,((o|0)<0)<<31>>31|0,y|0,A|0)|0;o=Xo(o|0,z|0,L|0,K|0)|0;o=Xo(o|0,z|0,n|0,a|0)|0;o=bp(o|0,z|0,16)|0;a=u+4|0;c[u>>2]=m+(c[u>>2]|0);c[a>>2]=o+(c[a>>2]|0);a=r+i|0;q=(a>>16)+q|0;r=a&65535;e=e+-1|0;if((e|0)<=(j|0))break;else{n=w;P=v;u=u+8|0;v=o;w=m;s=s+k|0;p=p+l|0;o=P}}d=d+(t<<1<<2)|0;e=j;p=v;n=w}if(!e){L=o;M=p;N=m;P=n;c[F>>2]=L;c[G>>2]=M;c[H>>2]=N;c[I>>2]=P;return}a=((g|0)<0)<<31>>31;t=((f|0)<0)<<31>>31;s=e;e=p;while(1){p=r>>6;P=O(b[x+(q+-1<<1)>>1]|0,b[23412+(p<<1)>>1]|0)|0;P=(O(b[x+(q<<1)>>1]|0,b[25460+(p<<1)>>1]|0)|0)+P|0;P=P+(O(b[x+(q+2<<1)>>1]|0,b[27508+(p<<1)>>1]|0)|0)|0;p=P+(O(b[x+(q+1<<1)>>1]|0,b[29556+(p<<1)>>1]|0)|0)>>14;p=Wo(p|0,((p|0)<0)<<31>>31|0,B|0,C|0)|0;P=z;N=Wo(p|0,P|0,g|0,a|0)|0;M=z;K=Wo(m|0,((m|0)<0)<<31>>31|0,D|0,E|0)|0;L=z;n=Wo(n|0,((n|0)<0)<<31>>31|0,y|0,A|0)|0;n=Xo(n|0,z|0,K|0,L|0)|0;n=Xo(n|0,z|0,N|0,M|0)|0;n=bp(n|0,z|0,16)|0;P=Wo(p|0,P|0,f|0,t|0)|0;p=z;M=Wo(o|0,((o|0)<0)<<31>>31|0,D|0,E|0)|0;N=z;e=Wo(e|0,((e|0)<0)<<31>>31|0,y|0,A|0)|0;e=Xo(e|0,z|0,M|0,N|0)|0;e=Xo(e|0,z|0,P|0,p|0)|0;e=bp(e|0,z|0,16)|0;p=d+4|0;c[d>>2]=n+(c[d>>2]|0);c[p>>2]=e+(c[p>>2]|0);p=r+i|0;s=s+-1|0;if(!s)break;else{N=m;P=o;d=d+8|0;o=e;m=n;r=p&65535;q=(p>>16)+q|0;n=N;e=P}}c[F>>2]=e;c[G>>2]=o;c[H>>2]=n;c[I>>2]=m;return}function ul(b){b=b|0;var c=0,d=0;c=a[b>>0]|0;if(!(c<<24>>24))return b|0;else d=0;while(1){if(c<<24>>24<0|(Qn(c<<24>>24)|0)==0)a[b+d>>0]=32;d=d+1|0;if(d>>>0>=(fo(b)|0)>>>0)break;c=a[b+d>>0]|0}if(!(a[b>>0]|0))return b|0;while(1){c=b+((fo(b)|0)+-1)|0;if((a[c>>0]|0)!=32){c=9;break}a[c>>0]=0;if(!(a[b>>0]|0)){c=9;break}}if((c|0)==9)return b|0;return 0}function vl(a){a=a|0;var b=0,d=0,e=0;gp(a+1568|0,0,1208)|0;h[a+2816>>3]=250.0;c[a+2832>>2]=8287;c[a+2836>>2]=64;c[a+2840>>2]=64;c[a+2844>>2]=64;b=a+2848|0;c[a+2788>>2]=0;c[a+9156>>2]=0;c[a+1696>>2]=0;c[a+1700>>2]=0;c[b>>2]=0;c[b+4>>2]=0;c[b+8>>2]=0;c[b+12>>2]=0;c[a+1704>>2]=4;c[a+1708>>2]=0;c[a+1712>>2]=0;c[a+1716>>2]=6;c[a+1720>>2]=125;c[a+1724>>2]=0;c[a+1728>>2]=0;c[a+9152>>2]=0;c[a+9164>>2]=0;h[a+2824>>3]=10.0;b=a+2868|0;d=0;do{e=d;d=d+1|0;c[a+1752+(e*12|0)>>2]=((O(c[b>>2]|0,((((d|0)/2|0|0)%2|0)*255|0)+-128|0)|0)/100|0)+128;c[a+1752+(e*12|0)+4>>2]=64;c[a+1752+(e*12|0)+8>>2]=0}while((d|0)!=64);return}function wl(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;c[a+1732>>2]=c[a+2844>>2];d=a+1724|0;b=c[d>>2]|0;if((b|0)>=0){if((b|0)>256){b=256;g=3}}else{b=0;g=3}if((g|0)==3)c[d>>2]=b;e=a+1696|0;d=c[e>>2]|0;if((d|0)>=0){if((d|0)>257){d=257;g=6}}else{d=0;g=6}if((g|0)==6)c[e>>2]=d;l=a+1708|0;d=c[l>>2]|0;if((d|0)>=0){if((d|0)>255){d=255;g=9}}else{d=0;g=9}if((g|0)==9)c[l>>2]=d;f=a+1712|0;e=c[f>>2]|0;if((e|0)>=0){if((e|0)>1024){e=1024;g=12}}else{e=0;g=12}if((g|0)==12)c[f>>2]=e;f=a+1704|0;e=c[f>>2]|0;if((e|0)>=0){if((e|0)>64){e=64;g=15}}else{e=0;g=15}if((g|0)==15)c[f>>2]=e;e=a+1728|0;if((c[e>>2]|0)>=(b|0))c[e>>2]=0;b=a+1716|0;if(((c[b>>2]|0)+-1|0)>>>0>254)c[b>>2]=6;e=a+1720|0;b=c[e>>2]|0;if((b|0)>=20){if((b|0)>255){b=255;g=22}}else{b=20;g=22}if((g|0)==22)c[e>>2]=b;if((d|0)<=0){k=a+1504|0;c[k>>2]=0;k=a+24|0;c[k>>2]=0;k=a+28|0;k=c[k>>2]|0;l=a+32|0;c[l>>2]=k;yl(a);zl(a);return}i=(c[a+2852>>2]&16384|0)==0;j=a+2836|0;k=a+1744|0;b=c[k>>2]|0;f=0;do{if(i)c[b+(f*764|0)+32>>2]=c[j>>2];e=c[b+(f*764|0)+36>>2]|0;if((e|0)>0){h=b+(f*764|0)+756|0;g=0;do{if(i)c[(c[h>>2]|0)+(g<<6)+4>>2]=c[j>>2];g=g+1|0}while((g|0)!=(e|0))}f=f+1|0}while((f|0)!=(d|0));d=b;b=0;while(1){xl(d+(b*764|0)+44|0);xl((c[k>>2]|0)+(b*764|0)+356|0);xl((c[k>>2]|0)+(b*764|0)+200|0);b=b+1|0;if((b|0)>=(c[l>>2]|0))break;d=c[k>>2]|0}k=a+1504|0;c[k>>2]=0;k=a+24|0;c[k>>2]=0;k=a+28|0;k=c[k>>2]|0;l=a+32|0;c[l>>2]=k;yl(a);zl(a);return}function xl(a){a=a|0;var b=0;b=c[a+4>>2]|0;if((b+-1|0)>>>0>31)c[a>>2]=c[a>>2]&-2;if(!((c[a+20>>2]|0)<(b|0)?(c[a+24>>2]|0)<(b|0):0))c[a>>2]=c[a>>2]&-5;if((c[a+12>>2]|0)<(b|0))return;c[a>>2]=c[a>>2]&-2;return}function yl(a){a=a|0;var b=0,d=0,e=0,f=0;e=a+2792|0;f=a+32|0;d=a+24|0;b=0;while(1){a=c[21448+(b*24|0)+16>>2]|0;if((b+-1|0)>>>0>=2?(121>>>b&1|0)==0:0)break;if(!(nn(e,21448+(b*24|0)|0,16)|0)){c[f>>2]=c[f>>2]|a;c[d>>2]=c[21448+(b*24|0)+20>>2]}b=b+1|0}return}function zl(a){a=a|0;var b=0,d=0;do switch(c[a+24>>2]|0){case 10:{c[a+2832>>2]=8363;c[a+2852>>2]=155125795;c[a+2856>>2]=3;return}case 1:{c[a+2832>>2]=8287;c[a+2852>>2]=0;c[a+2856>>2]=0;c[a+2860>>2]=0;return}case 2:{c[a+2832>>2]=8287;c[a+2852>>2]=268435456;c[a+2856>>2]=0;c[a+2860>>2]=1;return}case 3:{c[a+2832>>2]=8287;c[a+2852>>2]=4;c[a+2856>>2]=0;c[a+2860>>2]=1;return}case 4:{b=a+2852|0;d=c[b>>2]&536870976;c[a+2832>>2]=8363;c[b>>2]=d|1224737313;c[a+2856>>2]=2;return}case 5:{d=a+2852|0;b=c[d>>2]&536870976;c[a+2832>>2]=8363;c[d>>2]=b|1224737329;c[a+2856>>2]=2;return}case 6:{d=a+2852|0;b=c[d>>2]&536870976;c[a+2832>>2]=8363;c[d>>2]=b|150995505;c[a+2856>>2]=2;return}case 7:{c[a+2832>>2]=8363;c[a+2852>>2]=33554464;c[a+2856>>2]=1;return}case 8:{c[a+2832>>2]=8363;c[a+2852>>2]=100663328;c[a+2856>>2]=1;return}case 9:{c[a+2832>>2]=8363;c[a+2852>>2]=1228900387;c[a+2856>>2]=3;return}default:return}while(0)}function Al(a){a=a|0;var b=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;i=a+1568|0;k=a+1736|0;if(!(c[k>>2]|0)){l=-4;return l|0}if(!(c[a+1740>>2]|0)){l=-4;return l|0}l=a+1724|0;b=c[l>>2]|0;a:do if((b|0)>0){j=a+1696|0;f=c[j>>2]|0;e=0;while(1){if((d[a+2520+e>>0]|0|0)<(f|0))break;e=e+1|0;if((e|0)>=(b|0))break a}e=Xm(4,b)|0;g=a+9156|0;c[g>>2]=e;if(!e){l=-6;return l|0}else e=0;while(1){b=d[a+2520+e>>0]|0;if((b|0)<(f|0)?(c[(c[k>>2]|0)+(b<<2)>>2]|0)==0:0){if((ab(i,b)|0)<0){b=-6;e=18;break}f=c[j>>2]|0}if((b|0)<(f|0)?(h=c[(c[k>>2]|0)+(b<<2)>>2]|0,(h|0)!=0):0){b=c[h>>2]|0;b=(b|0)==0?1:b}else b=1;b=Xm(1,b)|0;c[(c[g>>2]|0)+(e<<2)>>2]=b;if(!(c[(c[g>>2]|0)+(e<<2)>>2]|0)){b=-6;e=18;break}e=e+1|0;if((e|0)>=(c[l>>2]|0)){b=0;e=18;break}}if((e|0)==18)return b|0}while(0);c[l>>2]=0;l=0;return l|0}function Bl(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;b=a+9188|0;if((c[b>>2]|0)>1)Ki(a);c[b>>2]=0;vm(a);f=a+1740|0;b=c[f>>2]|0;if(b|0){e=a+1700|0;if((c[e>>2]|0)>0){d=0;do{Wm(c[b+(d<<2)>>2]|0);d=d+1|0;b=c[f>>2]|0}while((d|0)<(c[e>>2]|0))}Wm(b)}f=a+1736|0;b=c[f>>2]|0;if(b|0){e=a+1696|0;if((c[e>>2]|0)>0){d=0;do{Wm(c[b+(d<<2)>>2]|0);d=d+1|0;b=c[f>>2]|0}while((d|0)<(c[e>>2]|0))}Wm(b)}f=a+1744|0;b=c[f>>2]|0;if(b|0){e=a+1708|0;if((c[e>>2]|0)>0){d=0;do{Wm(c[b+(d*764|0)+756>>2]|0);Wm(c[(c[f>>2]|0)+(d*764|0)+760>>2]|0);d=d+1|0;b=c[f>>2]|0}while((d|0)<(c[e>>2]|0))}Wm(b)}h=a+1748|0;b=c[h>>2]|0;if(b|0){g=a+1712|0;d=c[g>>2]|0;if((d|0)>0){f=0;do{e=c[b+(f*52|0)+48>>2]|0;if(e){Wm(e+-4|0);d=c[g>>2]|0;b=c[h>>2]|0}f=f+1|0}while((f|0)<(d|0))}Wm(b);Wm(c[a+9160>>2]|0)}h=a+9164|0;b=c[h>>2]|0;if(b|0){g=a+1712|0;d=c[g>>2]|0;if((d|0)>0){f=0;do{e=c[b+(f*52|0)+48>>2]|0;if(e){Wm(e+-4|0);d=c[g>>2]|0;b=c[h>>2]|0}f=f+1|0}while((f|0)<(d|0))}Wm(b)}f=a+9156|0;b=c[f>>2]|0;if(!b){h=a+2788|0;h=c[h>>2]|0;Wm(h);h=a+2776|0;h=c[h>>2]|0;Wm(h);a=a+2780|0;a=c[a>>2]|0;Wm(a);return}e=a+1724|0;if((c[e>>2]|0)>0){d=0;do{Wm(c[b+(d<<2)>>2]|0);d=d+1|0;b=c[f>>2]|0}while((d|0)<(c[e>>2]|0))}Wm(b);h=a+2788|0;h=c[h>>2]|0;Wm(h);h=a+2776|0;h=c[h>>2]|0;Wm(h);a=a+2780|0;a=c[a>>2]|0;Wm(a);return}function Cl(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;m=a+1568|0;vl(a);e=19908;f=0;while(1){dm(b,0,0)|0;gm(b)|0;d=Ca[c[(c[e>>2]|0)+4>>2]&255](b,0,0)|0;g=f+1|0;if(!d){h=4;break}if((f+-49|0)>>>0<4){e=-1;break}else{e=19908+(g<<2)|0;f=g}}if((h|0)==4){dm(b,0,0)|0;e=Ca[c[(c[e>>2]|0)+8>>2]&255](m,b,0)|0;d=0}if(!(e|d))Dl(b,a+2792|0);if((d|0)<0){Wm(c[a+2780>>2]|0);Wm(c[a+2776>>2]|0);a=-3;return a|0}a:do if(((e|0)>=0?(l=c[a+1704>>2]|0,(l|0)<=64):0)?(c[a+1724>>2]|0)<=256:0){k=(l|0)>0;if(k){e=a+1752|0;d=0;do{if((c[e+(d*12|0)+4>>2]|0)>>>0>255)break a;if((c[e+(d*12|0)>>2]|0)>>>0>255)break a;d=d+1|0}while((d|0)<(l|0))}d=c[a+1736>>2]|0;if(d|0){e=c[a+1696>>2]|0;if((e|0)>0){i=a+1700|0;j=a+1740|0;b=0;do{f=c[d+(b<<2)>>2]|0;if(!f)break a;if(k){h=0;do{g=c[f+4+(h<<2)>>2]|0;if((g|0)<0)break a;if((g|0)>=(c[i>>2]|0))break a;h=h+1|0;if(!(c[(c[j>>2]|0)+(g<<2)>>2]|0))break a}while((h|0)<(l|0))}b=b+1|0}while((b|0)<(e|0))}ul(m)|0;e=a+1708|0;if((c[e>>2]|0)>0){f=a+1744|0;d=0;do{ul((c[f>>2]|0)+(d*764|0)|0)|0;d=d+1|0}while((d|0)<(c[e>>2]|0))}e=a+1712|0;if((c[e>>2]|0)>0){f=a+1748|0;d=0;do{ul((c[f>>2]|0)+(d*52|0)|0)|0;d=d+1|0}while((d|0)<(c[e>>2]|0))}wl(a);d=Al(a)|0;if((d|0)<0){Bl(a);a=d;return a|0}else{nk(a);c[a+9188>>2]=1;a=0;return a|0}}}while(0);Bl(a);a=-4;return a|0}function Dl(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0;h=l;l=l+16480|0;f=h+88|0;g=h;if((mm(c[b+4>>2]|0)|0)<1){e=d+16|0;do{a[d>>0]=0;d=d+1|0}while((d|0)<(e|0));l=h;return}dm(b,0,0)|0;Zj(g);e=cm(f,1,16384,b)|0;if((e|0)>0)do{_j(g,f,e);e=cm(f,1,16384,b)|0}while((e|0)>0);ak(d,g);l=h;return}function El(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=(((d|0)==0)<<31>>31)+d|0;d=jm(b,e)|0;if(!d){a=-6;return a|0}if((c[a+9188>>2]|0)>0)Bl(a);c[a+2784>>2]=0;c[a+2780>>2]=0;c[a+2776>>2]=0;c[a+2808>>2]=e;a=Cl(a,d)|0;lm(d);return a|0}function Fl(a){a=a|0;var b=0,e=0;if((Gl(a)|0)<=0){a=-1;return a|0}b=c[a>>2]|0;e=a+4|0;a=c[e>>2]|0;c[e>>2]=a+1;a=d[b+a>>0]|0;return a|0}function Gl(a){a=a|0;var b=0;b=c[a+8>>2]|0;if((b|0)<=-1){a=2147483647;return a|0}a=c[a+4>>2]|0;a=(a|0)>-1?b-a|0:0;return a|0}function Hl(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;g=O(d,b)|0;f=Gl(e)|0;if((b|0)==0|(d|0)==0|(f|0)<1){b=0;return b|0}d=g>>>0>f>>>0?f:g;g=e+4|0;ep(a|0,(c[e>>2]|0)+(c[g>>2]|0)|0,d|0)|0;c[g>>2]=(c[g>>2]|0)+d;b=(d>>>0)/(b>>>0)|0;return b|0}function Il(a,b,d){a=a|0;b=b|0;d=d|0;switch(d|0){case 2:{d=c[a+8>>2]|0;if((d|0)<0){b=-1;return b|0}c[a+4>>2]=d+b;b=0;return b|0}case 1:{if((c[a+8>>2]|0)>-1){if((Gl(a)|0)<(b|0)){b=-1;return b|0}a=a+4|0;d=c[a>>2]|0;if((b|0)<(0-d|0)){b=-1;return b|0}}else{a=a+4|0;d=c[a>>2]|0}c[a>>2]=d+b;b=0;return b|0}default:{d=c[a+8>>2]|0;if((d|0)>-1?(b|0)<0|(d|0)<(b|0):0){b=-1;return b|0}c[a+4>>2]=b;b=0;return b|0}}return 0}function Jl(a){a=a|0;return a|0}function Kl(a){a=a|0;if((c[a+8>>2]|0)<1){a=0;return a|0}a=(Gl(a)|0)<1&1;return a|0}function Ll(a,b){a=a|0;b=b|0;var d=0;d=Vm(12)|0;if(!d){b=0;return b|0}c[d>>2]=a;c[d+4>>2]=0;c[d+8>>2]=b;b=d;return b|0}function Ml(a){a=a|0;Wm(a);return}function Nl(a){a=a|0;var b=0,d=0,e=0;e=l;l=l+16|0;d=e;switch(c[a>>2]|0){case 0:{b=Jj(c[a+8>>2]|0,d)|0;d=c[d>>2]|0;if(d)c[a+12>>2]=d;break}case 1:{b=Ol(c[a+8>>2]|0)|0;break}default:b=0}l=e;return b|0}function Ol(a){a=a|0;return (Fl(a)|0)&255|0}function Pl(a){a=a|0;var b=0,d=0,e=0;e=l;l=l+16|0;d=e;switch(c[a>>2]|0){case 0:{b=Ij(c[a+8>>2]|0,d)|0;d=c[d>>2]|0;if(d)c[a+12>>2]=d;break}case 1:{b=Ql(c[a+8>>2]|0)|0;break}default:b=0}l=e;return b|0}function Ql(b){b=b|0;var c=0,d=0;d=l;l=l+16|0;c=d;a[c>>0]=-1;Hl(c,1,1,b)|0;l=d;return a[c>>0]|0}function Rl(a){a=a|0;var b=0,d=0,e=0;e=l;l=l+16|0;d=e;switch(c[a>>2]|0){case 0:{b=Kj(c[a+8>>2]|0,d)|0;d=c[d>>2]|0;if(d)c[a+12>>2]=d;break}case 1:{b=Sl(c[a+8>>2]|0)|0;break}default:b=0}l=e;return b|0}function Sl(b){b=b|0;var d=0,e=0,f=0;d=Tl(b)|0;e=b+4|0;f=c[e>>2]|0;if((d|0)>1){b=(c[b>>2]|0)+f|0;d=2;b=Qj(a[b>>0]|0,a[b+1>>0]|0)|0}else b=-1;c[e>>2]=f+d;return b|0}function Tl(a){a=a|0;var b=0;b=c[a+8>>2]|0;if((b|0)<=-1){a=2147483647;return a|0}a=c[a+4>>2]|0;a=(a|0)>-1?b-a|0:0;return a|0}function Ul(a){a=a|0;var b=0,d=0,e=0;e=l;l=l+16|0;d=e;switch(c[a>>2]|0){case 0:{b=Lj(c[a+8>>2]|0,d)|0;d=c[d>>2]|0;if(d)c[a+12>>2]=d;break}case 1:{b=Vl(c[a+8>>2]|0)|0;break}default:b=0}l=e;return b|0}function Vl(b){b=b|0;var d=0,e=0,f=0;d=Tl(b)|0;e=b+4|0;f=c[e>>2]|0;if((d|0)>1){b=(c[b>>2]|0)+f|0;d=2;b=Rj(a[b>>0]|0,a[b+1>>0]|0)|0}else b=-1;c[e>>2]=f+d;return b|0}function Wl(a){a=a|0;var b=0,d=0,e=0;e=l;l=l+16|0;d=e;switch(c[a>>2]|0){case 0:{b=Mj(c[a+8>>2]|0,d)|0;d=c[d>>2]|0;if(d)c[a+12>>2]=d;break}case 1:{b=Xl(c[a+8>>2]|0)|0;break}default:b=0}l=e;return b|0}function Xl(b){b=b|0;var d=0,e=0,f=0;f=Tl(b)|0;d=b+4|0;e=c[d>>2]|0;if((f|0)<=2){b=-1;f=e+f|0;c[d>>2]=f;return b|0}b=(c[b>>2]|0)+e|0;f=3;b=Sj(a[b>>0]|0,a[b+1>>0]|0,a[b+2>>0]|0)|0;f=e+f|0;c[d>>2]=f;return b|0}function Yl(a){a=a|0;var b=0,d=0,e=0;e=l;l=l+16|0;d=e;switch(c[a>>2]|0){case 0:{b=Nj(c[a+8>>2]|0,d)|0;d=c[d>>2]|0;if(d)c[a+12>>2]=d;break}case 1:{b=Zl(c[a+8>>2]|0)|0;break}default:b=0}l=e;return b|0}function Zl(b){b=b|0;var d=0,e=0,f=0;f=Tl(b)|0;d=b+4|0;e=c[d>>2]|0;if((f|0)<=2){b=-1;f=e+f|0;c[d>>2]=f;return b|0}b=(c[b>>2]|0)+e|0;f=3;b=Tj(a[b>>0]|0,a[b+1>>0]|0,a[b+2>>0]|0)|0;f=e+f|0;c[d>>2]=f;return b|0}function _l(a){a=a|0;var b=0,d=0,e=0;e=l;l=l+16|0;d=e;switch(c[a>>2]|0){case 0:{b=Oj(c[a+8>>2]|0,d)|0;d=c[d>>2]|0;if(d)c[a+12>>2]=d;break}case 1:{b=$l(c[a+8>>2]|0)|0;break}default:b=0}l=e;return b|0}function $l(a){a=a|0;var b=0,d=0,e=0;b=Tl(a)|0;d=a+4|0;e=c[d>>2]|0;if((b|0)>3){b=4;a=Uj((c[a>>2]|0)+e|0)|0}else a=-1;c[d>>2]=e+b;return a|0}function am(a){a=a|0;var b=0,d=0,e=0;e=l;l=l+16|0;d=e;switch(c[a>>2]|0){case 0:{b=Pj(c[a+8>>2]|0,d)|0;d=c[d>>2]|0;if(d)c[a+12>>2]=d;break}case 1:{b=bm(c[a+8>>2]|0)|0;break}default:b=0}l=e;return b|0}function bm(a){a=a|0;var b=0,d=0,e=0;b=Tl(a)|0;d=a+4|0;e=c[d>>2]|0;if((b|0)>3){b=4;a=Vj((c[a>>2]|0)+e|0)|0}else a=-1;c[d>>2]=e+b;return a|0}function cm(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;switch(c[e>>2]|0){case 0:{f=e+8|0;b=Oo(a,b,d,c[f>>2]|0)|0;if((b|0)==(d|0)){e=d;return e|0}a=c[f>>2]|0;if(!(zo(a)|0)){a=(yo(a)|0)!=0;a=a?-1:-2}else a=c[10299]|0;c[e+12>>2]=a;e=b;return e|0}case 1:{a=Hl(a,b,d,c[e+8>>2]|0)|0;if((a|0)==(d|0)){e=d;return e|0}c[e+12>>2]=c[10299];e=a;return e|0}default:{e=0;return e|0}}return 0}function dm(a,b,d){a=a|0;b=b|0;d=d|0;switch(c[a>>2]|0){case 0:{b=Ao(c[a+8>>2]|0,b,d)|0;if((b|0)>=0){a=b;return a|0}c[a+12>>2]=c[10299];a=b;return a|0}case 1:{b=Il(c[a+8>>2]|0,b,d)|0;if((b|0)>=0){a=b;return a|0}c[a+12>>2]=c[10299];a=b;return a|0}default:{a=-1;return a|0}}return 0}function em(a){a=a|0;var b=0;switch(c[a>>2]|0){case 0:{b=Po(c[a+8>>2]|0)|0;if((b|0)>=0){a=b;return a|0}c[a+12>>2]=c[10299];a=b;return a|0}case 1:{b=Jl(c[(c[a+8>>2]|0)+4>>2]|0)|0;if((b|0)>=0){a=b;return a|0}c[a+12>>2]=c[10299];a=b;return a|0}default:{a=-1;return a|0}}return 0}function fm(a){a=a|0;switch(c[a>>2]|0){case 0:{a=yo(c[a+8>>2]|0)|0;break}case 1:{a=Kl(c[a+8>>2]|0)|0;break}default:a=-1}return a|0}function gm(a){a=a|0;var b=0;b=a+12|0;a=c[b>>2]|0;c[b>>2]=0;return a|0}function hm(a,b){a=a|0;b=b|0;var d=0;d=Vm(16)|0;if(!d){d=0;return d|0}c[d+12>>2]=0;c[d>>2]=0;b=po(a,b)|0;c[d+8>>2]=b;do if(b|0){a=im(b)|0;c[d+4>>2]=a;if((a|0)<0){vo(b)|0;break}else return d|0}while(0);Wm(d);d=0;return d|0}function im(a){a=a|0;var b=0,c=0;b=Po(a)|0;if((b|0)<=-1){a=b;return a|0}if((Ao(a,0,2)|0)<0){a=-1;return a|0}c=Po(a)|0;a=(Ao(a,b,0)|0)<0;a=a?-1:c;return a|0}function jm(a,b){a=a|0;b=b|0;var d=0;d=Vm(16)|0;if(!d){b=0;return b|0}c[d+12>>2]=0;c[d>>2]=1;c[d+8>>2]=Ll(a,b)|0;c[d+4>>2]=b;b=d;return b|0}function km(a){a=a|0;var b=0;b=Vm(16)|0;if(!b){a=0;return a|0}c[b+12>>2]=0;c[b>>2]=0;c[b+8>>2]=a;c[b+4>>2]=im(a)|0;a=b;return a|0}function lm(a){a=a|0;switch(c[a>>2]|0){case 0:{vo(c[a+8>>2]|0)|0;break}case 1:{Ml(c[a+8>>2]|0);break}default:{}}Wm(a);return}function mm(a){a=a|0;return a|0}function nm(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;o=c[e+424>>2]|0;if((c[b+12>>2]|0)==0?c[e>>2]&67584|0:0)c[o+4>>2]=0;n=b+1744|0;i=c[n>>2]|0;l=e+44|0;j=c[l>>2]|0;r=o+4|0;p=c[r>>2]|0;g=c[i+(j*764|0)+760>>2]|0;k=d[g+12+p>>0]|0;q=a[g+76+p>>0]&127;if((k|0)<(c[i+(j*764|0)+36>>2]|0)?(h=c[(c[i+(j*764|0)+756>>2]|0)+(k<<6)+40>>2]|0,m=e+52|0,(h|0)!=(c[m>>2]|0)):0){c[m>>2]=h;qi(b,f,h);g=c[(c[n>>2]|0)+((c[l>>2]|0)*764|0)+760>>2]|0}if((p|0)<(c[g+8>>2]|0)){p=p+1|0;c[r>>2]=p;r=o+8|0;c[r>>2]=q;return}p=c[g+4>>2]|0;c[r>>2]=p;r=o+8|0;c[r>>2]=q;return}function om(a){a=a|0;var b=0;b=Xm(1,140)|0;c[a+760>>2]=b;if(!b){a=-1;return a|0}c[b>>2]=68929562;a=0;return a|0}function pm(a){a=a|0;var b=0;b=Xm(1,12)|0;c[a+424>>2]=b;if(!b){a=-1;return a|0}c[b>>2]=68929562;a=0;return a|0}function qm(b){b=b|0;var c=0;b=b+4|0;c=b;a[c>>0]=0;a[c+1>>0]=0;a[c+2>>0]=0;a[c+3>>0]=0;b=b+4|0;a[b>>0]=0;a[b+1>>0]=0;a[b+2>>0]=0;a[b+3>>0]=0;return}function rm(a){a=a|0;Wm(a);return}function sm(a){a=a|0;var b=0;b=Xm(1,4)|0;c[a+7584>>2]=b;if(!b){a=-1;return a|0}c[b>>2]=68929562;a=0;return a|0}function tm(a){a=a|0;Wm(a);return}function um(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0;if(d<<24>>24!=-78)return;g=b+188|0;f=b+172|0;d=36269+((e&255)<<4)|0;b=f+16|0;do{a[f>>0]=a[d>>0]|0;f=f+1|0;d=d+1|0}while((f|0)<(b|0));c[g>>2]=16;return}function vm(a){a=a|0;var b=0,d=0;d=a+1568|0;a=c[a+9152>>2]|0;if(!a)return;b=c[a>>2]|0;if((b|0)<133303461){switch(b|0){case 68929562:break;default:return}tm(a);return}else{switch(b|0){case 133303461:break;default:return}Bk(d);return}}function wm(a,b){a=a|0;b=b|0;a:do if(a|0){a=c[a>>2]|0;if((a|0)<133303461){switch(a|0){case 68929562:break;default:break a}if((pm(b)|0)<0)a=-1;else break;return a|0}else{switch(a|0){case 133303461:break;default:break a}if((xk(b)|0)<0)a=-1;else break;return a|0}}while(0);b=0;return b|0}function xm(a,b){a=a|0;b=b|0;if(!a)return;a=c[a>>2]|0;if((a|0)<133303461){switch(a|0){case 68929562:break;default:return}rm(c[b+424>>2]|0);return}else{switch(a|0){case 133303461:break;default:return}zk(c[b+424>>2]|0);return}}function ym(a,b){a=a|0;b=b|0;if(!a)return;a=c[a>>2]|0;if((a|0)<133303461){switch(a|0){case 68929562:break;default:return}qm(c[b+424>>2]|0);return}else{switch(a|0){case 133303461:break;default:return}yk(c[b+424>>2]|0);return}}function zm(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=c[b+44>>2]|0;if((e|0)>=(c[a+1708>>2]|0))return;e=c[(c[a+1744>>2]|0)+(e*764|0)+760>>2]|0;if(!e)return;e=c[e>>2]|0;if((e|0)<133303461){switch(e|0){case 68929562:break;default:return}nm(a,b,d);return}else{switch(e|0){case 133303461:break;default:return}vk(a,b,d);return}}function Am(a,b){a=a|0;b=b|0;var d=0,e=0;d=c[b+44>>2]|0;e=c[b+76>>2]|0;if((d|0)>=(c[a+1708>>2]|0)){b=e;return b|0}d=c[(c[a+1744>>2]|0)+(d*764|0)+760>>2]|0;if(!d){b=e;return b|0}d=c[d>>2]|0;if((d|0)<133303461){switch(d|0){case 68929562:break;default:{b=e;return b|0}}b=(O(c[(c[b+424>>2]|0)+8>>2]|0,e)|0)/64|0;return b|0}else{switch(d|0){case 133303461:break;default:{b=e;return b|0}}b=(O(c[(c[b+424>>2]|0)+76>>2]|0,e)|0)/64|0;return b|0}return 0}function Bm(a){a=a|0;var b=0;b=c[a+424>>2]|0;if((b|0)!=0?(c[b>>2]|0)==133303461:0)a=tk(a)|0;else a=0;return a|0}function Cm(a,b){a=a|0;b=b|0;var d=0;d=c[b+424>>2]|0;if((d|0)!=0?(c[d>>2]|0)==133303461:0)a=uk(a,b)|0;else a=0;return a|0}function Dm(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;e=c[a+424>>2]|0;if(!e)return;e=c[e>>2]|0;if((e|0)<133303461){switch(e|0){case 68929562:break;default:return}um(a,b,d);return}else{switch(e|0){case 133303461:break;default:return}Ck(a,b);return}}function Em(a,b){a=a|0;b=b|0;var d=0;d=c[a+1708>>2]|0;if((d|0)<=(b|0))if(((c[a+9172>>2]|0)+d|0)>(b|0)){b=b-d|0;d=a+9180|0}else{a=0;return a|0}else d=a+1744|0;a=(c[d>>2]|0)+(b*764|0)|0;return a|0}function Fm(a,b){a=a|0;b=b|0;var d=0;d=c[a+1712>>2]|0;if((d|0)<=(b|0))if(((c[a+9176>>2]|0)+d|0)>(b|0)){b=b-d|0;d=a+9184|0}else{a=0;return a|0}else d=a+1748|0;a=(c[d>>2]|0)+(b*52|0)|0;return a|0}function Gm(){Ki(c[9744]|0);Bl(c[9744]|0);qk(c[9744]|0);return 0}function Hm(){var a=0;mj(c[9744]|0);a=c[10153]|0;c[10157]=a;c[10158]=a+64;return 40628}function Im(){return c[(c[9744]|0)+4>>2]|0}function Jm(){lj(c[9744]|0);return 0}function Km(){return c[9760]|0}function Lm(){return c[(c[9744]|0)+1724>>2]|0}function Mm(){mj(c[9744]|0);return 0}function Nm(){return c[9745]|0}function Om(){return c[9756]|0}function Pm(){return c[9757]|0}function Qm(){c[9744]=pk()|0;return 0}function Rm(a,b,d){a=a|0;b=b|0;d=d|0;d=(d|0)>4e3?d:4e3;c[9745]=(d|0)<49170?d:49170;return El(c[9744]|0,a,b)|0}function Sm(){return Ni(c[9744]|0)|0}function Tm(a){a=a|0;sk(c[9744]|0,a);return}function Um(){Ji(c[9744]|0,c[9745]|0);return 0}function Vm(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;x=l;l=l+16|0;o=x;do if(a>>>0<245){k=a>>>0<11?16:a+11&-8;a=k>>>3;n=c[10159]|0;d=n>>>a;if(d&3|0){e=(d&1^1)+a|0;f=40676+(e<<1<<2)|0;b=f+8|0;a=c[b>>2]|0;g=a+8|0;d=c[g>>2]|0;if((f|0)==(d|0))c[10159]=n&~(1<>2]=f;c[b>>2]=d}w=e<<3;c[a+4>>2]=w|3;w=a+w+4|0;c[w>>2]=c[w>>2]|1;w=g;l=x;return w|0}m=c[10161]|0;if(k>>>0>m>>>0){if(d|0){h=2<>>12&16;d=d>>>h;a=d>>>5&8;d=d>>>a;f=d>>>2&4;d=d>>>f;b=d>>>1&2;d=d>>>b;e=d>>>1&1;e=(a|h|f|b|e)+(d>>>e)|0;d=40676+(e<<1<<2)|0;b=d+8|0;f=c[b>>2]|0;h=f+8|0;a=c[h>>2]|0;if((d|0)==(a|0)){a=n&~(1<>2]=d;c[b>>2]=a;a=n}g=(e<<3)-k|0;c[f+4>>2]=k|3;f=f+k|0;c[f+4>>2]=g|1;c[f+g>>2]=g;if(m|0){e=c[10164]|0;b=m>>>3;d=40676+(b<<1<<2)|0;b=1<>2]|0}c[b>>2]=e;c[a+12>>2]=e;c[e+8>>2]=a;c[e+12>>2]=d}c[10161]=g;c[10164]=f;w=h;l=x;return w|0}i=c[10160]|0;if(i){d=(i&0-i)+-1|0;h=d>>>12&16;d=d>>>h;g=d>>>5&8;d=d>>>g;j=d>>>2&4;d=d>>>j;a=d>>>1&2;d=d>>>a;e=d>>>1&1;e=c[40940+((g|h|j|a|e)+(d>>>e)<<2)>>2]|0;d=(c[e+4>>2]&-8)-k|0;a=c[e+16+(((c[e+16>>2]|0)==0&1)<<2)>>2]|0;if(!a){j=d;h=e}else{do{h=(c[a+4>>2]&-8)-k|0;j=h>>>0>>0;d=j?h:d;e=j?a:e;a=c[a+16+(((c[a+16>>2]|0)==0&1)<<2)>>2]|0}while((a|0)!=0);j=d;h=e}g=h+k|0;if(h>>>0>>0){f=c[h+24>>2]|0;b=c[h+12>>2]|0;do if((b|0)==(h|0)){a=h+20|0;b=c[a>>2]|0;if(!b){a=h+16|0;b=c[a>>2]|0;if(!b){d=0;break}}while(1){e=b+20|0;d=c[e>>2]|0;if(d|0){b=d;a=e;continue}e=b+16|0;d=c[e>>2]|0;if(!d)break;else{b=d;a=e}}c[a>>2]=0;d=b}else{d=c[h+8>>2]|0;c[d+12>>2]=b;c[b+8>>2]=d;d=b}while(0);do if(f|0){b=c[h+28>>2]|0;a=40940+(b<<2)|0;if((h|0)==(c[a>>2]|0)){c[a>>2]=d;if(!d){c[10160]=i&~(1<>2]|0)!=(h|0)&1)<<2)>>2]=d;if(!d)break}c[d+24>>2]=f;b=c[h+16>>2]|0;if(b|0){c[d+16>>2]=b;c[b+24>>2]=d}b=c[h+20>>2]|0;if(b|0){c[d+20>>2]=b;c[b+24>>2]=d}}while(0);if(j>>>0<16){w=j+k|0;c[h+4>>2]=w|3;w=h+w+4|0;c[w>>2]=c[w>>2]|1}else{c[h+4>>2]=k|3;c[g+4>>2]=j|1;c[g+j>>2]=j;if(m|0){e=c[10164]|0;b=m>>>3;d=40676+(b<<1<<2)|0;b=1<>2]|0}c[b>>2]=e;c[a+12>>2]=e;c[e+8>>2]=a;c[e+12>>2]=d}c[10161]=j;c[10164]=g}w=h+8|0;l=x;return w|0}else n=k}else n=k}else n=k}else if(a>>>0<=4294967231){a=a+11|0;k=a&-8;e=c[10160]|0;if(e){d=0-k|0;a=a>>>8;if(a)if(k>>>0>16777215)j=31;else{n=(a+1048320|0)>>>16&8;v=a<>>16&4;v=v<>>16&2;j=14-(m|n|j)+(v<>>15)|0;j=k>>>(j+7|0)&1|j<<1}else j=0;a=c[40940+(j<<2)>>2]|0;a:do if(!a){f=0;a=0;v=57}else{f=0;h=k<<((j|0)==31?0:25-(j>>>1)|0);i=a;a=0;while(1){g=(c[i+4>>2]&-8)-k|0;if(g>>>0>>0)if(!g){d=0;f=i;a=i;v=61;break a}else{d=g;a=i}g=c[i+20>>2]|0;i=c[i+16+(h>>>31<<2)>>2]|0;f=(g|0)==0|(g|0)==(i|0)?f:g;g=(i|0)==0;if(g){v=57;break}else h=h<<((g^1)&1)}}while(0);if((v|0)==57){if((f|0)==0&(a|0)==0){a=2<>>12&16;a=a>>>j;i=a>>>5&8;a=a>>>i;m=a>>>2&4;a=a>>>m;n=a>>>1&2;a=a>>>n;f=a>>>1&1;f=c[40940+((i|j|m|n|f)+(a>>>f)<<2)>>2]|0;a=0}if(!f){i=d;j=a}else v=61}if((v|0)==61)while(1){v=0;m=(c[f+4>>2]&-8)-k|0;n=m>>>0>>0;d=n?m:d;a=n?f:a;f=c[f+16+(((c[f+16>>2]|0)==0&1)<<2)>>2]|0;if(!f){i=d;j=a;break}else v=61}if((j|0)!=0?i>>>0<((c[10161]|0)-k|0)>>>0:0){h=j+k|0;if(j>>>0>=h>>>0){w=0;l=x;return w|0}g=c[j+24>>2]|0;b=c[j+12>>2]|0;do if((b|0)==(j|0)){a=j+20|0;b=c[a>>2]|0;if(!b){a=j+16|0;b=c[a>>2]|0;if(!b){b=0;break}}while(1){f=b+20|0;d=c[f>>2]|0;if(d|0){b=d;a=f;continue}f=b+16|0;d=c[f>>2]|0;if(!d)break;else{b=d;a=f}}c[a>>2]=0}else{w=c[j+8>>2]|0;c[w+12>>2]=b;c[b+8>>2]=w}while(0);do if(g){a=c[j+28>>2]|0;d=40940+(a<<2)|0;if((j|0)==(c[d>>2]|0)){c[d>>2]=b;if(!b){e=e&~(1<>2]|0)!=(j|0)&1)<<2)>>2]=b;if(!b)break}c[b+24>>2]=g;a=c[j+16>>2]|0;if(a|0){c[b+16>>2]=a;c[a+24>>2]=b}a=c[j+20>>2]|0;if(a){c[b+20>>2]=a;c[a+24>>2]=b}}while(0);do if(i>>>0>=16){c[j+4>>2]=k|3;c[h+4>>2]=i|1;c[h+i>>2]=i;b=i>>>3;if(i>>>0<256){d=40676+(b<<1<<2)|0;a=c[10159]|0;b=1<>2]|0}c[b>>2]=h;c[a+12>>2]=h;c[h+8>>2]=a;c[h+12>>2]=d;break}b=i>>>8;if(b)if(i>>>0>16777215)b=31;else{v=(b+1048320|0)>>>16&8;w=b<>>16&4;w=w<>>16&2;b=14-(u|v|b)+(w<>>15)|0;b=i>>>(b+7|0)&1|b<<1}else b=0;d=40940+(b<<2)|0;c[h+28>>2]=b;a=h+16|0;c[a+4>>2]=0;c[a>>2]=0;a=1<>2]=h;c[h+24>>2]=d;c[h+12>>2]=h;c[h+8>>2]=h;break}a=i<<((b|0)==31?0:25-(b>>>1)|0);d=c[d>>2]|0;while(1){if((c[d+4>>2]&-8|0)==(i|0)){v=97;break}e=d+16+(a>>>31<<2)|0;b=c[e>>2]|0;if(!b){v=96;break}else{a=a<<1;d=b}}if((v|0)==96){c[e>>2]=h;c[h+24>>2]=d;c[h+12>>2]=h;c[h+8>>2]=h;break}else if((v|0)==97){v=d+8|0;w=c[v>>2]|0;c[w+12>>2]=h;c[v>>2]=h;c[h+8>>2]=w;c[h+12>>2]=d;c[h+24>>2]=0;break}}else{w=i+k|0;c[j+4>>2]=w|3;w=j+w+4|0;c[w>>2]=c[w>>2]|1}while(0);w=j+8|0;l=x;return w|0}else n=k}else n=k}else n=-1;while(0);d=c[10161]|0;if(d>>>0>=n>>>0){a=d-n|0;b=c[10164]|0;if(a>>>0>15){w=b+n|0;c[10164]=w;c[10161]=a;c[w+4>>2]=a|1;c[w+a>>2]=a;c[b+4>>2]=n|3}else{c[10161]=0;c[10164]=0;c[b+4>>2]=d|3;w=b+d+4|0;c[w>>2]=c[w>>2]|1}w=b+8|0;l=x;return w|0}h=c[10162]|0;if(h>>>0>n>>>0){u=h-n|0;c[10162]=u;w=c[10165]|0;v=w+n|0;c[10165]=v;c[v+4>>2]=u|1;c[w+4>>2]=n|3;w=w+8|0;l=x;return w|0}if(!(c[10277]|0)){c[10279]=4096;c[10278]=4096;c[10280]=-1;c[10281]=-1;c[10282]=0;c[10270]=0;a=o&-16^1431655768;c[o>>2]=a;c[10277]=a;a=4096}else a=c[10279]|0;i=n+48|0;j=n+47|0;g=a+j|0;e=0-a|0;k=g&e;if(k>>>0<=n>>>0){w=0;l=x;return w|0}a=c[10269]|0;if(a|0?(m=c[10267]|0,o=m+k|0,o>>>0<=m>>>0|o>>>0>a>>>0):0){w=0;l=x;return w|0}b:do if(!(c[10270]&4)){d=c[10165]|0;c:do if(d){f=41084;while(1){a=c[f>>2]|0;if(a>>>0<=d>>>0?(r=f+4|0,(a+(c[r>>2]|0)|0)>>>0>d>>>0):0)break;a=c[f+8>>2]|0;if(!a){v=118;break c}else f=a}b=g-h&e;if(b>>>0<2147483647){a=ip(b|0)|0;if((a|0)==((c[f>>2]|0)+(c[r>>2]|0)|0)){if((a|0)!=(-1|0)){h=a;g=b;v=135;break b}}else{e=a;v=126}}else b=0}else v=118;while(0);do if((v|0)==118){d=ip(0)|0;if((d|0)!=(-1|0)?(b=d,p=c[10278]|0,q=p+-1|0,b=((q&b|0)==0?0:(q+b&0-p)-b|0)+k|0,p=c[10267]|0,q=b+p|0,b>>>0>n>>>0&b>>>0<2147483647):0){r=c[10269]|0;if(r|0?q>>>0<=p>>>0|q>>>0>r>>>0:0){b=0;break}a=ip(b|0)|0;if((a|0)==(d|0)){h=d;g=b;v=135;break b}else{e=a;v=126}}else b=0}while(0);do if((v|0)==126){d=0-b|0;if(!(i>>>0>b>>>0&(b>>>0<2147483647&(e|0)!=(-1|0))))if((e|0)==(-1|0)){b=0;break}else{h=e;g=b;v=135;break b}a=c[10279]|0;a=j-b+a&0-a;if(a>>>0>=2147483647){h=e;g=b;v=135;break b}if((ip(a|0)|0)==(-1|0)){ip(d|0)|0;b=0;break}else{h=e;g=a+b|0;v=135;break b}}while(0);c[10270]=c[10270]|4;v=133}else{b=0;v=133}while(0);if(((v|0)==133?k>>>0<2147483647:0)?(s=ip(k|0)|0,r=ip(0)|0,u=r-s|0,t=u>>>0>(n+40|0)>>>0,!((s|0)==(-1|0)|t^1|s>>>0>>0&((s|0)!=(-1|0)&(r|0)!=(-1|0))^1)):0){h=s;g=t?u:b;v=135}if((v|0)==135){b=(c[10267]|0)+g|0;c[10267]=b;if(b>>>0>(c[10268]|0)>>>0)c[10268]=b;j=c[10165]|0;do if(j){f=41084;while(1){b=c[f>>2]|0;e=f+4|0;a=c[e>>2]|0;if((h|0)==(b+a|0)){v=145;break}d=c[f+8>>2]|0;if(!d)break;else f=d}if(((v|0)==145?(c[f+12>>2]&8|0)==0:0)?j>>>0>>0&j>>>0>=b>>>0:0){c[e>>2]=a+g;w=j+8|0;w=(w&7|0)==0?0:0-w&7;v=j+w|0;w=(c[10162]|0)+(g-w)|0;c[10165]=v;c[10162]=w;c[v+4>>2]=w|1;c[v+w+4>>2]=40;c[10166]=c[10281];break}if(h>>>0<(c[10163]|0)>>>0)c[10163]=h;d=h+g|0;a=41084;while(1){if((c[a>>2]|0)==(d|0)){v=153;break}b=c[a+8>>2]|0;if(!b)break;else a=b}if((v|0)==153?(c[a+12>>2]&8|0)==0:0){c[a>>2]=h;m=a+4|0;c[m>>2]=(c[m>>2]|0)+g;m=h+8|0;m=h+((m&7|0)==0?0:0-m&7)|0;b=d+8|0;b=d+((b&7|0)==0?0:0-b&7)|0;k=m+n|0;i=b-m-n|0;c[m+4>>2]=n|3;do if((b|0)!=(j|0)){if((b|0)==(c[10164]|0)){w=(c[10161]|0)+i|0;c[10161]=w;c[10164]=k;c[k+4>>2]=w|1;c[k+w>>2]=w;break}a=c[b+4>>2]|0;if((a&3|0)==1){h=a&-8;e=a>>>3;d:do if(a>>>0<256){a=c[b+8>>2]|0;d=c[b+12>>2]|0;if((d|0)==(a|0)){c[10159]=c[10159]&~(1<>2]=d;c[d+8>>2]=a;break}}else{g=c[b+24>>2]|0;a=c[b+12>>2]|0;do if((a|0)==(b|0)){e=b+16|0;d=e+4|0;a=c[d>>2]|0;if(!a){a=c[e>>2]|0;if(!a){a=0;break}else f=e}else f=d;while(1){e=a+20|0;d=c[e>>2]|0;if(d|0){a=d;f=e;continue}e=a+16|0;d=c[e>>2]|0;if(!d)break;else{a=d;f=e}}c[f>>2]=0}else{w=c[b+8>>2]|0;c[w+12>>2]=a;c[a+8>>2]=w}while(0);if(!g)break;d=c[b+28>>2]|0;e=40940+(d<<2)|0;do if((b|0)!=(c[e>>2]|0)){c[g+16+(((c[g+16>>2]|0)!=(b|0)&1)<<2)>>2]=a;if(!a)break d}else{c[e>>2]=a;if(a|0)break;c[10160]=c[10160]&~(1<>2]=g;e=b+16|0;d=c[e>>2]|0;if(d|0){c[a+16>>2]=d;c[d+24>>2]=a}d=c[e+4>>2]|0;if(!d)break;c[a+20>>2]=d;c[d+24>>2]=a}while(0);b=b+h|0;f=h+i|0}else f=i;b=b+4|0;c[b>>2]=c[b>>2]&-2;c[k+4>>2]=f|1;c[k+f>>2]=f;b=f>>>3;if(f>>>0<256){d=40676+(b<<1<<2)|0;a=c[10159]|0;b=1<>2]|0}c[b>>2]=k;c[a+12>>2]=k;c[k+8>>2]=a;c[k+12>>2]=d;break}b=f>>>8;do if(!b)a=0;else{if(f>>>0>16777215){a=31;break}v=(b+1048320|0)>>>16&8;w=b<>>16&4;w=w<>>16&2;a=14-(u|v|a)+(w<>>15)|0;a=f>>>(a+7|0)&1|a<<1}while(0);e=40940+(a<<2)|0;c[k+28>>2]=a;b=k+16|0;c[b+4>>2]=0;c[b>>2]=0;b=c[10160]|0;d=1<>2]=k;c[k+24>>2]=e;c[k+12>>2]=k;c[k+8>>2]=k;break}a=f<<((a|0)==31?0:25-(a>>>1)|0);d=c[e>>2]|0;while(1){if((c[d+4>>2]&-8|0)==(f|0)){v=194;break}e=d+16+(a>>>31<<2)|0;b=c[e>>2]|0;if(!b){v=193;break}else{a=a<<1;d=b}}if((v|0)==193){c[e>>2]=k;c[k+24>>2]=d;c[k+12>>2]=k;c[k+8>>2]=k;break}else if((v|0)==194){v=d+8|0;w=c[v>>2]|0;c[w+12>>2]=k;c[v>>2]=k;c[k+8>>2]=w;c[k+12>>2]=d;c[k+24>>2]=0;break}}else{w=(c[10162]|0)+i|0;c[10162]=w;c[10165]=k;c[k+4>>2]=w|1}while(0);w=m+8|0;l=x;return w|0}a=41084;while(1){b=c[a>>2]|0;if(b>>>0<=j>>>0?(w=b+(c[a+4>>2]|0)|0,w>>>0>j>>>0):0)break;a=c[a+8>>2]|0}f=w+-47|0;a=f+8|0;a=f+((a&7|0)==0?0:0-a&7)|0;f=j+16|0;a=a>>>0>>0?j:a;b=a+8|0;d=h+8|0;d=(d&7|0)==0?0:0-d&7;v=h+d|0;d=g+-40-d|0;c[10165]=v;c[10162]=d;c[v+4>>2]=d|1;c[v+d+4>>2]=40;c[10166]=c[10281];d=a+4|0;c[d>>2]=27;c[b>>2]=c[10271];c[b+4>>2]=c[10272];c[b+8>>2]=c[10273];c[b+12>>2]=c[10274];c[10271]=h;c[10272]=g;c[10274]=0;c[10273]=b;b=a+24|0;do{v=b;b=b+4|0;c[b>>2]=7}while((v+8|0)>>>0>>0);if((a|0)!=(j|0)){g=a-j|0;c[d>>2]=c[d>>2]&-2;c[j+4>>2]=g|1;c[a>>2]=g;b=g>>>3;if(g>>>0<256){d=40676+(b<<1<<2)|0;a=c[10159]|0;b=1<>2]|0}c[b>>2]=j;c[a+12>>2]=j;c[j+8>>2]=a;c[j+12>>2]=d;break}b=g>>>8;if(b)if(g>>>0>16777215)d=31;else{v=(b+1048320|0)>>>16&8;w=b<>>16&4;w=w<>>16&2;d=14-(u|v|d)+(w<>>15)|0;d=g>>>(d+7|0)&1|d<<1}else d=0;e=40940+(d<<2)|0;c[j+28>>2]=d;c[j+20>>2]=0;c[f>>2]=0;b=c[10160]|0;a=1<>2]=j;c[j+24>>2]=e;c[j+12>>2]=j;c[j+8>>2]=j;break}a=g<<((d|0)==31?0:25-(d>>>1)|0);d=c[e>>2]|0;while(1){if((c[d+4>>2]&-8|0)==(g|0)){v=216;break}e=d+16+(a>>>31<<2)|0;b=c[e>>2]|0;if(!b){v=215;break}else{a=a<<1;d=b}}if((v|0)==215){c[e>>2]=j;c[j+24>>2]=d;c[j+12>>2]=j;c[j+8>>2]=j;break}else if((v|0)==216){v=d+8|0;w=c[v>>2]|0;c[w+12>>2]=j;c[v>>2]=j;c[j+8>>2]=w;c[j+12>>2]=d;c[j+24>>2]=0;break}}}else{w=c[10163]|0;if((w|0)==0|h>>>0>>0)c[10163]=h;c[10271]=h;c[10272]=g;c[10274]=0;c[10168]=c[10277];c[10167]=-1;b=0;do{w=40676+(b<<1<<2)|0;c[w+12>>2]=w;c[w+8>>2]=w;b=b+1|0}while((b|0)!=32);w=h+8|0;w=(w&7|0)==0?0:0-w&7;v=h+w|0;w=g+-40-w|0;c[10165]=v;c[10162]=w;c[v+4>>2]=w|1;c[v+w+4>>2]=40;c[10166]=c[10281]}while(0);b=c[10162]|0;if(b>>>0>n>>>0){u=b-n|0;c[10162]=u;w=c[10165]|0;v=w+n|0;c[10165]=v;c[v+4>>2]=u|1;c[w+4>>2]=n|3;w=w+8|0;l=x;return w|0}}c[10299]=12;w=0;l=x;return w|0}function Wm(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;if(!a)return;d=a+-8|0;e=c[10163]|0;a=c[a+-4>>2]|0;b=a&-8;k=d+b|0;do if(!(a&1)){f=c[d>>2]|0;if(!(a&3))return;g=d+(0-f)|0;h=f+b|0;if(g>>>0>>0)return;if((g|0)==(c[10164]|0)){b=k+4|0;a=c[b>>2]|0;if((a&3|0)!=3){i=g;j=g;b=h;break}c[10161]=h;c[b>>2]=a&-2;c[g+4>>2]=h|1;c[g+h>>2]=h;return}d=f>>>3;if(f>>>0<256){a=c[g+8>>2]|0;b=c[g+12>>2]|0;if((b|0)==(a|0)){c[10159]=c[10159]&~(1<>2]=b;c[b+8>>2]=a;i=g;j=g;b=h;break}}f=c[g+24>>2]|0;a=c[g+12>>2]|0;do if((a|0)==(g|0)){d=g+16|0;b=d+4|0;a=c[b>>2]|0;if(!a){a=c[d>>2]|0;if(!a){d=0;break}else e=d}else e=b;while(1){d=a+20|0;b=c[d>>2]|0;if(b|0){a=b;e=d;continue}d=a+16|0;b=c[d>>2]|0;if(!b)break;else{a=b;e=d}}c[e>>2]=0;d=a}else{d=c[g+8>>2]|0;c[d+12>>2]=a;c[a+8>>2]=d;d=a}while(0);if(f){a=c[g+28>>2]|0;b=40940+(a<<2)|0;if((g|0)==(c[b>>2]|0)){c[b>>2]=d;if(!d){c[10160]=c[10160]&~(1<>2]|0)!=(g|0)&1)<<2)>>2]=d;if(!d){i=g;j=g;b=h;break}}c[d+24>>2]=f;b=g+16|0;a=c[b>>2]|0;if(a|0){c[d+16>>2]=a;c[a+24>>2]=d}a=c[b+4>>2]|0;if(a){c[d+20>>2]=a;c[a+24>>2]=d;i=g;j=g;b=h}else{i=g;j=g;b=h}}else{i=g;j=g;b=h}}else{i=d;j=d}while(0);if(i>>>0>=k>>>0)return;a=k+4|0;e=c[a>>2]|0;if(!(e&1))return;if(!(e&2)){a=c[10164]|0;if((k|0)==(c[10165]|0)){k=(c[10162]|0)+b|0;c[10162]=k;c[10165]=j;c[j+4>>2]=k|1;if((j|0)!=(a|0))return;c[10164]=0;c[10161]=0;return}if((k|0)==(a|0)){k=(c[10161]|0)+b|0;c[10161]=k;c[10164]=i;c[j+4>>2]=k|1;c[i+k>>2]=k;return}f=(e&-8)+b|0;d=e>>>3;do if(e>>>0<256){b=c[k+8>>2]|0;a=c[k+12>>2]|0;if((a|0)==(b|0)){c[10159]=c[10159]&~(1<>2]=a;c[a+8>>2]=b;break}}else{g=c[k+24>>2]|0;a=c[k+12>>2]|0;do if((a|0)==(k|0)){d=k+16|0;b=d+4|0;a=c[b>>2]|0;if(!a){a=c[d>>2]|0;if(!a){d=0;break}else e=d}else e=b;while(1){d=a+20|0;b=c[d>>2]|0;if(b|0){a=b;e=d;continue}d=a+16|0;b=c[d>>2]|0;if(!b)break;else{a=b;e=d}}c[e>>2]=0;d=a}else{d=c[k+8>>2]|0;c[d+12>>2]=a;c[a+8>>2]=d;d=a}while(0);if(g|0){a=c[k+28>>2]|0;b=40940+(a<<2)|0;if((k|0)==(c[b>>2]|0)){c[b>>2]=d;if(!d){c[10160]=c[10160]&~(1<>2]|0)!=(k|0)&1)<<2)>>2]=d;if(!d)break}c[d+24>>2]=g;b=k+16|0;a=c[b>>2]|0;if(a|0){c[d+16>>2]=a;c[a+24>>2]=d}a=c[b+4>>2]|0;if(a|0){c[d+20>>2]=a;c[a+24>>2]=d}}}while(0);c[j+4>>2]=f|1;c[i+f>>2]=f;if((j|0)==(c[10164]|0)){c[10161]=f;return}}else{c[a>>2]=e&-2;c[j+4>>2]=b|1;c[i+b>>2]=b;f=b}a=f>>>3;if(f>>>0<256){d=40676+(a<<1<<2)|0;b=c[10159]|0;a=1<>2]|0}c[a>>2]=j;c[b+12>>2]=j;c[j+8>>2]=b;c[j+12>>2]=d;return}a=f>>>8;if(a)if(f>>>0>16777215)b=31;else{i=(a+1048320|0)>>>16&8;k=a<>>16&4;k=k<>>16&2;b=14-(h|i|b)+(k<>>15)|0;b=f>>>(b+7|0)&1|b<<1}else b=0;e=40940+(b<<2)|0;c[j+28>>2]=b;c[j+20>>2]=0;c[j+16>>2]=0;a=c[10160]|0;d=1<>>1)|0);d=c[e>>2]|0;while(1){if((c[d+4>>2]&-8|0)==(f|0)){a=73;break}e=d+16+(b>>>31<<2)|0;a=c[e>>2]|0;if(!a){a=72;break}else{b=b<<1;d=a}}if((a|0)==72){c[e>>2]=j;c[j+24>>2]=d;c[j+12>>2]=j;c[j+8>>2]=j;break}else if((a|0)==73){i=d+8|0;k=c[i>>2]|0;c[k+12>>2]=j;c[i>>2]=j;c[j+8>>2]=k;c[j+12>>2]=d;c[j+24>>2]=0;break}}else{c[10160]=a|d;c[e>>2]=j;c[j+24>>2]=e;c[j+12>>2]=j;c[j+8>>2]=j}while(0);k=(c[10167]|0)+-1|0;c[10167]=k;if(!k)a=41092;else return;while(1){a=c[a>>2]|0;if(!a)break;else a=a+8|0}c[10167]=-1;return}function Xm(a,b){a=a|0;b=b|0;var d=0;if(a){d=O(b,a)|0;if((b|a)>>>0>65535)d=((d>>>0)/(a>>>0)|0|0)==(b|0)?d:-1}else d=0;b=Vm(d)|0;if(!b)return b|0;if(!(c[b+-4>>2]&3))return b|0;gp(b|0,0,d|0)|0;return b|0}function Ym(a,b){a=a|0;b=b|0;var d=0,e=0;if(!a){a=Vm(b)|0;return a|0}if(b>>>0>4294967231){c[10299]=12;a=0;return a|0}d=Zm(a+-8|0,b>>>0<11?16:b+11&-8)|0;if(d|0){a=d+8|0;return a|0}d=Vm(b)|0;if(!d){a=0;return a|0}e=c[a+-4>>2]|0;e=(e&-8)-((e&3|0)==0?8:4)|0;ep(d|0,a|0,(e>>>0>>0?e:b)|0)|0;Wm(a);a=d;return a|0}function Zm(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;m=a+4|0;l=c[m>>2]|0;d=l&-8;i=a+d|0;if(!(l&3)){if(b>>>0<256){a=0;return a|0}if(d>>>0>=(b+4|0)>>>0?(d-b|0)>>>0<=c[10279]<<1>>>0:0)return a|0;a=0;return a|0}if(d>>>0>=b>>>0){d=d-b|0;if(d>>>0<=15)return a|0;k=a+b|0;c[m>>2]=l&1|b|2;c[k+4>>2]=d|3;b=k+d+4|0;c[b>>2]=c[b>>2]|1;_m(k,d);return a|0}if((i|0)==(c[10165]|0)){k=(c[10162]|0)+d|0;e=k-b|0;d=a+b|0;if(k>>>0<=b>>>0){a=0;return a|0}c[m>>2]=l&1|b|2;c[d+4>>2]=e|1;c[10165]=d;c[10162]=e;return a|0}if((i|0)==(c[10164]|0)){f=(c[10161]|0)+d|0;if(f>>>0>>0){a=0;return a|0}d=f-b|0;e=l&1;if(d>>>0>15){l=a+b|0;k=l+d|0;c[m>>2]=e|b|2;c[l+4>>2]=d|1;c[k>>2]=d;e=k+4|0;c[e>>2]=c[e>>2]&-2;e=l}else{c[m>>2]=e|f|2;e=a+f+4|0;c[e>>2]=c[e>>2]|1;e=0;d=0}c[10161]=d;c[10164]=e;return a|0}e=c[i+4>>2]|0;if(e&2|0){a=0;return a|0}j=(e&-8)+d|0;if(j>>>0>>0){a=0;return a|0}k=j-b|0;f=e>>>3;do if(e>>>0<256){e=c[i+8>>2]|0;d=c[i+12>>2]|0;if((d|0)==(e|0)){c[10159]=c[10159]&~(1<>2]=d;c[d+8>>2]=e;break}}else{h=c[i+24>>2]|0;d=c[i+12>>2]|0;do if((d|0)==(i|0)){f=i+16|0;e=f+4|0;d=c[e>>2]|0;if(!d){d=c[f>>2]|0;if(!d){f=0;break}else g=f}else g=e;while(1){f=d+20|0;e=c[f>>2]|0;if(e|0){d=e;g=f;continue}f=d+16|0;e=c[f>>2]|0;if(!e)break;else{d=e;g=f}}c[g>>2]=0;f=d}else{f=c[i+8>>2]|0;c[f+12>>2]=d;c[d+8>>2]=f;f=d}while(0);if(h|0){d=c[i+28>>2]|0;e=40940+(d<<2)|0;if((i|0)==(c[e>>2]|0)){c[e>>2]=f;if(!f){c[10160]=c[10160]&~(1<>2]|0)!=(i|0)&1)<<2)>>2]=f;if(!f)break}c[f+24>>2]=h;e=i+16|0;d=c[e>>2]|0;if(d|0){c[f+16>>2]=d;c[d+24>>2]=f}d=c[e+4>>2]|0;if(d|0){c[f+20>>2]=d;c[d+24>>2]=f}}}while(0);d=l&1;if(k>>>0<16){c[m>>2]=j|d|2;b=a+j+4|0;c[b>>2]=c[b>>2]|1;return a|0}else{l=a+b|0;c[m>>2]=d|b|2;c[l+4>>2]=k|3;b=l+k+4|0;c[b>>2]=c[b>>2]|1;_m(l,k);return a|0}return 0}function _m(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0;j=a+b|0;d=c[a+4>>2]|0;do if(!(d&1)){e=c[a>>2]|0;if(!(d&3))return;g=a+(0-e)|0;h=e+b|0;if((g|0)==(c[10164]|0)){a=j+4|0;d=c[a>>2]|0;if((d&3|0)!=3){i=g;a=h;break}c[10161]=h;c[a>>2]=d&-2;c[g+4>>2]=h|1;c[g+h>>2]=h;return}b=e>>>3;if(e>>>0<256){d=c[g+8>>2]|0;a=c[g+12>>2]|0;if((a|0)==(d|0)){c[10159]=c[10159]&~(1<>2]=a;c[a+8>>2]=d;i=g;a=h;break}}f=c[g+24>>2]|0;d=c[g+12>>2]|0;do if((d|0)==(g|0)){b=g+16|0;a=b+4|0;d=c[a>>2]|0;if(!d){d=c[b>>2]|0;if(!d){b=0;break}else e=b}else e=a;while(1){b=d+20|0;a=c[b>>2]|0;if(a|0){d=a;e=b;continue}b=d+16|0;a=c[b>>2]|0;if(!a)break;else{d=a;e=b}}c[e>>2]=0;b=d}else{b=c[g+8>>2]|0;c[b+12>>2]=d;c[d+8>>2]=b;b=d}while(0);if(f){d=c[g+28>>2]|0;a=40940+(d<<2)|0;if((g|0)==(c[a>>2]|0)){c[a>>2]=b;if(!b){c[10160]=c[10160]&~(1<>2]|0)!=(g|0)&1)<<2)>>2]=b;if(!b){i=g;a=h;break}}c[b+24>>2]=f;a=g+16|0;d=c[a>>2]|0;if(d|0){c[b+16>>2]=d;c[d+24>>2]=b}d=c[a+4>>2]|0;if(d){c[b+20>>2]=d;c[d+24>>2]=b;i=g;a=h}else{i=g;a=h}}else{i=g;a=h}}else{i=a;a=b}while(0);d=j+4|0;e=c[d>>2]|0;if(!(e&2)){d=c[10164]|0;if((j|0)==(c[10165]|0)){j=(c[10162]|0)+a|0;c[10162]=j;c[10165]=i;c[i+4>>2]=j|1;if((i|0)!=(d|0))return;c[10164]=0;c[10161]=0;return}if((j|0)==(d|0)){j=(c[10161]|0)+a|0;c[10161]=j;c[10164]=i;c[i+4>>2]=j|1;c[i+j>>2]=j;return}f=(e&-8)+a|0;b=e>>>3;do if(e>>>0<256){a=c[j+8>>2]|0;d=c[j+12>>2]|0;if((d|0)==(a|0)){c[10159]=c[10159]&~(1<>2]=d;c[d+8>>2]=a;break}}else{g=c[j+24>>2]|0;d=c[j+12>>2]|0;do if((d|0)==(j|0)){b=j+16|0;a=b+4|0;d=c[a>>2]|0;if(!d){d=c[b>>2]|0;if(!d){b=0;break}else e=b}else e=a;while(1){b=d+20|0;a=c[b>>2]|0;if(a|0){d=a;e=b;continue}b=d+16|0;a=c[b>>2]|0;if(!a)break;else{d=a;e=b}}c[e>>2]=0;b=d}else{b=c[j+8>>2]|0;c[b+12>>2]=d;c[d+8>>2]=b;b=d}while(0);if(g|0){d=c[j+28>>2]|0;a=40940+(d<<2)|0;if((j|0)==(c[a>>2]|0)){c[a>>2]=b;if(!b){c[10160]=c[10160]&~(1<>2]|0)!=(j|0)&1)<<2)>>2]=b;if(!b)break}c[b+24>>2]=g;a=j+16|0;d=c[a>>2]|0;if(d|0){c[b+16>>2]=d;c[d+24>>2]=b}d=c[a+4>>2]|0;if(d|0){c[b+20>>2]=d;c[d+24>>2]=b}}}while(0);c[i+4>>2]=f|1;c[i+f>>2]=f;if((i|0)==(c[10164]|0)){c[10161]=f;return}}else{c[d>>2]=e&-2;c[i+4>>2]=a|1;c[i+a>>2]=a;f=a}d=f>>>3;if(f>>>0<256){b=40676+(d<<1<<2)|0;a=c[10159]|0;d=1<>2]|0}c[d>>2]=i;c[a+12>>2]=i;c[i+8>>2]=a;c[i+12>>2]=b;return}d=f>>>8;if(d)if(f>>>0>16777215)a=31;else{h=(d+1048320|0)>>>16&8;j=d<>>16&4;j=j<>>16&2;a=14-(g|h|a)+(j<>>15)|0;a=f>>>(a+7|0)&1|a<<1}else a=0;e=40940+(a<<2)|0;c[i+28>>2]=a;c[i+20>>2]=0;c[i+16>>2]=0;d=c[10160]|0;b=1<>2]=i;c[i+24>>2]=e;c[i+12>>2]=i;c[i+8>>2]=i;return}a=f<<((a|0)==31?0:25-(a>>>1)|0);b=c[e>>2]|0;while(1){if((c[b+4>>2]&-8|0)==(f|0)){d=69;break}e=b+16+(a>>>31<<2)|0;d=c[e>>2]|0;if(!d){d=68;break}else{a=a<<1;b=d}}if((d|0)==68){c[e>>2]=i;c[i+24>>2]=b;c[i+12>>2]=i;c[i+8>>2]=i;return}else if((d|0)==69){h=b+8|0;j=c[h>>2]|0;c[j+12>>2]=i;c[h>>2]=i;c[i+8>>2]=j;c[i+12>>2]=b;c[i+24>>2]=0;return}}function $m(a){a=a|0;var b=0,d=0;b=l;l=l+16|0;d=b;c[d>>2]=en(c[a+60>>2]|0)|0;a=cn(oa(6,d|0)|0)|0;l=b;return a|0}function an(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0;n=l;l=l+48|0;i=n+16|0;f=n;e=n+32|0;j=a+28|0;g=c[j>>2]|0;c[e>>2]=g;k=a+20|0;g=(c[k>>2]|0)-g|0;c[e+4>>2]=g;c[e+8>>2]=b;c[e+12>>2]=d;g=g+d|0;h=a+60|0;c[f>>2]=c[h>>2];c[f+4>>2]=e;c[f+8>>2]=2;b=cn(ia(146,f|0)|0)|0;a:do if((g|0)!=(b|0)){f=2;while(1){if((b|0)<0)break;g=g-b|0;p=c[e+4>>2]|0;o=b>>>0>p>>>0;e=o?e+8|0:e;f=(o<<31>>31)+f|0;p=b-(o?p:0)|0;c[e>>2]=(c[e>>2]|0)+p;o=e+4|0;c[o>>2]=(c[o>>2]|0)-p;c[i>>2]=c[h>>2];c[i+4>>2]=e;c[i+8>>2]=f;b=cn(ia(146,i|0)|0)|0;if((g|0)==(b|0)){m=3;break a}}c[a+16>>2]=0;c[j>>2]=0;c[k>>2]=0;c[a>>2]=c[a>>2]|32;if((f|0)==2)d=0;else d=d-(c[e+4>>2]|0)|0}else m=3;while(0);if((m|0)==3){p=c[a+44>>2]|0;c[a+16>>2]=p+(c[a+48>>2]|0);c[j>>2]=p;c[k>>2]=p}l=n;return d|0}function bn(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=l;l=l+32|0;g=f;e=f+20|0;c[g>>2]=c[a+60>>2];c[g+4>>2]=0;c[g+8>>2]=b;c[g+12>>2]=e;c[g+16>>2]=d;if((cn(ga(140,g|0)|0)|0)<0){c[e>>2]=-1;a=-1}else a=c[e>>2]|0;l=f;return a|0}function cn(a){a=a|0;if(a>>>0>4294963200){c[10299]=0-a;a=-1}return a|0}function dn(){return 41196}function en(a){a=a|0;return a|0}function fn(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0;k=l;l=l+32|0;f=k;i=k+16|0;c[i>>2]=d;g=i+4|0;j=b+48|0;m=c[j>>2]|0;c[g>>2]=e-((m|0)!=0&1);h=b+44|0;c[i+8>>2]=c[h>>2];c[i+12>>2]=m;c[f>>2]=c[b+60>>2];c[f+4>>2]=i;c[f+8>>2]=2;f=cn(ha(145,f|0)|0)|0;if((f|0)>=1){i=c[g>>2]|0;if(f>>>0>i>>>0){g=c[h>>2]|0;h=b+4|0;c[h>>2]=g;c[b+8>>2]=g+(f-i);if(!(c[j>>2]|0))f=e;else{c[h>>2]=g+1;a[d+(e+-1)>>0]=a[g>>0]|0;f=e}}}else c[b>>2]=c[b>>2]|f&48^16;l=k;return f|0}function gn(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0;g=l;l=l+32|0;f=g;c[b+36>>2]=144;if((c[b>>2]&64|0)==0?(c[f>>2]=c[b+60>>2],c[f+4>>2]=21523,c[f+8>>2]=g+16,na(54,f|0)|0):0)a[b+75>>0]=-1;f=an(b,d,e)|0;l=g;return f|0}function hn(a){a=a|0;var b=0;b=(jn(a)|0)==0;return (b?a:a|32)|0}function jn(a){a=a|0;return (a+-65|0)>>>0<26|0}function kn(a){a=a|0;var b=0,e=0;e=l;l=l+16|0;b=e;if((ln(a)|0)==0?(Ca[c[a+32>>2]&255](a,b,1)|0)==1:0)b=d[b>>0]|0;else b=-1;l=e;return b|0}function ln(b){b=b|0;var d=0,e=0;e=b+74|0;d=a[e>>0]|0;a[e>>0]=d+255|d;e=b+20|0;d=b+28|0;if((c[e>>2]|0)>>>0>(c[d>>2]|0)>>>0)Ca[c[b+36>>2]&255](b,0,0)|0;c[b+16>>2]=0;c[d>>2]=0;c[e>>2]=0;d=c[b>>2]|0;if(!(d&4)){e=(c[b+44>>2]|0)+(c[b+48>>2]|0)|0;c[b+8>>2]=e;c[b+4>>2]=e;d=d<<27>>31}else{c[b>>2]=d|32;d=-1}return d|0}function mn(b,c){b=b|0;c=c|0;var d=0,e=0;d=a[b>>0]|0;e=a[c>>0]|0;if(!(d<<24>>24==0?1:d<<24>>24!=e<<24>>24))do{b=b+1|0;c=c+1|0;d=a[b>>0]|0;e=a[c>>0]|0}while(!(d<<24>>24==0?1:d<<24>>24!=e<<24>>24));return (d&255)-(e&255)|0}function nn(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;a:do if(!d)b=0;else{while(1){e=a[b>>0]|0;f=a[c>>0]|0;if(e<<24>>24!=f<<24>>24)break;d=d+-1|0;if(!d){b=0;break a}else{b=b+1|0;c=c+1|0}}b=(e&255)-(f&255)|0}while(0);return b|0}function on(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0;if(!d)e=0;else{h=a[b>>0]|0;f=h&255;g=a[c>>0]|0;e=g&255;a:do if(h<<24>>24)do{d=d+-1|0;if(!(h<<24>>24==g<<24>>24&((d|0)!=0&g<<24>>24!=0)))break a;b=b+1|0;c=c+1|0;h=a[b>>0]|0;f=h&255;g=a[c>>0]|0;e=g&255}while(h<<24>>24!=0);while(0);e=f-e|0}return e|0}function pn(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0;p=l;l=l+128|0;g=p+124|0;h=p;n=h;q=21892;r=n+124|0;do{c[n>>2]=c[q>>2];n=n+4|0;q=q+4|0}while((n|0)<(r|0));if((d+-1|0)>>>0>2147483646)if(!d){i=1;j=g;o=4}else c[10299]=75;else{i=d;j=b;o=4}if((o|0)==4?(r=-2-j|0,r=i>>>0>r>>>0?r:i,c[h+48>>2]=r,m=h+20|0,c[m>>2]=j,c[h+44>>2]=j,q=j+r|0,k=h+16|0,c[k>>2]=q,c[h+28>>2]=q,qn(h,e,f)|0,r|0):0){r=c[m>>2]|0;a[r+(((r|0)==(c[k>>2]|0))<<31>>31)>>0]=0}l=p;return}function qn(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0;r=l;l=l+224|0;n=r+120|0;q=r+80|0;p=r;o=r+136|0;f=q;g=f+40|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));c[n>>2]=c[e>>2];if((rn(0,d,n,p,q)|0)<0)e=-1;else{e=c[b>>2]|0;m=e&32;if((a[b+74>>0]|0)<1)c[b>>2]=e&-33;h=b+48|0;if(!(c[h>>2]|0)){g=b+44|0;f=c[g>>2]|0;c[g>>2]=o;i=b+28|0;c[i>>2]=o;k=b+20|0;c[k>>2]=o;c[h>>2]=80;j=b+16|0;c[j>>2]=o+80;e=rn(b,d,n,p,q)|0;if(f){Ca[c[b+36>>2]&255](b,0,0)|0;e=(c[k>>2]|0)==0?-1:e;c[g>>2]=f;c[h>>2]=0;c[j>>2]=0;c[i>>2]=0;c[k>>2]=0}}else e=rn(b,d,n,p,q)|0;q=c[b>>2]|0;c[b>>2]=q|m;e=(q&32|0)==0?e:-1}l=r;return e|0}function rn(d,e,f,g,i){d=d|0;e=e|0;f=f|0;g=g|0;i=i|0;var j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;H=l;l=l+64|0;D=H+16|0;A=H;y=H+24|0;G=H+8|0;C=H+20|0;c[D>>2]=e;F=(d|0)!=0;x=y+40|0;E=x;y=y+39|0;B=G+4|0;q=e;e=0;j=0;n=0;a:while(1){do if((e|0)>-1)if((j|0)>(2147483647-e|0)){c[10299]=75;e=-1;break}else{e=j+e|0;break}while(0);j=a[q>>0]|0;if(!(j<<24>>24)){w=87;break}else k=q;b:while(1){switch(j<<24>>24){case 37:{j=k;w=9;break b}case 0:{j=k;break b}default:{}}v=k+1|0;c[D>>2]=v;j=a[v>>0]|0;k=v}c:do if((w|0)==9)while(1){w=0;if((a[j+1>>0]|0)!=37)break c;k=k+1|0;j=j+2|0;c[D>>2]=j;if((a[j>>0]|0)==37)w=9;else break}while(0);k=k-q|0;if(F)tn(d,q,k);if(k|0){q=j;j=k;continue}m=j+1|0;k=(a[m>>0]|0)+-48|0;if(k>>>0<10){v=(a[j+2>>0]|0)==36;s=v?k:-1;p=v?1:n;m=v?j+3|0:m}else{s=-1;p=n}c[D>>2]=m;j=a[m>>0]|0;k=(j<<24>>24)+-32|0;d:do if(k>>>0<32){n=0;while(1){k=1<>2]=m;j=a[m>>0]|0;k=(j<<24>>24)+-32|0;if(k>>>0>=32){o=n;break}}}else o=0;while(0);if(j<<24>>24==42){k=m+1|0;j=(a[k>>0]|0)+-48|0;if(j>>>0<10?(a[m+2>>0]|0)==36:0){c[i+(j<<2)>>2]=10;n=1;j=m+3|0;k=c[g+((a[k>>0]|0)+-48<<3)>>2]|0}else{if(p|0){e=-1;break}if(F){n=(c[f>>2]|0)+(4-1)&~(4-1);v=c[n>>2]|0;c[f>>2]=n+4;n=0;j=k;k=v}else{n=0;j=k;k=0}}c[D>>2]=j;u=(k|0)<0;m=j;r=u?o|8192:o;v=n;u=u?0-k|0:k}else{j=un(D)|0;if((j|0)<0){e=-1;break}m=c[D>>2]|0;r=o;v=p;u=j}do if((a[m>>0]|0)==46){j=m+1|0;if((a[j>>0]|0)!=42){c[D>>2]=j;o=un(D)|0;j=c[D>>2]|0;break}j=m+2|0;k=(a[j>>0]|0)+-48|0;if(k>>>0<10?(a[m+3>>0]|0)==36:0){c[i+(k<<2)>>2]=10;o=c[g+((a[j>>0]|0)+-48<<3)>>2]|0;j=m+4|0;c[D>>2]=j;break}if(v|0){e=-1;break a}if(F){t=(c[f>>2]|0)+(4-1)&~(4-1);k=c[t>>2]|0;c[f>>2]=t+4}else k=0;c[D>>2]=j;o=k}else{j=m;o=-1}while(0);p=0;while(1){if(((a[j>>0]|0)+-65|0)>>>0>57){e=-1;break a}t=j+1|0;c[D>>2]=t;k=a[(a[j>>0]|0)+-65+(36525+(p*58|0))>>0]|0;n=k&255;if((n+-1|0)>>>0<8){j=t;p=n}else break}if(!(k<<24>>24)){e=-1;break}m=(s|0)>-1;do if(k<<24>>24==19)if(m){e=-1;break a}else w=49;else{if(m){c[i+(s<<2)>>2]=n;n=g+(s<<3)|0;s=c[n+4>>2]|0;w=A;c[w>>2]=c[n>>2];c[w+4>>2]=s;w=49;break}if(!F){e=0;break a}vn(A,n,f)}while(0);if((w|0)==49?(w=0,!F):0){q=t;j=0;n=v;continue}n=a[j>>0]|0;n=(p|0)!=0&(n&15|0)==3?n&-33:n;k=r&-65537;s=(r&8192|0)==0?r:k;e:do switch(n|0){case 110:switch((p&255)<<24>>24){case 0:{c[c[A>>2]>>2]=e;q=t;j=0;n=v;continue a}case 1:{c[c[A>>2]>>2]=e;q=t;j=0;n=v;continue a}case 2:{q=c[A>>2]|0;c[q>>2]=e;c[q+4>>2]=((e|0)<0)<<31>>31;q=t;j=0;n=v;continue a}case 3:{b[c[A>>2]>>1]=e;q=t;j=0;n=v;continue a}case 4:{a[c[A>>2]>>0]=e;q=t;j=0;n=v;continue a}case 6:{c[c[A>>2]>>2]=e;q=t;j=0;n=v;continue a}case 7:{q=c[A>>2]|0;c[q>>2]=e;c[q+4>>2]=((e|0)<0)<<31>>31;q=t;j=0;n=v;continue a}default:{q=t;j=0;n=v;continue a}}case 112:{j=s|8;k=o>>>0>8?o:8;n=120;w=61;break}case 88:case 120:{j=s;k=o;w=61;break}case 111:{r=A;q=c[r>>2]|0;r=c[r+4>>2]|0;p=xn(q,r,x)|0;k=E-p|0;j=s;k=(s&8|0)==0|(o|0)>(k|0)?o:k+1|0;m=0;o=36989;w=67;break}case 105:case 100:{k=A;j=c[k>>2]|0;k=c[k+4>>2]|0;if((k|0)<0){j=Yo(0,0,j|0,k|0)|0;k=z;m=A;c[m>>2]=j;c[m+4>>2]=k;m=1;n=36989;w=66;break e}else{m=(s&2049|0)!=0&1;n=(s&2048|0)==0?((s&1|0)==0?36989:36991):36990;w=66;break e}}case 117:{k=A;j=c[k>>2]|0;k=c[k+4>>2]|0;m=0;n=36989;w=66;break}case 99:{a[y>>0]=c[A>>2];q=y;p=k;n=1;m=0;k=36989;j=x;break}case 109:{j=zn(c[10299]|0)|0;w=71;break}case 115:{j=c[A>>2]|0;j=j|0?j:36999;w=71;break}case 67:{c[G>>2]=c[A>>2];c[B>>2]=0;c[A>>2]=G;j=G;o=-1;w=75;break}case 83:{j=c[A>>2]|0;if(!o){Bn(d,32,u,0,s);j=0;w=84}else w=75;break}case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:{q=t;j=Dn(d,+h[A>>3],u,o,s,n)|0;n=v;continue a}default:{p=s;n=o;m=0;k=36989;j=x}}while(0);f:do if((w|0)==61){r=A;q=c[r>>2]|0;r=c[r+4>>2]|0;p=wn(q,r,x,n&32)|0;o=(j&8|0)==0|(q|0)==0&(r|0)==0;m=o?0:2;o=o?36989:36989+(n>>4)|0;w=67}else if((w|0)==66){q=j;r=k;p=yn(j,k,x)|0;j=s;k=o;o=n;w=67}else if((w|0)==71){w=0;s=An(j,0,o)|0;r=(s|0)==0;q=j;p=k;n=r?o:s-j|0;m=0;k=36989;j=r?j+o|0:s}else if((w|0)==75){w=0;m=0;k=0;p=j;while(1){n=c[p>>2]|0;if(!n)break;k=Cn(C,n)|0;if((k|0)<0|k>>>0>(o-m|0)>>>0)break;m=k+m|0;if(o>>>0>m>>>0)p=p+4|0;else break}if((k|0)<0){e=-1;break a}Bn(d,32,u,m,s);if(!m){j=0;w=84}else{n=0;while(1){k=c[j>>2]|0;if(!k){j=m;w=84;break f}k=Cn(C,k)|0;n=k+n|0;if((n|0)>(m|0)){j=m;w=84;break f}tn(d,C,k);if(n>>>0>=m>>>0){j=m;w=84;break}else j=j+4|0}}}while(0);if((w|0)==67){w=0;n=(q|0)!=0|(r|0)!=0;s=(k|0)!=0|n;n=((n^1)&1)+(E-p)|0;q=s?p:x;p=(k|0)>-1?j&-65537:j;n=s?((k|0)>(n|0)?k:n):k;k=o;j=x}else if((w|0)==84){w=0;Bn(d,32,u,j,s^8192);q=t;j=(u|0)>(j|0)?u:j;n=v;continue}s=j-q|0;r=(n|0)<(s|0)?s:n;n=r+m|0;j=(u|0)<(n|0)?n:u;Bn(d,32,j,n,p);tn(d,k,m);Bn(d,48,j,n,p^65536);Bn(d,48,r,s,0);tn(d,q,s);Bn(d,32,j,n,p^8192);q=t;n=v}g:do if((w|0)==87)if(!d)if(!n)e=0;else{e=1;while(1){j=c[i+(e<<2)>>2]|0;if(!j){j=0;break}vn(g+(e<<3)|0,j,f);e=e+1|0;if((e|0)>=10){e=1;break g}}while(1){e=e+1|0;if(j|0){e=-1;break g}if((e|0)>=10){e=1;break g}j=c[i+(e<<2)>>2]|0}}while(0);l=H;return e|0}function sn(){return 0}function tn(a,b,d){a=a|0;b=b|0;d=d|0;if(!(c[a>>2]&32))Nn(b,d,a)|0;return}function un(b){b=b|0;var d=0,e=0,f=0;d=c[b>>2]|0;e=(a[d>>0]|0)+-48|0;if(e>>>0<10){f=d;d=0;do{d=e+(d*10|0)|0;f=f+1|0;c[b>>2]=f;e=(a[f>>0]|0)+-48|0}while(e>>>0<10)}else d=0;return d|0}function vn(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0.0;a:do if(b>>>0<=20)do switch(b|0){case 9:{e=(c[d>>2]|0)+(4-1)&~(4-1);b=c[e>>2]|0;c[d>>2]=e+4;c[a>>2]=b;break a}case 10:{e=(c[d>>2]|0)+(4-1)&~(4-1);b=c[e>>2]|0;c[d>>2]=e+4;e=a;c[e>>2]=b;c[e+4>>2]=((b|0)<0)<<31>>31;break a}case 11:{e=(c[d>>2]|0)+(4-1)&~(4-1);b=c[e>>2]|0;c[d>>2]=e+4;e=a;c[e>>2]=b;c[e+4>>2]=0;break a}case 12:{e=(c[d>>2]|0)+(8-1)&~(8-1);b=e;f=c[b>>2]|0;b=c[b+4>>2]|0;c[d>>2]=e+8;e=a;c[e>>2]=f;c[e+4>>2]=b;break a}case 13:{f=(c[d>>2]|0)+(4-1)&~(4-1);e=c[f>>2]|0;c[d>>2]=f+4;e=(e&65535)<<16>>16;f=a;c[f>>2]=e;c[f+4>>2]=((e|0)<0)<<31>>31;break a}case 14:{f=(c[d>>2]|0)+(4-1)&~(4-1);e=c[f>>2]|0;c[d>>2]=f+4;f=a;c[f>>2]=e&65535;c[f+4>>2]=0;break a}case 15:{f=(c[d>>2]|0)+(4-1)&~(4-1);e=c[f>>2]|0;c[d>>2]=f+4;e=(e&255)<<24>>24;f=a;c[f>>2]=e;c[f+4>>2]=((e|0)<0)<<31>>31;break a}case 16:{f=(c[d>>2]|0)+(4-1)&~(4-1);e=c[f>>2]|0;c[d>>2]=f+4;f=a;c[f>>2]=e&255;c[f+4>>2]=0;break a}case 17:{f=(c[d>>2]|0)+(8-1)&~(8-1);g=+h[f>>3];c[d>>2]=f+8;h[a>>3]=g;break a}case 18:{f=(c[d>>2]|0)+(8-1)&~(8-1);g=+h[f>>3];c[d>>2]=f+8;h[a>>3]=g;break a}default:break a}while(0);while(0);return}function wn(b,c,e,f){b=b|0;c=c|0;e=e|0;f=f|0;if(!((b|0)==0&(c|0)==0))do{e=e+-1|0;a[e>>0]=d[37041+(b&15)>>0]|0|f;b=bp(b|0,c|0,4)|0;c=z}while(!((b|0)==0&(c|0)==0));return e|0}function xn(b,c,d){b=b|0;c=c|0;d=d|0;if(!((b|0)==0&(c|0)==0))do{d=d+-1|0;a[d>>0]=b&7|48;b=bp(b|0,c|0,3)|0;c=z}while(!((b|0)==0&(c|0)==0));return d|0}function yn(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;if(c>>>0>0|(c|0)==0&b>>>0>4294967295)while(1){e=ap(b|0,c|0,10,0)|0;d=d+-1|0;a[d>>0]=e&255|48;e=b;b=$o(b|0,c|0,10,0)|0;if(!(c>>>0>9|(c|0)==9&e>>>0>4294967295))break;else c=z}if(b)while(1){d=d+-1|0;a[d>>0]=(b>>>0)%10|0|48;if(b>>>0<10)break;else b=(b>>>0)/10|0}return d|0}function zn(a){a=a|0;return In(a,c[5551]|0)|0}function An(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;h=d&255;f=(e|0)!=0;a:do if(f&(b&3|0)!=0){g=d&255;while(1){if((a[b>>0]|0)==g<<24>>24)break a;b=b+1|0;e=e+-1|0;f=(e|0)!=0;if(!(f&(b&3|0)!=0)){i=5;break}}}else i=5;while(0);b:do if((i|0)==5)if(f){g=d&255;if((a[b>>0]|0)!=g<<24>>24){f=O(h,16843009)|0;c:do if(e>>>0>3)while(1){h=c[b>>2]^f;if((h&-2139062144^-2139062144)&h+-16843009|0)break;b=b+4|0;e=e+-4|0;if(e>>>0<=3){i=11;break c}}else i=11;while(0);if((i|0)==11)if(!e){e=0;break}while(1){if((a[b>>0]|0)==g<<24>>24)break b;b=b+1|0;e=e+-1|0;if(!e){e=0;break}}}}else e=0;while(0);return (e|0?b:0)|0}function Bn(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0;g=l;l=l+256|0;f=g;if((c|0)>(d|0)&(e&73728|0)==0){e=c-d|0;gp(f|0,b|0,(e>>>0<256?e:256)|0)|0;if(e>>>0>255){d=e;do{tn(a,f,256);d=d+-256|0}while(d>>>0>255);e=e&255}tn(a,f,e)}l=g;return}function Cn(a,b){a=a|0;b=b|0;if(!a)a=0;else a=Hn(a,b)|0;return a|0}function Dn(b,e,f,g,h,i){b=b|0;e=+e;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,m=0,n=0,o=0,p=0,q=0,r=0.0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;H=l;l=l+560|0;m=H+8|0;u=H;G=H+524|0;F=G;n=H+512|0;c[u>>2]=0;E=n+12|0;En(e)|0;if((z|0)<0){D=1;B=37006;e=-e}else{D=(h&2049|0)!=0&1;B=(h&2048|0)==0?((h&1|0)==0?37007:37012):37009}En(e)|0;C=z&2146435072;do if(C>>>0<2146435072|(C|0)==2146435072&0<0){r=+Fn(e,u)*2.0;j=r!=0.0;if(j)c[u>>2]=(c[u>>2]|0)+-1;w=i|32;if((w|0)==97){s=i&32;q=(s|0)==0?B:B+9|0;p=D|2;j=12-g|0;do if(!(g>>>0>11|(j|0)==0)){e=8.0;do{j=j+-1|0;e=e*16.0}while((j|0)!=0);if((a[q>>0]|0)==45){e=-(e+(-r-e));break}else{e=r+e-e;break}}else e=r;while(0);k=c[u>>2]|0;j=(k|0)<0?0-k|0:k;j=yn(j,((j|0)<0)<<31>>31,E)|0;if((j|0)==(E|0)){j=n+11|0;a[j>>0]=48}a[j+-1>>0]=(k>>31&2)+43;o=j+-2|0;a[o>>0]=i+15;m=(g|0)<1;n=(h&8|0)==0;k=G;while(1){D=~~e;j=k+1|0;a[k>>0]=d[37041+D>>0]|s;e=(e-+(D|0))*16.0;if((j-F|0)==1?!(n&(m&e==0.0)):0){a[j>>0]=46;j=k+2|0}if(!(e!=0.0))break;else k=j}D=j-F|0;F=E-o|0;E=(g|0)!=0&(D+-2|0)<(g|0)?g+2|0:D;j=F+p+E|0;Bn(b,32,f,j,h);tn(b,q,p);Bn(b,48,f,j,h^65536);tn(b,G,D);Bn(b,48,E-D|0,0,0);tn(b,o,F);Bn(b,32,f,j,h^8192);break}k=(g|0)<0?6:g;if(j){j=(c[u>>2]|0)+-28|0;c[u>>2]=j;e=r*268435456.0}else{j=c[u>>2]|0;e=r}C=(j|0)<0?m:m+288|0;m=C;do{y=~~e>>>0;c[m>>2]=y;m=m+4|0;e=(e-+(y>>>0))*1.0e9}while(e!=0.0);if((j|0)>0){n=C;o=m;while(1){p=(j|0)<29?j:29;j=o+-4|0;if(j>>>0>=n>>>0){m=0;do{x=cp(c[j>>2]|0,0,p|0)|0;x=Xo(x|0,z|0,m|0,0)|0;y=z;v=ap(x|0,y|0,1e9,0)|0;c[j>>2]=v;m=$o(x|0,y|0,1e9,0)|0;j=j+-4|0}while(j>>>0>=n>>>0);if(m){n=n+-4|0;c[n>>2]=m}}m=o;while(1){if(m>>>0<=n>>>0)break;j=m+-4|0;if(!(c[j>>2]|0))m=j;else break}j=(c[u>>2]|0)-p|0;c[u>>2]=j;if((j|0)>0)o=m;else break}}else n=C;if((j|0)<0){g=((k+25|0)/9|0)+1|0;t=(w|0)==102;do{s=0-j|0;s=(s|0)<9?s:9;if(n>>>0>>0){p=(1<>>s;q=0;j=n;do{y=c[j>>2]|0;c[j>>2]=(y>>>s)+q;q=O(y&p,o)|0;j=j+4|0}while(j>>>0>>0);j=(c[n>>2]|0)==0?n+4|0:n;if(!q){n=j;j=m}else{c[m>>2]=q;n=j;j=m+4|0}}else{n=(c[n>>2]|0)==0?n+4|0:n;j=m}m=t?C:n;m=(j-m>>2|0)>(g|0)?m+(g<<2)|0:j;j=(c[u>>2]|0)+s|0;c[u>>2]=j}while((j|0)<0);j=n;g=m}else{j=n;g=m}y=C;if(j>>>0>>0){m=(y-j>>2)*9|0;o=c[j>>2]|0;if(o>>>0>=10){n=10;do{n=n*10|0;m=m+1|0}while(o>>>0>=n>>>0)}}else m=0;t=(w|0)==103;v=(k|0)!=0;n=k-((w|0)!=102?m:0)+((v&t)<<31>>31)|0;if((n|0)<(((g-y>>2)*9|0)+-9|0)){o=n+9216|0;n=C+4+(((o|0)/9|0)+-1024<<2)|0;o=((o|0)%9|0)+1|0;if((o|0)<9){p=10;do{p=p*10|0;o=o+1|0}while((o|0)!=9)}else p=10;q=c[n>>2]|0;s=(q>>>0)%(p>>>0)|0;o=(n+4|0)==(g|0);if(!(o&(s|0)==0)){r=(((q>>>0)/(p>>>0)|0)&1|0)==0?9007199254740992.0:9007199254740994.0;x=(p|0)/2|0;e=s>>>0>>0?.5:o&(s|0)==(x|0)?1.0:1.5;if(D){x=(a[B>>0]|0)==45;r=x?-r:r;e=x?-e:e}o=q-s|0;c[n>>2]=o;if(r+e!=r){x=o+p|0;c[n>>2]=x;if(x>>>0>999999999){m=n;while(1){n=m+-4|0;c[m>>2]=0;if(n>>>0>>0){j=j+-4|0;c[j>>2]=0}x=(c[n>>2]|0)+1|0;c[n>>2]=x;if(x>>>0>999999999)m=n;else break}}m=(y-j>>2)*9|0;p=c[j>>2]|0;if(p>>>0>=10){o=10;do{o=o*10|0;m=m+1|0}while(p>>>0>=o>>>0)}}}w=n+4|0;x=j;j=g>>>0>w>>>0?w:g}else{x=j;j=g}w=j;while(1){if(w>>>0<=x>>>0){u=0;break}j=w+-4|0;if(!(c[j>>2]|0))w=j;else{u=1;break}}g=0-m|0;do if(t){j=((v^1)&1)+k|0;if((j|0)>(m|0)&(m|0)>-5){k=j+-1-m|0;o=i+-1|0}else{k=j+-1|0;o=i+-2|0}j=h&8;if(!j){if(u?(A=c[w+-4>>2]|0,(A|0)!=0):0)if(!((A>>>0)%10|0)){j=10;n=0;do{j=j*10|0;n=n+1|0}while(!((A>>>0)%(j>>>0)|0|0))}else n=0;else n=9;j=((w-y>>2)*9|0)+-9|0;if((o|32|0)==102){i=j-n|0;i=(i|0)>0?i:0;s=0;k=(k|0)<(i|0)?k:i;break}else{i=j+m-n|0;i=(i|0)>0?i:0;s=0;k=(k|0)<(i|0)?k:i;break}}else s=j}else{s=h&8;o=i}while(0);t=k|s;p=(t|0)!=0&1;q=(o|32|0)==102;if(q){v=0;j=(m|0)>0?m:0}else{j=(m|0)<0?g:m;j=yn(j,((j|0)<0)<<31>>31,E)|0;n=E;if((n-j|0)<2)do{j=j+-1|0;a[j>>0]=48}while((n-j|0)<2);a[j+-1>>0]=(m>>31&2)+43;j=j+-2|0;a[j>>0]=o;v=j;j=n-j|0}j=D+1+k+p+j|0;Bn(b,32,f,j,h);tn(b,B,D);Bn(b,48,f,j,h^65536);if(q){p=x>>>0>C>>>0?C:x;s=G+9|0;q=s;o=G+8|0;n=p;do{m=yn(c[n>>2]|0,0,s)|0;if((n|0)==(p|0)){if((m|0)==(s|0)){a[o>>0]=48;m=o}}else if(m>>>0>G>>>0){gp(G|0,48,m-F|0)|0;do m=m+-1|0;while(m>>>0>G>>>0)}tn(b,m,q-m|0);n=n+4|0}while(n>>>0<=C>>>0);if(t|0)tn(b,37057,1);if(n>>>0>>0&(k|0)>0)while(1){m=yn(c[n>>2]|0,0,s)|0;if(m>>>0>G>>>0){gp(G|0,48,m-F|0)|0;do m=m+-1|0;while(m>>>0>G>>>0)}tn(b,m,(k|0)<9?k:9);n=n+4|0;m=k+-9|0;if(!(n>>>0>>0&(k|0)>9)){k=m;break}else k=m}Bn(b,48,k+9|0,9,0)}else{u=u?w:x+4|0;if((k|0)>-1){t=G+9|0;g=(s|0)==0;s=t;o=0-F|0;q=G+8|0;p=x;do{m=yn(c[p>>2]|0,0,t)|0;if((m|0)==(t|0)){a[q>>0]=48;m=q}do if((p|0)==(x|0)){n=m+1|0;tn(b,m,1);if(g&(k|0)<1){m=n;break}tn(b,37057,1);m=n}else{if(m>>>0<=G>>>0)break;gp(G|0,48,m+o|0)|0;do m=m+-1|0;while(m>>>0>G>>>0)}while(0);F=s-m|0;tn(b,m,(k|0)>(F|0)?F:k);k=k-F|0;p=p+4|0}while(p>>>0>>0&(k|0)>-1)}Bn(b,48,k+18|0,18,0);tn(b,v,E-v|0)}Bn(b,32,f,j,h^8192)}else{G=(i&32|0)!=0;j=D+3|0;Bn(b,32,f,j,h&-65537);tn(b,B,D);tn(b,e!=e|0.0!=0.0?(G?37033:37037):G?37025:37029,3);Bn(b,32,f,j,h^8192)}while(0);l=H;return ((j|0)<(f|0)?f:j)|0}function En(a){a=+a;var b=0;h[j>>3]=a;b=c[j>>2]|0;z=c[j+4>>2]|0;return b|0}function Fn(a,b){a=+a;b=b|0;return +(+Gn(a,b))}function Gn(a,b){a=+a;b=b|0;var d=0,e=0,f=0;h[j>>3]=a;d=c[j>>2]|0;e=c[j+4>>2]|0;f=bp(d|0,e|0,52)|0;switch(f&2047){case 0:{if(a!=0.0){a=+Gn(a*18446744073709551616.0,b);d=(c[b>>2]|0)+-64|0}else d=0;c[b>>2]=d;break}case 2047:break;default:{c[b>>2]=(f&2047)+-1022;c[j>>2]=d;c[j+4>>2]=e&-2146435073|1071644672;a=+h[j>>3]}}return +a}function Hn(b,d){b=b|0;d=d|0;do if(b){if(d>>>0<128){a[b>>0]=d;b=1;break}if(!(c[c[5551]>>2]|0))if((d&-128|0)==57216){a[b>>0]=d;b=1;break}else{c[10299]=84;b=-1;break}if(d>>>0<2048){a[b>>0]=d>>>6|192;a[b+1>>0]=d&63|128;b=2;break}if(d>>>0<55296|(d&-8192|0)==57344){a[b>>0]=d>>>12|224;a[b+1>>0]=d>>>6&63|128;a[b+2>>0]=d&63|128;b=3;break}if((d+-65536|0)>>>0<1048576){a[b>>0]=d>>>18|240;a[b+1>>0]=d>>>12&63|128;a[b+2>>0]=d>>>6&63|128;a[b+3>>0]=d&63|128;b=4;break}else{c[10299]=84;b=-1;break}}else b=1;while(0);return b|0}function In(b,e){b=b|0;e=e|0;var f=0,g=0;f=0;while(1){if((d[37059+f>>0]|0)==(b|0)){g=2;break}f=f+1|0;if((f|0)==87){f=87;b=37147;g=5;break}}if((g|0)==2)if(!f)f=37147;else{b=37147;g=5}if((g|0)==5)while(1){do{g=b;b=b+1|0}while((a[g>>0]|0)!=0);f=f+-1|0;if(!f){f=b;break}else g=5}return Jn(f,c[e+20>>2]|0)|0}function Jn(a,b){a=a|0;b=b|0;return Kn(a,b)|0}function Kn(a,b){a=a|0;b=b|0;if(!b)b=0;else b=Ln(c[b>>2]|0,c[b+4>>2]|0,a)|0;return (b|0?b:a)|0}function Ln(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;o=(c[b>>2]|0)+1794895138|0;h=Mn(c[b+8>>2]|0,o)|0;f=Mn(c[b+12>>2]|0,o)|0;g=Mn(c[b+16>>2]|0,o)|0;a:do if((h>>>0>>2>>>0?(n=d-(h<<2)|0,f>>>0>>0&g>>>0>>0):0)?((g|f)&3|0)==0:0){n=f>>>2;m=g>>>2;l=0;while(1){k=h>>>1;j=l+k|0;i=j<<1;g=i+n|0;f=Mn(c[b+(g<<2)>>2]|0,o)|0;g=Mn(c[b+(g+1<<2)>>2]|0,o)|0;if(!(g>>>0>>0&f>>>0<(d-g|0)>>>0)){f=0;break a}if(a[b+(g+f)>>0]|0){f=0;break a}f=mn(e,b+g|0)|0;if(!f)break;f=(f|0)<0;if((h|0)==1){f=0;break a}else{l=f?l:j;h=f?k:h-k|0}}f=i+m|0;g=Mn(c[b+(f<<2)>>2]|0,o)|0;f=Mn(c[b+(f+1<<2)>>2]|0,o)|0;if(f>>>0>>0&g>>>0<(d-f|0)>>>0)f=(a[b+(f+g)>>0]|0)==0?b+f|0:0;else f=0}else f=0;while(0);return f|0}function Mn(a,b){a=a|0;b=b|0;var c=0;c=dp(a|0)|0;return ((b|0)==0?a:c)|0}function Nn(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;g=e+16|0;f=c[g>>2]|0;if(!f)if(!(On(e)|0)){f=c[g>>2]|0;h=5}else f=0;else h=5;a:do if((h|0)==5){j=e+20|0;i=c[j>>2]|0;g=i;if((f-i|0)>>>0>>0){f=Ca[c[e+36>>2]&255](e,b,d)|0;break}b:do if((a[e+75>>0]|0)>-1){i=d;while(1){if(!i){h=g;e=0;g=d;f=b;break b}f=i+-1|0;if((a[b+f>>0]|0)==10)break;else i=f}f=Ca[c[e+36>>2]&255](e,b,i)|0;if(f>>>0>>0)break a;h=c[j>>2]|0;e=i;g=d-i|0;f=b+i|0}else{h=g;e=0;g=d;f=b}while(0);ep(h|0,f|0,g|0)|0;c[j>>2]=(c[j>>2]|0)+g;f=e+g|0}while(0);return f|0}function On(b){b=b|0;var d=0,e=0;d=b+74|0;e=a[d>>0]|0;a[d>>0]=e+255|e;d=c[b>>2]|0;if(!(d&8)){c[b+8>>2]=0;c[b+4>>2]=0;d=c[b+44>>2]|0;c[b+28>>2]=d;c[b+20>>2]=d;c[b+16>>2]=d+(c[b+48>>2]|0);d=0}else{c[b>>2]=d|32;d=-1}return d|0}function Pn(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;e=a+20|0;f=c[e>>2]|0;a=(c[a+16>>2]|0)-f|0;a=a>>>0>d>>>0?d:a;ep(f|0,b|0,a|0)|0;c[e>>2]=(c[e>>2]|0)+a;return d|0}function Qn(a){a=a|0;return (a+-32|0)>>>0<95|0}function Rn(a){a=a|0;Sn(c[a>>2]|0);Wm(a);return}function Sn(a){a=a|0;var b=0,d=0;b=l;l=l+16|0;d=b;c[d>>2]=en(a)|0;a=oa(6,d|0)|0;cn((a|0)==-4?0:a)|0;l=b;return}function Tn(a){a=a|0;var b=0,d=0,e=0;e=l;l=l+16|0;d=e+8|0;b=Un(a,589824,e)|0;do if((b|0)>=0){a=Xm(1,2072)|0;if(!a){c[d>>2]=b;oa(6,d|0)|0;a=0;break}else{c[a>>2]=b;break}}else a=0;while(0);l=e;return a|0}function Un(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;h=l;l=l+48|0;g=h+16|0;f=h;e=h+32|0;if(!(b&4194368))e=0;else{c[e>>2]=d;i=(c[e>>2]|0)+(4-1)&~(4-1);d=c[i>>2]|0;c[e>>2]=i+4;e=d}c[f>>2]=a;c[f+4>>2]=b|32768;c[f+8>>2]=e;e=ma(5,f|0)|0;if(!((b&524288|0)==0|(e|0)<0)){c[g>>2]=e;c[g+4>>2]=2;c[g+8>>2]=1;la(221,g|0)|0}i=cn(e)|0;l=h;return i|0}function Vn(a){a=a|0;var b=0,d=0,f=0,g=0,h=0,i=0;i=l;l=l+16|0;d=i;g=a+8|0;b=c[g>>2]|0;f=a+12|0;a:do if((b|0)<(c[f>>2]|0))h=6;else{c[d>>2]=c[a>>2];c[d+4>>2]=a+24;c[d+8>>2]=2048;b=ka(220,d|0)|0;if((b|0)>=1){c[f>>2]=b;c[g>>2]=0;b=0;h=6;break}switch(b|0){case 0:case -2:{b=0;break a}default:{}}c[10299]=0-b;b=0}while(0);if((h|0)==6){h=a+24+b|0;c[g>>2]=(e[h+8>>1]|0)+b;c[a+4>>2]=c[h+4>>2];b=h}l=i;return b|0}function Wn(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0;m=l;l=l+208|0;j=m+8|0;k=m;f=b<<2;i=k;c[i>>2]=1;c[i+4>>2]=0;a:do if(f|0){c[j+4>>2]=4;c[j>>2]=4;b=4;d=4;e=2;while(1){b=b+4+d|0;c[j+(e<<2)>>2]=b;if(b>>>0>>0){i=d;d=b;e=e+1|0;b=i}else break}g=a+f+-4|0;if(g>>>0>a>>>0){h=g;i=k+4|0;e=1;d=a;b=1;do{do if((e&3|0)!=3){f=b+-1|0;if((c[j+(f<<2)>>2]|0)>>>0<(h-d|0)>>>0)Xn(d,b,j);else Zn(d,e,c[i>>2]|0,b,0,j);if((b|0)==1){_n(k,1);b=0;break}else{_n(k,f);b=1;break}}else{Xn(d,b,j);Yn(k,2);b=b+2|0}while(0);e=c[k>>2]|1;c[k>>2]=e;d=d+4|0}while(d>>>0>>0);g=i;f=c[i>>2]|0}else{g=k+4|0;f=0;e=1;d=a;b=1}Zn(d,e,f,b,0,j);f=k+4|0;while(1){if((b|0)==1&(e|0)==1){if(!(c[f>>2]|0))break a}else if((b|0)>=2){_n(k,2);a=b+-2|0;c[k>>2]=c[k>>2]^7;Yn(k,1);Zn(d+(0-(c[j+(a<<2)>>2]|0))+-4|0,c[k>>2]|0,c[g>>2]|0,b+-1|0,1,j);_n(k,1);e=c[k>>2]|1;c[k>>2]=e;i=d+-4|0;Zn(i,e,c[g>>2]|0,a,1,j);d=i;b=a;continue}a=$n(k)|0;Yn(k,a);e=c[k>>2]|0;d=d+-4|0;b=a+b|0}}while(0);l=m;return}function Xn(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;k=l;l=l+240|0;j=k;c[j>>2]=a;a:do if((b|0)>1){i=a;e=a;a=1;while(1){e=e+-4|0;g=b+-2|0;f=e+(0-(c[d+(g<<2)>>2]|0))|0;if((Lh(i,f)|0)>-1?(Lh(i,e)|0)>-1:0)break a;h=a+1|0;a=j+(a<<2)|0;if((Lh(f,e)|0)>-1){c[a>>2]=f;a=f;b=b+-1|0}else{c[a>>2]=e;a=e;b=g}if((b|0)<=1){a=h;break a}i=c[j>>2]|0;e=a;a=h}}else a=1;while(0);bo(j,a);l=k;return}function Yn(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=a+4|0;if(b>>>0>31){d=c[f>>2]|0;c[a>>2]=d;c[f>>2]=0;e=0;b=b+-32|0}else{d=c[a>>2]|0;e=c[f>>2]|0}c[a>>2]=e<<32-b|d>>>b;c[f>>2]=e>>>b;return}function Zn(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,m=0,n=0;n=l;l=l+240|0;k=n+232|0;m=n;c[k>>2]=b;j=k+4|0;c[j>>2]=d;c[m>>2]=a;a:do if((b|0)!=1|(d|0)!=0?(h=a+(0-(c[g+(e<<2)>>2]|0))|0,(Lh(h,a)|0)>=1):0){b=h;i=1;h=(f|0)==0;while(1){if(h&(e|0)>1){h=a+-4|0;if((Lh(h,b)|0)>-1){b=a;h=i;d=10;break a}if((Lh(h+(0-(c[g+(e+-2<<2)>>2]|0))|0,b)|0)>-1){b=a;h=i;d=10;break a}}d=i+1|0;c[m+(i<<2)>>2]=b;f=$n(k)|0;Yn(k,f);e=f+e|0;if(!((c[k>>2]|0)!=1|(c[j>>2]|0)!=0)){h=d;d=10;break a}h=b+(0-(c[g+(e<<2)>>2]|0))|0;if((Lh(h,c[m>>2]|0)|0)<1){h=d;d=10;break}else{a=b;b=h;i=d;h=1}}}else d=9;while(0);if((d|0)==9?(f|0)==0:0){b=a;h=1;d=10}if((d|0)==10){bo(m,h);Xn(b,e,g)}l=n;return}function _n(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;f=a+4|0;if(b>>>0>31){d=c[a>>2]|0;c[f>>2]=d;c[a>>2]=0;e=0;b=b+-32|0}else{d=c[f>>2]|0;e=c[a>>2]|0}c[f>>2]=e>>>(32-b|0)|d<>2]=e<>2]|0)+-1|0)|0;if(!b){a=ao(c[a+4>>2]|0)|0;return ((a|0)==0?0:a+32|0)|0}else return b|0;return 0}function ao(a){a=a|0;var b=0;if(a)if(!(a&1)){b=0;do{b=b+1|0;a=a>>>1}while(!(a&1|0))}else b=0;else b=32;return b|0}function bo(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;i=l;l=l+256|0;f=i;a:do if((e|0)>=2){c[b+(e<<2)>>2]=f;h=c[b>>2]|0;c[f>>2]=d[h>>0]|d[h+1>>0]<<8|d[h+2>>0]<<16|d[h+3>>0]<<24;f=0;while(1){j=b+(f<<2)|0;f=f+1|0;g=b+(f<<2)|0;k=c[g>>2]|0;k=d[k>>0]|d[k+1>>0]<<8|d[k+2>>0]<<16|d[k+3>>0]<<24;a[h>>0]=k;a[h+1>>0]=k>>8;a[h+2>>0]=k>>16;a[h+3>>0]=k>>24;c[j>>2]=(c[j>>2]|0)+4;if((f|0)==(e|0))break a;h=c[g>>2]|0}}while(0);l=i;return}function co(a){a=a|0;var b=0.0,d=0,e=0;if((a|0)<=1023)if((a|0)<-1022){e=a+1022|0;d=(e|0)<-1022;a=a+2044|0;a=d?((a|0)>-1022?a:-1022):e;b=d?0.0:2.2250738585072014e-308}else b=1.0;else{d=a+-1023|0;e=(d|0)>1023;a=a+-2046|0;a=e?((a|0)<1023?a:1023):d;b=e?t:8988465674311579538646525.0e283}d=cp(a+1023|0,0,52)|0;e=z;c[j>>2]=d;c[j+4>>2]=e;return +(b*+h[j>>3])}function eo(b,c){b=b|0;c=c|0;var e=0,f=0,g=0;e=a[b>>0]|0;f=e&255;a:do if(e<<24>>24){g=b;do{b=a[c>>0]|0;if(!(b<<24>>24))break a;if(e<<24>>24!=b<<24>>24?(e=hn(f)|0,(e|0)!=(hn(b&255)|0)):0)break a;g=g+1|0;c=c+1|0;e=a[g>>0]|0;f=e&255}while(e<<24>>24!=0)}while(0);g=hn(f)|0;return g-(hn(d[c>>0]|0)|0)|0}function fo(b){b=b|0;var d=0,e=0,f=0;f=b;a:do if(!(f&3)){d=b;e=4}else{d=f;while(1){if(!(a[b>>0]|0))break a;b=b+1|0;d=b;if(!(d&3)){d=b;e=4;break}}}while(0);if((e|0)==4){while(1){b=c[d>>2]|0;if(!((b&-2139062144^-2139062144)&b+-16843009))d=d+4|0;else break}if((b&255)<<24>>24)do d=d+1|0;while((a[d>>0]|0)!=0)}return d-f|0}function go(b,c){b=b|0;c=c|0;b=ho(b,c)|0;return ((a[b>>0]|0)==(c&255)<<24>>24?b:0)|0}function ho(b,d){b=b|0;d=d|0;var e=0,f=0,g=0;f=d&255;a:do if(!f)b=b+(fo(b)|0)|0;else{if(b&3){e=d&255;do{g=a[b>>0]|0;if(g<<24>>24==0?1:g<<24>>24==e<<24>>24)break a;b=b+1|0}while((b&3|0)!=0)}f=O(f,16843009)|0;e=c[b>>2]|0;b:do if(!((e&-2139062144^-2139062144)&e+-16843009))do{g=e^f;if((g&-2139062144^-2139062144)&g+-16843009|0)break b;b=b+4|0;e=c[b>>2]|0}while(!((e&-2139062144^-2139062144)&e+-16843009|0));while(0);e=d&255;while(1){g=a[b>>0]|0;if(g<<24>>24==0?1:g<<24>>24==e<<24>>24)break;else b=b+1|0}}while(0);return b|0}function io(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;f=l;l=l+16|0;g=f;c[g>>2]=e;pn(a,b,d,g);l=f;return}function jo(a){a=a|0;return +(+co(a))}function ko(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=O(c,b)|0;d=Nn(a,e,d)|0;if((d|0)==(e|0))d=(b|0)==0?0:c;else d=(d>>>0)/(b>>>0)|0;return d|0}function lo(a){a=a|0;var b=0;if(c[a+68>>2]|0){b=c[a+116>>2]|0;a=a+112|0;if(b|0)c[b+112>>2]=c[a>>2];a=c[a>>2]|0;c[((a|0)==0?22248:a+116|0)>>2]=b}return}function mo(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,m=0;m=l;l=l+16|0;j=m;k=e&255;a[j>>0]=k;h=b+16|0;g=c[h>>2]|0;if(!g)if(!(On(b)|0)){g=c[h>>2]|0;i=4}else f=-1;else i=4;do if((i|0)==4){i=b+20|0;h=c[i>>2]|0;if(h>>>0>>0?(f=e&255,(f|0)!=(a[b+75>>0]|0)):0){c[i>>2]=h+1;a[h>>0]=k;break}if((Ca[c[b+36>>2]&255](b,j,1)|0)==1)f=d[j>>0]|0;else f=-1}while(0);l=m;return f|0}function no(a,b){a=a|0;b=b|0;var d=0,e=0;d=l;l=l+16|0;e=d;c[e>>2]=a;c[e+4>>2]=b;a=cn(ja(195,e|0)|0)|0;l=d;return a|0}function oo(a){a=a|0;var b=0,c=0;c=(fo(a)|0)+1|0;b=Vm(c)|0;if(!b)b=0;else ep(b|0,a|0,c|0)|0;return b|0}function po(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;i=l;l=l+48|0;h=i+32|0;g=i+16|0;e=i;if(An(38951,a[d>>0]|0,4)|0){f=qo(d)|0;c[e>>2]=b;c[e+4>>2]=f|32768;c[e+8>>2]=438;e=cn(ma(5,e|0)|0)|0;if((e|0)>=0){if(f&524288|0){c[g>>2]=e;c[g+4>>2]=2;c[g+8>>2]=1;la(221,g|0)|0}b=ro(e,d)|0;if(!b){c[h>>2]=e;oa(6,h|0)|0;b=0}}else b=0}else{c[10299]=22;b=0}l=i;return b|0}function qo(b){b=b|0;var c=0,d=0,e=0;d=(go(b,43)|0)==0;c=a[b>>0]|0;d=d?c<<24>>24!=114&1:2;e=(go(b,120)|0)==0;d=e?d:d|128;b=(go(b,101)|0)==0;b=b?d:d|524288;b=c<<24>>24==114?b:b|64;b=c<<24>>24==119?b|512:b;return (c<<24>>24==97?b|1024:b)|0}function ro(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,o=0;o=l;l=l+64|0;m=o+40|0;k=o+24|0;j=o+16|0;g=o;n=o+56|0;f=a[d>>0]|0;if(An(38951,f<<24>>24,4)|0){e=Vm(1156)|0;if(!e)e=0;else{h=e;i=h+124|0;do{c[h>>2]=0;h=h+4|0}while((h|0)<(i|0));if(!(go(d,43)|0))c[e>>2]=f<<24>>24==114?8:4;if(go(d,101)|0){c[g>>2]=b;c[g+4>>2]=2;c[g+8>>2]=1;la(221,g|0)|0;f=a[d>>0]|0}if(f<<24>>24==97){c[j>>2]=b;c[j+4>>2]=3;f=la(221,j|0)|0;if(!(f&1024)){c[k>>2]=b;c[k+4>>2]=4;c[k+8>>2]=f|1024;la(221,k|0)|0}d=c[e>>2]|128;c[e>>2]=d}else d=c[e>>2]|0;c[e+60>>2]=b;c[e+44>>2]=e+132;c[e+48>>2]=1024;f=e+75|0;a[f>>0]=-1;if((d&8|0)==0?(c[m>>2]=b,c[m+4>>2]=21523,c[m+8>>2]=n,(na(54,m|0)|0)==0):0)a[f>>0]=10;c[e+32>>2]=148;c[e+36>>2]=144;c[e+40>>2]=145;c[e+12>>2]=1;if(!(c[10284]|0))c[e+76>>2]=-1;so(e)|0}}else{c[10299]=22;e=0}l=o;return e|0}function so(a){a=a|0;var b=0;to();b=c[10302]|0;c[a+56>>2]=b;if(b|0)c[b+52>>2]=a;c[10302]=a;uo();return a|0}function to(){da(41200);return}function uo(){pa(41200);return}function vo(a){a=a|0;var b=0,d=0,e=0;lo(a);e=(c[a>>2]&1|0)!=0;if(!e){to();d=c[a+52>>2]|0;b=a+56|0;if(d|0)c[d+56>>2]=c[b>>2];b=c[b>>2]|0;if(b|0)c[b+52>>2]=d;if((c[10302]|0)==(a|0))c[10302]=b;uo()}d=wo(a)|0;d=Aa[c[a+12>>2]&1](a)|0|d;b=c[a+92>>2]|0;if(b|0)Wm(b);if(!e)Wm(a);return d|0}function wo(a){a=a|0;var b=0;if(!a){if(!(c[5472]|0))a=0;else a=wo(c[5472]|0)|0;to();b=c[10302]|0;if(b)do{if((c[b+20>>2]|0)>>>0>(c[b+28>>2]|0)>>>0)a=xo(b)|0|a;b=c[b+56>>2]|0}while((b|0)!=0);uo()}else a=xo(a)|0;return a|0}function xo(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;h=a+20|0;g=a+28|0;if((c[h>>2]|0)>>>0>(c[g>>2]|0)>>>0?(Ca[c[a+36>>2]&255](a,0,0)|0,(c[h>>2]|0)==0):0)b=-1;else{f=a+4|0;b=c[f>>2]|0;e=a+8|0;d=c[e>>2]|0;if(b>>>0>>0)Ca[c[a+40>>2]&255](a,b-d|0,1)|0;c[a+16>>2]=0;c[g>>2]=0;c[h>>2]=0;c[e>>2]=0;c[f>>2]=0;b=0}return b|0}function yo(a){a=a|0;return (c[a>>2]|0)>>>4&1|0}function zo(a){a=a|0;return (c[a>>2]|0)>>>5&1|0}function Ao(a,b,c){a=a|0;b=b|0;c=c|0;return Co(a,b,c)|0}function Bo(a,b,d){a=a|0;b=b|0;d=d|0;var e=0;a=l;l=l+16|0;e=a;c[e>>2]=d;qn(21640,b,e)|0;l=a;return}function Co(a,b,c){a=a|0;b=b|0;c=c|0;return Do(a,b,c)|0}function Do(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0;if((d|0)==1)b=b-(c[a+8>>2]|0)+(c[a+4>>2]|0)|0;f=a+20|0;e=a+28|0;if((c[f>>2]|0)>>>0>(c[e>>2]|0)>>>0?(Ca[c[a+36>>2]&255](a,0,0)|0,(c[f>>2]|0)==0):0)b=-1;else{c[a+16>>2]=0;c[e>>2]=0;c[f>>2]=0;if((Ca[c[a+40>>2]&255](a,b,d)|0)<0)b=-1;else{c[a+8>>2]=0;c[a+4>>2]=0;c[a>>2]=c[a>>2]&-17;b=0}}return b|0}function Eo(a,b){a=a|0;b=b|0;return Fo(a,b,(fo(a)|0)+1|0)|0}function Fo(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;e=c&255;do{if(!d){c=0;break}d=d+-1|0;c=b+d|0}while((a[c>>0]|0)!=e<<24>>24);return c|0}function Go(a){a=a|0;var b=0,d=0;b=l;l=l+16|0;d=b;c[d>>2]=a;cn(fa(10,d|0)|0)|0;l=b;return}function Ho(a,b,c){a=a|0;b=b|0;c=c|0;Io(a,b,c);return a|0}function Io(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;g=d;a:do if(!((g^b)&3)){f=(e|0)!=0;if(f&(g&3|0)!=0)do{g=a[d>>0]|0;a[b>>0]=g;if(!(g<<24>>24))break a;e=e+-1|0;d=d+1|0;b=b+1|0;f=(e|0)!=0}while(f&(d&3|0)!=0);if(f){if(a[d>>0]|0){b:do if(e>>>0>3){f=d;while(1){d=c[f>>2]|0;if((d&-2139062144^-2139062144)&d+-16843009|0){d=f;break b}c[b>>2]=d;e=e+-4|0;d=f+4|0;b=b+4|0;if(e>>>0>3)f=d;else break}}while(0);h=11}}else e=0}else h=11;while(0);c:do if((h|0)==11)if(!e)e=0;else while(1){h=a[d>>0]|0;a[b>>0]=h;if(!(h<<24>>24))break c;e=e+-1|0;b=b+1|0;if(!e){e=0;break}else d=d+1|0}while(0);gp(b|0,0,e|0)|0;return}function Jo(){var a=0,b=0,d=0;b=38968;b=Wo(c[b>>2]|0,c[b+4>>2]|0,1284865837,1481765933)|0;b=Xo(b|0,z|0,1,0)|0;a=z;d=38968;c[d>>2]=b;c[d+4>>2]=a;a=bp(b|0,a|0,33)|0;return a|0}function Ko(a){a=a|0;var b=0,e=0,f=0;do if((c[a+76>>2]|0)>=0?(sn()|0)!=0:0){e=a+4|0;b=c[e>>2]|0;if(b>>>0<(c[a+8>>2]|0)>>>0){c[e>>2]=b+1;b=d[b>>0]|0;break}else{b=kn(a)|0;break}}else f=3;while(0);do if((f|0)==3){e=a+4|0;b=c[e>>2]|0;if(b>>>0<(c[a+8>>2]|0)>>>0){c[e>>2]=b+1;b=d[b>>0]|0;break}else{b=kn(a)|0;break}}while(0);return b|0}function Lo(a){a=a|0;return Mo(a)|0}function Mo(a){a=a|0;var b=0;if(!(c[a>>2]&128))b=1;else b=(c[a+20>>2]|0)>>>0>(c[a+28>>2]|0)>>>0?2:1;b=Ca[c[a+40>>2]&255](a,0,b)|0;if((b|0)>=0)b=b-(c[a+8>>2]|0)+(c[a+4>>2]|0)+(c[a+20>>2]|0)-(c[a+28>>2]|0)|0;return b|0}function No(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;g=b&255;h=b&255;do if((c[d+76>>2]|0)>=0?(sn()|0)!=0:0){if((h|0)!=(a[d+75>>0]|0)?(j=d+20|0,f=c[j>>2]|0,f>>>0<(c[d+16>>2]|0)>>>0):0){c[j>>2]=f+1;a[f>>0]=g;break}mo(d,b)|0}else k=3;while(0);do if((k|0)==3){if((h|0)!=(a[d+75>>0]|0)?(i=d+20|0,e=c[i>>2]|0,e>>>0<(c[d+16>>2]|0)>>>0):0){c[i>>2]=e+1;a[e>>0]=g;break}mo(d,b)|0}while(0);return}function Oo(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0;j=O(e,d)|0;e=(d|0)==0?0:e;h=f+74|0;g=a[h>>0]|0;a[h>>0]=g+255|g;h=f+4|0;g=c[h>>2]|0;k=(c[f+8>>2]|0)-g|0;i=k>>>0>>0?k:j;if((k|0)>0){ep(b|0,g|0,i|0)|0;c[h>>2]=g+i;g=b+i|0;h=j-i|0}else{g=b;h=j}a:do if(h){i=f+32|0;while(1){if(ln(f)|0)break;b=Ca[c[i>>2]&255](f,g,h)|0;if((b+1|0)>>>0<2)break;h=h-b|0;if(!h)break a;else g=g+b|0}e=((j-h|0)>>>0)/(d>>>0)|0}while(0);return e|0}function Po(a){a=a|0;return Lo(a)|0}function Qo(a,b){a=a|0;b=b|0;var d=0,e=0;d=l;l=l+16|0;e=d;c[e>>2]=b;qn(21764,a,e)|0;l=d;return}function Ro(b){b=b|0;var d=0,e=0,f=0;f=l;l=l+16|0;e=f;ca(0,e|0)|0;d=0;e=(c[e+4>>2]|0)*65537^(e>>>4)+b;while(1){a[b+d>>0]=(e&15)+65|e<<1&32;d=d+1|0;if((d|0)==6)break;else e=e>>>5}l=f;return b|0}function So(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0;i=l;l=l+16|0;g=i;d=fo(b)|0;a:do if(d>>>0>=6?(f=b+d+-6|0,(nn(f,38955,6)|0)==0):0){e=100;do{Ro(f)|0;c[g>>2]=384;d=Un(b,194,g)|0;if((d|0)>-1)break a;e=e+-1|0}while((e|0)!=0&(c[10299]|0)==17);a[f>>0]=a[38955]|0;a[f+1>>0]=a[38956]|0;a[f+2>>0]=a[38957]|0;a[f+3>>0]=a[38958]|0;a[f+4>>0]=a[38959]|0;a[f+5>>0]=a[38960]|0;d=-1}else h=3;while(0);if((h|0)==3){c[10299]=22;d=-1}l=i;return d|0}function To(a){a=a|0;return So(a)|0}function Uo(){}function Vo(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;f=a&65535;e=b&65535;c=O(e,f)|0;d=a>>>16;a=(c>>>16)+(O(e,d)|0)|0;e=b>>>16;b=O(e,f)|0;return (z=(a>>>16)+(O(e,d)|0)+(((a&65535)+b|0)>>>16)|0,a+b<<16|c&65535|0)|0}function Wo(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;e=a;f=c;c=Vo(e,f)|0;a=z;return (z=(O(b,f)|0)+(O(d,e)|0)+a|a&0,c|0|0)|0}function Xo(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;c=a+c>>>0;return (z=b+d+(c>>>0>>0|0)>>>0,c|0)|0}function Yo(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;d=b-d-(c>>>0>a>>>0|0)>>>0;return (z=d,a-c>>>0|0)|0}function Zo(b){b=b|0;var c=0;c=a[n+(b&255)>>0]|0;if((c|0)<8)return c|0;c=a[n+(b>>8&255)>>0]|0;if((c|0)<8)return c+8|0;c=a[n+(b>>16&255)>>0]|0;if((c|0)<8)return c+16|0;return (a[n+(b>>>24)>>0]|0)+24|0}function _o(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;l=a;j=b;k=j;h=d;n=e;i=n;if(!k){g=(f|0)!=0;if(!i){if(g){c[f>>2]=(l>>>0)%(h>>>0);c[f+4>>2]=0}n=0;f=(l>>>0)/(h>>>0)>>>0;return (z=n,f)|0}else{if(!g){n=0;f=0;return (z=n,f)|0}c[f>>2]=a|0;c[f+4>>2]=b&0;n=0;f=0;return (z=n,f)|0}}g=(i|0)==0;do if(h){if(!g){g=(R(i|0)|0)-(R(k|0)|0)|0;if(g>>>0<=31){m=g+1|0;i=31-g|0;b=g-31>>31;h=m;a=l>>>(m>>>0)&b|k<>>(m>>>0)&b;g=0;i=l<>2]=a|0;c[f+4>>2]=j|b&0;n=0;f=0;return (z=n,f)|0}g=h-1|0;if(g&h|0){i=(R(h|0)|0)+33-(R(k|0)|0)|0;p=64-i|0;m=32-i|0;j=m>>31;o=i-32|0;b=o>>31;h=i;a=m-1>>31&k>>>(o>>>0)|(k<>>(i>>>0))&b;b=b&k>>>(i>>>0);g=l<>>(o>>>0))&j|l<>31;break}if(f|0){c[f>>2]=g&l;c[f+4>>2]=0}if((h|0)==1){o=j|b&0;p=a|0|0;return (z=o,p)|0}else{p=Zo(h|0)|0;o=k>>>(p>>>0)|0;p=k<<32-p|l>>>(p>>>0)|0;return (z=o,p)|0}}else{if(g){if(f|0){c[f>>2]=(k>>>0)%(h>>>0);c[f+4>>2]=0}o=0;p=(k>>>0)/(h>>>0)>>>0;return (z=o,p)|0}if(!l){if(f|0){c[f>>2]=0;c[f+4>>2]=(k>>>0)%(i>>>0)}o=0;p=(k>>>0)/(i>>>0)>>>0;return (z=o,p)|0}g=i-1|0;if(!(g&i)){if(f|0){c[f>>2]=a|0;c[f+4>>2]=g&k|b&0}o=0;p=k>>>((Zo(i|0)|0)>>>0);return (z=o,p)|0}g=(R(i|0)|0)-(R(k|0)|0)|0;if(g>>>0<=30){b=g+1|0;i=31-g|0;h=b;a=k<>>(b>>>0);b=k>>>(b>>>0);g=0;i=l<>2]=a|0;c[f+4>>2]=j|b&0;o=0;p=0;return (z=o,p)|0}while(0);if(!h){k=i;j=0;i=0}else{m=d|0|0;l=n|e&0;k=Xo(m|0,l|0,-1,-1)|0;d=z;j=i;i=0;do{e=j;j=g>>>31|j<<1;g=i|g<<1;e=a<<1|e>>>31|0;n=a>>>31|b<<1|0;Yo(k|0,d|0,e|0,n|0)|0;p=z;o=p>>31|((p|0)<0?-1:0)<<1;i=o&1;a=Yo(e|0,n|0,o&m|0,(((p|0)<0?-1:0)>>31|((p|0)<0?-1:0)<<1)&l|0)|0;b=z;h=h-1|0}while((h|0)!=0);k=j;j=0}h=0;if(f|0){c[f>>2]=a;c[f+4>>2]=b}o=(g|0)>>>31|(k|h)<<1|(h<<1|g>>>31)&0|j;p=(g<<1|0>>>31)&-2|i;return (z=o,p)|0}function $o(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return _o(a,b,c,d,0)|0}function ap(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;g=l;l=l+16|0;f=g|0;_o(a,b,d,e,f)|0;l=g;return (z=c[f+4>>2]|0,c[f>>2]|0)|0}function bp(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){z=b>>>c;return a>>>c|(b&(1<>>c-32|0}function cp(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){z=b<>>32-c;return a<>8&255)<<16|(a>>16&255)<<8|a>>>24|0}function ep(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;if((e|0)>=8192)return ta(b|0,d|0,e|0)|0;h=b|0;g=b+e|0;if((b&3)==(d&3)){while(b&3){if(!e)return h|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}e=g&-4|0;f=e-64|0;while((b|0)<=(f|0)){c[b>>2]=c[d>>2];c[b+4>>2]=c[d+4>>2];c[b+8>>2]=c[d+8>>2];c[b+12>>2]=c[d+12>>2];c[b+16>>2]=c[d+16>>2];c[b+20>>2]=c[d+20>>2];c[b+24>>2]=c[d+24>>2];c[b+28>>2]=c[d+28>>2];c[b+32>>2]=c[d+32>>2];c[b+36>>2]=c[d+36>>2];c[b+40>>2]=c[d+40>>2];c[b+44>>2]=c[d+44>>2];c[b+48>>2]=c[d+48>>2];c[b+52>>2]=c[d+52>>2];c[b+56>>2]=c[d+56>>2];c[b+60>>2]=c[d+60>>2];b=b+64|0;d=d+64|0}while((b|0)<(e|0)){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0}}else{e=g-4|0;while((b|0)<(e|0)){a[b>>0]=a[d>>0]|0;a[b+1>>0]=a[d+1>>0]|0;a[b+2>>0]=a[d+2>>0]|0;a[b+3>>0]=a[d+3>>0]|0;b=b+4|0;d=d+4|0}}while((b|0)<(g|0)){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0}return h|0}function fp(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;if((c|0)<(b|0)&(b|0)<(c+d|0)){e=b;c=c+d|0;b=b+d|0;while((d|0)>0){b=b-1|0;c=c-1|0;d=d-1|0;a[b>>0]=a[c>>0]|0}b=e}else ep(b,c,d)|0;return b|0}function gp(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;h=b+e|0;d=d&255;if((e|0)>=67){while(b&3){a[b>>0]=d;b=b+1|0}f=h&-4|0;g=f-64|0;i=d|d<<8|d<<16|d<<24;while((b|0)<=(g|0)){c[b>>2]=i;c[b+4>>2]=i;c[b+8>>2]=i;c[b+12>>2]=i;c[b+16>>2]=i;c[b+20>>2]=i;c[b+24>>2]=i;c[b+28>>2]=i;c[b+32>>2]=i;c[b+36>>2]=i;c[b+40>>2]=i;c[b+44>>2]=i;c[b+48>>2]=i;c[b+52>>2]=i;c[b+56>>2]=i;c[b+60>>2]=i;b=b+64|0}while((b|0)<(f|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}return h-e|0}function hp(a){a=+a;return a>=0.0?+A(a+.5):+N(a-.5)}function ip(a){a=a|0;var b=0,d=0;d=a+15&-16|0;b=c[i>>2]|0;a=b+d|0;if((d|0)>0&(a|0)<(b|0)|(a|0)<0){W()|0;ea(12);return -1}c[i>>2]=a;if((a|0)>(V()|0)?(U()|0)==0:0){c[i>>2]=b;ea(12);return -1}return b|0}function jp(a,b){a=a|0;b=b|0;return Aa[a&1](b|0)|0}function kp(a,b,c){a=a|0;b=b|0;c=c|0;return Ba[a&63](b|0,c|0)|0}function lp(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return Ca[a&255](b|0,c|0,d|0)|0}function mp(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;return Da[a&127](b|0,c|0,d|0,e|0)|0}function np(a,b,c){a=a|0;b=b|0;c=c|0;Ea[a&1](b|0,c|0)}function op(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;Fa[a&31](b|0,c|0,d|0,e|0,f|0,g|0,h|0,i|0,j|0)}function pp(a){a=a|0;S(0);return 0}function qp(a,b){a=a|0;b=b|0;S(1);return 0}function rp(a,b,c){a=a|0;b=b|0;c=c|0;S(2);return 0}function sp(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;S(3);return 0}function tp(a,b){a=a|0;b=b|0;S(4)}function up(a,b,c,d,e,f,g,h,i){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;S(5)} // EMSCRIPTEN_END_FUNCS -var Ha=[np,Hk,Ik,cl,dl,Um,np,np];var Ia=[op,pg,rg,tg,vg,xg,zg,Bg,Dg,Fg,Hg,Kg,Mg,Og,Qg,Sg,Ug,Wg,Yg,_g,ah,ch,gh,ih,kh,mh,oh,qh,sh,yh,Ah,Ch,Eh,Hh,Jh,Lh,Nh,Gk,bl,op,op,op,op,op,op,op,op,op,op,op,op,op,op,op,op,op,op,op,op,op,op,op,op,op];var Ja=[pp,gb,hb,bc,cc,fc,gc,ic,jc,lc,mc,nc,oc,pc,qc,rc,sc,tc,uc,vc,wc,Fc,Gc,Kc,Lc,Mc,Nc,Oc,Pc,gd,hd,md,nd,od,pd,ud,vd,xd,yd,Bd,Cd,Dd,Ed,Id,Jd,Ld,Md,Nd,Od,Pd,Qd,Rd,Sd,Td,Ud,Xd,Yd,Zd,_d,he,ie,je,ke,le,me,we,xe,ye,ze,Ae,Be,De,Ee,Le,Me,Ne,Oe,$e,af,ef,ff,gf,hf,mf,nf,vf,wf,Df,Ef,Ff,Gf,If,Jf,Lf,Mf,Tf,Uf,$f,ag,bg,cg,dg,eg,fg,gg,hg,ig,og,qg,sg,ug,wg,yg,Ag,Cg,Eg,Gg,Ig,Jg,Lg,Ng,Pg,Rg,Tg,Vg,Xg,Zg,$g,bh,dh,eh,fh,hh,jh,lh,nh,ph,rh,xh,zh,Bh,Dh,Gh,Ih,Kh,Mh,Vm,Wm,_m,Hn,Zm,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp,pp];var Ka=[qp,xc,yc,zc,Ac,Bc,Cc,Dc,Ec,Qc,Rc,Sc,Tc,Uc,Vc,Wc,Xc,Yc,Zc,_c,qd,rd,sd,Fd,Gd,Hd,$d,ae,be,ce,de,ee,fe,ge,Fe,Ge,He,Ie,Je,Ke,Pe,Qe,Re,Se,Te,Ue,Ve,We,Xe,Ye,Ze,xf,yf,zf,Af,Bf,Cf,Nf,Of,Pf,Qf,Rf,Sf,Vf,Wf,Xf,Yf,Zf,_f,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp];var La=[rp,eb];var Ma=[sp,el,gl,sp];var Na=[tp,fl];var Oa=[up,Nk,Ok,Jk,Kk,Tk,Uk,Rk,Sk,Xk,Yk,Vk,Wk,$k,al,Zk,_k,Pk,Qk,Lk,Mk,hl,up,up,up,up,up,up,up,up,up,up];return{___divdi3:Uo,___muldi3:Wo,___udivdi3:Xo,___uremdi3:Yo,_bitshift64Lshr:Zo,_bitshift64Shl:_o,_endXmp:zm,_free:Pm,_getMusicInfo:Am,_getXmpCurrentPosition:Bm,_getXmpFrameInfo:Cm,_getXmpLoopCount:Dm,_getXmpMaxPosition:Em,_getXmpModuleInfo:Fm,_getXmpSampleRate:Gm,_getXmpSoundBuffer:Hm,_getXmpSoundBufferLen:Im,_i64Add:Qo,_i64Subtract:Ro,_initXmp:Jm,_llvm_bswap_i32:$o,_loadXmpModule:Km,_malloc:Om,_memcpy:ap,_memmove:bp,_memset:cp,_playXmpFrame:Lm,_realloc:Rm,_round:dp,_sbrk:ep,_seekXmpPosition:Mm,_startXmpPlayer:Nm,dynCall_ii:fp,dynCall_iii:gp,dynCall_iiii:hp,dynCall_iiiii:ip,dynCall_vii:jp,dynCall_viii:kp,dynCall_viiii:lp,dynCall_viiiiii:mp,establishStackSpace:Sa,getTempRet0:Va,runPostSets:Po,setTempRet0:Ua,setThrew:Ta,stackAlloc:Pa,stackRestore:Ra,stackSave:Qa}}) +var Aa=[pp,$m];var Ba=[qp,gg,ig,lg,ng,pg,rg,tg,vg,xg,zg,Cg,Eg,Gg,Ig,Kg,Mg,Og,Qg,Sg,Ug,Wg,bh,dh,fh,hh,jh,nh,ph,rh,th,zh,Bh,Dh,Gh,Ih,Kh,Nh,Ph,Rh,Th,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp,qp];var Ca=[rp,Mb,Nb,Rb,Sb,Wb,Xb,Zb,_b,$b,ac,bc,cc,dc,ec,fc,gc,hc,ic,rc,sc,tc,uc,Nc,Oc,Yc,Zc,_c,$c,ed,fd,hd,id,ld,md,nd,od,sd,td,vd,wd,xd,yd,zd,Ad,Bd,Cd,Fd,Gd,Hd,Id,Ud,Vd,Wd,Xd,Yd,Zd,he,ie,je,ke,le,me,oe,pe,we,xe,ye,ze,Me,Ne,Re,Se,Te,Ue,Ye,Ze,ff,gf,of,pf,qf,rf,tf,uf,wf,xf,Ef,Ff,Mf,Nf,Of,Pf,Qf,Rf,Sf,Tf,Uf,Vf,Wf,Xf,fg,hg,kg,mg,og,qg,sg,ug,wg,yg,Ag,Bg,Dg,Fg,Hg,Jg,Lg,Ng,Pg,Rg,Tg,Vg,Yg,$g,ah,ch,eh,gh,ih,mh,oh,qh,sh,yh,Ah,Ch,Fh,Hh,Jh,Mh,Oh,Qh,Sh,an,bn,gn,Pn,fn,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp,rp];var Da=[sp,jc,kc,lc,mc,nc,oc,pc,qc,vc,wc,xc,yc,zc,Ac,Bc,Cc,Dc,Ec,Fc,ad,bd,cd,pd,qd,rd,Jd,Kd,Ld,Md,Nd,Od,Pd,Qd,qe,re,se,te,ue,ve,Ae,Be,Ce,De,Ee,Fe,Ge,He,Ie,Je,Ke,hf,jf,kf,lf,mf,nf,yf,zf,Af,Bf,Cf,Df,Gf,Hf,If,Jf,Kf,Lf,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp,sp];var Ea=[tp,Xa];var Fa=[up,el,fl,gl,hl,il,jl,kl,ll,ml,nl,ol,pl,ql,rl,sl,tl,al,bl,cl,dl,Yh,bi,ai,ci,up,up,up,up,up,up,up];return{___errno_location:dn,___muldi3:Wo,___udivdi3:$o,___uremdi3:ap,_bitshift64Lshr:bp,_bitshift64Shl:cp,_endXmp:Gm,_free:Wm,_getMusicInfo:Hm,_getXmpCurrentPosition:Im,_getXmpFrameInfo:Jm,_getXmpLoopCount:Km,_getXmpMaxPosition:Lm,_getXmpModuleInfo:Mm,_getXmpSampleRate:Nm,_getXmpSoundBuffer:Om,_getXmpSoundBufferLen:Pm,_i64Add:Xo,_i64Subtract:Yo,_initXmp:Qm,_llvm_bswap_i32:dp,_loadXmpModule:Rm,_malloc:Vm,_memcpy:ep,_memmove:fp,_memset:gp,_playXmpFrame:Sm,_realloc:Ym,_round:hp,_sbrk:ip,_seekXmpPosition:Tm,_startXmpPlayer:Um,dynCall_ii:jp,dynCall_iii:kp,dynCall_iiii:lp,dynCall_iiiii:mp,dynCall_vii:np,dynCall_viiiiiiiii:op,establishStackSpace:Ja,getTempRet0:Ma,runPostSets:Uo,setTempRet0:La,setThrew:Ka,stackAlloc:Ga,stackRestore:Ia,stackSave:Ha}}) // EMSCRIPTEN_END_ASM -(c.l,c.m,buffer);c.___divdi3=Z.___divdi3;c.___muldi3=Z.___muldi3;c.___udivdi3=Z.___udivdi3;c.___uremdi3=Z.___uremdi3;c._bitshift64Lshr=Z._bitshift64Lshr;c._bitshift64Shl=Z._bitshift64Shl;c._endXmp=Z._endXmp;var Ma=c._free=Z._free;c._getMusicInfo=Z._getMusicInfo;c._getXmpCurrentPosition=Z._getXmpCurrentPosition; -c._getXmpFrameInfo=Z._getXmpFrameInfo;c._getXmpLoopCount=Z._getXmpLoopCount;c._getXmpMaxPosition=Z._getXmpMaxPosition;c._getXmpModuleInfo=Z._getXmpModuleInfo;c._getXmpSampleRate=Z._getXmpSampleRate;c._getXmpSoundBuffer=Z._getXmpSoundBuffer;c._getXmpSoundBufferLen=Z._getXmpSoundBufferLen;c._i64Add=Z._i64Add;c._i64Subtract=Z._i64Subtract;c._initXmp=Z._initXmp;c._llvm_bswap_i32=Z._llvm_bswap_i32;c._loadXmpModule=Z._loadXmpModule;var oa=c._malloc=Z._malloc;c._memcpy=Z._memcpy;c._memmove=Z._memmove; -c._memset=Z._memset;c._playXmpFrame=Z._playXmpFrame;c._realloc=Z._realloc;c._round=Z._round;c._sbrk=Z._sbrk;c._seekXmpPosition=Z._seekXmpPosition;c._startXmpPlayer=Z._startXmpPlayer;c.establishStackSpace=Z.establishStackSpace;c.getTempRet0=Z.getTempRet0;c.runPostSets=Z.runPostSets;c.setTempRet0=Z.setTempRet0;c.setThrew=Z.setThrew;var ka=c.stackAlloc=Z.stackAlloc,ja=c.stackRestore=Z.stackRestore,ia=c.stackSave=Z.stackSave;c.dynCall_ii=Z.dynCall_ii;c.dynCall_iii=Z.dynCall_iii;c.dynCall_iiii=Z.dynCall_iiii; -c.dynCall_iiiii=Z.dynCall_iiiii;c.dynCall_vii=Z.dynCall_vii;c.dynCall_viii=Z.dynCall_viii;c.dynCall_viiii=Z.dynCall_viiii;c.dynCall_viiiiii=Z.dynCall_viiiiii;c.asm=Z;c.ccall=function(a,b,d,e){var f=c["_"+a];assert(f,"Cannot call unknown function "+a+", make sure it is exported");var g=[];a=0;if(e)for(var l=0;l0&&(this._sampleRate=e),t>0&&(this._inputSampleRate=t);var i=Math.round(SAMPLES_PER_BUFFER*this._sampleRate/this._inputSampleRate)*this.getChannels();i>this._resampleBuffer.length&&(this._resampleBuffer=this.allocResampleBuffer(i))},allocResampleBuffer:function(e){return new Float32Array(e)},getCopiedAudio:function(e,t){var i;for(i=0;ithis._resampleBuffer.length&&(this._resampleBuffer=this.allocResampleBuffer(a)),this.resampleChannel(0,e,t,i),2==this._channels&&this.resampleChannel(1,e,t,i)}return i},resampleChannel:function(e,t,i,a){for(var r,n,s=0,o=0,d=a-0,h=i-0,u=Math.abs(d-s),l=s=d&&o>=h);)(r=2*p)>c&&(p+=c,s+=l),r2&&alert("fatal error: only 1 or 2 output channels supported"),this._backendAdapter=e,this._backendAdapter.setObserver(this),this._basePath=t,this._traceSwitch=!1,this._spectrumEnabled=a,this._songInfo={},this._onTrackReadyToPlay=n,this._onTrackEnd=s,this._onPlayerReady=r,this._onUpdate=o,this._tickerStepWidth=256,void 0!==d&&d.init(SAMPLES_PER_BUFFER,this._tickerStepWidth),this._externalTicker=d,this._currentTick=0,this._sourceBuffer,this._sourceBufferLen,this._numberOfSamplesRendered=0,this._numberOfSamplesToRender=0,this._sourceBufferIdx=0,this._currentPlaytime=0,this._currentTimeout=-1,setGlobalWebAudioCtx(),this._sampleRate=window._gPlayerAudioCtx.sampleRate,this._correctSampleRate=this._sampleRate,this._backendAdapter.resetSampleRate(this._sampleRate,-1),this._bufferSource,this._gainNode,this._analyzerNode,this._scriptNode,this._freqByteData=0,window.fileRequestCallback=this.fileRequestCallback.bind(this),window.fileSizeRequestCallback=this.fileSizeRequestCallback.bind(this),window.songUpdateCallback=this.songUpdateCallback.bind(this),this._isPaused=!1,this._isPlayerReady=!1,this._isSongReady=!1,this._initInProgress=!1,this._preLoadReady=!1,window.player=this,window.player.preloadFiles.bind(window.player)(i,function(){this._preLoadReady=!0,this._preLoadReady&&this._backendAdapter.isAdapterReady()&&this._backendAdapter.isManualSetupComplete()&&(this._isPlayerReady=!0,this._onPlayerReady())}.bind(this))},PlayerImpl.prototype={notify:function(){if(void 0!==this.deferredPreload&&this._backendAdapter.isAdapterReady()){var e=this.deferredPreload[0],t=this.deferredPreload[1];delete this.deferredPreload,this.preload(e,e.length,t)}this._preLoadReady&&this._backendAdapter.isAdapterReady()&&this._backendAdapter.isManualSetupComplete()&&(this._isPlayerReady=!0,this._onPlayerReady())},handleBackendEvent:function(){this.notify()},isReady:function(){return this._isPlayerReady},setTraceMode:function(e){this._traceSwitch=e},play:function(){this.initWebAudio(),this._isPaused=!1,void 0===this._bufferSource&&(this._bufferSource=window._gPlayerAudioCtx.createBufferSource(),this._bufferSource.start||(this._bufferSource.start=this._bufferSource.noteOn,this._bufferSource.stop=this._bufferSource.noteOff),this._bufferSource.start(0))},pause:function(){this.isWaitingForFile()||this._initInProgress||!this._isSongReady||(this._isPaused=!0)},isPaused:function(){return this._isPaused},resume:function(){this.isWaitingForFile()||this._initInProgress||!this._isSongReady||(this._isPaused=!1)},getCurrentTick:function(){var e=Math.ceil(SAMPLES_PER_BUFFER/this._tickerStepWidth)-1;return e=Math.min(e,this._currentTick)},setVolume:function(e){void 0!==this._gainNode&&(this._gainNode.gain.value=e)},isStereo:function(){return 2==this._backendAdapter.getChannels()},getSongInfo:function(){return this._songInfo},getSongInfoMeta:function(){return this._backendAdapter.getSongInfoMeta()},setPlaybackTimeout:function(e){this._currentPlaytime=0,this._currentTimeout=e/1e3*this._sampleRate},getPlaybackTimeout:function(e){return this._currentTimeout<0?-1:Math.round(this._currentTimeout/this._sampleRate)},getCurrentPlaytime:function(){return Math.round(this._currentPlaytime/this._sampleRate)},getFreqByteData:function(){return this._analyzerNode&&(0===this._freqByteData&&(this._freqByteData=new Uint8Array(this._analyzerNode.frequencyBinCount)),this._analyzerNode.getByteFrequencyData(this._freqByteData)),this._freqByteData},getMaxPlaybackPosition:function(){return this._backendAdapter.getMaxPlaybackPosition()},getPlaybackPosition:function(){return this._backendAdapter.getPlaybackPosition()},seekPlaybackPosition:function(e){return this._backendAdapter.seekPlaybackPosition(e)},loadMusicFromTmpFile:function(e,t,i,a,r){var n=e.name,s=(t.basePath?t.basePath:this._basePath)+n;if(!this.loadMusicDataFromCache(s,t,a)){var o=new FileReader;o.onload=function(){var e=this._backendAdapter.getPathAndFilename(n),r=new Uint8Array(o.result);void 0!==this._backendAdapter.registerFileData(e,r)?(this.getCache().setFile(s,r),this.prepareTrackForPlayback(s,o.result,t),i(n)):a()}.bind(this),o.onprogress=function(e){r&&r(e.total,e.loaded)}.bind(this),o.readAsArrayBuffer(e)}},loadMusicFromURL:function(e,t,i,a,r){var n=(t.basePath?t.basePath:this._basePath)+e;if(!this.loadMusicDataFromCache(n,t,a)){var s=new XMLHttpRequest;s.open("GET",n,!0),s.responseType="arraybuffer",s.onload=function(e){this.trace("loadMusicFromURL successfully loaded: "+n),this.prepareTrackForPlayback(n,s.response,t)?i(n):this.isWaitingForFile()||a()}.bind(this),s.onprogress=function(e){r&&r(e.total,e.loaded)}.bind(this),s.onreadystatuschange=function(e){4==oReq.readyState&&404==oReq.status&&this.trace("loadMusicFromURL failed to load: "+n)}.bind(this),s.send(null)}},uploadFile:function(e,t,i,a,r){var n=new FileReader;n.onload=function(){var r=this._backendAdapter.getPathAndFilename(e.name),s=new Uint8Array(n.result);if(void 0!==this._backendAdapter.registerFileData(r,s)){var o=this._backendAdapter.uploadFile(e.name,t);0===o?(i(e.name),this._onPlayerReady()):1==o&&i(e.name)}else a()}.bind(this),n.onprogress=function(e){r&&r(e.total,e.loaded)}.bind(this),n.readAsArrayBuffer(e)},prepareTrackForPlayback:function(e,t,i){return this._isPaused=!0,this.lastUsedFilename=e,this.lastUsedData=t,this.lastUsedOptions=i,this._isSongReady=!1,this.setWaitingForFile(!1),this.initIfNeeded(e,t,i)},trace:function(e){this._traceSwitch&&console.log(e)},setWait:function(e){this.setWaitingForFile(e)},getDefaultSampleRate:function(){return this._correctSampleRate},initIfNeeded:function(e,t,i){var a=this.loadMusicData(e,t,i);if(a<0)this._isSongReady=!1,this.setWaitingForFile(!0),this._initInProgress=!1;else{if(0===a)return this.setWaitingForFile(!1),this._isSongReady=!0,this._currentPlaytime=0,this._initInProgress=!1,this.trace("successfully completed init"),0!==this._backendAdapter.evalTrackOptions(i)?(this.trace("error preparing track options"),!1):(this.updateSongInfo(e),this._onTrackReadyToPlay(),this._isPaused=!1,!0);this._initInProgress=!1,this.trace("initIfNeeded - fatal error")}return!1},loadMusicDataFromCache:function(e,t,i){var a=this.getCache().getFile(e);return void 0!==a&&(this.prepareTrackForPlayback(e,a,t)||this.isWaitingForFile()||i(),!0)},initWebAudio:function(){void 0!==this._bufferSource?this._bufferSource.stop(0):(this._analyzerNode=window._gPlayerAudioCtx.createAnalyser(),this._scriptNode=this.createScriptProcessor(window._gPlayerAudioCtx),this._gainNode=window._gPlayerAudioCtx.createGain(),this._scriptNode.connect(this._gainNode),void 0!==this._externalTicker&&this.createTickerScriptProcessor(window._gPlayerAudioCtx).connect(this._gainNode),this._spectrumEnabled?(this._gainNode.connect(this._analyzerNode),this._analyzerNode.connect(window._gPlayerAudioCtx.destination)):this._gainNode.connect(window._gPlayerAudioCtx.destination))},updateSongInfo:function(e){this._songInfo={},this._backendAdapter.updateSongInfo(e,this._songInfo)},loadMusicData:function(e,t,i){if(this._backendAdapter.teardown(),t){var a=this._backendAdapter.getPathAndFilename(e),r=new Uint8Array(t);this._backendAdapter.registerFileData(a,r);var n=this._backendAdapter.loadMusicData(this._sampleRate,a[0],a[1],r,i);return 0===n&&this.resetBuffer(),n}},resetBuffer:function(){this._numberOfSamplesRendered=0,this._numberOfSamplesToRender=0,this._sourceBufferIdx=0},resetSampleRate:function(e){this._backendAdapter.resetSampleRate(e,-1),this.resetBuffer()},createScriptProcessor:function(e){var t=e.createScriptProcessor(SAMPLES_PER_BUFFER,0,this._backendAdapter.getChannels());return t.onaudioprocess=fetchSamples,t},createTickerScriptProcessor:function(e){var t;return(t=e.createScriptProcessor(256,0,1)).onaudioprocess=calcTick,t},fillEmpty:function(e,t,a){var r=e-this._numberOfSamplesRendered;for(i=0;i0&&this._currentPlaytime>this._currentTimeout?(this.trace("'song end' forced after "+this._currentTimeout/this._sampleRate+" secs"),n=1):(n=this._backendAdapter.computeAudioSamples(),void 0!==this._externalTicker&&this._externalTicker.computeAudioSamplesNotify()),0!==n)return this.fillEmpty(r,i,t),n<0?(this._isPaused=!0,this._isSongReady=!1,void this.setWaitingForFile(!0)):this.isWaitingForFile()?void 0:(n>1&&this.trace("playback aborted with an error"),void(this._onTrackEnd?this._onTrackEnd():this._isPaused=!0));this._sourceBuffer=this._backendAdapter.getAudioBuffer(),this._sourceBufferLen=this._backendAdapter.getAudioBufferLength(),this._numberOfSamplesToRender=this._backendAdapter.getResampledAudio(this._sourceBuffer,this._sourceBufferLen),this._sourceBufferIdx=0}var s=this._backendAdapter.getResampleBuffer();this.isStereo()?this.copySamplesStereo(s,i,t,r):this.copySamplesMono(s,i,t,r)}this._currentPlaytime+=r}void 0!==this._externalTicker&&(this._externalTicker.calcTickData(i,t),this._currentTick=0)},copySamplesStereo:function(e,t,i,a){var r;if(this._numberOfSamplesRendered+this._numberOfSamplesToRender>a){var n=a-this._numberOfSamplesRendered;for(r=0;ra){var n=a-this._numberOfSamplesRendered;for(r=0;r0&&(this._sampleRate=e),t>0&&(this._inputSampleRate=t);var i=Math.round(SAMPLES_PER_BUFFER*this._sampleRate/this._inputSampleRate)*this.getChannels();i>this._resampleBuffer.length&&(this._resampleBuffer=this.allocResampleBuffer(i))},allocResampleBuffer:function(e){return new Float32Array(e)},getCopiedAudio:function(e,t){var i;for(i=0;ithis._resampleBuffer.length&&(this._resampleBuffer=this.allocResampleBuffer(a)),this.resampleChannel(0,e,t,i),2==this._channels&&this.resampleChannel(1,e,t,i)}return i},resampleChannel:function(e,t,i,a){for(var r,n,s=0,o=0,d=a-0,h=i-0,u=Math.abs(d-s),l=s=d&&o>=h);)(r=2*p)>c&&(p+=c,s+=l),r2&&alert("fatal error: only 1 or 2 output channels supported"),this._backendAdapter=e,this._backendAdapter.setObserver(this),this._basePath=t,this._traceSwitch=!1,this._spectrumEnabled=a,this._songInfo={},this._onTrackReadyToPlay=n,this._onTrackEnd=s,this._onPlayerReady=r,this._onUpdate=o,this._tickerStepWidth=256,void 0!==d&&d.init(SAMPLES_PER_BUFFER,this._tickerStepWidth),this._externalTicker=d,this._currentTick=0,this._sourceBuffer,this._sourceBufferLen,this._numberOfSamplesRendered=0,this._numberOfSamplesToRender=0,this._sourceBufferIdx=0,this._currentPlaytime=0,this._currentTimeout=-1,setGlobalWebAudioCtx(),this._sampleRate=window._gPlayerAudioCtx.sampleRate,this._correctSampleRate=this._sampleRate,this._backendAdapter.resetSampleRate(this._sampleRate,-1),this._bufferSource,this._gainNode,this._analyzerNode,this._scriptNode,this._freqByteData=0,window.fileRequestCallback=this.fileRequestCallback.bind(this),window.fileSizeRequestCallback=this.fileSizeRequestCallback.bind(this),window.songUpdateCallback=this.songUpdateCallback.bind(this),this._isPaused=!1,this._isPlayerReady=!1,this._isSongReady=!1,this._initInProgress=!1,this._preLoadReady=!1,window.player=this,window.player.preloadFiles.bind(window.player)(i,function(){this._preLoadReady=!0,this._preLoadReady&&this._backendAdapter.isAdapterReady()&&this._backendAdapter.isManualSetupComplete()&&(this._isPlayerReady=!0,this._onPlayerReady())}.bind(this))},PlayerImpl.prototype={notify:function(){if(void 0!==this.deferredPreload&&this._backendAdapter.isAdapterReady()){var e=this.deferredPreload[0],t=this.deferredPreload[1];delete this.deferredPreload,this.preload(e,e.length,t)}this._preLoadReady&&this._backendAdapter.isAdapterReady()&&this._backendAdapter.isManualSetupComplete()&&(this._isPlayerReady=!0,this._onPlayerReady())},handleBackendEvent:function(){this.notify()},isReady:function(){return this._isPlayerReady},setTraceMode:function(e){this._traceSwitch=e},play:function(){this.initWebAudio(),this._isPaused=!1,void 0===this._bufferSource&&(this._bufferSource=window._gPlayerAudioCtx.createBufferSource(),this._bufferSource.start||(this._bufferSource.start=this._bufferSource.noteOn,this._bufferSource.stop=this._bufferSource.noteOff),this._bufferSource.start(0))},pause:function(){this.isWaitingForFile()||this._initInProgress||!this._isSongReady||(this._isPaused=!0)},isPaused:function(){return this._isPaused},resume:function(){this.isWaitingForFile()||this._initInProgress||!this._isSongReady||(this._isPaused=!1)},getCurrentTick:function(){var e=Math.ceil(SAMPLES_PER_BUFFER/this._tickerStepWidth)-1;return e=Math.min(e,this._currentTick)},setVolume:function(e){void 0!==this._gainNode&&(this._gainNode.gain.value=e)},isStereo:function(){return 2==this._backendAdapter.getChannels()},getSongInfo:function(){return this._songInfo},getSongInfoMeta:function(){return this._backendAdapter.getSongInfoMeta()},setPlaybackTimeout:function(e){this._currentPlaytime=0,this._currentTimeout=e/1e3*this._sampleRate},getPlaybackTimeout:function(e){return this._currentTimeout<0?-1:Math.round(this._currentTimeout/this._sampleRate)},getCurrentPlaytime:function(){return Math.round(this._currentPlaytime/this._sampleRate)},getFreqByteData:function(){return this._analyzerNode&&(0===this._freqByteData&&(this._freqByteData=new Uint8Array(this._analyzerNode.frequencyBinCount)),this._analyzerNode.getByteFrequencyData(this._freqByteData)),this._freqByteData},getMaxPlaybackPosition:function(){return this._backendAdapter.getMaxPlaybackPosition()},getPlaybackPosition:function(){return this._backendAdapter.getPlaybackPosition()},seekPlaybackPosition:function(e){return this._backendAdapter.seekPlaybackPosition(e)},loadMusicFromTmpFile:function(e,t,i,a,r){var n=e.name,s=(t.basePath?t.basePath:this._basePath)+n;if(!this.loadMusicDataFromCache(s,t,a)){var o=new FileReader;o.onload=function(){var e=this._backendAdapter.getPathAndFilename(n),r=new Uint8Array(o.result);void 0!==this._backendAdapter.registerFileData(e,r)?(this.getCache().setFile(s,r),this.prepareTrackForPlayback(s,o.result,t),i(n)):a()}.bind(this),o.onprogress=function(e){r&&r(e.total,e.loaded)}.bind(this),o.readAsArrayBuffer(e)}},loadMusicFromURL:function(e,t,i,a,r){var n=(t.basePath?t.basePath:this._basePath)+e;if(!this.loadMusicDataFromCache(n,t,a)){var s=new XMLHttpRequest;s.open("GET",n,!0),s.responseType="arraybuffer",s.onload=function(e){this.trace("loadMusicFromURL successfully loaded: "+n),this.prepareTrackForPlayback(n,s.response,t)?i(n):this.isWaitingForFile()||a()}.bind(this),s.onprogress=function(e){r&&r(e.total,e.loaded)}.bind(this),s.onreadystatuschange=function(e){4==oReq.readyState&&404==oReq.status&&this.trace("loadMusicFromURL failed to load: "+n)}.bind(this),s.send(null)}},uploadFile:function(e,t,i,a,r){var n=new FileReader;n.onload=function(){var r=this._backendAdapter.getPathAndFilename(e.name),s=new Uint8Array(n.result);if(void 0!==this._backendAdapter.registerFileData(r,s)){var o=this._backendAdapter.uploadFile(e.name,t);0===o?(i(e.name),this._onPlayerReady()):1==o&&i(e.name)}else a()}.bind(this),n.onprogress=function(e){r&&r(e.total,e.loaded)}.bind(this),n.readAsArrayBuffer(e)},prepareTrackForPlayback:function(e,t,i){return this._isPaused=!0,this.lastUsedFilename=e,this.lastUsedData=t,this.lastUsedOptions=i,this._isSongReady=!1,this.setWaitingForFile(!1),this.initIfNeeded(e,t,i)},trace:function(e){this._traceSwitch&&console.log(e)},setWait:function(e){this.setWaitingForFile(e)},getDefaultSampleRate:function(){return this._correctSampleRate},initIfNeeded:function(e,t,i){var a=this.loadMusicData(e,t,i);if(a<0)this._isSongReady=!1,this.setWaitingForFile(!0),this._initInProgress=!1;else{if(0===a)return this.setWaitingForFile(!1),this._isSongReady=!0,this._currentPlaytime=0,this._initInProgress=!1,this.trace("successfully completed init"),0!==this._backendAdapter.evalTrackOptions(i)?(this.trace("error preparing track options"),!1):(this.updateSongInfo(e),this._onTrackReadyToPlay(),this._isPaused=!1,!0);this._initInProgress=!1,this.trace("initIfNeeded - fatal error")}return!1},loadMusicDataFromCache:function(e,t,i){var a=this.getCache().getFile(e);return void 0!==a&&(this.prepareTrackForPlayback(e,a,t)||this.isWaitingForFile()||i(),!0)},initWebAudio:function(){if(void 0!==this._bufferSource)try{this._bufferSource.stop(0)}catch(e){}else this._analyzerNode=window._gPlayerAudioCtx.createAnalyser(),this._scriptNode=this.createScriptProcessor(window._gPlayerAudioCtx),this._gainNode=window._gPlayerAudioCtx.createGain(),this._scriptNode.connect(this._gainNode),void 0!==this._externalTicker&&this.createTickerScriptProcessor(window._gPlayerAudioCtx).connect(this._gainNode),this._spectrumEnabled?(this._gainNode.connect(this._analyzerNode),this._analyzerNode.connect(window._gPlayerAudioCtx.destination)):this._gainNode.connect(window._gPlayerAudioCtx.destination)},updateSongInfo:function(e){this._songInfo={},this._backendAdapter.updateSongInfo(e,this._songInfo)},loadMusicData:function(e,t,i){if(this._backendAdapter.teardown(),t){var a=this._backendAdapter.getPathAndFilename(e),r=new Uint8Array(t);this._backendAdapter.registerFileData(a,r);var n=this._backendAdapter.loadMusicData(this._sampleRate,a[0],a[1],r,i);return 0===n&&this.resetBuffer(),n}},resetBuffer:function(){this._numberOfSamplesRendered=0,this._numberOfSamplesToRender=0,this._sourceBufferIdx=0},resetSampleRate:function(e){this._backendAdapter.resetSampleRate(e,-1),this.resetBuffer()},createScriptProcessor:function(e){var t=e.createScriptProcessor(SAMPLES_PER_BUFFER,0,this._backendAdapter.getChannels());return t.onaudioprocess=fetchSamples,t},createTickerScriptProcessor:function(e){var t;return(t=e.createScriptProcessor(256,0,1)).onaudioprocess=calcTick,t},fillEmpty:function(e,t,a){var r=e-this._numberOfSamplesRendered;for(i=0;i0&&this._currentPlaytime>this._currentTimeout?(this.trace("'song end' forced after "+this._currentTimeout/this._sampleRate+" secs"),n=1):(n=this._backendAdapter.computeAudioSamples(),void 0!==this._externalTicker&&this._externalTicker.computeAudioSamplesNotify()),0!==n)return this.fillEmpty(r,i,t),n<0?(this._isPaused=!0,this._isSongReady=!1,void this.setWaitingForFile(!0)):this.isWaitingForFile()?void 0:(n>1&&this.trace("playback aborted with an error"),void(this._onTrackEnd?this._onTrackEnd():this._isPaused=!0));this._sourceBuffer=this._backendAdapter.getAudioBuffer(),this._sourceBufferLen=this._backendAdapter.getAudioBufferLength(),this._numberOfSamplesToRender=this._backendAdapter.getResampledAudio(this._sourceBuffer,this._sourceBufferLen),this._sourceBufferIdx=0}var s=this._backendAdapter.getResampleBuffer();this.isStereo()?this.copySamplesStereo(s,i,t,r):this.copySamplesMono(s,i,t,r)}this._currentPlaytime+=r}void 0!==this._externalTicker&&(this._externalTicker.calcTickData(i,t),this._currentTick=0)},copySamplesStereo:function(e,t,i,a){var r;if(this._numberOfSamplesRendered+this._numberOfSamplesToRender>a){var n=a-this._numberOfSamplesRendered;for(r=0;ra){var n=a-this._numberOfSamplesRendered;for(r=0;r htdocs/xmp3.js cat htdocs/xmp.js >> htdocs/xmp3.js cat shell-post.js >> htdocs/xmp3.js diff --git a/include/xmp.h b/include/xmp.h index 460ed94..e3d223e 100644 --- a/include/xmp.h +++ b/include/xmp.h @@ -5,11 +5,11 @@ extern "C" { #endif -#define XMP_VERSION "4.3.0" -#define XMP_VERCODE 0x040300 +#define XMP_VERSION "4.4.1" +#define XMP_VERCODE 0x040401 #define XMP_VER_MAJOR 4 -#define XMP_VER_MINOR 3 -#define XMP_VER_RELEASE 0 +#define XMP_VER_MINOR 4 +#define XMP_VER_RELEASE 1 #if defined(_WIN32) && !defined(__CYGWIN__) # if defined(BUILDING_STATIC) @@ -51,9 +51,12 @@ extern "C" { #define XMP_PLAYER_CFLAGS 5 /* Player flags for current module */ #define XMP_PLAYER_SMPCTL 6 /* Sample control flags */ #define XMP_PLAYER_VOLUME 7 /* Player module volume */ -#define XMP_PLAYER_STATE 8 /* Internal player state */ +#define XMP_PLAYER_STATE 8 /* Internal player state (read only) */ #define XMP_PLAYER_SMIX_VOLUME 9 /* SMIX volume */ #define XMP_PLAYER_DEFPAN 10 /* Default pan setting */ +#define XMP_PLAYER_MODE 11 /* Player personality */ +#define XMP_PLAYER_MIXER_TYPE 12 /* Current mixer (read only) */ +#define XMP_PLAYER_VOICES 13 /* Maximum number of mixer voices */ /* interpolation types */ #define XMP_INTERP_NEAREST 0 /* Nearest neighbor */ @@ -73,6 +76,25 @@ extern "C" { #define XMP_FLAGS_VBLANK (1 << 0) /* Use vblank timing */ #define XMP_FLAGS_FX9BUG (1 << 1) /* Emulate FX9 bug */ #define XMP_FLAGS_FIXLOOP (1 << 2) /* Emulate sample loop bug */ +#define XMP_FLAGS_A500 (1 << 3) /* Use Paula mixer in Amiga modules */ + +/* player modes */ +#define XMP_MODE_AUTO 0 /* Autodetect mode (default) */ +#define XMP_MODE_MOD 1 /* Play as a generic MOD player */ +#define XMP_MODE_NOISETRACKER 2 /* Play using Noisetracker quirks */ +#define XMP_MODE_PROTRACKER 3 /* Play using Protracker quirks */ +#define XMP_MODE_S3M 4 /* Play as a generic S3M player */ +#define XMP_MODE_ST3 5 /* Play using ST3 bug emulation */ +#define XMP_MODE_ST3GUS 6 /* Play using ST3+GUS quirks */ +#define XMP_MODE_XM 7 /* Play as a generic XM player */ +#define XMP_MODE_FT2 8 /* Play using FT2 bug emulation */ +#define XMP_MODE_IT 9 /* Play using IT quirks */ +#define XMP_MODE_ITSMP 10 /* Play using IT sample mode quirks */ + +/* mixer types */ +#define XMP_MIXER_STANDARD 0 /* Standard mixer */ +#define XMP_MIXER_A500 1 /* Amiga 500 */ +#define XMP_MIXER_A500F 2 /* Amiga 500 with led filter */ /* sample flags */ #define XMP_SMPCTL_SKIP (1 << 0) /* Don't load samples */ @@ -104,6 +126,8 @@ struct xmp_channel { int vol; /* Channel volume */ #define XMP_CHANNEL_SYNTH (1 << 0) /* Channel is synthesized */ #define XMP_CHANNEL_MUTE (1 << 1) /* Channel is muted */ +#define XMP_CHANNEL_SPLIT (1 << 2) /* Split Amiga channel in bits 5-4 */ +#define XMP_CHANNEL_SURROUND (1 << 4) /* Surround channel */ int flg; /* Channel flags */ }; @@ -169,7 +193,7 @@ struct xmp_instrument { int vde; /* Vibrato depth */ int vra; /* Vibrato rate */ int vsw; /* Vibrato sweep */ - int rvv; /* Random volume variation (IT) */ + int rvv; /* Random volume/pan variation (IT) */ int sid; /* Sample number */ #define XMP_INST_NNA_CUT 0x00 #define XMP_INST_NNA_CONT 0x01 @@ -202,6 +226,8 @@ struct xmp_sample { #define XMP_SAMPLE_LOOP_BIDIR (1 << 2) /* Bidirectional sample loop */ #define XMP_SAMPLE_LOOP_REVERSE (1 << 3) /* Backwards sample loop */ #define XMP_SAMPLE_LOOP_FULL (1 << 4) /* Play full sample before looping */ +#define XMP_SAMPLE_SLOOP (1 << 5) /* Sample has sustain loop */ +#define XMP_SAMPLE_SLOOP_BIDIR (1 << 6) /* Bidirectional sustain loop */ #define XMP_SAMPLE_SYNTH (1 << 15) /* Data contains synth patch */ int flg; /* Flags */ unsigned char *data; /* Sample data */ @@ -230,7 +256,7 @@ struct xmp_module { struct xmp_track **xxt; /* Tracks */ struct xmp_instrument *xxi; /* Instruments */ struct xmp_sample *xxs; /* Samples */ - struct xmp_channel xxc[64]; /* Channel info */ + struct xmp_channel xxc[XMP_MAX_CHANNELS]; /* Channel info */ unsigned char xxo[XMP_MAX_MOD_LENGTH]; /* Orders */ }; @@ -239,8 +265,6 @@ struct xmp_test_info { char type[XMP_NAME_SIZE]; /* Module format */ }; -#define XMP_PERIOD_BASE 6847 /* C4 period */ - struct xmp_module_info { unsigned char md5[16]; /* MD5 message digest */ int vol_base; /* Volume scale */ @@ -271,7 +295,7 @@ struct xmp_frame_info { /* Current frame information */ int sequence; /* Current sequence */ struct xmp_channel_info { /* Current channel information */ - unsigned int period; /* Sample period */ + unsigned int period; /* Sample period (* 4096) */ unsigned int position; /* Sample position */ short pitchbend; /* Linear bend from base note*/ unsigned char note; /* Current base note number */ diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index 7b2196e..0000000 --- a/src/Makefile +++ /dev/null @@ -1,23 +0,0 @@ - -SRC_OBJS = virtual.o format.o period.o player.o read_event.o \ - dataio.o mkstemp.o fnmatch.o md5.o lfo.o envelope.o scan.o \ - control.o med_extras.o filter.o fmopl.o effects.o mixer.o \ - synth_null.o mix_all.o adlib.o load_helpers.o load.o hio.o \ - hmn_extras.o extras.o smix.o memio.o - -SRC_DFILES = Makefile $(SRC_OBJS:.o=.c) common.h effects.h envelope.h \ - fmopl.h format.h lfo.h list.h mixer.h period.h player.h \ - synth.h virtual.h fnmatch.h md5.h precomp_lut.h \ - med_extras.h hio.h hmn_extras.h extras.h memio.h mdataio.h - -SRC_PATH = src - -OBJS += $(addprefix $(SRC_PATH)/,$(SRC_OBJS)) - -default-src:: - $(MAKE) -C .. - -dist-src:: - mkdir -p $(DIST)/$(SRC_PATH) - cp -RPp $(addprefix $(SRC_PATH)/,$(SRC_DFILES)) $(DIST)/$(SRC_PATH) - diff --git a/src/adlib.c b/src/adlib.c deleted file mode 100644 index 872dcfa..0000000 --- a/src/adlib.c +++ /dev/null @@ -1,355 +0,0 @@ -/* Extended Module Player - * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr - * - * This file is part of the Extended Module Player and is distributed - * under the terms of the GNU Lesser General Public License. See COPYING.LIB - * for more information. - */ - -#include -#include "xmp.h" -#include "common.h" -#include "synth.h" -#include "fmopl.h" - -/* Use the old GPL-compatible version */ -#define USE_OLD_FMOPL - -struct adlib { -#ifdef USE_OLD_FMOPL - FM_OPL *ym3812; -#define YM3812ResetChip(which) OPLResetChip(a->ym3812) -#define YM3812Write(which,addr,val) OPLWrite(a->ym3812, addr, val) -#define YM3812Read(which,addr) OPLRead(a->ym3812, addr) -#define YM3812Init(num,clock,rate) \ - ((((struct adlib *)(SYNTH_CHIP(ctx)))->ym3812 = OPLCreate(OPL_TYPE_IO, clock, rate)) != NULL) -#define YM3812Shutdown() OPLDestroy(a->ym3812) -#define YM3812UpdateOne(which,tmp_bk,count,vl,vr,stereo) \ - YM3812UpdateOne(a->ym3812, tmp_bk, count, vl, vr, stereo) -#endif - -#define NUM_SYNTH_CHANNEL 9 - int voc2ch[NUM_SYNTH_CHANNEL]; -}; - -/* - * ------+-----------------------------------+-----------------------+ - * offset| SBI data format | YM3812 base port - * ------+-----------------------------------+-----------------------+ - * 0 Modulator Sound Characteristics 20 - * 1 Carrier Sound Characteristics - * Bit 7: AM Modulation (am) - * Bit 6: Vibrato (vibrato) - * Bit 5: Sustaining Sound - * Bit 4: Envelop Scaling - * Bits 3-0: Frequency Multiplier - * ------+-----------------------------------+-----------------------+ - * 2 Modulator Scaling/Output Level 40 - * 3 Carrier Scaling/Output Level - * Bits 7-6: Level Scaling - * Bits 5-0: Output Level - * ------+-----------------------------------+-----------------------+ - * 4 Modulator Attack/Decay 60 - * 5 Carrier Attack/Decay - * Bits 7-4: Attack Rate - * Bits 3-0: Decay Rate - * ------+-----------------------------------+-----------------------+ - * 6 Modulator Sustain/Release 80 - * 7 Carrier Sustain/Release - * Bits 7-4: Sustain Level - * Bits 3-0: Release Rate - * ------+-----------------------------------+-----------------------+ - * 8 Modulator Wave Select E0 - * 9 Carrier Wave Select - * Bits 7-2: All bits clear - * Bits 1-0: Wave Select - * ------+-----------------------------------+-----------------------+ - * 10 Feedback/Connection C0 - * Bits 7-4: All bits clear - * Bits 3-1: Modulator Feedback - * Bit 0: Connection - * ------+-----------------------------------+-----------------------+ - */ - -static const int register_base[11] = { - 0x20, 0x20, 0x40, 0x40, - 0x60, 0x60, 0x80, 0x80, - 0xe0, 0xe0, 0xc0 -}; - -static const int register_offset[2][9] = { - /* Channel 1 2 3 4 5 6 7 8 9 */ - /* Operator 1 */ {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12}, - /* Operator 2 */ {0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15} -}; - -/* - * In octave 4, the F-number values for the chromatic scale and their - * corresponding frequencies would be: - * - * F Number Frequency Note - * 16B 277.2 C# - * 181 293.7 D - * 198 311.1 D# - * 1B0 329.6 E - * 1CA 349.2 F - * 1E5 370.0 F# - * 202 392.0 G - * 220 415.3 G# - * 241 440.0 A - * 263 466.2 A# - * 287 493.9 B - * 2AE 523.3 C - */ - -static const int ym3812_note[] = { - 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, - 0x1e5, 0x202, 0x220, 0x241, 0x263, 0x287, - 0x2ae -}; - - -#undef DEBUG_ADLIB - -#ifdef DEBUG_ADLIB -#include -#include -#define DELAY(x) do { int i; for (i = 0; i < x; i++) inb (0x388); } while (0) -#endif - -/* - * After writing to the register port, you must wait twelve cycles before - * sending the data; after writing the data, eighty-four cycles must elapse - * before any other sound card operation may be performed. - * - * The most accurate method of producing the delay is to read the register - * port six times after writing to the register port, and read the register - * port thirty-five times after writing to the data port. - */ - -static inline int opl_write(struct adlib *a, int addr, int val) -{ -#ifdef DEBUG_ADLIB - outb(addr, 0x388); - DELAY(5); - outb(val, 0x389); - DELAY(35); - return 0; -#else - YM3812Write(0, 0, addr); - return YM3812Write(0, 1, val); -#endif -} - -static inline uint8 opl_read(struct adlib *a, int addr) -{ -#ifdef DEBUG_ADLIB - int x; - - outb(addr, 0x388); - DELAY(5); - x = inb(0x389); - DELAY(35); - return x; -#else - YM3812Write(0, 0, addr); - return YM3812Read(0, 1); -#endif -} - -static struct adlib *adlib_new() -{ - struct adlib *a; - int i; - - a = malloc(sizeof (struct adlib)); - if (a == NULL) - return NULL; - - for (i = 0; i < NUM_SYNTH_CHANNEL; i++) { - a->voc2ch[i] = -1; - } - - return a; -} - -static void adlib_destroy(struct adlib *a) -{ - free(a); -} - -static int synth_getchannel(struct context_data *ctx, int c) -{ - struct adlib *a = SYNTH_CHIP(ctx); - int i, freech = -1; - - for (c++, i = 0; i < NUM_SYNTH_CHANNEL; i++) { - if (a->voc2ch[i] == c) { - return i; - } - - if (a->voc2ch[i] < 0) { - freech = i; - break; - } - } - if (freech != -1) { - a->voc2ch[freech] = c; - } - - return freech; -} - -static void synth_chreset(struct context_data *ctx) -{ - struct adlib *a = SYNTH_CHIP(ctx); - int i; - - for (i = 0; i < NUM_SYNTH_CHANNEL; i++) { - a->voc2ch[i] = -1; - } -} - -static void synth_setpatch(struct context_data *ctx, int c, uint8 *data) -{ - struct adlib *a = SYNTH_CHIP(ctx); - int i, x; - - if ((c = synth_getchannel(ctx, c)) < 0) - return; - - for (i = 0; i < 10; i++) - opl_write(a, register_base[i] + register_offset[i % 2][c], - data[i]); - opl_write(a, register_base[10] + c, data[10]); - - x = opl_read(a, 0xb0 + c); - opl_write(a, 0xb0 + c, x & ~0x20); -} - -/* - * Bytes A0-B8 - Octave / F-Number / Key-On - * - * 7 6 5 4 3 2 1 0 - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | F-Number (least significant byte) | (A0-A8) - * | | - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * - * 7 6 5 4 3 2 1 0 - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | Unused | Key | Octave | F-Number | (B0-B8) - * | | On | | most sig. | - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * - * bit 5 - Channel is voiced when set, silent when clear. - * bits 4-2 - Octave (0-7). 0 is lowest, 7 is highest. - * bits 1-0 - Most significant bits of F-number. - */ - -static void synth_setnote(struct context_data *ctx, int c, int note, int bend) -{ - struct adlib *a = SYNTH_CHIP(ctx); - int n, f, o; - - if ((c = synth_getchannel(ctx, c)) < 0) - return; - - n = note % 12; - f = ym3812_note[n] + (ym3812_note[n + 1] - ym3812_note[n]) * bend / 100; - o = note / 12 - 2; - - if (o < 0) - o = 0; - - opl_write(a, 0xa0 + c, f & 0xff); - opl_write(a, 0xb0 + c, 0x20 | ((o << 2) & 0x1c) | ((f >> 8) & 0x03)); -} - -static void synth_setvol(struct context_data *ctx, int c, int vol) -{ - struct adlib *a = SYNTH_CHIP(ctx); - int b, ofs; - - if ((c = synth_getchannel(ctx, c)) < 0) - return; - - if (vol > 63) - vol = 63; - - /* Check if operator 1 produces sound */ - if (opl_read(a, 0xc8 + c)) { - ofs = register_offset[0][c]; - b = opl_read(a, 0x40 + ofs); - opl_write(a, 0x40 + ofs, (b & 0xc0) | (63 - vol)); - } - - ofs = register_offset[1][c]; - b = opl_read(a, 0x40 + ofs); - opl_write(a, 0x40 + ofs, (b & 0xc0) | (63 - vol)); -} - -static int synth_init(struct context_data *ctx, int freq) -{ - SYNTH_CHIP(ctx) = adlib_new(); - if (SYNTH_CHIP(ctx) == NULL) - return -1; - -#ifdef DEBUG_ADLIB - ioperm(0x388, 2, 1); -#endif - synth_chreset(ctx); - - return YM3812Init(1, 3579545, freq); -} - -static int synth_reset(struct context_data *ctx) -{ - struct adlib *a = SYNTH_CHIP(ctx); - -#ifdef DEBUG_ADLIB - int i; - - for (i = 0; i < 9; i++) { - opl_write(a, ym3812, 0xb0 + i, 0); - } -#else - YM3812ResetChip(0); -#endif - synth_chreset(ctx); - - return 0; -} - -static int synth_deinit(struct context_data *ctx) -{ - struct adlib *a = SYNTH_CHIP(ctx); - - synth_reset(ctx); - YM3812Shutdown(); - - adlib_destroy(a); - - return 0; -} - -static void synth_mixer(struct context_data *ctx, int32 *tmp_bk, int count, int vl, int vr, int stereo) -{ - struct adlib *a = SYNTH_CHIP(ctx); - - if (!tmp_bk) - return; - - YM3812UpdateOne(0, tmp_bk, count, vl, vr, stereo); -} - - -const struct synth_info synth_adlib = { - synth_init, - synth_deinit, - synth_reset, - synth_setpatch, - synth_setnote, - synth_setvol, - synth_mixer -}; diff --git a/src/common.h b/src/common.h index 2c076a7..1646441 100644 --- a/src/common.h +++ b/src/common.h @@ -10,7 +10,7 @@ #include "xmp.h" #if defined(__GNUC__) || defined(__clang__) -#if !defined(WIN32) && !defined(ANDROID) && !defined(__APPLE__) && !defined(__AMIGA__) && !defined(B_BEOS_VERSION) && !defined(__ATHEOS__) && !defined(EMSCRIPTEN) && !defined(__MINT__) +#if !defined(WIN32) && !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__AMIGA__) && !defined(B_BEOS_VERSION) && !defined(__ATHEOS__) && !defined(EMSCRIPTEN) && !defined(__MINT__) #define USE_VERSIONED_SYMBOLS #endif #endif @@ -33,15 +33,18 @@ typedef unsigned int uint32; #ifdef _MSC_VER /* MSVC++6.0 has no long long */ typedef signed __int64 int64; typedef unsigned __int64 uint64; -#elif !defined B_BEOS_VERSION /*BeOS has its own int64 definition */ +#elif !defined B_BEOS_VERSION /* BeOS has its own int64 definition */ typedef unsigned long long uint64; typedef signed long long int64; #endif +#ifndef LIBXMP_CORE_PLAYER +#define LIBXMP_PAULA_SIMULATOR +#endif + /* Constants */ #define PAL_RATE 250.0 /* 1 / (50Hz * 80us) */ #define NTSC_RATE 208.0 /* 1 / (60Hz * 80us) */ -#define C4_FREQ 130812 /* 440Hz / (2 ^ (21 / 12)) * 1000 */ #define C4_PAL_RATE 8287 /* 7093789.2 / period (C4) * 2 */ #define C4_NTSC_RATE 8363 /* 7159090.5 / period (C4) * 2 */ @@ -49,7 +52,7 @@ typedef signed long long int64; /* [Amiga] CPU clock = 1.6 * PCCF = 7.0937892 MHz */ #define DEFAULT_AMPLIFY 1 -#define DEFAULT_MIX 70 +#define DEFAULT_MIX 100 #define MSN(x) (((x)&0xf0)>>4) #define LSN(x) ((x)&0x0f) @@ -88,7 +91,7 @@ void __inline CLIB_DECL D_(const char *text, ...) { do {} while (0); } #endif #endif -#elif defined ANDROID +#elif defined __ANDROID__ #ifdef DEBUG #include @@ -109,7 +112,7 @@ void __inline CLIB_DECL D_(const char *text, ...) { do {} while (0); } #define D_CRIT "\x1b[31m" #define D_WARN "\x1b[36m" #define D_(args...) do { \ - printf("\x1b[33m%s \x1b[37m[%s:%d] " D_INFO, __PRETTY_FUNCTION__, \ + printf("\x1b[33m%s \x1b[37m[%s:%d] " D_INFO, __FUNCTION__, \ __FILE__, __LINE__); printf (args); printf ("\x1b[0m\n"); \ } while (0) #else @@ -118,14 +121,6 @@ void __inline CLIB_DECL D_(const char *text, ...) { do {} while (0); } #endif /* !_MSC_VER */ -#ifdef HAVE_STRLCPY -#define strncpy strlcpy -#endif - -#ifdef HAVE_STRLCAT -#define strncat strlcat -#endif - #ifdef _MSC_VER #define dup _dup #define fileno _fileno @@ -142,9 +137,8 @@ void __inline CLIB_DECL D_(const char *text, ...) { do {} while (0); } /* Quirks */ #define QUIRK_S3MLOOP (1 << 0) /* S3M loop mode */ #define QUIRK_ENVFADE (1 << 1) /* Fade at end of envelope */ -#define QUIRK_INVLOOP (1 << 2) /* Enable effect EF invert loop */ -#define QUIRK_FUNKIT (1 << 3) /* Enable effect EF funk it */ -#define QUIRK_ST3GVOL (1 << 4) /* ST 3 weird global volume effect */ +#define QUIRK_PROTRACK (1 << 2) /* Use Protracker-specific quirks */ +#define QUIRK_ST3BUGS (1 << 4) /* Scream Tracker 3 bug compatibility */ #define QUIRK_FINEFX (1 << 5) /* Enable 0xf/0xe for fine effects */ #define QUIRK_VSALL (1 << 6) /* Volume slides in all frames */ #define QUIRK_PBALL (1 << 7) /* Pitch bending in all frames */ @@ -152,8 +146,8 @@ void __inline CLIB_DECL D_(const char *text, ...) { do {} while (0); } #define QUIRK_VOLPDN (1 << 9) /* Set priority to volume slide down */ #define QUIRK_UNISLD (1 << 10) /* Unified pitch slide/portamento */ #define QUIRK_ITVPOR (1 << 11) /* Disable fine bends in IT vol fx */ -#define QUIRK_LINEAR (1 << 12) /* Linear periods */ -#define QUIRK_MODRNG (1 << 13) /* Limit periods to MOD range */ +#define QUIRK_FTMOD (1 << 12) /* Flag for multichannel mods */ +/*#define QUIRK_MODRNG (1 << 13)*/ /* Limit periods to MOD range */ #define QUIRK_INSVOL (1 << 14) /* Use instrument volume */ #define QUIRK_VIRTUAL (1 << 15) /* Enable virtual channels */ #define QUIRK_FILTER (1 << 16) /* Enable filter */ @@ -163,26 +157,26 @@ void __inline CLIB_DECL D_(const char *text, ...) { do {} while (0); } #define QUIRK_VIBALL (1 << 20) /* Vibrato in all frames */ #define QUIRK_VIBINV (1 << 21) /* Vibrato has inverse waveform */ #define QUIRK_PRENV (1 << 22) /* Portamento resets envelope & fade */ -#define QUIRK_S3MLFO (1 << 23) /* S3M-style LFO waveforms */ +#define QUIRK_ITOLDFX (1 << 23) /* IT old effects mode */ #define QUIRK_S3MRTG (1 << 24) /* S3M-style retrig when count == 0 */ #define QUIRK_RTDELAY (1 << 25) /* Delay effect retrigs instrument */ -#define QUIRK_MLKDLY (1 << 26) /* MilkyTracker-style delay effect */ -#define QUIRK_ENVSUS (1 << 27) /* Key release jumps to sus point */ -#define QUIRK_S3MPMEM (1 << 28) /* S3M-style parameter memory */ -#define QUIRK_XMFINE (1 << 29) /* XM-style fine tune */ +#define QUIRK_FT2BUGS (1 << 26) /* FT2 bug compatibility */ +#define QUIRK_MARKER (1 << 27) /* Patterns 0xfe and 0xff reserved */ +#define QUIRK_NOBPM (1 << 28) /* Adjust speed only, no BPM */ +#define QUIRK_ARPMEM (1 << 29) /* Arpeggio has memory (S3M_ARPEGGIO) */ +#define QUIRK_RSTCHN (1 << 30) /* Reset channel on sample end */ #define HAS_QUIRK(x) (m->quirk & (x)) /* Format quirks */ #define QUIRKS_ST3 (QUIRK_S3MLOOP | QUIRK_VOLPDN | QUIRK_FINEFX | \ - QUIRK_S3MPMEM | QUIRK_S3MRTG | QUIRK_S3MLFO ) -#define QUIRKS_FT2 (QUIRK_RTDELAY | QUIRK_FINEFX | QUIRK_ENVSUS | \ - QUIRK_XMFINE ) + QUIRK_S3MRTG | QUIRK_MARKER | QUIRK_RSTCHN ) +#define QUIRKS_FT2 (QUIRK_RTDELAY | QUIRK_FINEFX ) #define QUIRKS_IT (QUIRK_S3MLOOP | QUIRK_FINEFX | QUIRK_VIBALL | \ QUIRK_ENVFADE | QUIRK_ITVPOR | QUIRK_KEYOFF | \ - QUIRK_VIRTUAL | QUIRK_FILTER | QUIRK_S3MLFO | \ - QUIRK_IGSTPOR | QUIRK_S3MRTG ) + QUIRK_VIRTUAL | QUIRK_FILTER | QUIRK_RSTCHN | \ + QUIRK_IGSTPOR | QUIRK_S3MRTG | QUIRK_MARKER ) /* DSP effects */ #define DSP_EFFECT_CUTOFF 0x02 @@ -196,6 +190,19 @@ void __inline CLIB_DECL D_(const char *text, ...) { do {} while (0); } #define MED_TIME_FACTOR 2.64 #define MAX_SEQUENCES 16 +#define MAX_SAMPLE_SIZE 0x10000000 +#define MAX_SAMPLES 1024 + +#define IS_PLAYER_MODE_MOD() (m->read_event_type == READ_EVENT_MOD) +#define IS_PLAYER_MODE_FT2() (m->read_event_type == READ_EVENT_FT2) +#define IS_PLAYER_MODE_ST3() (m->read_event_type == READ_EVENT_ST3) +#define IS_PLAYER_MODE_IT() (m->read_event_type == READ_EVENT_IT) +#define IS_PLAYER_MODE_MED() (m->read_event_type == READ_EVENT_MED) +#define IS_PERIOD_MODRNG() (m->period_type == PERIOD_MODRNG) +#define IS_PERIOD_LINEAR() (m->period_type == PERIOD_LINEAR) +#define IS_PERIOD_CSPD() (m->period_type == PERIOD_CSPD) + +#define IS_AMIGA_MOD() (IS_PLAYER_MODE_MOD() && IS_PERIOD_MODRNG()) struct ord_data { int speed; @@ -203,6 +210,9 @@ struct ord_data { int gvl; int time; int start_row; +#ifndef LIBXMP_CORE_PLAYER + int st26_speed; +#endif }; @@ -217,6 +227,11 @@ struct smix_data { struct xmp_sample *xxs; }; +/* This will be added to the sample structure in the next API revision */ +struct extra_sample_data { + double c5spd; +}; + struct module_data { struct xmp_module mod; @@ -231,6 +246,7 @@ struct module_data { int c4rate; /* C4 replay rate */ int volbase; /* Volume base */ int gvolbase; /* Global volume base */ + int gvol; /* Global volume */ int *vol_table; /* Volume translation table */ int quirk; /* player quirks */ #define READ_EVENT_MOD 0 @@ -239,21 +255,23 @@ struct module_data { #define READ_EVENT_IT 3 #define READ_EVENT_MED 4 int read_event_type; +#define PERIOD_AMIGA 0 +#define PERIOD_MODRNG 1 +#define PERIOD_LINEAR 2 +#define PERIOD_CSPD 3 + int period_type; int smpctl; /* sample control flags */ int defpan; /* default pan setting */ struct ord_data xxo_info[XMP_MAX_MOD_LENGTH]; - int num_sequences; struct xmp_sequence seq_data[MAX_SEQUENCES]; - char *instrument_path; - void *extra; /* format-specific extra fields */ - - const struct synth_info *synth; - void *synth_chip; - char **scan_cnt; /* scan counters */ + struct extra_sample_data *xtra; +#ifndef LIBXMP_CORE_DISABLE_IT + struct xmp_sample *xsmp; /* sustain loop samples */ +#endif }; @@ -264,8 +282,10 @@ struct player_data { int frame; int speed; int bpm; + int mode; int player_flags; int flags; + double current_time; double frame_time; @@ -281,7 +301,6 @@ struct player_data { int pbreak; int jump; int delay; - int skip_fetch; /* To emulate delay + break quirk */ int jumpline; int loop_chn; @@ -329,6 +348,11 @@ struct player_data { int in_size; char *in_buffer; } buffer_data; + +#ifndef LIBXMP_CORE_PLAYER + int st26_speed; /* For IceTracker speed effect */ +#endif + int filter; /* Amiga led filter */ }; struct mixer_data { @@ -344,7 +368,7 @@ struct mixer_data { int ticksize; int dtright; /* anticlick control, right channel */ int dtleft; /* anticlick control, left channel */ - int pbase; /* period base */ + double pbase; /* period base */ }; struct context_data { @@ -358,20 +382,21 @@ struct context_data { /* Prototypes */ -char *adjust_string (char *); -int exclude_match (char *); -int prepare_scan (struct context_data *); -int scan_sequences (struct context_data *); -int get_sequence (struct context_data *, int); - -int8 read8s (FILE *); -uint8 read8 (FILE *); -uint16 read16l (FILE *); -uint16 read16b (FILE *); -uint32 read24l (FILE *); -uint32 read24b (FILE *); -uint32 read32l (FILE *); -uint32 read32b (FILE *); +char *libxmp_adjust_string (char *); +int libxmp_exclude_match (char *); +int libxmp_prepare_scan (struct context_data *); +int libxmp_scan_sequences (struct context_data *); +int libxmp_get_sequence (struct context_data *, int); +int libxmp_set_player_mode (struct context_data *); + +int8 read8s (FILE *, int *err); +uint8 read8 (FILE *, int *err); +uint16 read16l (FILE *, int *err); +uint16 read16b (FILE *, int *err); +uint32 read24l (FILE *, int *err); +uint32 read24b (FILE *, int *err); +uint32 read32l (FILE *, int *err); +uint32 read32b (FILE *, int *err); void write8 (FILE *, uint8); void write16l (FILE *, uint16); void write16b (FILE *, uint16); @@ -386,12 +411,7 @@ uint32 readmem24b (uint8 *); uint32 readmem32l (uint8 *); uint32 readmem32b (uint8 *); -int get_temp_dir (char *, int); -#ifdef WIN32 -int mkstemp (char *); -#endif - -struct xmp_instrument *get_instrument(struct context_data *, int); -struct xmp_sample *get_sample(struct context_data *, int); +struct xmp_instrument *libxmp_get_instrument(struct context_data *, int); +struct xmp_sample *libxmp_get_sample(struct context_data *, int); #endif /* LIBXMP_COMMON_H */ diff --git a/src/control.c b/src/control.c index 822795d..58e019e 100644 --- a/src/control.c +++ b/src/control.c @@ -1,5 +1,5 @@ -/* Extended Module Player core player - * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr +/* Extended Module Player + * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -44,6 +44,7 @@ xmp_context xmp_create_context() ctx->state = XMP_STATE_UNLOADED; ctx->m.defpan = 100; + ctx->s.numvoc = SMIX_NUMVOC; return (xmp_context)ctx; } @@ -64,45 +65,57 @@ static void set_position(struct context_data *ctx, int pos, int dir) struct module_data *m = &ctx->m; struct xmp_module *mod = &m->mod; struct flow_control *f = &p->flow; - int seq, start; + int seq; + int has_marker; /* If dir is 0, we can jump to a different sequence */ if (dir == 0) { - seq = get_sequence(ctx, pos); + seq = libxmp_get_sequence(ctx, pos); } else { seq = p->sequence; } - if (seq == 0xff) + if (seq == 0xff) { return; + } - start = m->seq_data[seq].entry_point; + has_marker = HAS_QUIRK(QUIRK_MARKER); if (seq >= 0) { + int start = m->seq_data[seq].entry_point; + p->sequence = seq; if (pos >= 0) { - if (mod->xxo[pos] == 0xff) { - return; - } + int pat; - while (mod->xxo[pos] == 0xfe && pos > start) { + while (has_marker && mod->xxo[pos] == 0xfe) { if (dir < 0) { - pos--; + if (pos > start) { + pos--; + } } else { pos++; } } + pat = mod->xxo[pos]; - if (pos > p->scan[seq].ord) { - f->end_point = 0; - } else { - f->num_rows = mod->xxp[mod->xxo[p->ord]]->rows; - f->end_point = p->scan[seq].num; + if (pat < mod->pat) { + if (has_marker && pat == 0xff) { + return; + } + + if (pos > p->scan[seq].ord) { + f->end_point = 0; + } else { + f->num_rows = mod->xxp[pat]->rows; + f->end_point = p->scan[seq].num; + f->jumpline = 0; + } } } - if (pos < m->mod.len) { + if (pos < mod->len) { if (pos == 0) { p->pos = -1; } else { @@ -199,7 +212,7 @@ int xmp_seek_time(xmp_context opaque, int time) if (pat >= m->mod.pat) { continue; } - if (get_sequence(ctx, i) != p->sequence) { + if (libxmp_get_sequence(ctx, i) != p->sequence) { continue; } t = m->xxo_info[i].time; @@ -266,10 +279,13 @@ extern int xmp_set_player_v41__(xmp_context, int, int) __attribute__((alias("xmp_set_player_v40__"))); extern int xmp_set_player_v43__(xmp_context, int, int) __attribute__((alias("xmp_set_player_v40__"))); +extern int xmp_set_player_v44__(xmp_context, int, int) + __attribute__((alias("xmp_set_player_v40__"))); asm(".symver xmp_set_player_v40__, xmp_set_player@XMP_4.0"); asm(".symver xmp_set_player_v41__, xmp_set_player@XMP_4.1"); -asm(".symver xmp_set_player_v43__, xmp_set_player@@XMP_4.3"); +asm(".symver xmp_set_player_v43__, xmp_set_player@XMP_4.3"); +asm(".symver xmp_set_player_v44__, xmp_set_player@@XMP_4.4"); #define xmp_set_player__ xmp_set_player_v40__ #else @@ -284,10 +300,17 @@ int xmp_set_player__(xmp_context opaque, int parm, int val) struct mixer_data *s = &ctx->s; int ret = -XMP_ERROR_INVALID; + if (parm == XMP_PLAYER_SMPCTL || parm == XMP_PLAYER_DEFPAN) { /* these should be set before loading the module */ - if (ctx->state >= XMP_STATE_LOADED) + if (ctx->state >= XMP_STATE_LOADED) { + return -XMP_ERROR_STATE; + } + } else if (parm == XMP_PLAYER_VOICES) { + /* these should be set before start playing */ + if (ctx->state >= XMP_STATE_PLAYING) { return -XMP_ERROR_STATE; + } } else if (ctx->state < XMP_STATE_PLAYING) { return -XMP_ERROR_STATE; } @@ -316,11 +339,7 @@ int xmp_set_player__(xmp_context opaque, int parm, int val) ret = 0; break; case XMP_PLAYER_FLAGS: { - int vblank = p->flags & XMP_FLAGS_VBLANK; p->player_flags = val; - p->flags |= val; - if (vblank != (p->flags & XMP_FLAGS_VBLANK)) - scan_sequences(ctx); ret = 0; break; } @@ -329,7 +348,7 @@ int xmp_set_player__(xmp_context opaque, int parm, int val) int vblank = p->flags & XMP_FLAGS_VBLANK; p->flags = val; if (vblank != (p->flags & XMP_FLAGS_VBLANK)) - scan_sequences(ctx); + libxmp_scan_sequences(ctx); ret = 0; break; } case XMP_PLAYER_SMPCTL: @@ -356,6 +375,17 @@ int xmp_set_player__(xmp_context opaque, int parm, int val) ret = 0; } break; + + /* 4.4 */ + case XMP_PLAYER_MODE: + p->mode = val; + libxmp_set_player_mode(ctx); + libxmp_scan_sequences(ctx); + ret = 0; + break; + case XMP_PLAYER_VOICES: + s->numvoc = val; + break; } return ret; @@ -368,11 +398,14 @@ extern int xmp_get_player_v42__(xmp_context, int) __attribute__((alias("xmp_get_player_v40__"))); extern int xmp_get_player_v43__(xmp_context, int) __attribute__((alias("xmp_get_player_v40__"))); +extern int xmp_get_player_v44__(xmp_context, int) + __attribute__((alias("xmp_get_player_v40__"))); asm(".symver xmp_get_player_v40__, xmp_get_player@XMP_4.0"); asm(".symver xmp_get_player_v41__, xmp_get_player@XMP_4.1"); asm(".symver xmp_get_player_v42__, xmp_get_player@XMP_4.2"); -asm(".symver xmp_get_player_v43__, xmp_get_player@@XMP_4.3"); +asm(".symver xmp_get_player_v43__, xmp_get_player@XMP_4.3"); +asm(".symver xmp_get_player_v44__, xmp_get_player@@XMP_4.4"); #define xmp_get_player__ xmp_get_player_v40__ #else @@ -433,6 +466,28 @@ int xmp_get_player__(xmp_context opaque, int parm) case XMP_PLAYER_DEFPAN: ret = m->defpan; break; + + /* 4.4 */ + case XMP_PLAYER_MODE: + ret = p->mode; + break; + case XMP_PLAYER_MIXER_TYPE: + ret = XMP_MIXER_STANDARD; + if (p->flags & XMP_FLAGS_A500) { + if (IS_AMIGA_MOD()) { +#ifdef LIBXMP_PAULA_SIMULATOR + if (p->filter) { + ret = XMP_MIXER_A500F; + } else { + ret = XMP_MIXER_A500; + } +#endif + } + } + break; + case XMP_PLAYER_VOICES: + ret = s->numvoc; + break; } return ret; diff --git a/src/dataio.c b/src/dataio.c index 60760ec..a6af37e 100644 --- a/src/dataio.c +++ b/src/dataio.c @@ -1,5 +1,5 @@ -/* Extended Module Player core player - * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr +/* Extended Module Player + * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -20,83 +20,140 @@ * THE SOFTWARE. */ +#include #include "common.h" -inline uint8 read8(FILE *f) +#define read_byte(x) do { \ + (x) = fgetc(f); \ + if ((x) < 0) goto error; \ +} while (0) + +#define set_error(x) do { \ + if (err != NULL) *err = (x); \ +} while (0) + + +uint8 read8(FILE *f, int *err) { - return (uint8)fgetc(f); + int a; + + read_byte(a); + set_error(0); + return a; + + error: + set_error(ferror(f) ? errno : EOF); + return 0xff; } -int8 read8s(FILE *f) +int8 read8s(FILE *f, int *err) { - return (int8)fgetc(f); + int a; + + read_byte(a); + set_error(0); + return (int8)a; + + error: + set_error(ferror(f) ? errno : EOF); + return 0; } -uint16 read16l(FILE *f) +uint16 read16l(FILE *f, int *err) { - uint32 a, b; + int a, b; - a = read8(f); - b = read8(f); + read_byte(a); + read_byte(b); - return (b << 8) | a; + set_error(0); + return ((uint16)b << 8) | a; + + error: + set_error(ferror(f) ? errno : EOF); + return 0xffff; } -uint16 read16b(FILE *f) +uint16 read16b(FILE *f, int *err) { - uint32 a, b; + int a, b; - a = read8(f); - b = read8(f); + read_byte(a); + read_byte(b); + set_error(0); return (a << 8) | b; + + error: + set_error(ferror(f) ? errno : EOF); + return 0xffff; } -uint32 read24l(FILE *f) +uint32 read24l(FILE *f, int *err) { - uint32 a, b, c; - - a = read8(f); - b = read8(f); - c = read8(f); + int a, b, c; + read_byte(a); + read_byte(b); + read_byte(c); + + set_error(0); return (c << 16) | (b << 8) | a; + + error: + set_error(ferror(f) ? errno : EOF); + return 0xffffff; } -uint32 read24b(FILE *f) +uint32 read24b(FILE *f, int *err) { - uint32 a, b, c; - - a = read8(f); - b = read8(f); - c = read8(f); + int a, b, c; + read_byte(a); + read_byte(b); + read_byte(c); + + set_error(0); return (a << 16) | (b << 8) | c; + + error: + set_error(ferror(f) ? errno : EOF); + return 0xffffff; } -uint32 read32l(FILE *f) +uint32 read32l(FILE *f, int *err) { - uint32 a, b, c, d; + int a, b, c, d; - a = read8(f); - b = read8(f); - c = read8(f); - d = read8(f); + read_byte(a); + read_byte(b); + read_byte(c); + read_byte(d); + set_error(0); return (d << 24) | (c << 16) | (b << 8) | a; + + error: + set_error(ferror(f) ? errno : EOF); + return 0xffffffff; } -uint32 read32b(FILE *f) +uint32 read32b(FILE *f, int *err) { - uint32 a, b, c, d; + int a, b, c, d; - a = read8(f); - b = read8(f); - c = read8(f); - d = read8(f); + read_byte(a); + read_byte(b); + read_byte(c); + read_byte(d); + set_error(0); return (a << 24) | (b << 16) | (c << 8) | d; + + error: + set_error(ferror(f) ? errno : EOF); + return 0xffffffff; } uint16 readmem16l(uint8 *m) diff --git a/src/depacker.h b/src/depacker.h new file mode 100644 index 0000000..df19d79 --- /dev/null +++ b/src/depacker.h @@ -0,0 +1,28 @@ +#ifndef XMP_DEPACKER_H +#define XMP_DEPACKER_H + +#include + +extern struct depacker libxmp_depacker_zip; +extern struct depacker libxmp_depacker_lha; +extern struct depacker libxmp_depacker_gzip; +extern struct depacker libxmp_depacker_bzip2; +extern struct depacker libxmp_depacker_xz; +extern struct depacker libxmp_depacker_compress; +extern struct depacker libxmp_depacker_pp; +extern struct depacker libxmp_depacker_sqsh; +extern struct depacker libxmp_depacker_arc; +extern struct depacker libxmp_depacker_arcfs; +extern struct depacker libxmp_depacker_mmcmp; +extern struct depacker libxmp_depacker_muse; +extern struct depacker libxmp_depacker_lzx; +extern struct depacker libxmp_depacker_s404; +extern struct depacker libxmp_depacker_xfd; +extern struct depacker libxmp_depacker_oxm; + +struct depacker { + int (*const test)(unsigned char *); + int (*const depack)(FILE *, FILE *); +}; + +#endif diff --git a/src/depackers/Makefile b/src/depackers/Makefile deleted file mode 100644 index d81999b..0000000 --- a/src/depackers/Makefile +++ /dev/null @@ -1,21 +0,0 @@ - -DEPACKERS_OBJS = ppdepack.o unsqsh.o mmcmp.o readrle.o readlzw.o \ - unarc.o arcfs.o xfd.o inflate.o muse.o unlzx.o s404_dec.o \ - unzip.o gunzip.o uncompress.o unxz.o bunzip2.o unlha.o \ - xz_dec_lzma2.o xz_dec_stream.o oxm.o vorbis.o crc32.o - -DEPACKERS_DFILES = Makefile $(DEPACKERS_OBJS:.o=.c) readhuff.h readlzw.h \ - readrle.h inflate.h xz_lzma2.h README.unxz xz.h \ - xz_private.h xz_stream.h xz_config.h vorbis.h crc32.h - -DEPACKERS_PATH = src/depackers - -OBJS += $(addprefix $(DEPACKERS_PATH)/,$(DEPACKERS_OBJS)) - -default-depackers:: - $(MAKE) -C .. - -dist-depackers:: - mkdir -p $(DIST)/$(DEPACKERS_PATH) - cp -RPp $(addprefix $(DEPACKERS_PATH)/,$(DEPACKERS_DFILES)) $(DIST)/$(DEPACKERS_PATH) - diff --git a/src/depackers/arcfs.c b/src/depackers/arcfs.c index 0b7203b..42cdf37 100644 --- a/src/depackers/arcfs.c +++ b/src/depackers/arcfs.c @@ -17,6 +17,7 @@ #include #include #include "common.h" +#include "depacker.h" #include "readrle.h" #include "readhuff.h" #include "readlzw.h" @@ -37,32 +38,49 @@ static int read_file_header(FILE *in, struct archived_file_header_tag *hdrp) { int hlen, start /*, ver*/; int i; + int error; - fseek(in, 8, SEEK_CUR); /* skip magic */ - hlen = read32l(in) / 36; - start = read32l(in); - /*ver =*/ read32l(in); - - read32l(in); - /*ver =*/ read32l(in); - - fseek(in, 68, SEEK_CUR); /* reserved */ + if (fseek(in, 8, SEEK_CUR) < 0) /* skip magic */ + return -1; + hlen = read32l(in, &error) / 36; + if (error != 0) return -1; + start = read32l(in, &error); + if (error != 0) return -1; + /*ver =*/ read32l(in, &error); + if (error != 0) return -1; + + read32l(in, &error); + if (error != 0) return -1; + /*ver =*/ read32l(in, &error); + if (error != 0) return -1; + + if (fseek(in, 68, SEEK_CUR) < 0) /* reserved */ + return -1; for (i = 0; i < hlen; i++) { - int x = read8(in); + int x = read8(in, &error); + if (error != 0) return -1; if (x == 0) /* end? */ break; hdrp->method = x & 0x7f; - fread(hdrp->name, 1, 11, in); + if (fread(hdrp->name, 1, 11, in) != 11) { + return -1; + } hdrp->name[12] = 0; - hdrp->orig_size = read32l(in); - read32l(in); - read32l(in); - x = read32l(in); - hdrp->compressed_size = read32l(in); - hdrp->offset = read32l(in); + hdrp->orig_size = read32l(in, &error); + if (error != 0) return -1; + read32l(in, &error); + if (error != 0) return -1; + read32l(in, &error); + if (error != 0) return -1; + x = read32l(in, &error); + if (error != 0) return -1; + hdrp->compressed_size = read32l(in, &error); + if (error != 0) return -1; + hdrp->offset = read32l(in, &error); + if (error != 0) return -1; if (x == 1) /* deleted */ continue; @@ -78,7 +96,7 @@ static int read_file_header(FILE *in, struct archived_file_header_tag *hdrp) break; } - return 1; + return 0; } /* read file data, assuming header has just been read from in @@ -92,16 +110,22 @@ static unsigned char *read_file_data(FILE *in, unsigned char *data; int siz = hdrp->compressed_size; - if ((data = malloc(siz)) == NULL) - return NULL; - - fseek(in, hdrp->offset, SEEK_SET); + if ((data = malloc(siz)) == NULL) { + goto err; + } + if (fseek(in, hdrp->offset, SEEK_SET) < 0) { + goto err2; + } if (fread(data, 1, siz, in) != siz) { - free(data); - data = NULL; + goto err2; } return data; + + err2: + free(data); + err: + return NULL; } static int arcfs_extract(FILE *in, FILE *out) @@ -110,7 +134,7 @@ static int arcfs_extract(FILE *in, FILE *out) unsigned char *data, *orig_data; int exitval = 0; - if (!read_file_header(in, &hdr)) + if (read_file_header(in, &hdr) < 0) return -1; if (hdr.method == 0) @@ -134,17 +158,17 @@ static int arcfs_extract(FILE *in, FILE *out) case 8: /* "Crunched" [sic] * (RLE+9-to-12-bit dynamic LZW, a *bit* like GIF) */ - orig_data = convert_lzw_dynamic(data, hdr.bits, 1, + orig_data = libxmp_convert_lzw_dynamic(data, hdr.bits, 1, hdr.compressed_size, hdr.orig_size, 0); break; case 9: /* "Squashed" (9-to-13-bit, no RLE) */ - orig_data = convert_lzw_dynamic(data, hdr.bits, 0, + orig_data = libxmp_convert_lzw_dynamic(data, hdr.bits, 0, hdr.compressed_size, hdr.orig_size, 0); break; case 127: /* "Compress" (9-to-16-bit, no RLE) ("Spark" only) */ - orig_data = convert_lzw_dynamic(data, hdr.bits, 0, + orig_data = libxmp_convert_lzw_dynamic(data, hdr.bits, 0, hdr.compressed_size, hdr.orig_size, 0); break; @@ -169,7 +193,12 @@ static int arcfs_extract(FILE *in, FILE *out) return exitval; } -int decrunch_arcfs(FILE * f, FILE * fo) +static int test_arcfs(unsigned char *b) +{ + return !memcmp(b, "Archive\0", 8); +} + +static int decrunch_arcfs(FILE * f, FILE * fo) { int ret; @@ -182,3 +211,8 @@ int decrunch_arcfs(FILE * f, FILE * fo) return 0; } + +struct depacker libxmp_depacker_arcfs = { + test_arcfs, + decrunch_arcfs +}; diff --git a/src/depackers/bunzip2.c b/src/depackers/bunzip2.c index 1bb35ab..f066b1a 100644 --- a/src/depackers/bunzip2.c +++ b/src/depackers/bunzip2.c @@ -40,6 +40,7 @@ #include #include #include "common.h" +#include "depacker.h" #include "crc32.h" /* Constants for huffman coding */ @@ -348,7 +349,8 @@ static int get_next_block(bunzip_data *bd) literal used is the one at the head of the mtfSymbol array.) */ if(runPos) { runPos=0; - if(dbufCount+t>=dbufSize) return RETVAL_DATA_ERROR; + if(t < 0 || t > dbufSize || dbufCount+t>=dbufSize) + return RETVAL_DATA_ERROR; uc = symToByte[mtfSymbol[0]]; byteCount[uc] += t; @@ -452,7 +454,7 @@ static int read_bunzip(bunzip_data *bd, char *outbuf, int len) /* Write next byte into output buffer, updating CRC */ outbuf[gotcount++] = current; bd->writeCRC=(((bd->writeCRC)<<8) - ^crc32_table_B[((bd->writeCRC)>>24)^current]); + ^libxmp_crc32_table_B[((bd->writeCRC)>>24)^current]); /* Loop now if we're outputting multiple copies of this byte */ if (bd->writeCopies) { --bd->writeCopies; @@ -553,15 +555,20 @@ static int start_bunzip(bunzip_data **bdp, FILE *in, char *inbuf, int len) return RETVAL_OK; } +static int test_bzip2(unsigned char *b) +{ + return b[0] == 'B' && b[1] == 'Z' && b[2] == 'h'; +} + /* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip data, not end of file.) */ -int decrunch_bzip2(FILE *src, FILE *dst) +static int decrunch_bzip2(FILE *src, FILE *dst) { char *outbuf; bunzip_data *bd; int i; - crc32_init_B(); + libxmp_crc32_init_B(); if(!(outbuf=malloc(IOBUF_SIZE))) return RETVAL_OUT_OF_MEMORY; if(!(i=start_bunzip(&bd,src,0,0))) { @@ -581,20 +588,7 @@ int decrunch_bzip2(FILE *src, FILE *dst) return i == 0 ? 0 : -1; } -#ifdef TESTING - -static char * const bunzip_errors[]={NULL,"Bad file checksum","Not bzip data", - "Unexpected input EOF","Unexpected output EOF","Data error", - "Out of memory","Obsolete (pre 0.9.5) bzip format not supported."}; - -/* Dumb little test thing, decompress stdin to stdout */ -int main(int argc, char *argv[]) -{ - int i=uncompressStream(0,1); - char c; - - if(i) fprintf(stderr,"%s\n", bunzip_errors[-i]); - else if(read(0,&c,1)) fprintf(stderr,"Trailing garbage ignored\n"); - return -i; -} -#endif +struct depacker libxmp_depacker_bzip2 = { + test_bzip2, + decrunch_bzip2 +}; diff --git a/src/depackers/crc32.c b/src/depackers/crc32.c index 44d3224..ad951af 100644 --- a/src/depackers/crc32.c +++ b/src/depackers/crc32.c @@ -24,8 +24,8 @@ #include "common.h" #include "crc32.h" -uint32 crc32_table_A[256]; -uint32 crc32_table_B[256]; +uint32 libxmp_crc32_table_A[256]; +uint32 libxmp_crc32_table_B[256]; static void crc_table_init_A(uint32 poly, uint32 *table) { @@ -61,45 +61,45 @@ static void crc_table_init_B(uint32 poly, uint32 *table) return; } -void crc32_init_A() +void libxmp_crc32_init_A() { static int flag = 0; if (flag) return; - crc_table_init_A(0xedb88320, crc32_table_A); + crc_table_init_A(0xedb88320, libxmp_crc32_table_A); flag = 1; } -void crc32_init_B() +void libxmp_crc32_init_B() { static int flag = 0; if (flag) return; - crc_table_init_B(0x04c11db7, crc32_table_B); + crc_table_init_B(0x04c11db7, libxmp_crc32_table_B); flag = 1; } -uint32 crc32_A1(const uint8 *buf, size_t size, uint32 crc) +uint32 libxmp_crc32_A1(const uint8 *buf, size_t size, uint32 crc) { crc = ~crc; while (size--) { - crc = crc32_table_A[*buf++ ^ (crc & 0xff)] ^ (crc >> 8); + crc = libxmp_crc32_table_A[*buf++ ^ (crc & 0xff)] ^ (crc >> 8); } return ~crc; } -uint32 crc32_A2(const uint8 *buf, size_t size, uint32 crc) +uint32 libxmp_crc32_A2(const uint8 *buf, size_t size, uint32 crc) { while (size--) { - crc = crc32_table_A[*buf++ ^ (crc & 0xff)] ^ (crc >> 8); + crc = libxmp_crc32_table_A[*buf++ ^ (crc & 0xff)] ^ (crc >> 8); } return crc; diff --git a/src/depackers/crc32.h b/src/depackers/crc32.h index bb58efc..b4dc9bb 100644 --- a/src/depackers/crc32.h +++ b/src/depackers/crc32.h @@ -1,14 +1,13 @@ -#ifndef XMP_CRC_H -#define XMP_CRC_H +#ifndef LIBXMP_CRC_H +#define LIBXMP_CRC_H -extern uint32 crc32_table_A[256]; -extern uint32 crc32_table_B[256]; +extern uint32 libxmp_crc32_table_A[256]; +extern uint32 libxmp_crc32_table_B[256]; -void crc32_init_A(void); -uint32 crc32_A1(const uint8 *, size_t, uint32); -uint32 crc32_A2(const uint8 *, size_t, uint32); - -void crc32_init_B(void); +void libxmp_crc32_init_A (void); +uint32 libxmp_crc32_A1 (const uint8 *, size_t, uint32); +uint32 libxmp_crc32_A2 (const uint8 *, size_t, uint32); +void libxmp_crc32_init_B (void); #endif diff --git a/src/depackers/gunzip.c b/src/depackers/gunzip.c index 6cb9317..db8cc6a 100644 --- a/src/depackers/gunzip.c +++ b/src/depackers/gunzip.c @@ -1,5 +1,5 @@ /* Extended Module Player - * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr + * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr * * This file is part of the Extended Module Player and is distributed * under the terms of the GNU Lesser General Public License. See COPYING.LIB @@ -9,6 +9,7 @@ #include #include "common.h" #include "inflate.h" +#include "depacker.h" #include "crc32.h" /* See RFC1952 for further information */ @@ -41,60 +42,67 @@ struct member { uint8 os; }; -int decrunch_gzip(FILE *in, FILE *out) +static int test_gzip(unsigned char *b) +{ + return b[0] == 31 && b[1] == 139; +} + +static int decrunch_gzip(FILE *in, FILE *out) { struct member member; int val, c; uint32 crc; - crc32_init_A(); + libxmp_crc32_init_A(); - member.id1 = read8(in); - member.id2 = read8(in); - member.cm = read8(in); - member.flg = read8(in); - member.mtime = read32l(in); - member.xfl = read8(in); - member.os = read8(in); + member.id1 = read8(in, NULL); + member.id2 = read8(in, NULL); + member.cm = read8(in, NULL); + member.flg = read8(in, NULL); + member.mtime = read32l(in, NULL); + member.xfl = read8(in, NULL); + member.os = read8(in, NULL); if (member.cm != 0x08) { return -1; } if (member.flg & FLAG_FEXTRA) { - int xlen = read16l(in); - fseek(in, xlen, SEEK_CUR); + int xlen = read16l(in, NULL); + if (fseek(in, xlen, SEEK_CUR) < 0) { + return -1; + } } if (member.flg & FLAG_FNAME) { do { - c = read8(in); + c = read8(in, NULL); } while (c != 0); } if (member.flg & FLAG_FCOMMENT) { do { - c = read8(in); + c = read8(in, NULL); } while (c != 0); } if (member.flg & FLAG_FHCRC) { - read16l(in); + read16l(in, NULL); } - val = inflate(in, out, &crc, 1); + val = libxmp_inflate(in, out, &crc, 1); if (val != 0) { return -1; } /* Check CRC32 */ - val = read32l(in); + val = read32l(in, NULL); if (val != crc) { return -1; } /* Check file size */ - val = read32l(in); + val = read32l(in, NULL); if (val != ftell(out)) { return -1; } @@ -102,3 +110,7 @@ int decrunch_gzip(FILE *in, FILE *out) return 0; } +struct depacker libxmp_depacker_gzip = { + test_gzip, + decrunch_gzip +}; diff --git a/src/depackers/inflate.c b/src/depackers/inflate.c index 9cdbb06..4dc786d 100644 --- a/src/depackers/inflate.c +++ b/src/depackers/inflate.c @@ -6,8 +6,8 @@ #include "inflate.h" #include "crc32.h" -#define read_int_b(x) read32b(x) -#define read_word(x) read16l(x) +#define read_int_b(x) read32b(x, NULL) +#define read_word(x) read16l(x, NULL) #define ZIP #undef DEBUG @@ -53,7 +53,13 @@ struct huffman_tree_t short int right; }; -static const int length_codes[29] = { 3,4,5,6,7,8,9,10,11,13,15,17,19, +#define DIST_CODES_SIZE 30 +#define LENGTH_CODES_SIZE 29 +#define HUFFMAN_TREE_SIZE 1024 +#define DYN_HUFF_TRANS_SIZE 19 + +static const int length_codes[LENGTH_CODES_SIZE] = { + 3,4,5,6,7,8,9,10,11,13,15,17,19, 23,27,31,35,43,51,59,67,83,99,115, 131,163,195,227,258 }; @@ -61,7 +67,7 @@ static const int length_extra_bits[29] = { 0,0,0,0,0,0,0,0,1,1,1,1, 2,2,2,2,3,3,3,3,4,4,4,4, 5,5,5,5,0 }; -static const int dist_codes[30] = { 1,2,3,4,5,7,9,13,17,25, +static const int dist_codes[DIST_CODES_SIZE] = { 1,2,3,4,5,7,9,13,17,25, 33,49,65,97,129,193,257,385,513,769, 1025,1537,2049,3073,4097,6145,8193, 12289,16385,24577 }; @@ -70,7 +76,8 @@ static const int dist_extra_bits[30] = { 0,0,0,0,1,1,2,2,3,3, 4,4,5,5,6,6,7,7,8,8, 9,9,10,10,11,11,12,12,13,13 }; -static const int dyn_huff_trans[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, +static const int dyn_huff_trans[DYN_HUFF_TRANS_SIZE] = { + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; static const unsigned char reverse[256] = { @@ -103,6 +110,7 @@ int print_binary(int b, int l) } #endif +#if 0 static int kunzip_inflate_free(struct inflate_data *data) { if (data->huffman_tree_len_static!=0) @@ -110,6 +118,7 @@ static int kunzip_inflate_free(struct inflate_data *data) return 0; } +#endif #if 0 static unsigned int get_alder(FILE *out) @@ -276,7 +285,7 @@ printf("load_fixed_huffman()\n"); return 0; } -static int load_codes(FILE *in, struct bitstream_t *bitstream, int *lengths, int count, int *hclen_code_length, int *hclen_code, struct huffman_tree_t *huffman_tree) +static int load_codes(FILE *in, struct bitstream_t *bitstream, int *lengths, int len_size, int count, int *hclen_code_length, int *hclen_code, struct huffman_tree_t *huffman_tree) { int r,t,c,x; int code,curr_code; @@ -322,6 +331,10 @@ static int load_codes(FILE *in, struct bitstream_t *bitstream, int *lengths, int if (t<=15) { + /* Sanity check */ + if (r >= len_size) + return -1; + lengths[r++]=t; } else @@ -342,6 +355,10 @@ static int load_codes(FILE *in, struct bitstream_t *bitstream, int *lengths, int bitstream->bitptr-=2; bitstream->holding=bitstream->holding&((1<bitptr)-1); + /* Sanity check */ + if (r + x + 3 >= len_size) + return -1; + for (c=0; cholding=bitstream->holding&((1<bitptr)-1); c=x+3; + + /* Sanity check */ + if (r + c >= len_size) + return -1; + memset(&lengths[r],0,sizeof(int)*c); r=r+c; } @@ -376,13 +398,20 @@ static int load_codes(FILE *in, struct bitstream_t *bitstream, int *lengths, int bitstream->holding=bitstream->holding&((1<bitptr)-1); c=x+11; + + /* Sanity check */ + if (r + c >= len_size) + return -1; + memset(&lengths[r],0,sizeof(int)*c); r=r+c; } else { - fprintf(stderr, "unzip: error in bitstream reading in literal code length %d\n",t); +#ifdef DEBUG + fprintf(stderr, "inflate: error in bitstream reading in literal code length %d\n",t); +#endif return -1; } } @@ -510,6 +539,10 @@ static int load_dynamic_huffman(FILE *in, struct huffman_t *huffman, struct bits hdist=(reverse[hdist]>>3)+1; hclen=(reverse[hclen]>>4)+4; + /* Sanity check */ + if (hclen > DYN_HUFF_TRANS_SIZE) + return -1; + /* printf("%d %d %d\n",hclen,sizeof(struct huffman_tree_t),hclen*sizeof(struct huffman_tree_t)); */ #ifdef DEBUG @@ -527,16 +560,18 @@ static int load_dynamic_huffman(FILE *in, struct huffman_t *huffman, struct bits for (t=0; tbitptr<3) { bitstream->holding=reverse[getc(in)]+(bitstream->holding<<8); bitstream->bitptr+=8; } - hclen_code_lengths[dyn_huff_trans[t]]=(bitstream->holding>>(bitstream->bitptr-3)); - hclen_code_lengths[dyn_huff_trans[t]]=reverse[hclen_code_lengths[dyn_huff_trans[t]]]>>5; - bitstream->bitptr-=3; - bitstream->holding=bitstream->holding&((1<bitptr)-1); + len = bitstream->holding >> (bitstream->bitptr-3); + hclen_code_lengths[dyn_huff_trans[t]] = reverse[len] >> 5; + bitstream->bitptr -= 3; + bitstream->holding = bitstream->holding&((1<bitptr)-1); } #ifdef DEBUG @@ -610,7 +645,7 @@ static int load_dynamic_huffman(FILE *in, struct huffman_t *huffman, struct bits memset(huffman->len,0,288*sizeof(int)); /* memset(huffman->code,0,288*sizeof(int)); */ - res = load_codes(in,bitstream,huffman->len,hlit,hclen_code_lengths,hclen_code,huffman_tree_len); + res = load_codes(in,bitstream,huffman->len,288,hlit,hclen_code_lengths,hclen_code,huffman_tree_len); if (res < 0) return -1; @@ -641,7 +676,7 @@ static int load_dynamic_huffman(FILE *in, struct huffman_t *huffman, struct bits memset(huffman->dist_len,0,33*sizeof(int)); /* memset(huffman->dist_code,0,33*sizeof(int)); */ - res = load_codes(in,bitstream,huffman->dist_len,hdist,hclen_code_lengths,hclen_code,huffman_tree_dist); + res = load_codes(in,bitstream,huffman->dist_len,33,hdist,hclen_code_lengths,hclen_code,huffman_tree_dist); if (res < 0) return -1; @@ -682,7 +717,11 @@ int decompress(FILE *in, struct huffman_t *huffman, struct bitstream_t *bitstrea { /* bitstream->holding+=(getc(in)<bitptr); */ /* bitstream->bitptr+=8; */ - bitstream->holding=getc(in); + int x = getc(in); + if (x == EOF) { + return -1; + } + bitstream->holding=x; bitstream->bitptr=8; } #ifdef DEBUG @@ -709,6 +748,14 @@ int decompress(FILE *in, struct huffman_t *huffman, struct bitstream_t *bitstrea curr_leaf=huffman_tree_len[curr_leaf].right; } + /* Sanity check */ + if (curr_leaf >= HUFFMAN_TREE_SIZE) { +#ifdef DEBUG + fprintf(stderr, "inflate: corrupt huffman tree\n"); +#endif + return -1; + } + bitstream->bitptr-=1; bitstream->holding>>=1; } @@ -733,7 +780,7 @@ int decompress(FILE *in, struct huffman_t *huffman, struct bitstream_t *bitstrea if (window_ptr>=WINDOW_SIZE) { fwrite(window,1,WINDOW_SIZE,out); - huffman->checksum=crc32_A2(huffman->window,WINDOW_SIZE,huffman->checksum); + huffman->checksum=libxmp_crc32_A2(huffman->window,WINDOW_SIZE,huffman->checksum); window_ptr=0; } } @@ -752,6 +799,11 @@ int decompress(FILE *in, struct huffman_t *huffman, struct bitstream_t *bitstrea fflush(stdout); #endif code=code-257; + + /* Sanity check */ + if (code >= LENGTH_CODES_SIZE) + return -1; + len=length_codes[code]; if (length_extra_bits[code]!=0) { @@ -826,11 +878,27 @@ int decompress(FILE *in, struct huffman_t *huffman, struct bitstream_t *bitstrea curr_leaf=huffman_tree_dist[curr_leaf].right; } + /* Sanity check */ + if (curr_leaf >= HUFFMAN_TREE_SIZE) { +#ifdef DEBUG + fprintf(stderr, "inflate: corrupt huffman tree\n"); +#endif + return -1; + } + bitstream->bitptr-=1; bitstream->holding>>=1; } } + /* Sanity check */ + if (code >= DIST_CODES_SIZE) { +#ifdef DEBUG + fprintf(stderr, "inflate: corrupt input\n"); +#endif + return -1; + } + dist=dist_codes[code]; if (dist_extra_bits[code]!=0) @@ -891,7 +959,7 @@ exit(0); if (window_ptr>=WINDOW_SIZE) { fwrite(window,1,WINDOW_SIZE,out); - huffman->checksum=crc32_A2(huffman->window,WINDOW_SIZE,huffman->checksum); + huffman->checksum=libxmp_crc32_A2(huffman->window,WINDOW_SIZE,huffman->checksum); window_ptr=0; } } @@ -910,7 +978,7 @@ exit(0); return 0; } -int inflate(FILE *in, FILE *out, uint32 *checksum, int is_zip) +int libxmp_inflate(FILE *in, FILE *out, uint32 *checksum, int is_zip) { /* #ifndef ZIP */ unsigned char CMF, FLG; @@ -931,14 +999,18 @@ int inflate(FILE *in, FILE *out, uint32 *checksum, int is_zip) data.huffman_tree_len_static=0; - huffman_tree_len=malloc(1024*sizeof(struct huffman_tree_t)); + huffman_tree_len=malloc(HUFFMAN_TREE_SIZE * sizeof(struct huffman_tree_t)); if (huffman_tree_len == NULL) goto err; - huffman_tree_dist=malloc(1024*sizeof(struct huffman_tree_t)); + memset(huffman_tree_len, 0xff, HUFFMAN_TREE_SIZE * sizeof(struct huffman_tree_t)); + + huffman_tree_dist=malloc(HUFFMAN_TREE_SIZE * sizeof(struct huffman_tree_t)); if (huffman_tree_dist == NULL) goto err2; + memset(huffman_tree_dist, 0xff, HUFFMAN_TREE_SIZE * sizeof(struct huffman_tree_t)); + huffman.window_ptr=0; #ifdef DEBUG @@ -946,8 +1018,16 @@ int inflate(FILE *in, FILE *out, uint32 *checksum, int is_zip) #endif if (!is_zip) { - CMF=getc(in); - FLG=getc(in); + int x; + if ((x = getc(in)) < 0) { + goto err3; + } + CMF=x; + + if ((x = getc(in)) < 0) { + goto err3; + } + FLG=x; #ifdef DEBUG printf(" CMF: %d\n",CMF); @@ -1022,12 +1102,16 @@ if (!is_zip) { for (t=0; t=WINDOW_SIZE) { fwrite(huffman.window,1,WINDOW_SIZE,out); - huffman.checksum=crc32_A2(huffman.window,WINDOW_SIZE,huffman.checksum); + huffman.checksum=libxmp_crc32_A2(huffman.window,WINDOW_SIZE,huffman.checksum); huffman.window_ptr=0; } } @@ -1041,7 +1125,9 @@ if (!is_zip) { goto err4; } - decompress(in, &huffman, &bitstream, data.huffman_tree_len_static, 0, out, &data); + if (decompress(in, &huffman, &bitstream, data.huffman_tree_len_static, 0, out, &data) < 0) { + goto err4; + } /* free(huffman_tree_len); huffman_tree_len=0; @@ -1053,10 +1139,13 @@ if (!is_zip) { /* Dynamic Huffman */ res = load_dynamic_huffman(in,&huffman,&bitstream,huffman_tree_len,huffman_tree_dist); - if (res < 0) + if (res < 0) { goto err4; + } - decompress(in, &huffman, &bitstream, huffman_tree_len, huffman_tree_dist, out, &data); + if (decompress(in, &huffman, &bitstream, huffman_tree_len, huffman_tree_dist, out, &data) < 0) { + goto err4; + } } else @@ -1074,7 +1163,7 @@ if (!is_zip) { if (huffman.window_ptr!=0) { fwrite(huffman.window,1,huffman.window_ptr,out); - huffman.checksum=crc32_A2(huffman.window,huffman.window_ptr,huffman.checksum); + huffman.checksum=libxmp_crc32_A2(huffman.window,huffman.window_ptr,huffman.checksum); } @@ -1083,7 +1172,7 @@ if (!is_zip) { *checksum=huffman.checksum^0xffffffff; - kunzip_inflate_free(&data); + free(data.huffman_tree_len_static); /* for gzip */ if (bitstream.bitptr == 8) { @@ -1094,7 +1183,7 @@ if (!is_zip) { return 0; err4: - kunzip_inflate_free(&data); + free(data.huffman_tree_len_static); err3: free(huffman_tree_dist); err2: diff --git a/src/depackers/inflate.h b/src/depackers/inflate.h index 1e946ba..a6de9b5 100644 --- a/src/depackers/inflate.h +++ b/src/depackers/inflate.h @@ -1,10 +1,10 @@ -#ifndef XMP_INFLATE_H -#define XMP_INFLATE_H +#ifndef LIBXMP_INFLATE_H +#define LIBXMP_INFLATE_H struct inflate_data { struct huffman_tree_t *huffman_tree_len_static; }; -int inflate(FILE *, FILE *, uint32 *, int); +int libxmp_inflate (FILE *, FILE *, uint32 *, int); #endif diff --git a/src/depackers/mmcmp.c b/src/depackers/mmcmp.c index 3d0996d..e898761 100644 --- a/src/depackers/mmcmp.c +++ b/src/depackers/mmcmp.c @@ -27,6 +27,7 @@ #include #include #include "common.h" +#include "depacker.h" #define MMCMP_COMP 0x0001 #define MMCMP_DELTA 0x0002 @@ -91,7 +92,7 @@ static uint32 get_bits(FILE *f, int n, struct bit_buffer *bb) } while (bb->count < 24) { - bb->buffer |= read8(f) << bb->count; + bb->buffer |= read8(f, NULL) << bb->count; bb->count += 8; } @@ -112,7 +113,7 @@ static void block_copy(struct block *block, struct sub_block *sub, } } -static void block_unpack_16bit(struct block *block, struct sub_block *sub, +static int block_unpack_16bit(struct block *block, struct sub_block *sub, FILE *in, FILE *out) { struct bit_buffer bb; @@ -123,8 +124,12 @@ static void block_unpack_16bit(struct block *block, struct sub_block *sub, bb.count = 0; bb.buffer = 0; - fseek(out, sub->unpk_pos, SEEK_SET); - fseek(in, block->tt_entries, SEEK_SET); + if (fseek(out, sub->unpk_pos, SEEK_SET) < 0) { + return -1; + } + if (fseek(in, block->tt_entries, SEEK_SET) < 0) { + return -1; + } for (j = 0; j < block->sub_blk; ) { uint32 size = sub[j].unpk_size >> 1; @@ -174,12 +179,16 @@ static void block_unpack_16bit(struct block *block, struct sub_block *sub, break; pos = 0; - fseek(out, sub[j].unpk_pos, SEEK_SET); + if (fseek(out, sub[j].unpk_pos, SEEK_SET) < 0) { + return -1; + } } } + + return 0; } -static void block_unpack_8bit(struct block *block, struct sub_block *sub, +static int block_unpack_8bit(struct block *block, struct sub_block *sub, FILE *in, FILE *out) { struct bit_buffer bb; @@ -188,13 +197,19 @@ static void block_unpack_8bit(struct block *block, struct sub_block *sub, uint32 j, oldval = 0; uint8 ptable[0x100]; - fread(ptable, 1, 0x100, in); + if (fread(ptable, 1, 0x100, in) != 0x100) { + return -1; + } bb.count = 0; bb.buffer = 0; - fseek(out, sub->unpk_pos, SEEK_SET); - fseek(in, block->tt_entries, SEEK_SET); + if (fseek(out, sub->unpk_pos, SEEK_SET) < 0) { + return -1; + } + if (fseek(in, block->tt_entries, SEEK_SET) < 0) { + return -1; + } for (j = 0; j < block->sub_blk; ) { uint32 size = sub[j].unpk_size; @@ -235,68 +250,129 @@ static void block_unpack_8bit(struct block *block, struct sub_block *sub, if (pos >= size) { if (++j >= block->sub_blk) break; -; + pos = 0; - fseek(out, sub[j].unpk_pos, SEEK_SET); + if (fseek(out, sub[j].unpk_pos, SEEK_SET) < 0) { + return -1; + } } } + + return 0; +} + +static int test_mmcmp(unsigned char *b) +{ + return memcmp(b, "ziRCONia", 8) == 0; } -int decrunch_mmcmp(FILE *in, FILE *out) +static int decrunch_mmcmp(FILE *in, FILE *out) { struct header h; uint32 *table; uint32 i, j; + int error; /* Read file header */ - if (read32l(in) != 0x4352697A) /* ziRC */ - return -1; - if (read32l(in) != 0x61694e4f) /* ONia */ - return -1; - if (read16l(in) < 14) /* header size */ - return -1; + if (read32l(in, NULL) != 0x4352697A) /* ziRC */ + goto err; + if (read32l(in, NULL) != 0x61694e4f) /* ONia */ + goto err; + if (read16l(in, NULL) < 14) /* header size */ + goto err; /* Read header */ - h.version = read16l(in); - h.nblocks = read16l(in); - h.filesize = read32l(in); - h.blktable = read32l(in); - h.glb_comp = read8(in); - h.fmt_comp = read8(in); + h.version = read16l(in, &error); + if (error != 0) goto err; + h.nblocks = read16l(in, &error); + if (error != 0) goto err; + h.filesize = read32l(in, &error); + if (error != 0) goto err; + h.blktable = read32l(in, &error); + if (error != 0) goto err; + h.glb_comp = read8(in, &error); + if (error != 0) goto err; + h.fmt_comp = read8(in, &error); + if (error != 0) goto err; if (h.nblocks == 0) - return -1; + goto err; /* Block table */ - fseek(in, h.blktable, SEEK_SET); - table = malloc(h.nblocks * 4); - if (table == NULL) - return -1; + if (fseek(in, h.blktable, SEEK_SET) < 0) { + goto err; + } + + if ((table = malloc(h.nblocks * 4)) == NULL) { + goto err; + } for (i = 0; i < h.nblocks; i++) { - table[i] = read32l(in); + table[i] = read32l(in, &error); + if (error != 0) goto err2; } for (i = 0; i < h.nblocks; i++) { struct block block; struct sub_block *sub_block; + uint8 buf[20]; + + if (fseek(in, table[i], SEEK_SET) < 0) { + goto err2; + } - fseek(in, table[i], SEEK_SET); - block.unpk_size = read32l(in); - block.pk_size = read32l(in); - block.xor_chk = read32l(in); - block.sub_blk = read16l(in); - block.flags = read16l(in); - block.tt_entries = read16l(in); - block.num_bits = read16l(in); + if (fread(buf, 1, 20, in) != 20) { + goto err2; + } + + block.unpk_size = readmem32l(buf); + block.pk_size = readmem32l(buf + 4); + block.xor_chk = readmem32l(buf + 8); + block.sub_blk = readmem16l(buf + 12); + block.flags = readmem16l(buf + 14); + block.tt_entries = readmem16l(buf + 16); + block.num_bits = readmem16l(buf + 18); + + /* Sanity check */ + if (block.unpk_size <= 0 || block.pk_size <= 0) + goto err2; + if (block.tt_entries < 0 || block.pk_size <= block.tt_entries) + goto err2; + if (block.sub_blk <= 0) + goto err2; + if (block.flags & MMCMP_COMP) { + if (block.flags & MMCMP_16BIT) { + if (block.num_bits >= 16) { + goto err2; + } + } else { + if (block.num_bits >= 8) { + goto err2; + } + } + } sub_block = malloc(block.sub_blk * sizeof (struct sub_block)); if (sub_block == NULL) - goto err; + goto err2; for (j = 0; j < block.sub_blk; j++) { - sub_block[j].unpk_pos = read32l(in); - sub_block[j].unpk_size = read32l(in); + uint8 buf[8]; + + if (fread(buf, 1, 8, in) != 8) { + free(sub_block); + goto err2; + } + + sub_block[j].unpk_pos = readmem32l(buf); + sub_block[j].unpk_size = readmem32l(buf + 4); + + /* Sanity check */ + if (sub_block[j].unpk_pos < 0 || + sub_block[j].unpk_size < 0) { + free(sub_block); + goto err2; + } } block.tt_entries += ftell(in); @@ -306,10 +382,16 @@ int decrunch_mmcmp(FILE *in, FILE *out) block_copy(&block, sub_block, in, out); } else if (block.flags & MMCMP_16BIT) { /* Data is 16-bit packed */ - block_unpack_16bit(&block, sub_block, in, out); + if (block_unpack_16bit(&block, sub_block, in, out) < 0) { + free(sub_block); + goto err2; + } } else { /* Data is 8-bit packed */ - block_unpack_8bit(&block, sub_block, in, out); + if (block_unpack_8bit(&block, sub_block, in, out) < 0) { + free(sub_block); + goto err2; + } } free(sub_block); @@ -318,7 +400,13 @@ int decrunch_mmcmp(FILE *in, FILE *out) free(table); return 0; - err: + err2: free(table); + err: return -1; } + +struct depacker libxmp_depacker_mmcmp = { + test_mmcmp, + decrunch_mmcmp +}; diff --git a/src/depackers/muse.c b/src/depackers/muse.c index bd28631..ebae29a 100644 --- a/src/depackers/muse.c +++ b/src/depackers/muse.c @@ -1,5 +1,5 @@ /* Extended Module Player - * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr + * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr * * This file is part of the Extended Module Player and is distributed * under the terms of the GNU Lesser General Public License. See COPYING.LIB @@ -9,15 +9,34 @@ #include #include #include "common.h" +#include "depacker.h" #include "inflate.h" +static int test_muse(unsigned char *b) +{ + if (memcmp(b, "MUSE", 4) == 0) { + uint32 r = readmem32b(b + 4); + /* MOD2J2B uses 0xdeadbabe */ + if (r == 0xdeadbeaf || r == 0xdeadbabe) { + return 1; + } + } -int decrunch_muse(FILE *f, FILE *fo) + return 0; +} + +static int decrunch_muse(FILE *f, FILE *fo) { uint32 checksum; - fseek(f, 24, SEEK_SET); - inflate(f, fo, &checksum, 0); + if (fseek(f, 24, SEEK_SET) < 0) { + return -1; + } - return 0; + return libxmp_inflate(f, fo, &checksum, 0); } + +struct depacker libxmp_depacker_muse = { + test_muse, + decrunch_muse +}; diff --git a/src/depackers/oxm.c b/src/depackers/oxm.c index c0a5004..d73d2e9 100644 --- a/src/depackers/oxm.c +++ b/src/depackers/oxm.c @@ -1,9 +1,23 @@ /* Extended Module Player - * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr + * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr * - * This file is part of the Extended Module Player and is distributed - * under the terms of the GNU Lesser General Public License. See COPYING.LIB - * for more information. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ #include @@ -11,6 +25,7 @@ #include #include "vorbis.h" #include "common.h" +#include "depacker.h" #define MAGIC_OGGS 0x4f676753 @@ -28,37 +43,56 @@ int test_oxm(FILE *f) uint32 ilen; int slen[256]; uint8 buf[1024]; + int error; - fseek(f, 0, SEEK_SET); - if (fread(buf, 1, 16, f) < 16) + if (fseek(f, 0, SEEK_SET) < 0) { return -1; - if (memcmp(buf, "Extended Module:", 16)) + } + + if (fread(buf, 1, 80, f) != 80) { return -1; - - fseek(f, 60, SEEK_SET); - hlen = read32l(f); - fseek(f, 6, SEEK_CUR); - npat = read16l(f); - nins = read16l(f); + } + + hlen = readmem32l(buf + 60); + npat = readmem16l(buf + 70); + nins = readmem16l(buf + 72); - if (npat > 256 || nins > 128) + if (memcmp(buf, "Extended Module:", 16)) { return -1; + } - fseek(f, 60 + hlen, SEEK_SET); + if (npat > 256 || nins > 128) { + return -1; + } + + if (fseek(f, 60 + hlen, SEEK_SET) < 0) { + return -1; + } for (i = 0; i < npat; i++) { - len = read32l(f); - fseek(f, 3, SEEK_CUR); - plen = read16l(f); - fseek(f, len - 9 + plen, SEEK_CUR); + if (fread(buf, 1, 9, f) != 9) { + return -1; + } + len = readmem32l(buf); + plen = readmem16l(buf + 7); + + if (fseek(f, len - 9 + plen, SEEK_CUR) < 0) { + return -1; + } } for (i = 0; i < nins; i++) { - ilen = read32l(f); - if (ilen > 263) + ilen = read32l(f, &error); + if (error != 0) return -1; + if (ilen > 263) { + return -1; + } + if (fseek(f, -4, SEEK_CUR) < 0) { + return -1; + } + if (fread(buf, 1, ilen, f) != ilen) { /* instrument header */ return -1; - fseek(f, -4, SEEK_CUR); - fread(buf, ilen, 1, f); /* instrument header */ + } nsmp = readmem16l(buf + 27); if (nsmp > 255) @@ -68,16 +102,22 @@ int test_oxm(FILE *f) /* Read instrument data */ for (j = 0; j < nsmp; j++) { - slen[j] = read32l(f); - fseek(f, 36, SEEK_CUR); + slen[j] = read32l(f, &error); + if (error != 0) { + return -1; + } + if (fseek(f, 36, SEEK_CUR) < 0) { + return -1; + } } /* Read samples */ for (j = 0; j < nsmp; j++) { - read32b(f); - if (read32b(f) == MAGIC_OGGS) + read32b(f, NULL); + if (read32b(f, NULL) == MAGIC_OGGS) return 0; - fseek(f, slen[j] - 8, SEEK_CUR); + if (fseek(f, slen[j] - 8, SEEK_CUR) < 0) + return -1; } } @@ -89,18 +129,30 @@ static char *oggdec(FILE *f, int len, int res, int *newlen) int i, n, ch; /*int size;*/ uint8 *data, *pcm; - int16 *pcm16; + int16 *pcm16 = NULL; uint32 id; + int error; - /*size =*/ read32l(f); - id = read32b(f); - fseek(f, -8, SEEK_CUR); + /* Sanity check */ + if (len < 4) { + return NULL; + } + + /*size =*/ read32l(f, &error); + if (error != 0) + return NULL; + id = read32b(f, &error); + if (error != 0 || fseek(f, -8, SEEK_CUR) < 0) + return NULL; if ((data = calloc(1, len)) == NULL) return NULL; - read32b(f); - fread(data, 1, len - 4, f); + read32b(f, &error); + if (error != 0 || fread(data, 1, len - 4, f) != len - 4) { + free(data); + return NULL; + } if (id != MAGIC_OGGS) { /* copy input data if not Ogg file */ *newlen = len; @@ -110,8 +162,10 @@ static char *oggdec(FILE *f, int len, int res, int *newlen) n = stb_vorbis_decode_memory(data, len, &ch, &pcm16); free(data); - if (n <= 0) + if (n <= 0) { + free(pcm16); return NULL; + } pcm = (uint8 *)pcm16; @@ -142,57 +196,96 @@ static char *oggdec(FILE *f, int len, int res, int *newlen) return (char *)pcm; } -int decrunch_oxm(FILE *f, FILE *fo) +static int decrunch_oxm(FILE *f, FILE *fo) { int i, j, pos; int hlen, npat, len, plen; - int nins, nsmp; + int nins, nsmp, size; uint32 ilen; uint8 buf[1024]; struct xm_instrument xi[256]; char *pcm[256]; int newlen = 0; - fseek(f, 60, SEEK_SET); - hlen = read32l(f); - fseek(f, 6, SEEK_CUR); - npat = read16l(f); - nins = read16l(f); - - fseek(f, 60 + hlen, SEEK_SET); + if (fread(buf, 1, 80, f) != 80) { + return -1; + } + + hlen = readmem32l(buf + 60); + npat = readmem16l(buf + 70); + nins = readmem16l(buf + 72); + + if (npat > 256 || nins > 128) { + return -1; + } + + if (fseek(f, 60 + hlen, SEEK_SET) < 0) { + return -1; + } for (i = 0; i < npat; i++) { - len = read32l(f); - fseek(f, 3, SEEK_CUR); - plen = read16l(f); - fseek(f, len - 9 + plen, SEEK_CUR); + if (fread(buf, 1, 9, f) != 9) { + return -1; + } + len = readmem32l(buf); + plen = readmem16l(buf + 7); + + if (fseek(f, len - 9 + plen, SEEK_CUR) < 0) { + return -1; + } } pos = ftell(f); - fseek(f, 0, SEEK_SET); + if (pos < 0) { + return -1; + } + if (fseek(f, 0, SEEK_SET) < 0) { + return -1; + } move_data(fo, f, pos); /* module header + patterns */ for (i = 0; i < nins; i++) { - ilen = read32l(f); - if (ilen > 1024) + ilen = read32l(f, NULL); + if (ilen > 1024) { + D_(D_CRIT "ilen=%d\n", ilen); + return -1; + } + if (fseek(f, -4, SEEK_CUR) < 0) { return -1; - fseek(f, -4, SEEK_CUR); - fread(buf, ilen, 1, f); /* instrument header */ + } + if (fread(buf, ilen, 1, f) != 1) { /* instrument header */ + return -1; + } buf[26] = 0; fwrite(buf, ilen, 1, fo); nsmp = readmem16l(buf + 27); + size = readmem32l(buf + 29); - if (nsmp == 0) + if (nsmp == 0) { continue; + } + + /* Sanity check */ + if (nsmp > 0x10 || (nsmp > 0 && size > 0x100)) { + D_(D_CRIT "Sanity check: nsmp=%d size=%d", nsmp, size); + return -1; + } /* Read sample headers */ for (j = 0; j < nsmp; j++) { - xi[j].len = read32l(f); - fread(xi[j].buf, 1, 36, f); + xi[j].len = read32l(f, NULL); + if (xi[j].len > MAX_SAMPLE_SIZE) { + D_(D_CRIT "sample %d len = %d", j, xi[j].len); + return -1; + } + if (fread(xi[j].buf, 1, 36, f) != 36) { + return -1; + } } /* Read samples */ for (j = 0; j < nsmp; j++) { + D_(D_INFO "sample=%d len=%d\n", j, xi[j].len); if (xi[j].len > 0) { int res = 8; if (xi[j].buf[10] & 0x10) @@ -200,8 +293,9 @@ int decrunch_oxm(FILE *f, FILE *fo) pcm[j] = oggdec(f, xi[j].len, res, &newlen); xi[j].len = newlen; - if (pcm[j] == NULL) + if (pcm[j] == NULL) { return -1; + } } } @@ -222,3 +316,8 @@ int decrunch_oxm(FILE *f, FILE *fo) return 0; } + +struct depacker libxmp_depacker_oxm = { + NULL, + decrunch_oxm +}; diff --git a/src/depackers/ppdepack.c b/src/depackers/ppdepack.c index 969a61a..f5125c3 100644 --- a/src/depackers/ppdepack.c +++ b/src/depackers/ppdepack.c @@ -23,10 +23,10 @@ #include #include #include - #include "common.h" +#include "depacker.h" -#define val(p) ((p)[0]<<16 | (p)[1] << 8 | (p)[2]) +/* #define val(p) ((p)[0]<<16 | (p)[1] << 8 | (p)[2]) */ static int savefile(FILE *fo, void *mem, size_t length) @@ -145,7 +145,7 @@ static int ppdepack(uint8 *data, size_t len, FILE *fo) return -1; } - outlen = (data[len-4]<<16) | (data[len-3]<<8) | data[len-2]; + outlen = readmem24b(data + len - 4); /* fprintf(stderr, "decrunched length = %u bytes\n", outlen); */ @@ -170,7 +170,12 @@ static int ppdepack(uint8 *data, size_t len, FILE *fo) return success; } -int decrunch_pp(FILE *f, FILE *fo) +static int test_pp(unsigned char *b) +{ + return memcmp(b, "PP20", 4) == 0; +} + +static int decrunch_pp(FILE *f, FILE *fo) { uint8 *packed /*, *unpacked */; int plen, unplen; @@ -179,7 +184,9 @@ int decrunch_pp(FILE *f, FILE *fo) if (fo == NULL) goto err; - fstat(fileno(f), &st); + if (fstat(fileno(f), &st) < 0) + goto err; + plen = st.st_size; //counter = 0; @@ -201,7 +208,9 @@ int decrunch_pp(FILE *f, FILE *fo) goto err; } - fread (packed, plen, 1, f); + if (fread(packed, 1, plen, f) != plen) { + goto err1; + } /* Hmmh... original pp20 only support efficiency from 9 9 9 9 up to 9 10 12 13, afaik * but the xfd detection code says this... *sigh* @@ -219,12 +228,12 @@ int decrunch_pp(FILE *f, FILE *fo) } - if (((((val (packed +4) ) * 256 ) + packed[7] ) & 0xf0f0f0f0) != 0 ) { + if (((readmem24b(packed +4) * 256 + packed[7]) & 0xf0f0f0f0) != 0 ) { /*fprintf(stderr, "invalid efficiency(?)\n");*/ goto err1; } - unplen = val (packed + plen - 4); + unplen = readmem24b(packed + plen - 4); if (!unplen) { /*fprintf(stderr, "not a powerpacked file\n");*/ goto err1; @@ -244,3 +253,8 @@ int decrunch_pp(FILE *f, FILE *fo) err: return -1; } + +struct depacker libxmp_depacker_pp = { + test_pp, + decrunch_pp +}; diff --git a/src/depackers/readhuff.c b/src/depackers/readhuff.c new file mode 100644 index 0000000..d36d672 --- /dev/null +++ b/src/depackers/readhuff.c @@ -0,0 +1,152 @@ +/* nomarch 1.0 - extract old `.arc' archives. + * Copyright (C) 2001 Russell Marks. See unarc.c for license details. + * + * readhuff.c - read RLE+Huffman-compressed files (the CP/M `SQ' scheme). + */ + +/* I was originally going to adapt some old GPL'd Huffman code, + * but it turns out the format pretty much forces an array-based + * implementation. Not that I mind that :-), it just makes it + * a bit unusual. So this is from scratch (though it wasn't too hard). + */ + +#include +#include +#include "readrle.h" + +#include "readhuff.h" + + +struct huff_node_tag + { + /* data is stored as a negative `pointer' */ + int kids[2]; + }; + +#define READ_WORD(x,y) (x)=rawinput(y),(x)|=(rawinput(y)<<8) +#define VALUE_CONV(x) ((x)^0xffff) + +#define HUFF_EOF 256 + + +struct bits { + int bitbox,bitsleft; +}; + + +static int rawinput(struct data_in_out *io) +{ +if(io->data_in_pointdata_in_max) + return(*io->data_in_point++); +return(-1); +} + +static void rawoutput(int byte, struct data_in_out *io) +{ +if(io->data_out_pointdata_out_max) + *io->data_out_point++=byte; +} + + +static void bit_init(struct bits *bits) +{ + bits->bitbox=0; bits->bitsleft=0; +} + +static int bit_input(struct bits *bits, struct data_in_out *io) +{ + if(bits->bitsleft==0) + { + bits->bitbox=rawinput(io); + if(bits->bitbox==-1) return(-1); + bits->bitsleft=8; + } + + bits->bitsleft--; + return((bits->bitbox&(1<<(7-bits->bitsleft)))?1:0); +} + + +unsigned char *convert_huff(unsigned char *data_in, + unsigned long in_len, + unsigned long orig_len) +{ +unsigned char *data_out; +struct huff_node_tag *nodearr; +int nodes,f,b; +struct bits bits; +struct rledata rd; +struct data_in_out io; + +if((data_out=malloc(orig_len))==NULL) + fprintf(stderr,"nomarch: out of memory!\n"),exit(1); + +io.data_in_point=data_in; io.data_in_max=data_in+in_len; +io.data_out_point=data_out; io.data_out_max=data_out+orig_len; + +READ_WORD(nodes,&io); + +if(!nodes) + { + free(data_out); + return(NULL); + } + +if((nodearr=malloc(sizeof(struct huff_node_tag)*nodes))==NULL) + fprintf(stderr,"nomarch: out of memory!\n"),exit(1); + +/* apparently the tree can be empty (zero-length file?), so + * there's a preset entry which is required. In the context of + * .arc I'm sure this is cruft which we don't actually need, + * but just in case... + */ +nodearr[0].kids[0]=nodearr[0].kids[1]=VALUE_CONV(HUFF_EOF); + +for(f=0;f=nodes) + { + /* must be corrupt */ + free(nodearr); + free(data_out); + return(NULL); + } + + /* it seems we can't rely on getting the EOF code (even though we + * do >95% of the time!), so check for `real' EOF too. + * (worth checking in case of corrupt file too, I guess.) + */ + if((b=bit_input(&bits,&io))==-1) + { + f=VALUE_CONV(HUFF_EOF); + break; + } + + f=nodearr[f].kids[b]; + } + + f=VALUE_CONV(f); + if(f!=HUFF_EOF) + libxmp_outputrle(f,rawoutput,&rd,&io); + } +while(f!=HUFF_EOF); + +free(nodearr); + +return(data_out); +} diff --git a/src/depackers/readhuff.h b/src/depackers/readhuff.h index 66dd14e..8a8d44a 100644 --- a/src/depackers/readhuff.h +++ b/src/depackers/readhuff.h @@ -4,6 +4,11 @@ * readhuff.h */ -extern unsigned char *convert_huff(unsigned char *data_in, - unsigned long in_len, - unsigned long orig_len); +#ifndef LIBXMP_READHUFF_H +#define LIBXMP_READHUFF_H + +unsigned char *libxmp_convert_huff(unsigned char *data_in, + unsigned long in_len, + unsigned long orig_len); + +#endif diff --git a/src/depackers/readlzw.c b/src/depackers/readlzw.c index d8308fc..45aa6a5 100644 --- a/src/depackers/readlzw.c +++ b/src/depackers/readlzw.c @@ -68,7 +68,7 @@ static void outputchr(int chr, struct local_data *); static int findfirstchr(int code, struct local_data *); -static unsigned char *_convert_lzw_dynamic(unsigned char *data_in, +static unsigned char *convert_lzw_dynamic(unsigned char *data_in, int max_bits,int use_rle, unsigned long in_len, unsigned long orig_len, int q, @@ -84,7 +84,10 @@ data->quirk = q; data->global_use_rle=use_rle; data->maxstr=(1<maxstr > REALMAXSTR) + return NULL; + +if((data_out=calloc(1, orig_len))==NULL) { //fprintf(stderr,"nomarch: out of memory!\n"); return NULL; } @@ -93,7 +96,7 @@ data->io.data_in_point=data_in; data->io.data_in_max=data_in+in_len; data->io.data_out_point=data_out; data->io.data_out_max=data_out+orig_len; data->dc_bitbox=data->dc_bitsleft=0; data->codeofs=0; -outputrle(-1,NULL, &data->rd, &data->io); /* init RLE */ +libxmp_outputrle(-1,NULL, &data->rd, &data->io); /* init RLE */ data->oldver=0; csize=9; /* initial code size */ @@ -121,7 +124,7 @@ while(1) if(!readcode(&newcode,csize,data)) { //printf("readcode failed!\n"); break; -} + } //printf("newcode = %x\n", newcode); if (data->quirk & NOMARCH_QUIRK_END101) { @@ -211,7 +214,7 @@ if (~data->quirk & NOMARCH_QUIRK_NOCHK) { return(data_out); } -unsigned char *convert_lzw_dynamic(unsigned char *data_in, +unsigned char *libxmp_convert_lzw_dynamic(unsigned char *data_in, int max_bits,int use_rle, unsigned long in_len, unsigned long orig_len, int q) @@ -220,17 +223,32 @@ unsigned char *convert_lzw_dynamic(unsigned char *data_in, unsigned char *d; if ((data = malloc(sizeof (struct local_data))) == NULL) { - return NULL; + goto err; } - d = _convert_lzw_dynamic(data_in, max_bits, use_rle, in_len, + d = convert_lzw_dynamic(data_in, max_bits, use_rle, in_len, orig_len, q, data); + /* Sanity check */ + if (d == NULL) { + goto err2; + } + if (d + orig_len != data->io.data_out_point) { + free(d); + goto err2; + } + free(data); + return d; + + err2: + free(data); + err: + return NULL; } -unsigned char *read_lzw_dynamic(FILE *f, uint8 *buf, int max_bits,int use_rle, +unsigned char *libxmp_read_lzw_dynamic(FILE *f, uint8 *buf, int max_bits,int use_rle, unsigned long in_len, unsigned long orig_len, int q) { uint8 *buf2, *b; @@ -239,26 +257,41 @@ unsigned char *read_lzw_dynamic(FILE *f, uint8 *buf, int max_bits,int use_rle, struct local_data *data; if ((data = malloc(sizeof (struct local_data))) == NULL) { - return NULL; + goto err; } if ((buf2 = malloc(in_len)) == NULL) { //perror("read_lzw_dynamic"); - return NULL; + goto err2; } pos = ftell(f); - fread(buf2, 1, in_len, f); - b = _convert_lzw_dynamic(buf2, max_bits, use_rle, in_len, orig_len, q, data); + if (fread(buf2, 1, in_len, f) != in_len) { + if (~q & XMP_LZW_QUIRK_DSYM) { + goto err3; + } + } + b = convert_lzw_dynamic(buf2, max_bits, use_rle, in_len, orig_len, q, data); memcpy(buf, b, orig_len); size = q & NOMARCH_QUIRK_ALIGN4 ? ALIGN4(data->nomarch_input_size) : data->nomarch_input_size; - fseek(f, pos + size, SEEK_SET); + if (fseek(f, pos + size, SEEK_SET) < 0) { + goto err4; + } free(b); free(buf2); free(data); return buf; + + err4: + free(b); + err3: + free(buf2); + err2: + free(data); + err: + return NULL; } /* uggghhhh, this is agonisingly painful. It turns out that @@ -437,6 +470,12 @@ while(bitsfilleddc_bitbox&=0xff; data->dc_bitbox<<=got; bitsfilled+=got; + + /* Sanity check */ + if (bitsfilled > numbits) { + return 0; + } + (*newcode)|=((data->dc_bitbox>>8)<<(numbits-bitsfilled)); data->dc_bitsleft-=got; } @@ -490,7 +529,7 @@ if(io->data_out_pointdata_out_max) static void outputchr(int chr, struct local_data *data) { if(data->global_use_rle) - outputrle(chr,rawoutput,&data->rd,&data->io); + libxmp_outputrle(chr,rawoutput,&data->rd,&data->io); else rawoutput(chr,&data->io); } diff --git a/src/depackers/readlzw.h b/src/depackers/readlzw.h index 8db934d..5ff6375 100644 --- a/src/depackers/readlzw.h +++ b/src/depackers/readlzw.h @@ -6,6 +6,9 @@ * readlzw.h */ +#ifndef LIBXMP_READLZW_H +#define LIBXMP_READLZW_H + #define ALIGN4(x) (((x) + 3) & ~3L) /* Digital Symphony LZW quirk */ @@ -22,12 +25,13 @@ struct local_data; -unsigned char *convert_lzw_dynamic(unsigned char *data_in, - int bits,int use_rle, +uint8 *libxmp_convert_lzw_dynamic(unsigned char *data_in, + int bits,int use_rle, unsigned long in_len, unsigned long orig_len, int q); -uint8 *read_lzw_dynamic(FILE *f, uint8 *buf, int max_bits,int use_rle, +uint8 *libxmp_read_lzw_dynamic(FILE *f, uint8 *buf, int max_bits,int use_rle, unsigned long in_len, unsigned long orig_len, int q); +#endif diff --git a/src/depackers/readrle.c b/src/depackers/readrle.c index 034a2aa..53f6740 100644 --- a/src/depackers/readrle.c +++ b/src/depackers/readrle.c @@ -25,7 +25,7 @@ if(io->data_out_pointdata_out_max) /* call with -1 before starting, to make sure state is initialised */ -void outputrle(int chr,void (*outputfunc)(int, struct data_in_out *), struct rledata *rd, struct data_in_out *io) +void libxmp_outputrle(int chr,void (*outputfunc)(int, struct data_in_out *), struct rledata *rd, struct data_in_out *io) { int f; diff --git a/src/depackers/readrle.h b/src/depackers/readrle.h index 879d0cf..4524b5b 100644 --- a/src/depackers/readrle.h +++ b/src/depackers/readrle.h @@ -4,16 +4,23 @@ * readrle.h */ +#ifndef LIBXMP_READRLE_H +#define LIBXMP_READRLE_H + struct rledata { - int lastchr,repeating; + int lastchr,repeating; }; struct data_in_out { - unsigned char *data_in_point,*data_in_max; - unsigned char *data_out_point,*data_out_max; + unsigned char *data_in_point,*data_in_max; + unsigned char *data_out_point,*data_out_max; }; -extern void outputrle(int chr,void (*outputfunc)(int, struct data_in_out *), struct rledata *, struct data_in_out *); -extern unsigned char *convert_rle(unsigned char *data_in, +void libxmp_outputrle(int chr,void (*outputfunc)(int, struct data_in_out *), + struct rledata *, struct data_in_out *); + +unsigned char *libxmp_convert_rle(unsigned char *data_in, unsigned long in_len, unsigned long orig_len); + +#endif diff --git a/src/depackers/s404_dec.c b/src/depackers/s404_dec.c index ca7fa76..ac1de69 100644 --- a/src/depackers/s404_dec.c +++ b/src/depackers/s404_dec.c @@ -18,8 +18,8 @@ #include #include #include - #include "common.h" +#include "depacker.h" /* #include "compat.h" @@ -65,7 +65,7 @@ static int initGetb(struct bitstream *bs, uint8 *src, uint32 src_length) /* get nbits from the compressed stream */ -static uint16 getb(struct bitstream *bs, int nbits) +static int getb(struct bitstream *bs, int nbits) { bs->word &= 0x0000ffff; @@ -75,7 +75,10 @@ static uint16 getb(struct bitstream *bs, int nbits) /* assert((bs->word & 0x0000ffffU) == 0); */ /* Check that we don't go out of bounds */ - assert((uint8 *)bs->src >= bs->orgsrc); + /*assert((uint8 *)bs->src >= bs->orgsrc);*/ + if (bs->orgsrc > (uint8 *)bs->src) { + return -1; + } bs->word |= readmem16b((uint8 *)bs->src); bs->src--; @@ -115,7 +118,7 @@ static int checkS404File(uint32 *buf, /*size_t len,*/ } -static void decompressS404(uint8 *src, uint8 *orgdst, +static int decompressS404(uint8 *src, uint8 *orgdst, int32 dst_length, int32 src_length) { uint16 w; @@ -124,6 +127,7 @@ static void decompressS404(uint8 *src, uint8 *orgdst, uint8 *dst; int32 oLen = dst_length; struct bitstream bs; + int x; dst = orgdst + oLen; @@ -132,26 +136,50 @@ static void decompressS404(uint8 *src, uint8 *orgdst, /*printf("_bl: %02X, _bb: %04X, eff: %d\n",_bl,_bb, eff);*/ while (oLen > 0) { - w = getb(&bs, 9); + x = getb(&bs, 9); + + /* Sanity check */ + if (x < 0) { + return -1; + } + + w = x; /*printf("oLen: %d _bl: %02X, _bb: %04X, w: %04X\n",oLen,_bl,_bb,w);*/ if (w < 0x100) { - assert(dst > orgdst); + /*assert(dst > orgdst);*/ + if (orgdst >= dst) { + return -1; + } *--dst = w; /*printf("0+[8] -> %02X\n",w);*/ oLen--; } else if (w == 0x13e || w == 0x13f) { w <<= 4; - w |= getb(&bs, 4); + x = getb(&bs, 4); + /* Sanity check */ + if (x < 0) { + return -1; + } + w |= x; n = (w & 0x1f) + 14; oLen -= n; while (n-- > 0) { - w = getb(&bs, 8); + x = getb(&bs, 8); + /* Sanity check */ + if (x < 0) { + return -1; + } + w = x; /*printf("1+001+1111+[4] -> [8] -> %02X\n",w);*/ - assert(dst > orgdst); + /*assert(dst > orgdst);*/ + if (orgdst >= dst) { + return -1; + } + *--dst = w; } } else { @@ -162,18 +190,33 @@ static void decompressS404(uint8 *src, uint8 *orgdst, if (w & 0x20) { /* dist 545 -> */ w = (w & 0x1f) << (eff - 5); - w |= getb(&bs, eff - 5); + x = getb(&bs, eff - 5); + /* Sanity check */ + if (x < 0) { + return -1; + } + w |= x; w += 544; /* printf("1+1+[1]+1+[%d] -> ", eff); */ } else if (w & 0x30) { // dist 1 -> 32 w = (w & 0x0f) << 1; - w |= getb(&bs, 1); + x = getb(&bs, 1); + /* Sanity check */ + if (x < 0) { + return -1; + } + w |= x; /* printf("1+1+[1]+01+[5] %d %02X %d %04X-> ",n,w, _bl, _bb); */ } else { /* dist 33 -> 544 */ w = (w & 0x0f) << 5; - w |= getb(&bs, 5); + x = getb(&bs, 5); + /* Sanity check */ + if (x < 0) { + return -1; + } + w |= x; w += 32; /* printf("1+1+[1]+00+[9] -> "); */ } @@ -184,18 +227,33 @@ static void decompressS404(uint8 *src, uint8 *orgdst, if (w & 0x08) { /* dist 545 -> */ w = (w & 0x07) << (eff - 3); - w |= getb(&bs, eff - 3); + x = getb(&bs, eff - 3); + /* Sanity check */ + if (x < 0) { + return -1; + } + w |= x; w += 544; /* printf("1+01+[2]+1+[%d] -> ", eff); */ } else if (w & 0x0c) { /* dist 1 -> 32 */ w = (w & 0x03) << 3; - w |= getb(&bs, 3); + x = getb(&bs, 3); + /* Sanity check */ + if (x < 0) { + return -1; + } + w |= x; /* printf("1+01+[2]+01+[5] -> "); */ } else { /* dist 33 -> 544 */ w = (w & 0x03) << 7; - w |= getb(&bs, 7); + x = getb(&bs, 7); + /* Sanity check */ + if (x < 0) { + return -1; + } + w |= x; w += 32; /* printf("1+01+[2]+00+[9] -> "); */ } @@ -205,11 +263,21 @@ static void decompressS404(uint8 *src, uint8 *orgdst, if (w & 0x01) { /* dist 545 -> */ - w = getb(&bs, eff); + x = getb(&bs, eff); + /* Sanity check */ + if (x < 0) { + return -1; + } + w = x; w += 544; /* printf("1+001+[4]+1+[%d] -> ", eff); */ } else { - w = getb(&bs, 6); + x = getb(&bs, 6); + /* Sanity check */ + if (x < 0) { + return -1; + } + w = x; if (w & 0x20) { /* dist 1 -> 32 */ @@ -218,7 +286,12 @@ static void decompressS404(uint8 *src, uint8 *orgdst, } else { /* dist 33 -> 544 */ w <<= 4; - w |= getb(&bs, 4); + x = getb(&bs, 4); + /* Sanity check */ + if (x < 0) { + return -1; + } + w |= x; w += 32; /* printf("1+001+[4]+00+[9] -> "); */ @@ -226,21 +299,37 @@ static void decompressS404(uint8 *src, uint8 *orgdst, } } else { w = (w & 0x1f) << 3; - w |= getb(&bs, 3); + x = getb(&bs, 3); + /* Sanity check */ + if (x < 0) { + return -1; + } + w |= x; n = 23; while (w == 0xff) { n += w; - w = getb(&bs, 8); + x = getb(&bs, 8); + /* Sanity check */ + if (x < 0) { + return -1; + } + w = x; } n += w; - w = getb(&bs, 7); + x = getb(&bs, 7); + w = x; if (w & 0x40) { /* dist 545 -> */ w = (w & 0x3f) << (eff - 6); - w |= getb(&bs, eff - 6); + x = getb(&bs, eff - 6); + /* Sanity check */ + if (x < 0) { + return -1; + } + w |= x; w += 544; } else if (w & 0x20) { @@ -250,7 +339,12 @@ static void decompressS404(uint8 *src, uint8 *orgdst, } else { /* dist 33 -> 544; */ w <<= 4; - w |= getb(&bs, 4); + x = getb(&bs, 4); + /* Sanity check */ + if (x < 0) { + return -1; + } + w |= x; w += 32; /* printf("1+000+[8]+00+[9] -> "); */ @@ -263,16 +357,22 @@ static void decompressS404(uint8 *src, uint8 *orgdst, while (n-- > 0) { /* printf("Copying: %02X\n",dst[w]); */ dst--; - assert(dst >= orgdst); - assert((dst + w + 1) < (orgdst + dst_length)); + if (dst < orgdst || (dst + w + 1) >= (orgdst + dst_length)) + return -1; *dst = dst[w + 1]; } } } + + return 0; } +static int test_s404(unsigned char *b) +{ + return memcmp(b, "S404", 4) == 0; +} -int decrunch_s404(FILE *in, /* size_t s, */ FILE *out) +static int decrunch_s404(FILE *in, /* size_t s, */ FILE *out) { int32 oLen, sLen, pLen; uint8 *dst = NULL; @@ -285,20 +385,29 @@ int decrunch_s404(FILE *in, /* size_t s, */ FILE *out) src = buf = malloc(st.st_size); if (src == NULL) return -1; - fread(buf, 1, st.st_size, in); + if (fread(buf, 1, st.st_size, in) != st.st_size) { + goto error; + } if (checkS404File((uint32 *) src, /*s,*/ &oLen, &pLen, &sLen)) { /*fprintf(stderr,"S404 Error: checkS404File() failed..\n");*/ goto error; } + /* Sanity check */ + if (oLen < 0 || pLen < 0 || pLen + 16 < 0 || pLen + 16 >= st.st_size) { + goto error; + } + if ((dst = malloc(oLen)) == NULL) { /*fprintf(stderr,"S404 Error: malloc(%d) failed..\n", oLen);*/ goto error; } /* src + 16 skips S404 header */ - decompressS404(src + 16, dst, oLen, pLen); + if (decompressS404(src + 16, dst, oLen, pLen) < 0) { + goto error1; + } if (fwrite(dst, oLen, 1, out) == 0) { /*fprintf(stderr,"S404 Error: fwrite() failed..\n");*/ @@ -316,10 +425,7 @@ int decrunch_s404(FILE *in, /* size_t s, */ FILE *out) return -1; } - -#if 0 -struct decruncher decruncher_s404 = { - .name = "StoneCracker S404", - .decrunch = decrunch_s404 +struct depacker libxmp_depacker_s404 = { + test_s404, + decrunch_s404 }; -#endif diff --git a/src/depackers/unarc.c b/src/depackers/unarc.c index 10137c3..7664af1 100644 --- a/src/depackers/unarc.c +++ b/src/depackers/unarc.c @@ -26,7 +26,9 @@ #include #include #include +#include #include "common.h" +#include "depacker.h" #include "readrle.h" #include "readhuff.h" #include "readlzw.h" @@ -78,18 +80,15 @@ static int read_file_header(FILE * in, struct archived_file_header_tag *hdrp) return 0; /* extract the bits from buf */ - hdrp->compressed_size = - (buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24)); - hdrp->date = (buf[4] | (buf[5] << 8)); - hdrp->time = (buf[6] | (buf[7] << 8)); - hdrp->crc = (buf[8] | (buf[9] << 8)); /* yes, only 16-bit CRC */ + hdrp->compressed_size = readmem32l(buf); + hdrp->date = readmem16l(buf + 4); + hdrp->time = readmem16l(buf + 6); + hdrp->crc = readmem16l(buf + 8); /* yes, only 16-bit CRC */ hdrp->has_crc = 1; if (hdrp->method == 1) hdrp->orig_size = hdrp->compressed_size; else - hdrp->orig_size = - (buf[10] | (buf[11] << 8) | (buf[12] << 16) | - (buf[13] << 24)); + hdrp->orig_size = readmem32l(buf + 10); /* make *sure* name is asciiz */ hdrp->name[12] = 0; @@ -230,6 +229,7 @@ static int arc_extract(FILE *in, FILE *out) switch (hdr.method) { case 2: /* no compression */ orig_data = data; + hdr.orig_size = hdr.compressed_size; break; #if 0 @@ -246,12 +246,12 @@ static int arc_extract(FILE *in, FILE *out) break; case 5: /* "crunched" (12-bit static LZW) */ - orig_data = convert_lzw_dynamic(data, 0, 0, + orig_data = libxmp_convert_lzw_dynamic(data, 0, 0, hdr.compressed_size, hdr.orig_size, 0); break; case 6: /* "crunched" (RLE+12-bit static LZW) */ - orig_data = convert_lzw_dynamic(data, 0, 1, + orig_data = libxmp_convert_lzw_dynamic(data, 0, 1, hdr.compressed_size, hdr.orig_size, 0); break; @@ -266,18 +266,18 @@ static int arc_extract(FILE *in, FILE *out) case 8: /* "Crunched" [sic] * (RLE+9-to-12-bit dynamic LZW, a *bit* like GIF) */ - orig_data = convert_lzw_dynamic(data, 12, 1, + orig_data = libxmp_convert_lzw_dynamic(data, 12, 1, hdr.compressed_size, hdr.orig_size, NOMARCH_QUIRK_SKIPMAX); break; case 9: /* "Squashed" (9-to-13-bit, no RLE) */ - orig_data = convert_lzw_dynamic(data, 13, 0, + orig_data = libxmp_convert_lzw_dynamic(data, 13, 0, hdr.compressed_size, hdr.orig_size, 0); break; case 127: /* "Compress" (9-to-16-bit, no RLE) ("Spark" only) */ - orig_data = convert_lzw_dynamic(data, 16, 0, + orig_data = libxmp_convert_lzw_dynamic(data, 16, 0, hdr.compressed_size, hdr.orig_size, 0); break; @@ -306,7 +306,50 @@ static int arc_extract(FILE *in, FILE *out) return exitval; } -int decrunch_arc(FILE *f, FILE *fo) +static int test_arc(unsigned char *b) +{ + if (b[0] == 0x1a) { + int x = b[1] & 0x7f; + int i, flag = 0; + long size; + + /* check file name */ + for (i = 0; i < 13; i++) { + if (b[2 + i] == 0) { + if (i == 0) /* name can't be empty */ + flag = 1; + break; + } + if (!isprint(b[2 + i])) { /* name must be printable */ + flag = 1; + break; + } + } + + size = readmem32l(b + 15); /* max file size is 512KB */ + if (size < 0 || size > 512 * 1024) + flag = 1; + + if (flag == 0) { + if (x >= 1 && x <= 9 && x != 7) { + /* Arc */ + return 1; + } else if (x == 0x7f) { + /* !Spark */ + return 1; + } + } + } + + return 0; +} + +static int decrunch_arc(FILE *f, FILE *fo) { return arc_extract(f, fo); } + +struct depacker libxmp_depacker_arc = { + test_arc, + decrunch_arc +}; diff --git a/src/depackers/uncompress.c b/src/depackers/uncompress.c index 1404e07..2f51b59 100644 --- a/src/depackers/uncompress.c +++ b/src/depackers/uncompress.c @@ -2,6 +2,7 @@ #include #include +#include "depacker.h" #define MAGIC_1 31 /* First byte of compressed file */ #define MAGIC_2 157 /* Second byte of compressed file */ @@ -39,6 +40,11 @@ typedef long int cmp_code_int; #define clear_htab() memset(htab, -1, sizeof(htab)) #define clear_tab_prefixof() memset(codetab, 0, 256); +static int test_compress(unsigned char *b) +{ + return b[0] == 31 && b[1] == 157; +} + /* * Decompress stdin to stdout. This routine adapts to the codes in the * file building the "string" table on-the-fly; requiring no table to @@ -46,7 +52,7 @@ typedef long int cmp_code_int; * with those of the compress() routine. See the definitions above. */ -int decrunch_compress(FILE * in, FILE * out) +static int decrunch_compress(FILE * in, FILE * out) { char_type *stackp; code_int code; @@ -257,3 +263,8 @@ int decrunch_compress(FILE * in, FILE * out) return 0; } + +struct depacker libxmp_depacker_compress = { + test_compress, + decrunch_compress +}; diff --git a/src/depackers/unlha.c b/src/depackers/unlha.c index 97f3935..4a6e30e 100644 --- a/src/depackers/unlha.c +++ b/src/depackers/unlha.c @@ -26,6 +26,7 @@ #include #include #include "common.h" +#include "depacker.h" #define LZHUFF0_METHOD 0x2D6C6830 /* -lh0- */ #define LZHUFF1_METHOD 0x2D6C6831 /* -lh1- */ @@ -207,7 +208,7 @@ static void init_getbits(struct LhADecrData *dat) /* ------------------------------------------------------------------------ */ -static void make_table(struct LhADecrData *dat, int16 nchar, uint8 bitlen[], int16 tablebits, uint16 table[]) +static int make_table(struct LhADecrData *dat, int16 nchar, uint8 bitlen[], int16 tablebits, uint16 table[], int table_size) { uint16 count[17]; /* count of bitlen */ uint16 weight[17]; /* 0x10000ul >> bitlen */ @@ -242,7 +243,7 @@ static void make_table(struct LhADecrData *dat, int16 nchar, uint8 bitlen[], int if(total & 0xFFFF) { dat->error = 1; - return; + return -1; } /* shift data for make table. */ @@ -255,27 +256,55 @@ static void make_table(struct LhADecrData *dat, int16 nchar, uint8 bitlen[], int /* initialize */ j = start[tablebits + 1] >> m; k = 1 << tablebits; - if(j != 0) + if(j != 0) { + + /* Sanity check */ + if (k > table_size) { + return -1; + } + for(i = j; i < k; i++) table[i] = 0; + } /* create table and tree */ for(j = 0; j < nchar; j++) { k = bitlen[j]; + + /* Sanity check */ + if(k >= 17) + return -1; + if(k == 0) continue; l = start[k] + weight[k]; + if(k <= tablebits) { + /* Sanity check */ + if (l > table_size) { + return -1; + } + /* code in table */ for(i = start[k]; i < l; i++) table[i] = j; } else { +#if 0 + /* CID 156018 (#1 of 1): Logically dead code (DEADCODE) + * dead_error_line: Execution cannot reach this statement: return -1; + */ + /* Sanity check */ + if(k >= 17) + return -1; +#endif + /* code not in table */ - p = &table[(i = start[k]) >> m]; + i = start[k]; + p = &table[i >> m]; i <<= tablebits; n = k - tablebits; /* make tree (n length) */ @@ -297,12 +326,12 @@ static void make_table(struct LhADecrData *dat, int16 nchar, uint8 bitlen[], int start[k] = l; } - return; + return 0; } /* ------------------------------------------------------------------------ */ -static void read_pt_len(struct LhADecrData *dat, int16 nn, int16 nbit, int16 i_special) +static int read_pt_len(struct LhADecrData *dat, int16 nn, int16 nbit, int16 i_special) { int16 i, c, n; @@ -342,11 +371,14 @@ static void read_pt_len(struct LhADecrData *dat, int16 nn, int16 nbit, int16 i_s } while(i < nn) dat->d.st.pt_len[i++] = 0; - make_table(dat, nn, dat->d.st.pt_len, 8, dat->d.st.pt_table); + if (make_table(dat, nn, dat->d.st.pt_len, 8, dat->d.st.pt_table, 256) < 0) + return -1; } + + return 0; } -static void read_c_len(struct LhADecrData *dat) +static int read_c_len(struct LhADecrData *dat) { int16 i, c, n; @@ -387,6 +419,11 @@ static void read_c_len(struct LhADecrData *dat) c = getbits(dat, 4) + 3; else c = getbits(dat, CBIT) + 20; + + /* Sanity check */ + if (i + c >= NC) + return -1; + while(--c >= 0) dat->d.st.c_len[i++] = 0; } @@ -395,20 +432,26 @@ static void read_c_len(struct LhADecrData *dat) } while(i < NC) dat->d.st.c_len[i++] = 0; - make_table(dat, NC, dat->d.st.c_len, 12, dat->d.st.c_table); + if (make_table(dat, NC, dat->d.st.c_len, 12, dat->d.st.c_table, 4096) < 0) + return -1; } + + return 0; } -static uint16 decode_c_st1(struct LhADecrData *dat) +static int decode_c_st1(struct LhADecrData *dat) { uint16 j, mask; if(!dat->d.st.blocksize) { dat->d.st.blocksize = getbits(dat, 16); - read_pt_len(dat, NT, TBIT, 3); - read_c_len(dat); - read_pt_len(dat, dat->d.st.np, dat->d.st.pbit, -1); + if (read_pt_len(dat, NT, TBIT, 3) < 0) + return -1; + if (read_c_len(dat) < 0) + return -1; + if (read_pt_len(dat, dat->d.st.np, dat->d.st.pbit, -1) < 0) + return -1; } dat->d.st.blocksize--; j = dat->d.st.c_table[dat->bitbuf >> 4]; @@ -457,7 +500,7 @@ static uint16 decode_p_st1(struct LhADecrData *dat) return j; } -static void decode_start_st1(struct LhADecrData *dat) +static int decode_start_st1(struct LhADecrData *dat) { if(dat->DicBit <= 13) { @@ -474,6 +517,8 @@ static void decode_start_st1(struct LhADecrData *dat) } init_getbits(dat); // dat->d.st.blocksize = 0; /* done automatically */ + + return 0; } /* ------------------------------------------------------------------------ */ @@ -713,7 +758,7 @@ static void update_c(struct LhADecrData *dat, int32 p) } while(q != ROOT_C); } -static uint16 decode_c_dyn(struct LhADecrData *dat) +static int decode_c_dyn(struct LhADecrData *dat) { int32 c; int16 buf, cnt; @@ -807,7 +852,7 @@ static void ready_made(struct LhADecrData *dat, int32 method) } } -static void decode_start_fix(struct LhADecrData *dat) +static int decode_start_fix(struct LhADecrData *dat) { dat->d.st.n_max = 314; dat->d.st.maxmatch = 60; @@ -815,7 +860,10 @@ static void decode_start_fix(struct LhADecrData *dat) dat->d.st.np = 1 << (12 - 6); start_c_dyn(dat); ready_made(dat, 0); - make_table(dat, dat->d.st.np, dat->d.st.pt_len, 8, dat->d.st.pt_table); + if (make_table(dat, dat->d.st.np, dat->d.st.pt_len, 8, dat->d.st.pt_table, 256) < 0) + return -1; + + return 0; } static uint16 decode_p_st0(struct LhADecrData *dat) @@ -854,7 +902,7 @@ static void decode_start_st0(struct LhADecrData *dat) dat->d.st.np = 1 << (MAX_DICBIT - 6); } -static void read_tree_c(struct LhADecrData *dat) /* read tree from file */ +static int read_tree_c(struct LhADecrData *dat) /* read tree from file */ { int32 i, c; @@ -871,10 +919,13 @@ static void read_tree_c(struct LhADecrData *dat) /* read tree from file */ memset(dat->d.st.c_len, 0, N1); for(i = 0; i < 4096; i++) dat->d.st.c_table[i] = c; - return; + return 0; } } - make_table(dat, N1, dat->d.st.c_len, 12, dat->d.st.c_table); + if (make_table(dat, N1, dat->d.st.c_len, 12, dat->d.st.c_table, 4096) < 0) + return -1; + + return 0; } static void read_tree_p(struct LhADecrData *dat) /* read tree from file */ @@ -897,14 +948,15 @@ static void read_tree_p(struct LhADecrData *dat) /* read tree from file */ } } -static uint16 decode_c_st0(struct LhADecrData *dat) +static int decode_c_st0(struct LhADecrData *dat) { int32 i, j; if(!dat->d.st.blocksize) /* read block head */ { dat->d.st.blocksize = getbits(dat, BUFBITS); /* read block blocksize */ - read_tree_c(dat); + if (read_tree_c(dat) < 0) + return -1; if(getbits(dat, 1)) { read_tree_p(dat); @@ -913,7 +965,8 @@ static uint16 decode_c_st0(struct LhADecrData *dat) { ready_made(dat, 1); } - make_table(dat, NP, dat->d.st.pt_len, 8, dat->d.st.pt_table); + if (make_table(dat, NP, dat->d.st.pt_len, 8, dat->d.st.pt_table, 256) < 0) + return -1; } dat->d.st.blocksize--; j = dat->d.st.c_table[dat->bitbuf >> 4]; @@ -1343,8 +1396,8 @@ static int32 LhA_Decrunch(FILE *in, FILE *out, int size, uint32 Method) int32 err = 0; if((dd = calloc(sizeof(struct LhADecrData), 1))) { - void (*DecodeStart)(struct LhADecrData *); - uint16 (*DecodeC)(struct LhADecrData *); + int (*DecodeStart)(struct LhADecrData *); + int (*DecodeC)(struct LhADecrData *); uint16 (*DecodeP)(struct LhADecrData *); /* most often used stuff */ @@ -1428,7 +1481,11 @@ static int32 LhA_Decrunch(FILE *in, FILE *out, int size, uint32 Method) dicsiz = 1 << dd->DicBit; +#ifdef ENABLE_LARC offset = (Method == LARC_METHOD || Method == PMARC2_METHOD) ? 0x100 - 2 : 0x100 - 3; +#else + offset = 0x100 - 3; +#endif if((text = dd->text = calloc(dicsiz, 1))) { @@ -1437,7 +1494,10 @@ static int32 LhA_Decrunch(FILE *in, FILE *out, int size, uint32 Method) */ memset(text, ' ', (size_t) dicsiz); - DecodeStart(dd); + if (DecodeStart(dd) < 0) { + goto error; + } + --dicsiz; /* now used with AND */ while(1) { @@ -1445,13 +1505,20 @@ static int32 LhA_Decrunch(FILE *in, FILE *out, int size, uint32 Method) break; c = DecodeC(dd); + if (c < 0) { + goto error; + } if (dd->error) break; if(c <= UCHAR_MAX) { - text[dd->loc++] = fputc(c, out); + int res = fputc(c, out); + if (res < 0) { + goto error; + } + text[dd->loc++] = res; dd->loc &= dicsiz; dd->count++; } @@ -1462,7 +1529,11 @@ static int32 LhA_Decrunch(FILE *in, FILE *out, int size, uint32 Method) dd->count += c; while(c--) { - text[dd->loc++] = fputc(text[i++ & dicsiz], out); + int res = fputc(text[i++ & dicsiz], out); + if (res < 0) { + goto error; + } + text[dd->loc++] = res; dd->loc &= dicsiz; } } @@ -1478,6 +1549,11 @@ static int32 LhA_Decrunch(FILE *in, FILE *out, int size, uint32 Method) else err = -1; return err; + +error: + free(dd->text); + free(dd); + return -1; } /* @@ -1630,6 +1706,7 @@ static int get_header(FILE *f, struct lha_data *data) { uint8 buf[21]; int size, level, namelen; + int error; memset(data, 0, sizeof(struct lha_data)); if (fread(buf, 1, 21, f) != 21) @@ -1642,22 +1719,47 @@ static int get_header(FILE *f, struct lha_data *data) data->method = readmem32b(buf + 2); data->packed_size = readmem32l(buf + 7); data->original_size = readmem32l(buf + 11); - namelen = read8(f); - fread(data->name, 1, namelen, f); - data->crc = read16l(f); - fseek(f, size + 2 - 24 - namelen, SEEK_CUR); + namelen = read8(f, &error); + if (error != 0) { + return -1; + } + if (fread(data->name, 1, namelen, f) != namelen) { + return -1; + } + data->crc = read16l(f, &error); + if (error != 0) { + return -1; + } + if (fseek(f, size + 2 - 24 - namelen, SEEK_CUR) < 0) { + return -1; + } break; case 1: size = buf[0]; data->method = readmem32b(buf + 2); data->packed_size = readmem32l(buf + 7); data->original_size = readmem32l(buf + 11); - namelen = read8(f); - fread(data->name, 1, namelen, f); - data->crc = read16l(f); - fseek(f, size - (22 + namelen) - 2, SEEK_CUR); - while ((size = read16l(f)) != 0) { - fseek(f, size - 2, SEEK_CUR); + namelen = read8(f, &error); + if (error != 0) { + return -1; + } + if (fread(data->name, 1, namelen, f) != namelen) { + return -1; + } + data->crc = read16l(f, &error); + if (error != 0) { + return -1; + } + if (fseek(f, size - (22 + namelen) - 2, SEEK_CUR) < 0) { + return -1; + } + while ((size = read16l(f, &error)) != 0) { + if (error != 0) { + return -1; + } + if (fseek(f, size - 2, SEEK_CUR) < 0) { + return -1; + } data->packed_size -= size; } break; @@ -1668,14 +1770,36 @@ static int get_header(FILE *f, struct lha_data *data) data->method = readmem32b(buf + 2); data->packed_size = readmem32l(buf + 7); data->original_size = readmem32l(buf + 11); - data->crc = read16l(f); - read8(f); /* skip OS id */ - while ((size = read16l(f)) != 0) { - int type = read8(f); + data->crc = read16l(f, &error); + if (error != 0) { + return -1; + } + read8(f, &error); /* skip OS id */ + if (error != 0) { + return -1; + } + while ((size = read16l(f, &error)) != 0) { + int type; + int s = size - 3; + if (error != 0) { + return -1; + } + type = read8(f, &error); + if (error != 0) { + return -1; + } if (type == 0x01) { - fread(data->name, 1, size - 3, f); + /* Sanity check */ + if (s < 0 || s > 256) { + return -1; + } + if (fread(data->name, 1, s, f) != s) { + return -1; + } } else { - fseek(f, size - 3, SEEK_CUR); + if (fseek(f, s, SEEK_CUR) < 0) { + return -1; + } } } break; @@ -1686,7 +1810,12 @@ static int get_header(FILE *f, struct lha_data *data) return 0; } -int decrunch_lha(FILE *in, FILE *out) +static int test_lha(unsigned char *b) { + return b[2] == '-' && b[3] == 'l' && b[4] == 'h' && b[6] == '-' && + b[20] <= 3; +} + +static int decrunch_lha(FILE *in, FILE *out) { struct lha_data data; @@ -1695,15 +1824,17 @@ int decrunch_lha(FILE *in, FILE *out) break; #if 0 -printf("method = %x\n", data.method); -printf("name = %s\n", data.name); -printf("packed size = %d\n", data.packed_size); -printf("original size = %d\n", data.original_size); -printf("position = %lx\n", ftell(in)); + printf("method = %x\n", data.method); + printf("name = %s\n", data.name); + printf("packed size = %d\n", data.packed_size); + printf("original size = %d\n", data.original_size); + printf("position = %lx\n", ftell(in)); #endif - if (exclude_match(data.name)) { - fseek(in, data.packed_size, SEEK_CUR); + if (libxmp_exclude_match(data.name)) { + if (fseek(in, data.packed_size, SEEK_CUR) < 0) { + return -1; + } continue; } return LhA_Decrunch(in, out, data.original_size, data.method); @@ -1712,3 +1843,7 @@ printf("position = %lx\n", ftell(in)); return -1; } +struct depacker libxmp_depacker_lha = { + test_lha, + decrunch_lha +}; diff --git a/src/depackers/unlzx.c b/src/depackers/unlzx.c index 6466ac6..44f811c 100644 --- a/src/depackers/unlzx.c +++ b/src/depackers/unlzx.c @@ -27,6 +27,7 @@ #include #include #include "common.h" +#include "depacker.h" #include "crc32.h" #if 0 @@ -142,7 +143,8 @@ struct LZXDecrData { uint8 literal_len[768]; uint16 literal_table[5120]; - uint8 read_buffer[16384]; /* have a reasonable sized read buffer */ + /* Was 16384, coverity scan reported overrun */ + uint8 read_buffer[16385]; /* have a reasonable sized read buffer */ uint8 buffer[258 + 65536 + 258]; /* allow overrun for speed */ }; @@ -476,6 +478,7 @@ static int read_literal_table(struct LZXDecrData *decr) uint32 symbol, pos, count, fix, max_symbol; uint8 *src; int abort = 0; + int x; control = decr->control; shift = decr->shift; @@ -652,7 +655,18 @@ static int read_literal_table(struct LZXDecrData *decr) control += *src++ << (8 + shift); control += *src++ << shift; } - symbol = table_four[decr->literal_len[pos] + 17 - symbol]; + + /* Sanity check */ + if (pos >= 768) + return -1; + + x = decr->literal_len[pos] + 17 - symbol; + + /* Sanity check */ + if (x >= 34) + return -1; + + symbol = table_four[x]; while (pos < max_symbol && count--) decr->literal_len[pos++] = symbol; @@ -821,7 +835,7 @@ static int extract_normal(FILE * in_file, struct LZXDecrData *decr) /*printf("Extracting \"%s\"...", node->filename); fflush(stdout); */ - if (exclude_match(node->filename)) { + if (libxmp_exclude_match(node->filename)) { out_file = NULL; } else { out_file = decr->outfile; @@ -899,7 +913,7 @@ static int extract_normal(FILE * in_file, struct LZXDecrData *decr) if (count > decr->unpack_size) count = decr->unpack_size; /* take only what we need */ - decr->sum = crc32_A1(pos, count, decr->sum); + decr->sum = libxmp_crc32_A1(pos, count, decr->sum); if (out_file) { /* Write the data to the file */ abort = 1; @@ -965,7 +979,7 @@ static int extract_archive(FILE * in_file, struct LZXDecrData *decr) /* Must set the field to 0 before calculating the crc */ memset(decr->archive_header + 26, 0, 4); - decr->sum = crc32_A1(decr->archive_header, 31, decr->sum); + decr->sum = libxmp_crc32_A1(decr->archive_header, 31, decr->sum); temp = decr->archive_header[30]; /* filename length */ actual = fread(decr->header_filename, 1, temp, in_file); @@ -980,7 +994,7 @@ static int extract_archive(FILE * in_file, struct LZXDecrData *decr) } decr->header_filename[temp] = 0; - decr->sum = crc32_A1(decr->header_filename, temp, decr->sum); + decr->sum = libxmp_crc32_A1(decr->header_filename, temp, decr->sum); temp = decr->archive_header[14]; /* comment length */ actual = fread(decr->header_comment, 1, temp, in_file); @@ -995,7 +1009,7 @@ static int extract_archive(FILE * in_file, struct LZXDecrData *decr) } decr->header_comment[temp] = 0; - decr->sum = crc32_A1(decr->header_comment, temp, decr->sum); + decr->sum = libxmp_crc32_A1(decr->header_comment, temp, decr->sum); if (decr->sum != decr->crc) { /* fprintf(stderr, "CRC: Archive_Header\n"); */ @@ -1044,9 +1058,13 @@ static int extract_archive(FILE * in_file, struct LZXDecrData *decr) break; } +#if 0 if (abort) break; /* a read error occured */ + /* CID 129002 (#1 of 1): Logically dead code (DEADCODE) + * dead_error_begin: Execution cannot reach this statement: + */ temp_node = decr->filename_list; /* free the list now */ while ((node = temp_node)) { temp_node = node->next; @@ -1059,6 +1077,7 @@ static int extract_archive(FILE * in_file, struct LZXDecrData *decr) /* perror("FSeek(Data)"); */ break; } +#endif } while (!abort); @@ -1072,24 +1091,40 @@ static int extract_archive(FILE * in_file, struct LZXDecrData *decr) return result; } -int decrunch_lzx(FILE *f, FILE *fo) +static int test_lzx(unsigned char *b) +{ + return memcmp(b, "LZX", 3) == 0; +} + +static int decrunch_lzx(FILE *f, FILE *fo) { struct LZXDecrData *decr; if (fo == NULL) - return -1; + goto err; - decr = malloc(sizeof(struct LZXDecrData)); + decr = calloc(1, sizeof(struct LZXDecrData)); if (decr == NULL) - return -1; + goto err; - fseek(f, 10, SEEK_CUR); /* skip header */ + if (fseek(f, 10, SEEK_CUR) < 0) /* skip header */ + goto err2; - crc32_init_A(); + libxmp_crc32_init_A(); decr->outfile = fo; extract_archive(f, decr); free(decr); return 0; + + err2: + free(decr); + err: + return -1; } + +struct depacker libxmp_depacker_lzx = { + test_lzx, + decrunch_lzx +}; diff --git a/src/depackers/unsqsh.c b/src/depackers/unsqsh.c index c00e725..e089666 100644 --- a/src/depackers/unsqsh.c +++ b/src/depackers/unsqsh.c @@ -29,6 +29,7 @@ #include #include #include "common.h" +#include "depacker.h" struct io { uint8 *src; @@ -80,7 +81,7 @@ static int get_bits_final(struct io *io, int count) return r; } -static int copy_data(struct io *io, int d1, int *data) +static int copy_data(struct io *io, int d1, int *data, uint8 *dest_start, uint8 *dest_end) { uint8 *copy_src; int dest_offset, count, copy_len; @@ -126,7 +127,13 @@ static int copy_data(struct io *io, int d1, int *data) copy_src = io->dest + dest_offset - get_bits(io, count) - 1; + /* Sanity check */ + if (copy_src < dest_start || copy_src + copy_len >= dest_end) { + return -1; + } + do { + //printf("dest=%p src=%p end=%p\n", io->dest, copy_src, dest_end); *io->dest++ = *copy_src++; } while (copy_len--); @@ -135,7 +142,7 @@ static int copy_data(struct io *io, int d1, int *data) return d1; } -static void unsqsh_block(struct io *io, uint8 *dest_end) +static int unsqsh_block(struct io *io, uint8 *dest_start, uint8 *dest_end) { int d1, d2, data, unpack_len, count, old_count; @@ -148,7 +155,9 @@ static void unsqsh_block(struct io *io, uint8 *dest_end) do { if (d1 < 8) { if (get_bits(io, 1)) { - d1 = copy_data(io, d1, &data); + d1 = copy_data(io, d1, &data, dest_start, dest_end); + if (d1 < 0) + return -1; d2 -= d2 >> 3; continue; } @@ -171,7 +180,9 @@ static void unsqsh_block(struct io *io, uint8 *dest_end) } } else { if (get_bits(io, 1) == 0) { - d1 = copy_data(io, d1, &data); + d1 = copy_data(io, d1, &data, dest_start, dest_end); + if (d1 < 0) + return -1; d2 -= d2 >> 3; continue; } @@ -216,24 +227,34 @@ static void unsqsh_block(struct io *io, uint8 *dest_end) d2 -= d2 >> 3; } while (io->dest < dest_end); + + return 0; } -static int unsqsh(uint8 *src, uint8 *dest, int len) +static int unsqsh(uint8 *src, int srclen, uint8 *dest, int destlen) { + int len = destlen; int decrunched = 0; int type; int sum, packed_size, unpacked_size; int lchk; - uint8 *c, *dest_end; + uint8 *c, *dest_start, *dest_end; uint8 bc[3]; struct io io; io.src = src; io.dest = dest; + dest_start = io.dest; + c = src + 20; while (len) { + /* Sanity check */ + if (c >= src + srclen) { + return -1; + } + type = *c++; c++; /* hchk */ @@ -246,6 +267,15 @@ static int unsqsh(uint8 *src, uint8 *dest, int len) unpacked_size = readmem16b(c); /* unpacked */ c += 2; + /* Sanity check */ + if (packed_size <= 0 || unpacked_size <= 0) { + return -1; + } + + if (c + packed_size + 3 > src + srclen) { + return -1; + } + io.src = c + 2; memcpy(bc, c + packed_size, 3); memset(c + packed_size, 0, 3); @@ -272,13 +302,20 @@ static int unsqsh(uint8 *src, uint8 *dest, int len) } len -= unpacked_size; - decrunched += unpacked_size;; + decrunched += unpacked_size; + + /* Sanity check */ + if (decrunched > destlen) { + return -1; + } packed_size = (packed_size + 3) & 0xfffc; c += packed_size; dest_end = io.dest + unpacked_size; - unsqsh_block(&io, dest_end); + if (unsqsh_block(&io, dest_start, dest_end) < 0) { + return -1; + } io.dest = dest_end; } @@ -287,20 +324,31 @@ static int unsqsh(uint8 *src, uint8 *dest, int len) } -int decrunch_sqsh(FILE * f, FILE * fo) +static int test_sqsh(unsigned char *b) +{ + return memcmp(b, "XPKF", 4) == 0 && memcmp(b + 8, "SQSH", 4) == 0; +} + +static int decrunch_sqsh(FILE * f, FILE * fo) { unsigned char *src, *dest; int srclen, destlen; - if (read32b(f) != 0x58504b46) /* XPKF */ + if (read32b(f, NULL) != 0x58504b46) /* XPKF */ goto err; - srclen = read32b(f); + srclen = read32b(f, NULL); - if (read32b(f) != 0x53515348) /* SQSH */ + /* Sanity check */ + if (srclen <= 8 || srclen > 0x100000) goto err; - destlen = read32b(f); + if (read32b(f, NULL) != 0x53515348) /* SQSH */ + goto err; + + destlen = read32b(f, NULL); + if (destlen < 0 || destlen > 0x100000) + goto err; if ((src = malloc(srclen + 3)) == NULL) goto err; @@ -311,7 +359,7 @@ int decrunch_sqsh(FILE * f, FILE * fo) if (fread(src, srclen - 8, 1, f) != 1) goto err3; - if (unsqsh(src, dest, destlen) != destlen) + if (unsqsh(src, srclen, dest, destlen) != destlen) goto err3; if (fwrite(dest, destlen, 1, fo) != 1) @@ -329,3 +377,8 @@ int decrunch_sqsh(FILE * f, FILE * fo) err: return -1; } + +struct depacker libxmp_depacker_sqsh = { + test_sqsh, + decrunch_sqsh +}; diff --git a/src/depackers/unxz.c b/src/depackers/unxz.c index dc52682..355d2ed 100644 --- a/src/depackers/unxz.c +++ b/src/depackers/unxz.c @@ -1,5 +1,5 @@ /* Extended Module Player - * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr + * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr * * This file is part of the Extended Module Player and is distributed * under the terms of the GNU Lesser General Public License. See COPYING.LIB @@ -9,20 +9,25 @@ #include #include #include - +#include "depacker.h" #include "xz.h" #include "crc32.h" #define BUFFER_SIZE 4096 -int decrunch_xz(FILE *in, FILE *out) +static int test_xz(unsigned char *b) +{ + return b[0] == 0xfd && b[3] == 'X' && b[4] == 'Z' && b[5] == 0x00; +} + +static int decrunch_xz(FILE *in, FILE *out) { struct xz_buf b; struct xz_dec *state; unsigned char *membuf; int ret = 0; - crc32_init_A(); + libxmp_crc32_init_A(); memset(&b, 0, sizeof(b)); if ((membuf = malloc(2 * BUFFER_SIZE)) == NULL) @@ -70,3 +75,8 @@ int decrunch_xz(FILE *in, FILE *out) return ret; } + +struct depacker libxmp_depacker_xz = { + test_xz, + decrunch_xz +}; diff --git a/src/depackers/unzip.c b/src/depackers/unzip.c index 42b93ee..f061401 100644 --- a/src/depackers/unzip.c +++ b/src/depackers/unzip.c @@ -19,6 +19,7 @@ Michael Kohn #include #include #include "common.h" +#include "depacker.h" #include "inflate.h" #include "crc32.h" @@ -41,8 +42,8 @@ struct zip_file_header #define QUIET -#define read_int(x) read32l(x) -#define read_word(x) read16l(x) +#define read_int(x) read32l(x, NULL) +#define read_word(x) read16l(x, NULL) /*-------------------------- fileio.c ---------------------------*/ @@ -53,7 +54,11 @@ int t; for (t=0; tskip_offset)*/ { marker=ftell(in); /* nasty code.. please make it nice later */ + if (marker < 0) { + return -1; + } name_size = header.file_name_length; if (name_size > 1023) { name_size = 1023; } - read_chars(in,name,name_size); + + if (read_chars(in,name,name_size) < 0) { + return -1; + } + name[name_size]=0; - fseek(in,marker,SEEK_SET); /* and part 2 of nasty code */ + if (fseek(in,marker,SEEK_SET) < 0) { /* and part 2 of nasty code */ + return -1; + } - if (!exclude_match(name)) { + if (!libxmp_exclude_match(name)) { break; } } - fseek(in,header.compressed_size+ + if (fseek(in,header.compressed_size+ header.file_name_length+ - header.extra_field_length,SEEK_CUR); + header.extra_field_length,SEEK_CUR) < 0) { + return -1; + } } if (i!=-1) @@ -255,7 +279,14 @@ char name[1024]; { return -1; } } -int decrunch_zip(FILE *in, FILE *out) +static int test_zip(unsigned char *b) +{ + return b[0] == 'P' && b[1] == 'K' && + ((b[2] == 3 && b[3] == 4) || (b[2] == '0' && b[3] == '0' && + b[4] == 'P' && b[5] == 'K' && b[6] == 3 && b[7] == 4)); +} + +static int decrunch_zip(FILE *in, FILE *out) { int offset; @@ -263,10 +294,16 @@ int decrunch_zip(FILE *in, FILE *out) if (offset < 0) return -1; - fseek(in, offset, SEEK_SET); + if (fseek(in, offset, SEEK_SET) < 0) + return -1; if (kunzip_file_with_name(in,out) < 0) - return -1; + return -1; return 0; } + +struct depacker libxmp_depacker_zip = { + test_zip, + decrunch_zip +}; diff --git a/src/depackers/unzoo.c b/src/depackers/unzoo.c new file mode 100644 index 0000000..5c41d56 --- /dev/null +++ b/src/depackers/unzoo.c @@ -0,0 +1,1163 @@ +/* + * Based on the public domain version by Martin Schoenert + * Refactored for libxmp by Claudio Matsuoka + * + * Copyright (C) 2013 Claudio Matsuoka + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +/* +Lempel-Ziv decompression. Mostly based on Tom Pfau's assembly language +code. The contents of this file are hereby released to the public domain. + -- Rahul Dhesi 1986/11/14 +*/ + +#include +#include +#include "common.h" + +#define STACKSIZE 4000 +#define INBUFSIZ (IN_BUF_SIZE - 10) /* avoid obo errors */ +#define OUTBUFSIZ (OUT_BUF_SIZE - 10) +#define MAXBITS 13 +#define CLEAR 256 /* clear code */ +#define Z_EOF 257 /* end of file marker */ +#define FIRST_FREE 258 /* first free code */ +#define MAXMAX 8192 /* max code + 1 */ + + +/* +The main I/O buffer (called in_buf_adr in zoo.c) is reused +in several places. +*/ + +#define IN_BUF_SIZE 8192 +#define OUT_BUF_SIZE 8192 + +/* MEM_BLOCK_SIZE must be no less than (2 * DICSIZ + MAXMATCH) +(see ar.h and lzh.h for values). The buffer of this size will +also hold an input buffer of IN_BUF_SIZE and an output buffer +of OUT_BUF_SIZE. FUDGE is a fudge factor, to keep some spare and +avoid off-by-one errors. */ + +#define FUDGE 8 +#define MEM_BLOCK_SIZE (8192 + 8192 + 256 + 8) + + +typedef FILE *BLOCKFILE; + +struct tabentry { + unsigned next; + char z_ch; +}; + +struct lzd_data { + unsigned stack_pointer; + unsigned *stack; + + char *out_buf_adr; /* output buffer */ + char *in_buf_adr; /* input buffer */ + BLOCKFILE in_f, out_f; + + char memflag; /* memory allocated? flag */ + struct tabentry *table; /* hash table from lzc.c */ + unsigned cur_code; + unsigned old_code; + unsigned in_code; + + unsigned free_code; + int nbits; + unsigned max_code; + + char fin_char; + char k; + + uint32 crccode; + uint32 *crctab; +}; + +#define push(x) { \ + data->stack[data->stack_pointer++] = (x); \ + if (data->stack_pointer >= STACKSIZE) \ + fprintf(stderr, "libxmp: stack overflow in lzd().\n"); \ + } +#define pop() (data->stack[--data->stack_pointer]) + +static unsigned masks[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff }; +static unsigned bit_offset; +static unsigned output_offset; + +#define BLOCKREAD(f,b,c) fread((b),1,(c),(f)) +#define BLOCKWRITE(f,b,c) fwrite((b),1,(c),(f)) + + +static void addbfcrc(char *buffer, int count, struct lzd_data *data) +{ + unsigned int localcrc; + + localcrc = data->crccode; + + for (; count--; ) + localcrc = (localcrc>>8) ^ data->crctab[(localcrc ^ (*buffer++)) & 0x00ff]; + + data->crccode = localcrc; +} + +/* rd_dcode() reads a code from the input (compressed) file and returns +its value. */ +static unsigned rd_dcode(struct lzd_data *data) +{ + register char *ptra, *ptrb; /* miscellaneous pointers */ + unsigned word; /* first 16 bits in buffer */ + unsigned byte_offset; + char nextch; /* next 8 bits in buffer */ + unsigned ofs_inbyte; /* offset within byte */ + + ofs_inbyte = bit_offset % 8; + byte_offset = bit_offset / 8; + bit_offset = bit_offset + data->nbits; + + /* assert(data->nbits >= 9 && data->nbits <= 13); */ + + if (byte_offset >= INBUFSIZ - 5) { + int space_left; + +#ifdef CHECK_BREAK + check_break(); +#endif + + /* assert(byte_offset >= INBUFSIZ - 5); */ + + bit_offset = ofs_inbyte + data->nbits; + space_left = INBUFSIZ - byte_offset; + ptrb = byte_offset + data->in_buf_adr; /* point to char */ + ptra = data->in_buf_adr; + /* we now move the remaining characters down buffer beginning */ + while (space_left > 0) { + *ptra++ = *ptrb++; + space_left--; + } + /* assert(ptra - data->in_buf_adr == ptrb - (data->in_buf_adr + byte_offset)); + assert(space_left == 0); */ + + if (BLOCKREAD (data->in_f, ptra, byte_offset) == -1) + fprintf(stderr, "libxmp: I/O error in lzd:rd_dcode.\n"); + byte_offset = 0; + } + ptra = byte_offset + data->in_buf_adr; + /* NOTE: "word = *((int *) ptra)" would not be independent of byte order. */ + word = (unsigned char) *ptra; ptra++; + word = word | ( ((unsigned char) *ptra) << 8 ); ptra++; + + nextch = *ptra; + if (ofs_inbyte != 0) { + /* shift nextch right by ofs_inbyte bits */ + /* and shift those bits right into word; */ + word = (word >> ofs_inbyte) | (((unsigned)nextch) << (16-ofs_inbyte)); + } + return (word & masks[data->nbits]); +} /* rd_dcode() */ + +static void init_dtab(struct lzd_data *data) +{ + data->nbits = 9; + data->max_code = 512; + data->free_code = FIRST_FREE; +} + +static void wr_dchar(int ch, struct lzd_data *data) +{ + if (output_offset >= OUTBUFSIZ) { /* if buffer full */ +#ifdef CHECK_BREAK + check_break(); +#endif + if (BLOCKWRITE (data->out_f, data->out_buf_adr, output_offset) != output_offset) + fprintf(stderr, "libxmp: write error in lzd:wr_dchar.\n"); + addbfcrc(data->out_buf_adr, output_offset, data); /* update CRC */ + output_offset = 0; /* restore empty buffer */ + } + /* assert(output_offset < OUTBUFSIZ); */ + data->out_buf_adr[output_offset++] = ch; /* store character */ +} /* wr_dchar() */ + +/* adds a code to table */ +static void ad_dcode(struct lzd_data *data) +{ + /* assert(data->nbits >= 9 && data->nbits <= 13); + assert(data->free_code <= MAXMAX+1); */ + data->table[data->free_code].z_ch = data->k; /* save suffix char */ + data->table[data->free_code].next = data->old_code; /* save prefix code */ + data->free_code++; + /* assert(data->nbits >= 9 && data->nbits <= 13); */ + if (data->free_code >= data->max_code) { + if (data->nbits < MAXBITS) { + data->nbits++; + /* assert(data->nbits >= 9 && data->nbits <= 13); */ + data->max_code = data->max_code << 1; /* double data->max_code */ + } + } +} + +static int lzd(BLOCKFILE input_f, BLOCKFILE output_f, uint32 *crc_table) +{ + struct lzd_data *data; + + data = (struct lzd_data *)calloc(1, sizeof (struct lzd_data)); + if (data == NULL) + goto err; + + data->in_f = input_f; /* make it avail to other fns */ + data->out_f = output_f; /* ditto */ + data->nbits = 9; + data->max_code = 512; + data->free_code = FIRST_FREE; + data->crctab = crc_table; + + /* + Here we allocate a large block of memory for the duration of the program. + lzc() and lzd() will use half of it each. Routine getfile() will use all + of it. Routine decode() will use the first 8192 bytes of it. Routine + encode() will use all of it. + + fudge/2 fudge/2 + [______________||________________|] + output buffer input buffer + */ + data->out_buf_adr = malloc(MEM_BLOCK_SIZE); + if (data->out_buf_adr == NULL) + goto err1; + + data->in_buf_adr = data->out_buf_adr + OUT_BUF_SIZE + (FUDGE/2); + + if (BLOCKREAD (data->in_f, data->in_buf_adr, INBUFSIZ) == -1) + goto err2; + + data->table = (struct tabentry *)malloc((MAXMAX+10) * sizeof(struct tabentry)); + if (data->table == NULL) + goto err2; + + data->stack = (unsigned *)malloc(sizeof (unsigned) * STACKSIZE + 20); + if (data->stack == NULL) + goto err3; + + init_dtab(data); /* initialize table */ + + while (1) { + data->cur_code = rd_dcode(data); + goteof: /* special case for CLEAR then Z_EOF, for 0-length files */ + if (data->cur_code == Z_EOF) { + if (output_offset != 0) { + if (BLOCKWRITE (data->out_f, data->out_buf_adr, output_offset) != output_offset) + fprintf(stderr, "libxmp: output error in lzd().\n"); + addbfcrc(data->out_buf_adr, output_offset, data); + } + + free(data->stack); + free(data->table); + free(data->out_buf_adr); + free(data); + return 0; + } + + /* assert(data->nbits >= 9 && data->nbits <= 13); */ + + if (data->cur_code == CLEAR) { + init_dtab(data); + data->fin_char = data->k = data->old_code = data->cur_code = rd_dcode(data); + if (data->cur_code == Z_EOF) /* special case for 0-length files */ + goto goteof; + + wr_dchar(data->k, data); + continue; + } + + data->in_code = data->cur_code; + if (data->cur_code >= data->free_code) { /* if code not in table (kkk) */ + data->cur_code = data->old_code; /* previous code becomes current */ + push(data->fin_char); + } + + while (data->cur_code > 255) { /* if code, not character */ + push(data->table[data->cur_code].z_ch); /* push suffix char */ + data->cur_code = data->table[data->cur_code].next; /* := .code */ + } + + /* assert(data->nbits >= 9 && data->nbits <= 13); */ + + data->k = data->fin_char = data->cur_code; + push(data->k); + while (data->stack_pointer != 0) { + wr_dchar(pop(), data); + } + /* assert(data->nbits >= 9 && data->nbits <= 13); */ + ad_dcode(data); + data->old_code = data->in_code; + + /* assert(data->nbits >= 9 && data->nbits <= 13); */ + } + + err3: + free(data->table); + err2: + free(data->out_buf_adr); + err1: + free(data); + err: + return -1; + +} /* lzd() */ + + + +/**************************************************************************** +** +*A unzoo.c Tools Martin Schoenert +** +*H @(#)$Id: unzoo.c,v 4.4 2000/05/29 08:56:57 sal Exp $ +** +*Y This file is in the Public Domain. +** +*****************************************************************************/ + +#include +#include +#include +#include "common.h" + +struct description { + char text[20]; /* "ZOO 2.10 Archive.Z" */ + uint32 magic; /* magic word 0xfdc4a7dc */ + uint32 posent; /* position of first directory ent. */ + uint32 klhvmh; /* two's complement of posent */ + uint8 majver; /* major version needed to extract */ + uint8 minver; /* minor version needed to extract */ + uint8 type; /* type of current member (0,1) */ + uint32 poscmt; /* position of comment, 0 if none */ + uint16 sizcmt; /* length of comment, 0 if none */ + uint8 modgen; /* gens. on, gen. limit */ + /* the following are not in the archive file and are computed */ + uint32 sizorg; /* uncompressed size of members */ + uint32 siznow; /* compressed size of members */ + uint32 number; /* number of members */ +}; + +struct entry { + uint32 magic; /* magic word 0xfdc4a7dc */ + uint8 type; /* type of current member (1) */ + uint8 method; /* packing method of member (0..2) */ + uint32 posnxt; /* position of next member */ + uint32 posdat; /* position of data */ + uint16 datdos; /* date (in DOS format) */ + uint16 timdos; /* time (in DOS format) */ + uint16 crcdat; /* crc value of member */ + uint32 sizorg; /* uncompressed size of member */ + uint32 siznow; /* compressed size of member */ + uint8 majver; /* major version needed to extract */ + uint8 minver; /* minor version needed to extract */ + uint8 delete; /* 1 if member is deleted, 0 else */ + uint8 spared; /* spare entry to pad entry */ + uint32 poscmt; /* position of comment, 0 if none */ + uint16 sizcmt; /* length of comment, 0 if none */ + char nams[14]; /* short name of member or archive */ + uint16 lvar; /* length of variable part */ + uint8 timzon; /* time zone */ + uint16 crcent; /* crc value of entry */ + uint8 lnamu; /* length of long name */ + uint8 ldiru; /* length of directory */ + char namu[256]; /* univ. name of member of archive */ + char diru[256]; /* univ. name of directory */ + uint16 system; /* system identifier */ + uint32 permis; /* file permissions */ + uint8 modgen; /* gens. on, last gen., gen. limit */ + uint16 ver; /* version number of member */ +}; + +/* LZW definitions */ +#define MAX_LIT 255 /* maximal literal code */ +#define MIN_LEN 3 /* minimal length of match */ +#define MAX_LEN 256 /* maximal length of match */ +#define MAX_CODE (MAX_LIT+1 + MAX_LEN+1 - MIN_LEN) +#define BITS_CODE 9 /* 2^BITS_CODE > MAX_CODE (+1?) */ +#define MAX_OFF 8192 /* 13 bit sliding directory */ +#define MAX_LOG 13 /* maximal log_2 of offset */ +#define BITS_LOG 4 /* 2^BITS_LOG > MAX_LOG (+1?) */ +#define MAX_PRE 18 /* maximal pre code */ +#define BITS_PRE 5 /* 2^BITS_PRE > MAX_PRE (+1?) */ + +struct local_data { + FILE *in; + FILE *out; + struct description desc; + struct entry entry; + char buffer[8192]; /* at least MAX_OFF */ + + uint32 crc; + uint32 crctab[256]; + + uint16 tree_left[2 * MAX_CODE + 1]; /* tree for codes (upper half) */ + uint16 tree_right[2 * MAX_CODE + 1]; /* and for offsets (lower half) */ + uint16 tabcode[4096]; /* table for fast lookup of codes */ + uint16 tablog[256]; /* table for fast lookup of logs */ + uint16 tabpre[256]; /* table for fast lookup of pres */ + uint8 lencode[MAX_CODE + 1]; /* number of bits used for code */ + uint8 lenlog[MAX_LOG + 1]; /* number of bits used for logs */ + uint8 lenpre[MAX_PRE + 1]; /* number of bits used for pres */ +}; + + +/**************************************************************************** +** +*F read_block(,) . . . . . read a block of bytes from the archive +*V desc . . . . . . . . . . . . . . . . . . . . . . header from the archive +*F read_description() . . . . . . . . . . read the header from the archive +*V entry . . . . . . . . . . . . . . . . header of a member from the archive +*F read_entry() . . . . . . . read the header of a member from the archive +** +** 'desc' is the description of the archive. +** +** 'read_description' reads the description of the archive that starts at the +** current position into the structure 'desc'. It should of course only +** be called at the start of the archive file. +** +** 'entry' is the directory entry of the current member from the archive. +** +** 'read_entry' reads the directory entry of a member that starts at the +** current position into the structure 'Entry'. +*/ + +static uint32 read_block(char *blk, uint32 len, struct local_data *data) +{ + int i, ch; + + for (i = 0; i < len; i++) { + if ((ch = read8(data->in)) == EOF) + return i; + else + *blk++ = ch; + } + + return len; +} + + +static int read_description(struct local_data *data) +{ + /* read the text at the beginning */ + read_block(data->desc.text, 20L, data); + data->desc.text[19] = '\0'; + + /* try to read the magic words */ + if ((data->desc.magic = read32l(data->in)) != (uint32)0xfdc4a7dcL) + return 0; + + /* read the old part of the description */ + data->desc.posent = read32l(data->in); + data->desc.klhvmh = read32l(data->in); + data->desc.majver = read8(data->in); + data->desc.minver = read8(data->in); + + /* read the new part of the description if present */ + data->desc.type = (34 < data->desc.posent ? read8(data->in) : 0); + data->desc.poscmt = (34 < data->desc.posent ? read32l(data->in) : 0); + data->desc.sizcmt = (34 < data->desc.posent ? read16l(data->in) : 0); + data->desc.modgen = (34 < data->desc.posent ? read8(data->in) : 0); + + /* initialize the fake entries */ + data->desc.sizorg = 0; + data->desc.siznow = 0; + data->desc.number = 0; + + /* indicate success */ + return 1; +} + + +static int read_entry(struct local_data *data) +{ + uint32 l; /* 'data->entry.lnamu+data->entry.ldiru' */ + + /* try to read the magic words */ + if ((data->entry.magic = read32l(data->in)) != (uint32)0xfdc4a7dcL) + return 0; + + /* read the fixed part of the directory entry */ + data->entry.type = read8(data->in); + data->entry.method = read8(data->in); + data->entry.posnxt = read32l(data->in); + data->entry.posdat = read32l(data->in); + data->entry.datdos = read16l(data->in); + data->entry.timdos = read16l(data->in); + data->entry.crcdat = read16l(data->in); + data->entry.sizorg = read32l(data->in); + data->entry.siznow = read32l(data->in); + data->entry.majver = read8(data->in); + data->entry.minver = read8(data->in); + data->entry.delete = read8(data->in); + data->entry.spared = read8(data->in); + data->entry.poscmt = read32l(data->in); + data->entry.sizcmt = read16l(data->in); + read_block(data->entry.nams, 13L, data); + data->entry.nams[13] = '\0'; + + /* handle the long name and the directory in the variable part */ + data->entry.lvar = (data->entry.type == 2 ? read16l(data->in) : 0); + data->entry.timzon = (data->entry.type == 2 ? read8(data->in) : 127); + data->entry.crcent = (data->entry.type == 2 ? read16l(data->in) : 0); + data->entry.lnamu = (0 < data->entry.lvar ? read8(data->in) : 0); + data->entry.ldiru = (1 < data->entry.lvar ? read8(data->in) : 0); + read_block(data->entry.namu, (uint32)data->entry.lnamu, data); + data->entry.namu[data->entry.lnamu] = '\0'; + read_block(data->entry.diru, (uint32)data->entry.ldiru, data); + data->entry.diru[data->entry.ldiru] = '\0'; + l = data->entry.lnamu + data->entry.ldiru; + data->entry.system = (l + 2 < data->entry.lvar ? read16l(data->in) : 0); + data->entry.permis = (l + 4 < data->entry.lvar ? read24l(data->in) : 0); + data->entry.modgen = (l + 7 < data->entry.lvar ? read8(data->in) : 0); + data->entry.ver = (l + 7 < data->entry.lvar ? read16l(data->in) : 0); + + /* indicate success */ + return 1; +} + +/**************************************************************************** +** +*F write_block(,) . . . . . . . write a block of bytes to a file +** +** 'write_block' writes bytes from the buffer to the file and +** returns the number of bytes actually written, which is less than +** only when a write error happened. +*/ +static uint32 write_block(char *blk, uint32 len, struct local_data *data) +{ + return fwrite(blk, 1, len, data->out); +} + +/**************************************************************************** +** +*V crc . . . . . . . . . . . . . . . . current cyclic redundancy check value +*F CRC_BYTE(,) . . . . . cyclic redundancy check value of a byte +*F init_crc() . . . . . . . . . . . initialize cylic redundancy check table +** +** 'crc' is used by the decoding functions to communicate the computed +** CRC-16 value to the calling function. +** +** 'CRC_BYTE' returns the new value that one gets by updating the old CRC-16 +** value with the additional byte . It is used to compute the +** ANSI CRC-16 value for each member of the archive. They idea is that if +** not too many bits of a member have corrupted, then the CRC-16 will be +** different, and so the corruption can be detected. +** +** 'init_crc' initialize the table that 'CRC_BYTE' uses. You must call this +** before using 'CRC_BYTE'. +** +** The ANSI CRC-16 value for a sequence of bits of lenght is +** computed by shifting the bits through the following shift register (where +** 'O' are the latches and '+' denotes logical xor) +** +** bit bit ... bit bit bit -->- +** -1 3 2 1 | +** V +** -<-------<---------------------------------------------------<----+ +** | | | ^ +** V V V | +** ->O-->O-+>O-->O-->O-->O-->O-->O-->O-->O-->O-->O-->O-->O-->O-+>O-->- +** MSB LSB +** +** Mathematically we compute in the polynomial ring $GF(2)[x]$ the remainder +** +** $$\sum_{i=1}^{i=length}{bit_i x^{length+16-i}} mod crcpol$$ +** +** where $crcpol = x^{16} + x^{15} + x^2 + 1$. Then the CRC-16 value +** consists of the coefficients of the remainder, with the constant +** coefficient being the most significant bit (MSB) and the coefficient of +** $x^{15}$ the least significant bit (LSB). +** +** Changing a single bit will always cause the CRC-16 value to change, +** because $x^{i} mod crcpol$ is never zero. +** +** Changing two bits will cause the CRC-16 value to change, unless the +** distance between the bits is a multiple of 32767, which is the order of +** $x$ modulo $crcpol = (x+1)(x^{15} + x + 1)$ ($x^{15}+x+1$ is primitive). +** +** Changing 16 adjacent bits will always cause the CRC value to change, +** because $x^{16}$ and $crcpol$ are relatively prime. +** +** David Schwaderer provided the CRC-16 calculation in PC Tech Journal 4/85. +*/ +#define CRC_BYTE(crc,byte) (((crc)>>8) ^ data->crctab[((crc)^(byte))&0xff]) + +static int init_crc(struct local_data *data) +{ + uint32 i, k; /* loop variables */ + + for (i = 0; i < 256; i++) { + data->crctab[i] = i; + for (k = 0; k < 8; k++) { + data->crctab[i] = (data->crctab[i] >> 1) ^ + ((data->crctab[i] & 1) ? 0xa001 : 0); + } + } + + return 1; +} + +/**************************************************************************** +** +*F decode_copy(). . . . . . . . . . . . extract an uncompressed member +** +** 'decode_copy' simply copies bytes from the archive to the output +** file. +*/ +static int decode_copy(uint32 size, struct local_data *data) +{ + uint32 siz; /* size of current block */ + uint32 crc; /* CRC-16 value */ + uint32 i; /* loop variable */ + + /* initialize the crc value */ + crc = 0; + + /* loop until everything has been copied */ + while (0 < size) { + + /* read as many bytes as possible in one go */ + siz = (sizeof(data->buffer) < size ? sizeof(data->buffer) : size); + if (read_block(data->buffer, siz, data) != siz) { + /* ErrMsg = "unexpected in the archive"; */ + return 0; + } + + /* write them */ + if (write_block(data->buffer, siz, data) != siz) { + /* ErrMsg = "cannot write output file"; */ + return 0; + } + + /* compute the crc */ + for (i = 0; i < siz; i++) + crc = CRC_BYTE(crc, data->buffer[i]); + + /* on to the next block */ + size -= siz; + } + + /* store the crc and indicate success */ + data->crc = crc; + return 1; +} + +/**************************************************************************** +** +*F decode_lzd() . . . . . . . . . . . . . . . extract a LZ compressed member +** +*N 1993/10/21 martin add LZD. +*/ +static int decode_lzd(struct local_data *data) +{ + if (lzd(data->in, data->out, data->crctab) == 0) + return 1; + else + return 0; +} + +/**************************************************************************** +** +*F decode_lzh() . . . . . . . . . . . . . . . extract a LZH compressed member +** +** 'decode_lzh' decodes a LZH (Lempel-Ziv 77 with dynamic Huffman coding) +** encoded member from the archive to the output file. +** +** Each member is encoded as a series of blocks. Each block starts with a +** 16 bit field that contains the number of codes in this block . +** The member is terminated by a block with 0 codes. +** +** Next each block contains the description of three Huffman codes, called +** pre code, literal/length code, and log code. The purpose of the pre code +** is to encode the description of the literal/length code. The purpose of +** the literal/length code and the log code is to encode the appropriate +** fields in the LZ code. I am too stupid to understand the format of the +** description. +** +** Then each block contains codewords. There are two kinds of +** codewords, *literals* and *copy instructions*. +** +** A literal represents a certain byte. For the moment imaging the literal +** as having 9 bits. The first bit is zero, the other 8 bits contain the +** byte. +** +** +--+----------------+ +** | 0| | +** +--+----------------+ +** +** When a literal is encountered, the byte that it represents is +** appended to the output. +** +** A copy instruction represents a certain sequence of bytes that appeared +** already earlier in the output. The copy instruction consists of three +** parts, the length, the offset logarithm, and the offset mantissa. +** +** +--+----------------+--------+--------------------+ +** | 1| -3 | | | +** +--+----------------+--------+--------------------+ +** +** is the length of the sequence which this copy instruction +** represents. We store '-3', because is never 0, 1, or 2; +** such sequences are better represented by 0, 1, or 2 literals. and +** together represent the offset at which the sequence of bytes +** already appeared. '-1' is the number of bits in the +** field, and the offset is $2^{-1} + $. For example +** +** +--+----------------+--------+----------+ +** | 1| 9 | 6 | 0 1 1 0 1| +** +--+----------------+--------+----------+ +** +** represents the sequence of 12 bytes that appeared $2^5 + 8 + 4 + 1 = 45$ +** bytes earlier in the output (so those 18 bits of input represent 12 bytes +** of output). +** +** When a copy instruction is encountered, the sequence of bytes +** that appeared bytes earlier in the output is again appended +** (copied) to the output. For this purpose the last bytes are +** remembered, where is the maximal used offset. In 'zoo' this +** maximal offset is $2^{13} = 8192$. The buffer in which those bytes are +** remembered is called a sliding window for reasons that should be +** obvious. +** +** To save even more space the first 9 bits of each code, which represent +** the type of code and either the literal value or the length, are encoded +** using a Huffman code called the literal/length code. Also the next 4 +** bits in copy instructions, which represent the logarithm of the offset, +** are encoded using a second Huffman code called the log code. +** +** Those codes are fixed, i.e., not adaptive, but may vary between the +** blocks, i.e., in each block literals/lengths and logs may be encoded by +** different codes. The codes are described at the beginning of each block. +** +** Haruhiko Okumura wrote the LZH code (originally for his 'ar' archiver). +*/ + +static int MakeTablLzh(int nchar, uint8 bitlen[], int tablebits, uint16 table[], struct local_data *data) +{ + uint16 count[17], weight[17], start[18], *p; + unsigned int i, k, len, ch, jutbits, avail, mask; + + for (i = 1; i <= 16; i++) + count[i] = 0; + for (i = 0; i < nchar; i++) + count[bitlen[i]]++; + + start[1] = 0; + for (i = 1; i <= 16; i++) + start[i + 1] = start[i] + (count[i] << (16 - i)); + if (start[17] != (uint16)((unsigned)1 << 16)) + return 0; + + jutbits = 16 - tablebits; + for (i = 1; i <= tablebits; i++) { + start[i] >>= jutbits; + weight[i] = (unsigned)1 << (tablebits - i); + } + while (i <= 16) { + weight[i] = (unsigned)1 << (16 - i); + i++; + } + + i = start[tablebits + 1] >> jutbits; + if (i != (uint16)((unsigned)1 << 16)) { + k = 1 << tablebits; + while (i != k) + table[i++] = 0; + } + + avail = nchar; + mask = (unsigned)1 << (15 - tablebits); + for (ch = 0; ch < nchar; ch++) { + if ((len = bitlen[ch]) == 0) + continue; + if (len <= tablebits) { + for (i = 0; i < weight[len]; i++) + table[i + start[len]] = ch; + } else { + k = start[len]; + p = &table[k >> jutbits]; + i = len - tablebits; + while (i != 0) { + if (*p == 0) { + data->tree_right[avail] = data->tree_left[avail] = 0; + *p = avail++; + } + if (k & mask) + p = &data->tree_right[*p]; + else + p = &data->tree_left[*p]; + k <<= 1; + i--; + } + *p = ch; + } + start[len] += weight[len]; + } + + /* indicate success */ + return 1; +} + +static int decode_lzh(struct local_data *data) +{ + uint32 cnt; /* number of codes in block */ + uint32 cnt2; /* number of stuff in pre code */ + uint32 code; /* code from the Archive */ + uint32 len; /* length of match */ + uint32 log; /* log_2 of offset of match */ + uint32 off; /* offset of match */ + uint32 pre; /* pre code */ + char *cur; /* current position in data->buffer */ + char *pos; /* position of match */ + char *end; /* pointer to the end of data->buffer */ + char *stp; /* stop pointer during copy */ + uint32 crc; /* cyclic redundancy check value */ + uint32 i; /* loop variable */ + uint32 bits; /* the bits we are looking at */ + uint32 bitc; /* number of bits that are valid */ + +#define PEEK_BITS(N) ((bits >> (bitc-(N))) & ((1L<<(N))-1)) +#define FLSH_BITS(N) if ( (bitc -= (N)) < 16 ) { bits = (bits<<16) + read16b(data->in); bitc += 16; } + + /* initialize bit source, output pointer, and crc */ + bits = 0; + bitc = 0; + FLSH_BITS(0); + cur = data->buffer; + end = data->buffer + MAX_OFF; + crc = 0; + + /* loop until all blocks have been read */ + cnt = PEEK_BITS(16); + FLSH_BITS(16); + while (cnt != 0) { + + /* read the pre code */ + cnt2 = PEEK_BITS(BITS_PRE); + FLSH_BITS(BITS_PRE); + if (cnt2 == 0) { + pre = PEEK_BITS(BITS_PRE); + FLSH_BITS(BITS_PRE); + for (i = 0; i < 256; i++) + data->tabpre[i] = pre; + for (i = 0; i <= MAX_PRE; i++) + data->lenpre[i] = 0; + } else { + i = 0; + while (i < cnt2) { + len = PEEK_BITS(3); + FLSH_BITS(3); + if (len == 7) { + while (PEEK_BITS(1)) { + len++; + FLSH_BITS(1); + } + FLSH_BITS(1); + } + data->lenpre[i++] = len; + if (i == 3) { + len = PEEK_BITS(2); + FLSH_BITS(2); + while (0 < len--) + data->lenpre[i++] = 0; + } + } + while (i <= MAX_PRE) + data->lenpre[i++] = 0; + if (!MakeTablLzh(MAX_PRE + 1, data->lenpre, 8, data->tabpre, data)) { + /* ErrMsg = "pre code description corrupted"; */ + return 0; + } + } + + /* read the code (using the pre code) */ + cnt2 = PEEK_BITS(BITS_CODE); + FLSH_BITS(BITS_CODE); + if (cnt2 == 0) { + code = PEEK_BITS(BITS_CODE); + FLSH_BITS(BITS_CODE); + for (i = 0; i < 4096; i++) + data->tabcode[i] = code; + for (i = 0; i <= MAX_CODE; i++) + data->lencode[i] = 0; + } else { + i = 0; + while (i < cnt2) { + len = data->tabpre[PEEK_BITS(8)]; + if (len <= MAX_PRE) { + FLSH_BITS(data->lenpre[len]); + } else { + FLSH_BITS(8); + do { + if (PEEK_BITS(1)) + len = data->tree_right[len]; + else + len = data->tree_left[len]; + FLSH_BITS(1); + } while (MAX_PRE < len); + } + if (len <= 2) { + if (len == 0) { + len = 1; + } else if (len == 1) { + len = PEEK_BITS(4) + 3; + FLSH_BITS(4); + } else { + len = PEEK_BITS(BITS_CODE) + 20; + FLSH_BITS(BITS_CODE); + } + while (0 < len--) + data->lencode[i++] = 0; + } else { + data->lencode[i++] = len - 2; + } + } + while (i <= MAX_CODE) + data->lencode[i++] = 0; + if (!MakeTablLzh(MAX_CODE + 1, data->lencode, 12, data->tabcode, data)) { + /* ErrMsg = "literal/length code description corrupted"; */ + return 0; + } + } + + /* read the log_2 of offsets */ + cnt2 = PEEK_BITS(BITS_LOG); + FLSH_BITS(BITS_LOG); + if (cnt2 == 0) { + log = PEEK_BITS(BITS_LOG); + FLSH_BITS(BITS_LOG); + for (i = 0; i < 256; i++) + data->tablog[i] = log; + for (i = 0; i <= MAX_LOG; i++) + data->lenlog[i] = 0; + } else { + i = 0; + while (i < cnt2) { + len = PEEK_BITS(3); + FLSH_BITS(3); + if (len == 7) { + while (PEEK_BITS(1)) { + len++; + FLSH_BITS(1); + } + FLSH_BITS(1); + } + data->lenlog[i++] = len; + } + while (i <= MAX_LOG) + data->lenlog[i++] = 0; + if (!MakeTablLzh(MAX_LOG + 1, data->lenlog, 8, data->tablog, data)) { + /* ErrMsg = "log code description corrupted"; */ + return 0; + } + } + + /* read the codes */ + while (0 < cnt--) { + /* try to decode the code the fast way */ + code = data->tabcode[PEEK_BITS(12)]; + + /* if this code needs more than 12 bits look it up in the tree */ + if (code <= MAX_CODE) { + FLSH_BITS(data->lencode[code]); + } else { + FLSH_BITS(12); + do { + if (PEEK_BITS(1)) + code = data->tree_right[code]; + else + code = data->tree_left[code]; + FLSH_BITS(1); + } while (MAX_CODE < code); + } + + /* if the code is a literal, stuff it into the buffer */ + if (code <= MAX_LIT) { + *cur++ = code; + crc = CRC_BYTE(crc, code); + if (cur == end) { + if (write_block(data->buffer, cur - data->buffer, data) != cur - data->buffer) { + /* ErrMsg = "cannot write output file"; */ + return 0; + } + cur = data->buffer; + } + } + + /* otherwise compute match length and offset and copy */ + else { + len = code - (MAX_LIT + 1) + MIN_LEN; + + /* try to decode the log_2 of the offset the fast way */ + log = data->tablog[PEEK_BITS(8)]; + /* if this log_2 needs more than 8 bits look in the tree */ + if (log <= MAX_LOG) { + FLSH_BITS(data->lenlog[log]); + } else { + FLSH_BITS(8); + do { + if (PEEK_BITS(1)) + log = data->tree_right[log]; + else + log = data->tree_left[log]; + FLSH_BITS(1); + } while (MAX_LOG < log); + } + + /* compute the offset */ + if (log == 0) { + off = 0; + } else { + off = + ((unsigned)1 << (log - 1)) + + PEEK_BITS(log - 1); + FLSH_BITS(log - 1); + } + + /* copy the match (this accounts for ~ 50% of the time) */ + pos = + data->buffer + + (((cur - data->buffer) - off - 1) & (MAX_OFF - + 1)); + if (cur < end - len && pos < end - len) { + stp = cur + len; + do { + code = *pos++; + crc = CRC_BYTE(crc, code); + *cur++ = code; + } while (cur < stp); + } else { + while (0 < len--) { + code = *pos++; + crc = CRC_BYTE(crc, code); + *cur++ = code; + if (pos == end) { + pos = data->buffer; + } + if (cur == end) { + if (write_block(data->buffer, cur - data->buffer, data) != cur - data->buffer) { + /* ErrMsg = "cannot write output file"; */ + return 0; + } + cur = data->buffer; + } + } + } + } + } + + cnt = PEEK_BITS(16); + FLSH_BITS(16); + } + + /* write out the rest of the buffer */ + if (write_block(data->buffer, cur - data->buffer, data) != cur - data->buffer) { + /* ErrMsg = "cannot write output file"; */ + return 0; + } + + /* indicate success */ + data->crc = crc; + return 1; +} + + +/**************************************************************************** +** +*F ExtrArch(,,,

,,,) . extract members
+**
+**  'ExtrArch' extracts the members  of the archive with  the name  that
+**  match one  of the file name  patterns '[0] .. [-1]'.
+**  If  is 0, members with comments starting with '!TEXT!' are extracted
+**  as text files and the other members are extracted as  binary files; if it
+**  is 1,  all members are extracted  as text files; if  it is 2, all members
+**  are  extracted as binary  files. If   is 0, no members are extracted
+**  and only tested  for integrity; if it  is 1, the  members are printed  to
+**  stdout, i.e., to the screen.  and if it  is 2, the members are extracted.
+**  If  is 0, members will not overwrite  existing files; otherwise they
+**  will.  
 is a prefix that is prepended to all path names.
+*/
+
+int decrunch_zoo(FILE *in, FILE *out)
+{
+	struct local_data *data;
+	int res;
+
+	data = (struct local_data *)calloc(1, sizeof (struct local_data));
+	if (data == NULL)
+		goto err;
+
+	init_crc(data);
+
+	data->in = in;
+
+	if (!read_description(data))
+		goto err1;
+
+	/* loop over the members of the archive */
+	data->entry.posnxt = data->desc.posent;
+	while (1) {
+		if (fseek(data->in, data->entry.posnxt, SEEK_SET) || !read_entry(data))
+			goto err1;
+		if (!data->entry.posnxt)
+			break;
+		if (data->entry.delete == 1)
+			continue;
+		if (exclude_match(data->entry.nams))
+			continue;
+
+		/* check that we can decode this file */
+		if ((data->entry.method > 2) || (data->entry.majver > 2)
+		    || (data->entry.majver == 3 && data->entry.minver > 1))
+			continue;
+
+	        /* decode the file */
+		if (fseek(data->in, data->entry.posdat, SEEK_SET))
+			continue;
+
+		data->out = out;
+
+	        if (data->entry.method == 0)
+			res = decode_copy(data->entry.siznow, data);
+		else if (data->entry.method == 1)
+			res = decode_lzd(data);
+		else if (data->entry.method == 2)
+			res = decode_lzh(data);
+		else
+			goto err1;
+
+		if (res == 0)
+			goto err1;
+	}
+
+	free(data);
+	return 0;
+
+    err1:
+	free(data);
+    err:
+	return -1;
+}
diff --git a/src/depackers/vorbis.c b/src/depackers/vorbis.c
index 45ed552..a198e83 100644
--- a/src/depackers/vorbis.c
+++ b/src/depackers/vorbis.c
@@ -34,7 +34,7 @@
 #endif
 
 #include "vorbis.h"
-
+#include "common.h"
 
 #ifndef STB_VORBIS_HEADER_ONLY
 
@@ -236,12 +236,14 @@
 #define MAX_BLOCKSIZE      (1 << MAX_BLOCKSIZE_LOG)
 
 
+#if 0
 typedef unsigned char  uint8;
 typedef   signed char   int8;
 typedef unsigned short uint16;
 typedef   signed short  int16;
 typedef unsigned int   uint32;
 typedef   signed int    int32;
+#endif
 
 #ifndef TRUE
 #define TRUE 1
@@ -567,7 +569,7 @@ static void *setup_malloc(vorb *f, int sz)
       return p;
    }
 #endif
-   return sz ? malloc(sz) : NULL;
+   return sz ? calloc(sz, 1) : NULL;
 }
 
 static void setup_free(vorb *f, void *p)
@@ -588,7 +590,7 @@ static void *setup_temp_malloc(vorb *f, int sz)
       return (char *) f->alloc.alloc_buffer + f->temp_offset;
    }
 #endif
-   return malloc(sz);
+   return calloc(sz, 1);
 }
 
 static void setup_temp_free(vorb *f, void *p, size_t sz)
@@ -605,7 +607,7 @@ static void setup_temp_free(vorb *f, void *p, size_t sz)
 #define CRC32_POLY    0x04c11db7   // from spec
 
 static uint32 crc_table[256];
-static void crc32_init_A(void)
+static void libxmp_crc32_init_A(void)
 {
    int i,j;
    uint32 s;
@@ -616,10 +618,12 @@ static void crc32_init_A(void)
    }
 }
 
-static __forceinline uint32 crc32_update(uint32 crc, uint8 byte)
+#if 0
+static __forceinline uint32 libxmp_crc32_update(uint32 crc, uint8 byte)
 {
    return (crc << 8) ^ crc_table[byte ^ (crc >> 24)];
 }
+#endif
 
 
 // used in setup, and for huffman that doesn't go fast path
@@ -706,6 +710,11 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values)
    memset(available, 0, sizeof(available));
    // find the first entry
    for (k=0; k < n; ++k) if (len[k] < NO_CODE) break;
+
+   // sanity check
+   if (k == n) return -1;
+   if (len[k] >= 32) return -1;
+
    if (k == n) { assert(c->sorted_entries == 0); return TRUE; }
    // add to the list
    add_entry(c, 0, k, m++, len[k], values);
@@ -726,8 +735,14 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values)
       // more than one free leaf at a given level, isn't totally
       // trivial to prove, but it seems true and the assert never
       // fires, so!
+
+      /* Sanity check */
+      if (z >= 32) {
+        return FALSE;
+      }
+
       while (z > 0 && !available[z]) --z;
-      if (z == 0) { assert(0); return FALSE; }
+      if (z == 0) { /*assert(0);*/ return FALSE; }
       res = available[z];
       available[z] = 0;
       add_entry(c, bit_reverse(res), i, m++, len[i], values);
@@ -775,7 +790,7 @@ static int uint32_compare(const void *p, const void *q)
 
 static int include_in_sort(Codebook *c, uint8 len)
 {
-   if (c->sparse) { assert(len != NO_CODE); return TRUE; }
+   if (c->sparse) { return (len != NO_CODE); }
    if (len == NO_CODE) return FALSE;
    if (len > STB_VORBIS_FAST_HUFFMAN_LENGTH) return TRUE;
    return FALSE;
@@ -850,8 +865,12 @@ static int lookup1_values(int entries, int dim)
    int r = (int) floor(exp((float) log((float) entries) / dim));
    if ((int) floor(pow((float) r+1, dim)) <= entries)   // (int) cast for MinGW warning;
       ++r;                                              // floor() to avoid _ftol() when non-CRT
-   assert(pow((float) r+1, dim) > entries);
-   assert((int) floor(pow((float) r, dim)) <= entries); // (int),floor() as above
+   if (pow((float) r+1, dim) <= entries) {
+      return -1;
+   }
+   if ((int) floor(pow((float) r, dim)) > entries) {	// (int),floor() as above
+      return -1;
+   }
    return r;
 }
 
@@ -884,8 +903,14 @@ static void compute_bitreverse(int n, uint16 *rev)
 {
    int ld = ilog(n) - 1; // ilog is off-by-one from normal definitions
    int i, n8 = n >> 3;
-   for (i=0; i < n8; ++i)
-      rev[i] = (bit_reverse(i) >> (32-ld+3)) << 2;
+   for (i=0; i < n8; ++i) {
+      /* CID 128660 (#1 of 1): Bad bit shift operation (BAD_SHIFT)
+       * large_shift: right shifting by more than 31 bits has undefined
+       * behavior. The shift amount, 32 - ld + 3, is 36.
+       */
+      int s = 32-ld+3;
+      rev[i] = s > 31 ? 0 : (bit_reverse(i) >> s) << 2;
+   }
 }
 
 static int init_blocksize(vorb *f, int b, int n)
@@ -1427,6 +1452,26 @@ static int codebook_decode(vorb *f, Codebook *c, float *output, int len)
 #endif
 
    z *= c->dimensions;
+
+#if 0
+   /* Sanity check */
+   if (c->lookup_type == 1) {
+      if (c->sparse) {
+         if (len + z > c->sorted_entries * c->dimensions) {
+            return FALSE;
+         }
+      } else {
+         if (len + z > c->entries * c->dimensions) {
+            return FALSE;
+         }
+      }
+   } else {
+      if (len + z > c->lookup_values) {
+         return FALSE;
+      }
+   }
+#endif
+
    if (c->sequence_p) {
       float last = CODEBOOK_ELEMENT_BASE(c);
       for (i=0; i < len; ++i) {
@@ -1718,7 +1763,7 @@ static float inverse_db_table[256] =
 int8 integer_divide_table[DIVTAB_NUMER][DIVTAB_DENOM]; // 2KB
 #endif
 
-static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y1, int n)
+static __forceinline int draw_line(float *output, int x0, int y0, int x1, int y1, int n)
 {
    int dy = y1 - y0;
    int adx = x1 - x0;
@@ -1728,6 +1773,11 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y
    int err = 0;
    int sy;
 
+   /* Sanity check */
+   if (adx == 0) {
+	return -1;
+   }
+
 #ifdef STB_VORBIS_DIVIDE_TABLE
    if (adx < DIVTAB_DENOM && ady < DIVTAB_NUMER) {
       if (dy < 0) {
@@ -1753,16 +1803,31 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y
 #endif
    ady -= abs(base) * adx;
    if (x1 > n) x1 = n;
+
+   /* Sanity check */
+   if (x >= n * 2 || y >= 256) {
+     return -1;
+   }
+
    LINE_OP(output[x], inverse_db_table[y]);
    for (++x; x < x1; ++x) {
       err += ady;
       if (err >= adx) {
          err -= adx;
          y += sy;
-      } else
+      } else {
          y += base;
+      }
+
+      /* Sanity check */
+      if (y >= 256) {
+        return -1;
+      }
+
       LINE_OP(output[x], inverse_db_table[y]);
    }
+
+   return 0;
 }
 
 static int residue_decode(vorb *f, Codebook *book, float *target, int offset, int n, int rtype)
@@ -1784,7 +1849,7 @@ static int residue_decode(vorb *f, Codebook *book, float *target, int offset, in
    return TRUE;
 }
 
-static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int rn, uint8 *do_not_decode)
+static int decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int rn, uint8 *do_not_decode)
 {
    int i,j,pass;
    Residue *r = f->residue_config + rn;
@@ -1991,10 +2056,18 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int
                   #endif
                   int b = r->residue_books[c][pass];
                   if (b >= 0) {
+                     Codebook *book;
+
                      float *target = residue_buffers[j];
                      int offset = r->begin + pcount * r->part_size;
                      int n = r->part_size;
-                     Codebook *book = f->codebooks + b;
+
+                     /* Sanity check */
+                     if (offset + n >= f->blocksize_1) {
+                        return FALSE;
+                     }
+
+                     book = f->codebooks + b;
                      if (!residue_decode(f, book, target, offset, n, rtype))
                         goto done;
                   }
@@ -2003,12 +2076,18 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int
          }
          #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
          ++class_set;
+         /* Sanity check */
+         if (class_set >= part_read) {
+             return FALSE;
+         }
          #endif
       }
    }
   done:
    stb_prof(0);
    temp_alloc_restore(f,temp_alloc_point);
+
+   return TRUE;
 }
 
 
@@ -2798,7 +2877,6 @@ static float *get_window(vorb *f, int len)
    len <<= 1;
    if (len == f->blocksize_0) return f->window[0];
    if (len == f->blocksize_1) return f->window[1];
-   assert(0);
    return NULL;
 }
 
@@ -2828,7 +2906,8 @@ static int do_floor(vorb *f, Mapping *map, int i, int n, float *target, YTYPE *f
          {
             int hy = finalY[j] * g->floor1_multiplier;
             int hx = g->Xlist[j];
-            draw_line(target, lx,ly, hx,hy, n2);
+            if (draw_line(target, lx,ly, hx,hy, n2) < 0)
+		return FALSE;
             lx = hx, ly = hy;
          }
       }
@@ -2990,6 +3069,10 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
             }
 
 #ifdef STB_VORBIS_NO_DEFER_FLOOR
+	    /* Sanity check */
+	    if (n >= f->blocksize_1)
+		return FALSE;
+
             do_floor(f, map, i, n, f->floor_buffers[i], finalY, step2_flag);
 #else
             // defer final floor computation until _after_ residue
@@ -3022,12 +3105,15 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
          zero_channel[map->chan[i].magnitude] = zero_channel[map->chan[i].angle] = FALSE;
       }
 
-// RESIDUE DECODE
+   // RESIDUE DECODE
    for (i=0; i < map->submaps; ++i) {
       float *residue_buffers[STB_VORBIS_MAX_CHANNELS];
       int r,t;
       uint8 do_not_decode[256];
       int ch = 0;
+
+      memset(do_not_decode, 0, 256);
+
       for (j=0; j < f->channels; ++j) {
          if (map->chan[j].mux == i) {
             if (zero_channel[j]) {
@@ -3042,7 +3128,9 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
       }
       r = map->submap_residue[i];
       t = f->residue_types[r];
-      decode_residue(f, residue_buffers, ch, n2, r, do_not_decode);
+      if (!decode_residue(f, residue_buffers, ch, n2, r, do_not_decode)) {
+         return FALSE;
+      }
    }
 
 #ifndef STB_VORBIS_NO_ALLOC_BUFFER
@@ -3187,6 +3275,12 @@ static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right)
    if (f->previous_length) {
       int i,j, n = f->previous_length;
       float *w = get_window(f, n);
+
+      /* Sanity check */
+      if (w == NULL) {
+         return -1;
+      }
+
       for (i=0; i < f->channels; ++i) {
          for (j=0; j < n; ++j)
             f->channel_buffers[i][left+j] =
@@ -3224,11 +3318,14 @@ static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right)
    return right - left;
 }
 
-static void vorbis_pump_first_frame(stb_vorbis *f)
+static int vorbis_pump_first_frame(stb_vorbis *f)
 {
    int len, right, left;
-   if (vorbis_decode_packet(f, &len, &left, &right))
-      vorbis_finish_frame(f, len, left, right);
+   if (vorbis_decode_packet(f, &len, &left, &right)) {
+      if (vorbis_finish_frame(f, len, left, right) < 0)
+         return -1;
+   }
+   return 0;
 }
 
 #ifndef STB_VORBIS_NO_PUSHDATA_API
@@ -3302,9 +3399,8 @@ static int start_decoder(vorb *f)
    uint8 header[6], x,y;
    int len,i,j,k, max_submaps = 0;
    int longest_floorlist=0;
-
+   int val;
    // first page, first packet
-
    if (!start_page(f))                              return FALSE;
    // validate page flag
    if (!(f->page_flag & PAGEFLAG_first_page))       return error(f, VORBIS_invalid_first_page);
@@ -3320,8 +3416,9 @@ static int start_decoder(vorb *f)
    if (!vorbis_validate(header))                    return error(f, VORBIS_invalid_first_page);
    // vorbis_version
    if (get32(f) != 0)                               return error(f, VORBIS_invalid_first_page);
-   f->channels = get8(f); if (!f->channels)         return error(f, VORBIS_invalid_first_page);
-   if (f->channels > STB_VORBIS_MAX_CHANNELS)       return error(f, VORBIS_too_many_channels);
+   val = get8(f); if (val == 0)                     return error(f, VORBIS_invalid_first_page);
+   if (val > STB_VORBIS_MAX_CHANNELS)               return error(f, VORBIS_too_many_channels);
+   f->channels = val;
    f->sample_rate = get32(f); if (!f->sample_rate)  return error(f, VORBIS_invalid_first_page);
    get32(f); // bitrate_maximum
    get32(f); // bitrate_nominal
@@ -3365,7 +3462,7 @@ static int start_decoder(vorb *f)
    }
    #endif
 
-   crc32_init_A(); // always init it, to avoid multithread race conditions
+   libxmp_crc32_init_A(); // always init it, to avoid multithread race conditions
 
    if (get8_packet(f) != VORBIS_packet_setup)       return error(f, VORBIS_invalid_setup);
    for (i=0; i < 6; ++i) header[i] = get8_packet(f);
@@ -3471,7 +3568,10 @@ static int start_decoder(vorb *f)
       }
 
       if (!compute_codewords(c, lengths, c->entries, values)) {
-         if (c->sparse) setup_temp_free(f, values, 0);
+         if (c->sparse) {
+            setup_temp_free(f, values, 0);
+            setup_temp_free(f, lengths, c->entries);
+         }
          return error(f, VORBIS_invalid_setup);
       }
 
@@ -3504,6 +3604,11 @@ static int start_decoder(vorb *f)
          c->sequence_p = get_bits(f,1);
          if (c->lookup_type == 1) {
             c->lookup_values = lookup1_values(c->entries, c->dimensions);
+
+	    /* Sanity check */
+            if (c->lookup_values <= 0) {
+              return FALSE;
+            }
          } else {
             c->lookup_values = c->entries * c->dimensions;
          }
@@ -3520,7 +3625,10 @@ static int start_decoder(vorb *f)
             int len, sparse = c->sparse;
             // pre-expand the lookup1-style multiplicands, to avoid a divide in the inner loop
             if (sparse) {
-               if (c->sorted_entries == 0) goto skip;
+               if (c->sorted_entries == 0) {
+                  setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values);
+                  goto skip;
+               }
                c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->sorted_entries * c->dimensions);
             } else
                c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->entries        * c->dimensions);
@@ -3542,6 +3650,12 @@ static int start_decoder(vorb *f)
                             //   !STB_VORBIS_DIVIDES_IN_CODEBOOK
                          #endif
                   div *= c->lookup_values;
+
+                  /* Sanity check */
+                  if (div == 0) {
+                    free(mults);
+                    return FALSE;
+                  }
                }
             }
             setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values);
@@ -3563,6 +3677,18 @@ static int start_decoder(vorb *f)
 
          #ifdef STB_VORBIS_CODEBOOK_FLOATS
          if (c->lookup_type == 2 && c->sequence_p) {
+
+            /* Sanity check */
+            if (c->sparse) {
+               if (c->lookup_values > c->sorted_entries * c->dimensions) {
+                  return FALSE;
+               }
+            } else {
+               if (c->lookup_values > c->entries * c->dimensions) {
+                  return FALSE;
+               }
+            }
+
             for (j=1; j < (int) c->lookup_values; ++j)
                c->multiplicands[j] = c->multiplicands[j-1];
             c->sequence_p = 0;
@@ -3661,6 +3787,12 @@ static int start_decoder(vorb *f)
       if (f->residue_types[i] > 2) return error(f, VORBIS_invalid_setup);
       r->begin = get_bits(f, 24);
       r->end = get_bits(f, 24);
+
+      /* Sanity check */
+      if (r->end - r->begin > 1024) {
+        return FALSE;
+      }
+
       r->part_size = get_bits(f,24)+1;
       r->classifications = get_bits(f,6)+1;
       r->classbook = get_bits(f,8);
@@ -3682,6 +3814,12 @@ static int start_decoder(vorb *f)
             }
          }
       }
+
+      /* Sanity check */
+      if (r->classbook >= f->codebook_count) {
+         return -1;
+      }
+
       // precompute the classifications[] array to avoid inner-loop mod/divide
       // call it 'classdata' since we already have r->classifications
       r->classdata = (uint8 **) setup_malloc(f, sizeof(*r->classdata) * f->codebooks[r->classbook].entries);
@@ -3983,10 +4121,10 @@ static int vorbis_search_for_page_pushdata(vorb *f, uint8 *data, int data_len)
                // scan everything up to the embedded crc (which we must 0)
                crc = 0;
                for (j=0; j < 22; ++j)
-                  crc = crc32_update(crc, data[i+j]);
+                  crc = libxmp_crc32_update(crc, data[i+j]);
                // now process 4 0-bytes
                for (   ; j < 26; ++j)
-                  crc = crc32_update(crc, 0);
+                  crc = libxmp_crc32_update(crc, 0);
                // len is the total number of bytes we need to scan
                n = f->page_crc_tests++;
                f->scan[n].bytes_left = len-j;
@@ -4016,7 +4154,7 @@ static int vorbis_search_for_page_pushdata(vorb *f, uint8 *data, int data_len)
       // m is the bytes to scan in the current chunk
       crc = f->scan[i].crc_so_far;
       for (j=0; j < m; ++j)
-         crc = crc32_update(crc, data[n+j]);
+         crc = libxmp_crc32_update(crc, data[n+j]);
       f->scan[i].bytes_left -= m;
       f->scan[i].crc_so_far = crc;
       if (f->scan[i].bytes_left == 0) {
@@ -4104,6 +4242,12 @@ int stb_vorbis_decode_frame_pushdata(
 
    // success!
    len = vorbis_finish_frame(f, len, left, right);
+
+   /* Sanity check */
+   if (len < 0) {
+      return -1;
+   }
+
    for (i=0; i < f->channels; ++i)
       f->outputs[i] = f->channel_buffers[i] + left;
 
@@ -4191,16 +4335,16 @@ static uint32 vorbis_find_page(stb_vorbis *f, uint32 *end, uint32 *last)
                header[i] = 0;
             crc = 0;
             for (i=0; i < 27; ++i)
-               crc = crc32_update(crc, header[i]);
+               crc = libxmp_crc32_update(crc, header[i]);
             len = 0;
             for (i=0; i < header[26]; ++i) {
                int s = get8(f);
-               crc = crc32_update(crc, s);
+               crc = libxmp_crc32_update(crc, s);
                len += s;
             }
             if (len && f->eof) return 0;
             for (i=0; i < len; ++i)
-               crc = crc32_update(crc, get8(f));
+               crc = libxmp_crc32_update(crc, get8(f));
             // finished parsing probable page
             if (crc == goal) {
                // we could now check that it's either got the last
@@ -4462,7 +4606,8 @@ static int vorbis_seek_frame_from_page(stb_vorbis *f, uint32 page_start, uint32
       frame_start += data_to_skip;
    } else {
       f->previous_length = 0;
-      vorbis_pump_first_frame(f);
+      if (vorbis_pump_first_frame(f) < 0)
+         return -1;
    }
 
    // at this point, the NEXT decoded frame will generate the desired sample
@@ -4498,7 +4643,8 @@ static int vorbis_seek_base(stb_vorbis *f, unsigned int sample_number, int fine)
       sample_number = f->p_last.last_decoded_sample-1;
 
    if (sample_number < f->p_first.last_decoded_sample) {
-      vorbis_seek_frame_from_page(f, p[0].page_start, 0, sample_number, fine);
+      if (vorbis_seek_frame_from_page(f, p[0].page_start, 0, sample_number, fine) < 0)
+         return -1;
       return 0;
    } else {
       int attempts=0;
@@ -4558,7 +4704,8 @@ static int vorbis_seek_base(stb_vorbis *f, unsigned int sample_number, int fine)
       }
 
       if (p[0].last_decoded_sample <= sample_number && sample_number < p[1].last_decoded_sample) {
-         vorbis_seek_frame_from_page(f, p[1].page_start, p[0].last_decoded_sample, sample_number, fine);
+         if (vorbis_seek_frame_from_page(f, p[1].page_start, p[0].last_decoded_sample, sample_number, fine) < 0)
+            return -1;
          return 0;
       }
       return error(f, VORBIS_seek_failed);
@@ -4680,7 +4827,18 @@ int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output)
       return 0;
    }
 
+   /* Sanity check */
+   if (len > f->blocksize_1) {
+      return -1;
+   }
+
    len = vorbis_finish_frame(f, len, left, right);
+
+   /* Sanity check */
+   if (len < 0) {
+      return -1;
+   }
+
    for (i=0; i < f->channels; ++i)
       f->outputs[i] = f->channel_buffers[i] + left;
 
@@ -4706,7 +4864,8 @@ stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *er
       f = vorbis_alloc(&p);
       if (f) {
          *f = p;
-         vorbis_pump_first_frame(f);
+         if (vorbis_pump_first_frame(f) < 0)
+            return NULL;
          return f;
       }
    }
@@ -4751,7 +4910,8 @@ stb_vorbis * stb_vorbis_open_memory(unsigned char *data, int len, int *error, st
       f = vorbis_alloc(&p);
       if (f) {
          *f = p;
-         vorbis_pump_first_frame(f);
+         if (vorbis_pump_first_frame(f) < 0)
+            return NULL;
          return f;
       }
    }
@@ -4906,6 +5066,11 @@ int stb_vorbis_get_frame_short(stb_vorbis *f, int num_c, short **buffer, int num
 {
    float **output;
    int len = stb_vorbis_get_frame_float(f, NULL, &output);
+
+   /* Sanity check */
+   if (len < 0)
+      return -1;
+
    if (len > num_samples) len = num_samples;
    if (len)
       convert_samples_short(num_c, buffer, 0, f->channels, output, 0, len);
@@ -5045,12 +5210,17 @@ int stb_vorbis_decode_memory(uint8 *mem, int len, int *channels, short **output)
 {
    int data_len, offset, total, limit, error;
    short *data;
-   stb_vorbis *v = stb_vorbis_open_memory(mem, len, &error, NULL);
+   stb_vorbis *v;
+
+   D_(D_INFO "vorbis_decode_memory (len=%d)", len);
+
+   v = stb_vorbis_open_memory(mem, len, &error, NULL);
    if (v == NULL) return -1;
    limit = v->channels * 4096;
    *channels = v->channels;
    offset = data_len = 0;
    total = limit;
+   D_(D_INFO "total=%d\n", total);
    data = (short *) malloc(total * sizeof(*data));
    if (data == NULL) {
       stb_vorbis_close(v);
@@ -5061,6 +5231,7 @@ int stb_vorbis_decode_memory(uint8 *mem, int len, int *channels, short **output)
       if (n == 0) break;
       data_len += n;
       offset += n * v->channels;
+      D_(D_INFO "offset=%d, limit=%d, total=%d", offset, limit, total);
       if (offset + limit > total) {
 	 short *data2;
 	 total *= 2;
diff --git a/src/depackers/xfd.c b/src/depackers/xfd.c
index d735d16..4f6e48b 100644
--- a/src/depackers/xfd.c
+++ b/src/depackers/xfd.c
@@ -69,7 +69,33 @@ void close_xfd(struct xfdBufferInfo *xfdobj, struct local_data *data)
 	}
 }
 
-int decrunch_xfd (FILE *f1, FILE *f2)
+static char *_test_xfd(unsigned char *buffer, int length)
+{
+	char *ret = NULL;
+	struct xfdBufferInfo *xfdobj;
+	struct local_data data;
+
+	if(xfdobj=open_xfd(&data))
+	{
+		xfdobj->xfdbi_SourceBuffer = buffer;
+		xfdobj->xfdbi_SourceBufLen = length;
+		xfdobj->xfdbi_Flags = XFDFB_RECOGTARGETLEN | XFDFB_RECOGEXTERN;
+
+		if(xfdRecogBuffer(xfdobj))
+		{
+			ret = xfdobj->xfdbi_PackerName;
+		}
+		close_xfd(xfdobj, &data);
+	}
+	return(ret);
+}
+
+static int test_xfd(unsigned char *b)
+{
+	return _test_xfd(b, 1024) != NULL;
+}
+
+static int decrunch_xfd(FILE *f1, FILE *f2)
 {
     struct xfdBufferInfo *xfdobj;
     uint8 *packed;
@@ -92,8 +118,8 @@ int decrunch_xfd (FILE *f1, FILE *f2)
 	{
 		xfdobj->xfdbi_SourceBufLen = plen;
 		xfdobj->xfdbi_SourceBuffer = packed;
-		xfdobj->xfdbi_Flags = XFDFB_RECOGEXTERN | XFDFB_RECOGTARGETLEN;
-		xfdobj->xfdbi_PackerFlags = XFDPFB_RECOGLEN;
+		xfdobj->xfdbi_Flags = XFDFF_RECOGEXTERN | XFDFF_RECOGTARGETLEN;
+		/* xfdobj->xfdbi_PackerFlags = XFDPFF_RECOGLEN; */
 		if(xfdRecogBuffer(xfdobj))
 		{
 			xfdobj->xfdbi_TargetBufMemType = MEMF_ANY;
@@ -113,25 +139,9 @@ int decrunch_xfd (FILE *f1, FILE *f2)
 	return(ret);
 }
 
-char *test_xfd	(unsigned char *buffer, int length)
-{
-	char *ret = NULL;
-	struct xfdBufferInfo *xfdobj;
-	struct local_data data;
-
-	if(xfdobj=open_xfd(&data))
-	{
-		xfdobj->xfdbi_SourceBuffer = buffer;
-		xfdobj->xfdbi_SourceBufLen = length;
-		xfdobj->xfdbi_Flags = XFDFB_RECOGTARGETLEN | XFDFB_RECOGEXTERN;
-
-		if(xfdRecogBuffer(xfdobj))
-		{
-			ret = xfdobj->xfdbi_PackerName;
-		}
-		close_xfd(xfdobj, &data);
-	}
-	return(ret);
-}
+struct depacker libxmp_depacker_xfd = {
+	test_xfd,
+	decrunch_xfd
+};
 
 #endif /* AMIGA */
diff --git a/src/depackers/xz_dec_stream.c b/src/depackers/xz_dec_stream.c
index 0038240..f1f32bd 100644
--- a/src/depackers/xz_dec_stream.c
+++ b/src/depackers/xz_dec_stream.c
@@ -243,7 +243,7 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b)
 		return XZ_DATA_ERROR;
 
 	if (s->check_type == XZ_CHECK_CRC32)
-		s->crc32 = crc32_A1(b->out + s->out_start,
+		s->crc32 = libxmp_crc32_A1(b->out + s->out_start,
 				b->out_pos - s->out_start, s->crc32);
 
 	if (ret == XZ_STREAM_END) {
@@ -268,7 +268,7 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b)
 #endif
 
 		s->block.hash.uncompressed += s->block.uncompressed;
-		s->block.hash.crc32 = crc32_A1(
+		s->block.hash.crc32 = libxmp_crc32_A1(
 				(const uint8 *)&s->block.hash,
 				sizeof(s->block.hash), s->block.hash.crc32);
 
@@ -283,7 +283,7 @@ static void index_update(struct xz_dec *s, const struct xz_buf *b)
 {
 	size_t in_used = b->in_pos - s->in_start;
 	s->index.size += in_used;
-	s->crc32 = crc32_A1(b->in + s->in_start, in_used, s->crc32);
+	s->crc32 = libxmp_crc32_A1(b->in + s->in_start, in_used, s->crc32);
 }
 
 /*
@@ -327,7 +327,7 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
 
 		case SEQ_INDEX_UNCOMPRESSED:
 			s->index.hash.uncompressed += s->vli;
-			s->index.hash.crc32 = crc32_A1(
+			s->index.hash.crc32 = libxmp_crc32_A1(
 					(const uint8 *)&s->index.hash,
 					sizeof(s->index.hash),
 					s->index.hash.crc32);
@@ -344,7 +344,7 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
  * Validate that the next four input bytes match the value of s->crc32.
  * s->pos must be zero when starting to validate the first byte.
  */
-static enum xz_ret crc32_validate(struct xz_dec *s, struct xz_buf *b)
+static enum xz_ret libxmp_crc32_validate(struct xz_dec *s, struct xz_buf *b)
 {
 	do {
 		if (b->in_pos == b->in_size)
@@ -390,7 +390,7 @@ static enum xz_ret dec_stream_header(struct xz_dec *s)
 	if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE))
 		return XZ_FORMAT_ERROR;
 
-	if (crc32_A1(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0)
+	if (libxmp_crc32_A1(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0)
 			!= get_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2))
 		return XZ_DATA_ERROR;
 
@@ -425,7 +425,7 @@ static enum xz_ret dec_stream_footer(struct xz_dec *s)
 	if (!memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE))
 		return XZ_DATA_ERROR;
 
-	if (crc32_A1(s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf))
+	if (libxmp_crc32_A1(s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf))
 		return XZ_DATA_ERROR;
 
 	/*
@@ -456,7 +456,7 @@ static enum xz_ret dec_block_header(struct xz_dec *s)
 	 * eight bytes so this is safe.
 	 */
 	s->temp.size -= 4;
-	if (crc32_A1(s->temp.buf, s->temp.size, 0)
+	if (libxmp_crc32_A1(s->temp.buf, s->temp.size, 0)
 			!= get_le32(s->temp.buf + s->temp.size))
 		return XZ_DATA_ERROR;
 
@@ -646,7 +646,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
 
 		case SEQ_BLOCK_CHECK:
 			if (s->check_type == XZ_CHECK_CRC32) {
-				ret = crc32_validate(s, b);
+				ret = libxmp_crc32_validate(s, b);
 				if (ret != XZ_STREAM_END)
 					return ret;
 			}
@@ -689,7 +689,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
 			s->sequence = SEQ_INDEX_CRC32;
 
 		case SEQ_INDEX_CRC32:
-			ret = crc32_validate(s, b);
+			ret = libxmp_crc32_validate(s, b);
 			if (ret != XZ_STREAM_END)
 				return ret;
 
diff --git a/src/effects.c b/src/effects.c
index ca70e7c..5d12802 100644
--- a/src/effects.c
+++ b/src/effects.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -34,16 +34,19 @@
 #define HAS_QUIRK(x) (m->quirk & (x))
 
 #define SET_LFO_NOTZERO(lfo, depth, rate) do { \
-	if ((depth) != 0) set_lfo_depth(lfo, depth); \
-	if ((rate) != 0) set_lfo_rate(lfo, rate); \
+	if ((depth) != 0) libxmp_lfo_set_depth(lfo, depth); \
+	if ((rate) != 0)  libxmp_lfo_set_rate(lfo, rate); \
 } while (0)
 
 #define EFFECT_MEMORY__(p, m) do { \
 	if ((p) == 0) { (p) = (m); } else { (m) = (p); } \
 } while (0)
 
+/* ST3 effect memory is not a bug, but it's a weird implementation and it's
+ * unlikely to be supported in anything other than ST3 (or OpenMPT).
+ */
 #define EFFECT_MEMORY(p, m) do { \
-	if (HAS_QUIRK(QUIRK_S3MPMEM)) { \
+	if (HAS_QUIRK(QUIRK_ST3BUGS)) { \
 		EFFECT_MEMORY__((p), xc->vol.memory); \
 	} else { \
 		EFFECT_MEMORY__((p), (m)); \
@@ -52,48 +55,69 @@
 
 #define EFFECT_MEMORY_SETONLY(p, m) do { \
 	EFFECT_MEMORY__((p), (m)); \
-	if (HAS_QUIRK(QUIRK_S3MPMEM)) { \
+	if (HAS_QUIRK(QUIRK_ST3BUGS)) { \
 		if ((p) != 0) { xc->vol.memory = (p); } \
 	} \
 } while (0)
 
 #define EFFECT_MEMORY_S3M(p) do { \
-	if (HAS_QUIRK(QUIRK_S3MPMEM)) { \
+	if (HAS_QUIRK(QUIRK_ST3BUGS)) { \
 		EFFECT_MEMORY__((p), xc->vol.memory); \
 	} \
 } while (0)
 
 
-static void do_toneporta(struct module_data *m,
+static void do_toneporta(struct context_data *ctx,
                                 struct channel_data *xc, int note)
 {
+	struct module_data *m = &ctx->m;
 	struct xmp_instrument *instrument = &m->mod.xxi[xc->ins];
 	int mapped = instrument->map[xc->key].ins;
-	struct xmp_subinstrument *sub = &instrument->sub[mapped];
+	struct xmp_subinstrument *sub;
+
+	if (mapped >= instrument->nsm) {
+		mapped = 0;
+	}
+
+	sub = &instrument->sub[mapped];
 
 	if (note >= 1 && note <= 0x80 && (uint32)xc->ins < m->mod.ins) {
 		note--;
-		xc->porta.target = note_to_period(note + sub->xpo +
-			instrument->map[xc->key].xpo, xc->finetune,
-			HAS_QUIRK(QUIRK_LINEAR), xc->per_adj);
+		xc->porta.target = libxmp_note_to_period(ctx, note + sub->xpo +
+			instrument->map[xc->key_porta].xpo, xc->finetune,
+			xc->per_adj);
 	}
 	xc->porta.dir = xc->period < xc->porta.target ? 1 : -1;
 }
 
-
-void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
-		uint8 note, uint8 fxt, uint8 fxp, int fnum)
+void libxmp_process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
+		struct xmp_event *e, int fnum)
 {
 	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
 	struct xmp_module *mod = &m->mod;
 	struct flow_control *f = &p->flow;
+	uint8 note, fxp, fxt;
 	int h, l;
 
+	/* key_porta is IT only */
+	if (m->read_event_type != READ_EVENT_IT) {
+		xc->key_porta = xc->key;
+	}
+
+	note = e->note;
+	if (fnum == 0) {
+		fxt = e->fxt;
+		fxp = e->fxp;
+	} else {
+		fxt = e->f2t;
+		fxp = e->f2p;
+	}
+
 	switch (fxt) {
 	case FX_ARPEGGIO:
 	      fx_arpeggio:
-		if (fxp != 0) {
+		if (!HAS_QUIRK(QUIRK_ARPMEM) || fxp != 0) {
 			xc->arpeggio.val[0] = 0;
 			xc->arpeggio.val[1] = MSN(fxp);
 			xc->arpeggio.val[2] = LSN(fxp);
@@ -103,6 +127,7 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 	case FX_S3M_ARPEGGIO:
 		EFFECT_MEMORY(fxp, xc->arpeggio.memory);
 		goto fx_arpeggio;
+
 #ifndef LIBXMP_CORE_PLAYER
 	case FX_OKT_ARP3:
 		if (fxp != 0) {
@@ -183,22 +208,24 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		}
 		break;
 	case FX_TONEPORTA:	/* Tone portamento */
+		EFFECT_MEMORY_SETONLY(fxp, xc->porta.memory);
+
+		if (fxp != 0) {
+			if (HAS_QUIRK(QUIRK_UNISLD)) /* IT compatible Gxx off */
+				xc->freq.memory = fxp;
+			xc->porta.slide = fxp;
+		}
+
 		if (HAS_QUIRK(QUIRK_IGSTPOR)) {
 			if (note == 0 && xc->porta.dir == 0)
 				break;
 		}
+
 		if (!IS_VALID_INSTRUMENT(xc->ins))
 			break;
 
-		do_toneporta(m, xc, note);
-
-		EFFECT_MEMORY_SETONLY(fxp, xc->porta.memory);
+		do_toneporta(ctx, xc, note);
 
-		if (fxp != 0) {
-			if (HAS_QUIRK(QUIRK_UNISLD)) /* IT compatible Gxx off */
-				xc->freq.memory = fxp;
-			xc->porta.slide = fxp;
-		}
 		SET(TONEPORTA);
 		break;
 
@@ -218,7 +245,7 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 	case FX_TONE_VSLIDE:	/* Toneporta + vol slide */
 		if (!IS_VALID_INSTRUMENT(xc->ins))
 			break;
-		do_toneporta(m, xc, note);
+		do_toneporta(ctx, xc, note);
 		SET(TONEPORTA);
 		goto fx_volslide;
 	case FX_VIBRA_VSLIDE:	/* Vibrato + vol slide */
@@ -226,20 +253,41 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		goto fx_volslide;
 
 	case FX_TREMOLO:	/* Tremolo */
-		EFFECT_MEMORY_SETONLY(fxp, xc->tremolo.memory);
+		EFFECT_MEMORY(fxp, xc->tremolo.memory);
 		SET(TREMOLO);
 		SET_LFO_NOTZERO(&xc->tremolo.lfo, LSN(fxp), MSN(fxp));
 		break;
 
 	case FX_SETPAN:		/* Set pan */
-		xc->pan.val = fxp;
+		if (HAS_QUIRK(QUIRK_PROTRACK)) {
+			break;
+		}
+	    fx_setpan:
+		/* From OpenMPT PanOff.xm:
+		 * "Another chapter of weird FT2 bugs: Note-Off + Note Delay
+		 *  + Volume Column Panning = Panning effect is ignored."
+		 */
+		if (!HAS_QUIRK(QUIRK_FT2BUGS)		/* If not FT2 */
+		    || fnum == 0			/* or not vol column */
+		    || e->note != XMP_KEY_OFF		/* or not keyoff */
+		    || e->fxt != FX_EXTENDED		/* or not delay */
+		    || MSN(e->fxp) != EX_DELAY) {
+			xc->pan.val = fxp;
+			xc->pan.surround = 0;
+		}
+		xc->rpv = 0;	/* storlek_20: set pan overrides random pan */
+		xc->pan.surround = 0;
 		break;
 	case FX_OFFSET:		/* Set sample offset */
+		EFFECT_MEMORY(fxp, xc->offset.memory);
 		SET(OFFSET);
-		if (fxp) {
-			xc->offset_val = xc->offset = fxp << 8;
-		} else {
-			xc->offset_val = xc->offset;
+		if (note) {
+			xc->offset.val &= xc->offset.val & ~0xffff;
+			xc->offset.val |= fxp << 8;
+			xc->offset.val2 = fxp << 8;
+		}
+		if (e->ins) {
+			xc->offset.val2 = fxp << 8;
 		}
 		break;
 	case FX_VOLSLIDE:	/* Volume slide */
@@ -282,16 +330,12 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 			xc->vol.memory = fxp;
 			h = MSN(fxp);
 			l = LSN(fxp);
-			if (HAS_QUIRK(QUIRK_VOLPDN)) {
-				if (fxp)
+			if (fxp) {
+				if (HAS_QUIRK(QUIRK_VOLPDN)) {
 					xc->vol.slide = l ? -l : h;
-			} else {
-				if (l == 0)
-					xc->vol.slide = h;
-				else if (h == 0)
-					xc->vol.slide = -l;
-				else
-					RESET(VOL_SLIDE);
+				} else {
+					xc->vol.slide = h ? h : -l;
+				}
 			}
 		}
 
@@ -312,12 +356,7 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		if (fxp) {
 			h = MSN(fxp);
 			l = LSN(fxp);
-			if (l == 0)
-				xc->vol.slide2 = h;
-			else if (h == 0)
-				xc->vol.slide2 = -l;
-			else
-				RESET(VOL_SLIDE_2);
+			xc->vol.slide2 = h ? h : -l;
 		}		
 		break;
 	case FX_JUMP:		/* Order jump */
@@ -329,6 +368,9 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 	case FX_VOLSET:		/* Volume set */
 		SET(NEW_VOL);
 		xc->volume = fxp;
+		if (xc->split) {
+			p->xc_data[xc->pair].volume = xc->volume;
+		}
 		break;
 	case FX_BREAK:		/* Pattern break */
 		p->flow.pbreak = 1;
@@ -339,30 +381,39 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		fxt = fxp >> 4;
 		fxp &= 0x0f;
 		switch (fxt) {
+		case EX_FILTER:		/* Amiga led filter */
+			if (IS_AMIGA_MOD()) {
+				p->filter = !(fxp & 1);
+			}
+			break;
 		case EX_F_PORTA_UP:	/* Fine portamento up */
-		    EFFECT_MEMORY(fxp, xc->fine_porta.up_memory);
-		    goto fx_f_porta_up;
+			EFFECT_MEMORY(fxp, xc->fine_porta.up_memory);
+			goto fx_f_porta_up;
 		case EX_F_PORTA_DN:	/* Fine portamento down */
-		    EFFECT_MEMORY(fxp, xc->fine_porta.down_memory);
-		    goto fx_f_porta_dn;
+			EFFECT_MEMORY(fxp, xc->fine_porta.down_memory);
+			goto fx_f_porta_dn;
 		case EX_GLISS:		/* Glissando toggle */
-			xc->gliss = fxp;
+			if (fxp) {
+				SET_NOTE(NOTE_GLISSANDO);
+			} else {
+				RESET_NOTE(NOTE_GLISSANDO);
+			}
 			break;
 		case EX_VIBRATO_WF:	/* Set vibrato waveform */
 			fxp &= 3;
-			if (HAS_QUIRK(QUIRK_S3MLFO) && fxp == 2)
-				fxp |= 0x10;
-			set_lfo_waveform(&xc->vibrato.lfo, fxp);
+			libxmp_lfo_set_waveform(&xc->vibrato.lfo, fxp);
 			break;
 		case EX_FINETUNE:	/* Set finetune */
-			fxp <<= 4;
-			if (!HAS_QUIRK(QUIRK_XMFINE) || note > 0)
-				goto fx_finetune;
+			if (!HAS_QUIRK(QUIRK_FT2BUGS) || note > 0) {
+				xc->finetune = (int8)(fxp << 4);
+			}
 			break;
 		case EX_PATTERN_LOOP:	/* Loop pattern */
 			if (fxp == 0) {
 				/* mark start of loop */
 				f->loop[chn].start = p->row;
+				if (HAS_QUIRK(QUIRK_FT2BUGS))
+				  p->flow.jumpline = p->row;
 			} else {
 				/* end of loop */
 				if (f->loop[chn].count) {
@@ -375,16 +426,17 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 							    p->row + 1;
 					}
 				} else {
-					if (f->loop[chn].start <= p->row) {
-						f->loop[chn].count = fxp;
-						f->loop_chn = ++chn;
-					}
+					f->loop[chn].count = fxp;
+					f->loop_chn = ++chn;
 				}
 			}
 			break;
 		case EX_TREMOLO_WF:	/* Set tremolo waveform */
-			set_lfo_waveform(&xc->tremolo.lfo, fxp & 3);
+			libxmp_lfo_set_waveform(&xc->tremolo.lfo, fxp & 3);
 			break;
+		case EX_SETPAN:
+			fxp <<= 4;
+			goto fx_setpan;
 		case EX_RETRIG:		/* Retrig note */
 			SET(RETRIG);
 			xc->retrig.val = fxp;
@@ -415,8 +467,12 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		}
 		break;
 	case FX_SPEED:		/* Set speed */
+		if (HAS_QUIRK(QUIRK_NOBPM) || p->flags & XMP_FLAGS_VBLANK) {
+			goto fx_s3m_speed;
+		}
+
 		/* speedup.xm needs BPM = 20 */
-		if (p->flags & XMP_FLAGS_VBLANK || fxp < 0x20) {
+		if (fxp < 0x20) {
 			goto fx_s3m_speed;
 		} else {
 			goto fx_s3m_bpm;
@@ -424,7 +480,6 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		break;
 
 	case FX_FINETUNE:
-	      fx_finetune:
 		xc->finetune = (int16) (fxp - 0x80);
 		break;
 
@@ -440,6 +495,7 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		SET(FINE_VOLS);
 		xc->vol.fslide = -fxp;
 		break;
+
 	case FX_F_PORTA_UP:	/* Fine portamento up */
 	    fx_f_porta_up:
 		if (fxp) {
@@ -456,24 +512,31 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		break;
 	case FX_PATT_DELAY:
 	    fx_patt_delay:
-		p->flow.delay = fxp;
+		if (m->read_event_type != READ_EVENT_ST3 || !p->flow.delay) {
+			p->flow.delay = fxp;
+		}
 		break;
 
 	case FX_S3M_SPEED:	/* Set S3M speed */
 		EFFECT_MEMORY_S3M(fxp);
 	    fx_s3m_speed:
-		if (fxp)
+		if (fxp) {
 			p->speed = fxp;
+#ifndef LIBXMP_CORE_PLAYER
+			p->st26_speed = 0;
+#endif
+		}
 		break;
 	case FX_S3M_BPM:	/* Set S3M BPM */
-            fx_s3m_bpm:
-		if (fxp >= 0x20) {
-			if (fxp < XMP_MIN_BPM)
-				fxp = XMP_MIN_BPM;
-			p->bpm = fxp;
-			p->frame_time = m->time_factor * m->rrate / p->bpm;
-		}
+	    fx_s3m_bpm: {
+		/* Lower time factor in MED allows lower BPM values */
+		int min_bpm = (int)(0.5 + m->time_factor * XMP_MIN_BPM / 10);
+		if (fxp < min_bpm)
+			fxp = min_bpm;
+		p->bpm = fxp;
+		p->frame_time = m->time_factor * m->rrate / p->bpm;
 		break;
+	}
 
 #ifndef LIBXMP_CORE_DISABLE_IT
 	case FX_IT_BPM:		/* Set IT BPM */
@@ -493,9 +556,40 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 	case FX_IT_ROWDELAY:
 		if (!f->rowdelay_set) {
 			f->rowdelay = fxp;
-			f->rowdelay_set = 1;
+			f->rowdelay_set = 3;
 		}
 		break;
+
+	/* From the OpenMPT VolColMemory.it test case:
+	 * "Volume column commands a, b, c and d (volume slide) share one
+	 *  effect memory, but it should not be shared with Dxy in the effect
+	 *  column. 
+	 */
+	case FX_VSLIDE_UP_2:	/* Fine volume slide up */
+		EFFECT_MEMORY(fxp, xc->vol.memory2);
+		SET(VOL_SLIDE_2);
+		xc->vol.slide2 = fxp;
+		break;
+	case FX_VSLIDE_DN_2:	/* Fine volume slide down */
+		EFFECT_MEMORY(fxp, xc->vol.memory2);
+		SET(VOL_SLIDE_2);
+		xc->vol.slide2 = -fxp;
+		break;
+	case FX_F_VSLIDE_UP_2:	/* Fine volume slide up */
+		EFFECT_MEMORY(fxp, xc->vol.memory2);
+		SET(FINE_VOLS_2);
+		xc->vol.fslide2 = fxp;
+		break;
+	case FX_F_VSLIDE_DN_2:	/* Fine volume slide down */
+		EFFECT_MEMORY(fxp, xc->vol.memory2);
+		SET(FINE_VOLS_2);
+		xc->vol.fslide2 = -fxp;
+		break;
+	case FX_IT_BREAK:	/* Pattern break with hex parameter */
+		p->flow.pbreak = 1;
+		p->flow.jumpline = fxp;
+		break;
+
 #endif
 
 	case FX_GLOBALVOL:	/* Set global volume */
@@ -521,11 +615,11 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 					xc->gvol.slide = 0;
 					xc->gvol.fslide = -l;
 				} else {
-					xc->gvol.slide = h - l;
+					xc->gvol.slide = h ? h : -l;
 					xc->gvol.fslide = 0;
 				}
 			} else {
-				xc->gvol.slide = h - l;
+				xc->gvol.slide = h ? h : -l;
 				xc->gvol.fslide = 0;
 			}
 		} else {
@@ -538,17 +632,33 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		xc->keyoff = fxp + 1;
 		break;
 	case FX_ENVPOS:		/* Set envelope position */
-		/* FIXME: Add OpenMPT quirk */
+		/* From OpenMPT SetEnvPos.xm:
+		 * "When using the Lxx effect, Fasttracker 2 only sets the
+		 *  panning envelope position if the volume envelope’s sustain
+		 *  flag is set.
+		 */
+		if (HAS_QUIRK(QUIRK_FT2BUGS)) {
+			struct xmp_instrument *instrument;
+			instrument = libxmp_get_instrument(ctx, xc->ins);
+			if (instrument != NULL) {
+				if (instrument->aei.flg & XMP_ENVELOPE_SUS) {
+					xc->p_idx = fxp;
+				}
+			}
+		} else {
+			xc->p_idx = fxp;
+		}
 		xc->v_idx = fxp;
 		xc->f_idx = fxp;
-		xc->p_idx = fxp;
 		break;
 	case FX_PANSLIDE:	/* Pan slide (XM) */
-		/* TODO: add memory */
+		EFFECT_MEMORY(fxp, xc->pan.memory);
 		SET(PAN_SLIDE);
-		if (fxp) {
-			xc->pan.slide = LSN(fxp) - MSN(fxp);
-		}
+		xc->pan.slide = LSN(fxp) - MSN(fxp);
+		break;
+	case FX_PANSL_NOMEM:	/* Pan slide (XM volume column) */
+		SET(PAN_SLIDE);
+		xc->pan.slide = LSN(fxp) - MSN(fxp);
 		break;
 
 #ifndef LIBXMP_CORE_DISABLE_IT
@@ -581,13 +691,21 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		}
 		SET(RETRIG);
 		break;
-	case FX_TREMOR:		/* Tremor */
+	case FX_TREMOR:			/* Tremor */
 		EFFECT_MEMORY(fxp, xc->tremor.memory);
-		if (MSN(fxp) == 0)
-			fxp |= 0x10;
-		if (LSN(fxp) == 0)
-			fxp |= 0x01;
-		xc->tremor.val = fxp;
+		xc->tremor.up = MSN(fxp);
+		xc->tremor.down = LSN(fxp);
+		if (IS_PLAYER_MODE_FT2()) {
+			xc->tremor.count |= 0x80;
+		} else {
+			if (xc->tremor.up == 0) {
+				xc->tremor.up++;
+			}
+			if (xc->tremor.down == 0) {
+				xc->tremor.down++;
+			}
+		}
+		SET(TREMOR);
 		break;
 	case FX_XF_PORTA:	/* Extra fine portamento */
 	      fx_xf_porta:
@@ -601,6 +719,9 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 			break;
 		}
 		break;
+	case FX_SURROUND:
+		xc->pan.surround = fxp;
+		break;
 
 #ifndef LIBXMP_CORE_DISABLE_IT
 	case FX_TRK_VOL:	/* Track volume setting */
@@ -627,19 +748,18 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 				goto fx_trk_fvslide;
 			}
 		}
-		SET(TRK_VSLIDE);
 
+		SET(TRK_VSLIDE);
 		if (fxp) {
 			h = MSN(fxp);
 			l = LSN(fxp);
 
 			xc->trackvol.memory = fxp;
-			if (l == 0)
-				xc->trackvol.slide = h;
-			else if (h == 0)
-				xc->trackvol.slide = -l;
-			else
-				RESET(TRK_VSLIDE);
+			if (HAS_QUIRK(QUIRK_VOLPDN)) {
+				xc->trackvol.slide = l ? -l : h;
+			} else {
+				xc->trackvol.slide = h ? h : -l;
+			}
 		}
 
 		break;
@@ -654,34 +774,50 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 	case FX_IT_INSTFUNC:
 		switch (fxp) {
 		case 0:	/* Past note cut */
-			virt_pastnote(ctx, chn, VIRT_ACTION_CUT);
+			libxmp_virt_pastnote(ctx, chn, VIRT_ACTION_CUT);
 			break;
 		case 1:	/* Past note off */
-			virt_pastnote(ctx, chn, VIRT_ACTION_OFF);
+			libxmp_virt_pastnote(ctx, chn, VIRT_ACTION_OFF);
 			break;
 		case 2:	/* Past note fade */
-			virt_pastnote(ctx, chn, VIRT_ACTION_FADE);
+			libxmp_virt_pastnote(ctx, chn, VIRT_ACTION_FADE);
 			break;
 		case 3:	/* Set NNA to note cut */
-			virt_setnna(ctx, chn, XMP_INST_NNA_CUT);
+			libxmp_virt_setnna(ctx, chn, XMP_INST_NNA_CUT);
 			break;
 		case 4:	/* Set NNA to continue */
-			virt_setnna(ctx, chn, XMP_INST_NNA_CONT);
+			libxmp_virt_setnna(ctx, chn, XMP_INST_NNA_CONT);
 			break;
 		case 5:	/* Set NNA to note off */
-			virt_setnna(ctx, chn, XMP_INST_NNA_OFF);
+			libxmp_virt_setnna(ctx, chn, XMP_INST_NNA_OFF);
 			break;
 		case 6:	/* Set NNA to note fade */
-			virt_setnna(ctx, chn, XMP_INST_NNA_FADE);
+			libxmp_virt_setnna(ctx, chn, XMP_INST_NNA_FADE);
 			break;
 		case 7:	/* Turn off volume envelope */
+			SET_PER(VENV_PAUSE);
 			break;
 		case 8:	/* Turn on volume envelope */
+			RESET_PER(VENV_PAUSE);
+			break;
+		case 9:	/* Turn off pan envelope */
+			SET_PER(PENV_PAUSE);
+			break;
+		case 0xa:	/* Turn on pan envelope */
+			RESET_PER(PENV_PAUSE);
+			break;
+		case 0xb:	/* Turn off pitch envelope */
+			SET_PER(FENV_PAUSE);
+			break;
+		case 0xc:	/* Turn on pitch envelope */
+			RESET_PER(FENV_PAUSE);
 			break;
 		}
 		break;
 	case FX_FLT_CUTOFF:
-		xc->filter.cutoff = fxp;
+		if (fxp < 0xfe || xc->filter.resonance > 0) {
+			xc->filter.cutoff = fxp;
+		}
 		break;
 	case FX_FLT_RESN:
 		xc->filter.resonance = fxp;
@@ -691,11 +827,70 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		SET_LFO_NOTZERO(&xc->panbrello.lfo, LSN(fxp) << 4, MSN(fxp));
 		break;
 	case FX_PANBRELLO_WF:	/* Panbrello waveform */
-		set_lfo_waveform(&xc->panbrello.lfo, fxp & 3);
+		libxmp_lfo_set_waveform(&xc->panbrello.lfo, fxp & 3);
+		break;
+	case FX_HIOFFSET:	/* High offset */
+		xc->offset.val &= 0xffff;
+		xc->offset.val |= fxp << 16;
 		break;
 #endif
 
 #ifndef LIBXMP_CORE_PLAYER
+
+	/* SFX effects */
+	case FX_VOL_ADD:
+		if (!IS_VALID_INSTRUMENT(xc->ins)) {
+			break;
+		}
+		SET(NEW_VOL);
+		xc->volume = m->mod.xxi[xc->ins].sub[0].vol + fxp;
+		if (xc->volume > m->volbase) {
+			xc->volume = m->volbase;
+		}
+		break;
+	case FX_VOL_SUB:
+		if (!IS_VALID_INSTRUMENT(xc->ins)) {
+			break;
+		}
+		SET(NEW_VOL);
+		xc->volume = m->mod.xxi[xc->ins].sub[0].vol - fxp;
+		if (xc->volume < 0) {
+			xc->volume =0;
+		}
+		break;
+	case FX_PITCH_ADD:
+		SET_PER(TONEPORTA);
+		xc->porta.target = libxmp_note_to_period(ctx, note - 1, xc->finetune, 0)
+			+ fxp;
+		xc->porta.slide = 2;
+		xc->porta.dir = 1;
+		break;
+	case FX_PITCH_SUB:
+		SET_PER(TONEPORTA);
+		xc->porta.target = libxmp_note_to_period(ctx, note - 1, xc->finetune, 0)
+			- fxp;
+		xc->porta.slide = 2;
+		xc->porta.dir = -1;
+		break;
+
+	/* Saga Musix says:
+	 *
+	 * "When both nibbles of an Fxx command are set, SoundTracker 2.6
+	 * applies the both values alternatingly, first the high nibble,
+	 * then the low nibble on the next row, then the high nibble again...
+	 * If only the high nibble is set, it should act like if only the low
+	 * nibble is set (i.e. F30 is the same as F03).
+	 */
+	case FX_ICE_SPEED:
+		if (fxp) {
+			if (LSN(fxp)) {
+				p->st26_speed = (MSN(fxp) << 8) | LSN(fxp);
+			} else {
+				p->st26_speed = MSN(fxp);
+			}
+		}
+		break;
+
 	case FX_VOLSLIDE_UP:	/* Vol slide with uint8 arg */
 		if (HAS_QUIRK(QUIRK_FINEFX)) {
 			h = MSN(fxp);
@@ -729,12 +924,7 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		if (fxp) {
 			h = MSN(fxp);
 			l = LSN(fxp);
-			if (l == 0)
-				xc->vol.fslide = h;
-			else if (h == 0)
-				xc->vol.fslide = -l;
-			else
-				RESET(FINE_VOLS);
+			xc->vol.fslide = h ? h : -l;
 		}		
 		break;
 	case FX_NSLIDE_DN:
@@ -802,7 +992,7 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		if (!IS_VALID_INSTRUMENT(xc->ins))
 			break;
 		SET_PER(TONEPORTA);
-		do_toneporta(m, xc, note);
+		do_toneporta(ctx, xc, note);
 		xc->porta.slide = fxp;
 		if (fxp == 0)
 			RESET_PER(TONEPORTA);
@@ -824,16 +1014,55 @@ void process_fx(struct context_data *ctx, struct channel_data *xc, int chn,
 		SET_LFO_NOTZERO(&xc->vibrato.lfo, LSN(fxp) << 3, MSN(fxp));
 		break;
 	case FX_SPEED_CP:	/* Set speed and ... */
-		if (fxp)
+		if (fxp) {
 			p->speed = fxp;
+			p->st26_speed = 0;
+		}
 		/* fall through */
 	case FX_PER_CANCEL:	/* Cancel persistent effects */
 		xc->per_flags = 0;
 		break;
+
+	/* 669 effects */
+
+	case FX_669_PORTA_UP:	/* 669 portamento up */
+		SET_PER(PITCHBEND);
+		xc->freq.slide = 80 * fxp;
+		if ((xc->freq.memory = fxp) == 0)
+			RESET_PER(PITCHBEND);
+		break;
+	case FX_669_PORTA_DN:	/* 669 portamento down */
+		SET_PER(PITCHBEND);
+		xc->freq.slide = -80 * fxp;
+		if ((xc->freq.memory = fxp) == 0)
+			RESET_PER(PITCHBEND);
+		break;
+	case FX_669_TPORTA:	/* 669 tone portamento */
+		if (!IS_VALID_INSTRUMENT(xc->ins))
+			break;
+		SET_PER(TONEPORTA);
+		do_toneporta(ctx, xc, note);
+		xc->porta.slide = 40 * fxp;
+		if (fxp == 0)
+			RESET_PER(TONEPORTA);
+		break;
+	case FX_669_FINETUNE:	/* 669 finetune */
+		xc->finetune = 80 * (int8)fxp;
+		break;
+	case FX_669_VIBRATO:	/* 669 vibrato */
+		if (LSN(fxp) != 0) {
+			libxmp_lfo_set_waveform(&xc->vibrato.lfo, 669);
+			SET_PER(VIBRATO);
+		} else {
+			RESET_PER(VIBRATO);
+		}
+		SET_LFO_NOTZERO(&xc->vibrato.lfo, 669, 1);
+		break;
 #endif
+
 	default:
 #ifndef LIBXMP_CORE_PLAYER
-		extras_process_fx(ctx, xc, chn, note, fxt, fxp, fnum);
+		libxmp_extras_process_fx(ctx, xc, chn, note, fxt, fxp, fnum);
 #endif
 		break;
 	}
diff --git a/src/effects.h b/src/effects.h
index ae5ce9f..b269bac 100644
--- a/src/effects.h
+++ b/src/effects.h
@@ -32,6 +32,7 @@
 #define FX_XF_PORTA	0x21
 
 /* Protracker extended effects */
+#define EX_FILTER	0x00
 #define EX_F_PORTA_UP	0x01
 #define EX_F_PORTA_DN	0x02
 #define EX_GLISS	0x03
@@ -39,6 +40,7 @@
 #define EX_FINETUNE	0x05
 #define EX_PATTERN_LOOP	0x06
 #define EX_TREMOLO_WF	0x07
+#define EX_SETPAN	0x08
 #define EX_RETRIG	0x09
 #define EX_F_VSLIDE_UP	0x0a
 #define EX_F_VSLIDE_DN	0x0b
@@ -57,7 +59,7 @@
 #define FX_F_NSLIDE_DN	0x75
 #define FX_F_NSLIDE_UP	0x76
 
-/* Persistent effects -- for 669, FNK and FAR */
+/* Persistent effects -- for FNK and FAR */
 #define FX_PER_PORTA_DN	0x78
 #define FX_PER_PORTA_UP	0x79
 #define FX_PER_TPORTA	0x7a
@@ -66,6 +68,13 @@
 #define FX_PER_VSLD_DN	0x7d
 #define FX_SPEED_CP	0x7e
 #define FX_PER_CANCEL	0x7f
+
+/* 669 frequency based effects */
+#define FX_669_PORTA_UP	0x60
+#define FX_669_PORTA_DN	0x61
+#define FX_669_TPORTA	0x62
+#define FX_669_FINETUNE	0x63
+#define FX_669_VIBRATO	0x64
 #endif
 
 #ifndef LIBXMP_CORE_DISABLE_IT
@@ -81,6 +90,8 @@
 #define FX_IT_PANSLIDE	0x89
 #define FX_PANBRELLO	0x8a
 #define FX_PANBRELLO_WF	0x8b
+#define FX_HIOFFSET	0x8c
+#define FX_IT_BREAK	0x8e	/* like FX_BREAK with hex parameter */
 #endif
 
 #ifndef LIBXMP_CORE_PLAYER
@@ -100,11 +111,17 @@
 #define FX_VOLSLIDE_DN	0xa1
 #define FX_F_VSLIDE	0xa5	/* IMF/MDL */
 #define FX_CHORUS	0xa9	/* IMF */
+#define FX_ICE_SPEED	0xa2
 #define FX_REVERB	0xaa	/* IMF */
 #define FX_MED_HOLD	0xb1	/* MMD hold/decay */
 #define FX_MEGAARP	0xb2	/* Smaksak effect 7: MegaArp */
+#define FX_VOL_ADD	0xb6	/* SFX change volume up */
+#define FX_VOL_SUB	0xb7	/* SFX change volume down */
+#define FX_PITCH_ADD	0xb8	/* SFX add steps to current note */
+#define FX_PITCH_SUB	0xb9	/* SFX add steps to current note */
 #endif
 
+#define FX_SURROUND	0x8d	/* S3M/IT */
 #define FX_S3M_SPEED	0xa3	/* S3M */
 #define FX_VOLSLIDE_2	0xa4
 #define FX_FINETUNE	0xa6
@@ -116,5 +133,11 @@
 #define FX_F_PORTA_DN	0xb0	/* MMD */
 #define FX_PATT_DELAY	0xb3	/* MMD */
 #define FX_S3M_ARPEGGIO	0xb4
+#define FX_PANSL_NOMEM	0xb5	/* XM volume column */
+
+#define FX_VSLIDE_UP_2	0xc0	/* IT volume column volume slide */
+#define FX_VSLIDE_DN_2	0xc1
+#define FX_F_VSLIDE_UP_2 0xc2
+#define FX_F_VSLIDE_DN_2 0xc3
 
 #endif /* LIBXMP_EFFECTS_H */
diff --git a/src/envelope.c b/src/envelope.c
deleted file mode 100644
index d6fdbed..0000000
--- a/src/envelope.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "common.h"
-#include "envelope.h"
-
-/* Envelope */
-
-int get_envelope(struct xmp_envelope *env, int x, int def, int *end)
-{
-	int x1, x2, y1, y2;
-	int16 *data = env->data;
-	int index;
-
-	*end = 0;
-
-	if (~env->flg & XMP_ENVELOPE_ON || env->npt <= 0)
-		return def;
-
-	index = (env->npt - 1) * 2;
-
-	x1 = data[index];		/* last node */
-	if (x >= x1 || index == 0) { 
-		*end = 1;
-		return data[index + 1];
-	}
-
-	do {
-		index -= 2;
-		x1 = data[index];
-	} while (index > 0 && x1 > x);
-
-	/* interpolate */
-	y1 = data[index + 1];
-	x2 = data[index + 2];
-
-	if (env->flg & XMP_ENVELOPE_LOOP && index == (env->lpe << 1)) {
-		index = (env->lps - 1) * 2;
-	}
-
-	y2 = data[index + 3];
-
-	return ((y2 - y1) * (x - x1) / (x2 - x1)) + y1;
-}
-
-
-int update_envelope(struct xmp_envelope *env, int x, int release, int sus_quirk)
-{
-	int16 *data = env->data;
-	int has_loop, has_sus;
-	int lpe, lps, sus, sue;
-
-	if (~env->flg & XMP_ENVELOPE_ON || env->npt <= 0) {
-		return x;
-	}
-
-	has_loop = env->flg & XMP_ENVELOPE_LOOP;
-	has_sus = env->flg & XMP_ENVELOPE_SUS;
-
-	lps = env->lps << 1;
-	lpe = env->lpe << 1;
-	sus = env->sus << 1;
-	sue = env->sue << 1;
-
-	/* FT2 and IT envelopes behave in a different way regarding loops,
-	 * sustain and release. When the sustain point is at the end of the
-	 * envelope loop end and the key is released, FT2 escapes the loop
-	 * while IT runs another iteration. (See EnvLoops.xm in the OpenMPT
-	 * test cases.)
-	 */
-	if (has_loop && has_sus && sus == lpe) {
-		if (sus_quirk && !release)
-			has_sus = 0;
-	}
-
-	if (env->flg & XMP_ENVELOPE_SLOOP) {
-		if (!release && has_sus) {
-			if (x == data[sue])
-				x = data[sus] - 1;
-		} else if (has_loop) {
-			if (x == data[lpe])
-				x = data[lps] - 1;
-		}
-	} else {
-		if (!release && has_sus && x == data[sus]) {
-			/* stay in the sustain point */
-			x--;
-		}
-
-		if (has_loop && x == data[lpe]) {
-	    		if (!(release && has_sus && sus == lpe))
-				x = data[lps] - 1;
-		}
-	}
-
-	if (x < 0xffff)	{	/* increment tick */
-		x++;
-	}
-
-	return x;
-}
-
-
-/* Returns: 0 if do nothing, <0 to reset channel, >0 if has fade */
-int check_envelope_fade(struct xmp_envelope *env, int x)
-{
-	int16 *data = env->data;
-	int index;
-
-	if (~env->flg & XMP_ENVELOPE_ON)
-		return 0;
-
-	index = (env->npt - 1) * 2;		/* last node */
-	if (x > data[index]) {
-		if (data[index + 1] == 0)
-			return -1;
-		else
-			return 1;
-	}
-
-	return 0;
-}
-
diff --git a/src/envelope.h b/src/envelope.h
deleted file mode 100644
index 3602641..0000000
--- a/src/envelope.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef LIBXMP_ENVELOPE_H
-#define LIBXMP_ENVELOPE_H
-
-/* Envelope */
-
-int get_envelope(struct xmp_envelope *, int, int, int *);
-int update_envelope(struct xmp_envelope *, int, int, int);
-int check_envelope_fade(struct xmp_envelope *, int);
-
-#endif
diff --git a/src/extras.c b/src/extras.c
index 2f18266..58a254c 100644
--- a/src/extras.c
+++ b/src/extras.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include 
@@ -17,61 +31,60 @@
  * Module extras
  */
 
-void release_module_extras(struct context_data *ctx)
+void libxmp_release_module_extras(struct context_data *ctx)
 {
 	struct module_data *m = &ctx->m;
 
 	if (HAS_MED_MODULE_EXTRAS(*m))
-		med_release_module_extras(m);
+		libxmp_med_release_module_extras(m);
 	else if (HAS_HMN_MODULE_EXTRAS(*m))
-		hmn_release_module_extras(m);
+		libxmp_hmn_release_module_extras(m);
 }
 
 /*
  * Channel extras
  */
 
-int new_channel_extras(struct context_data *ctx, struct channel_data *xc)
+int libxmp_new_channel_extras(struct context_data *ctx, struct channel_data *xc)
 {
 	struct module_data *m = &ctx->m;
 
 	if (HAS_MED_MODULE_EXTRAS(*m)) {
-		if (med_new_channel_extras(xc) < 0)
+		if (libxmp_med_new_channel_extras(xc) < 0)
 			return -1;
 	} else if (HAS_HMN_MODULE_EXTRAS(*m)) {
-		if (hmn_new_channel_extras(xc) < 0)
+		if (libxmp_hmn_new_channel_extras(xc) < 0)
 			return -1;
 	}
 
 	return 0;
 }
 
-void release_channel_extras(struct context_data *ctx, struct channel_data *xc)
+void libxmp_release_channel_extras(struct context_data *ctx, struct channel_data *xc)
 {
 	struct module_data *m = &ctx->m;
 
 	if (HAS_MED_CHANNEL_EXTRAS(*m))
-		med_release_channel_extras(xc);
+		libxmp_med_release_channel_extras(xc);
 	else if (HAS_HMN_CHANNEL_EXTRAS(*m))
-		hmn_release_channel_extras(xc);
+		libxmp_hmn_release_channel_extras(xc);
 }
 
-void reset_channel_extras(struct context_data *ctx, struct channel_data *xc)
+void libxmp_reset_channel_extras(struct context_data *ctx, struct channel_data *xc)
 {
 	struct module_data *m = &ctx->m;
 
 	if (HAS_MED_CHANNEL_EXTRAS(*m))
-		med_reset_channel_extras(xc);
+		libxmp_med_reset_channel_extras(xc);
 	else if (HAS_HMN_CHANNEL_EXTRAS(*m))
-		hmn_reset_channel_extras(xc);
+		libxmp_hmn_reset_channel_extras(xc);
 }
 
 /*
  * Player extras
  */
 
-void play_extras(struct context_data *ctx, struct channel_data *xc,
-			int chn, int t)
+void libxmp_play_extras(struct context_data *ctx, struct channel_data *xc, int chn)
 {
 	struct module_data *m = &ctx->m;
 
@@ -79,12 +92,12 @@ void play_extras(struct context_data *ctx, struct channel_data *xc,
 		return;
 
         if (HAS_MED_INSTRUMENT_EXTRAS(m->mod.xxi[xc->ins]))
-		med_play_extras(ctx, xc, chn, t);
+		libxmp_med_play_extras(ctx, xc, chn);
         else if (HAS_HMN_INSTRUMENT_EXTRAS(m->mod.xxi[xc->ins]))
-		hmn_play_extras(ctx, xc, chn, t);
+		libxmp_hmn_play_extras(ctx, xc, chn);
 }
 
-int extras_get_volume(struct context_data *ctx, struct channel_data *xc)
+int libxmp_extras_get_volume(struct context_data *ctx, struct channel_data *xc)
 {
 	struct module_data *m = &ctx->m;
 	int vol;
@@ -101,36 +114,36 @@ int extras_get_volume(struct context_data *ctx, struct channel_data *xc)
 	return vol;
 }
 
-int extras_get_period(struct context_data *ctx, struct channel_data *xc)
+int libxmp_extras_get_period(struct context_data *ctx, struct channel_data *xc)
 {
 	int period;
 
 	if (HAS_MED_CHANNEL_EXTRAS(*xc))
-		period = med_change_period(ctx, xc);
+		period = libxmp_med_change_period(ctx, xc);
 	else period = 0;
 
 	return period;
 }
 
-int extras_get_linear_bend(struct context_data *ctx, struct channel_data *xc)
+int libxmp_extras_get_linear_bend(struct context_data *ctx, struct channel_data *xc)
 {
 	int linear_bend;
 
 	if (HAS_MED_CHANNEL_EXTRAS(*xc))
-		linear_bend = med_linear_bend(ctx, xc);
+		linear_bend = libxmp_med_linear_bend(ctx, xc);
 	else if (HAS_HMN_CHANNEL_EXTRAS(*xc))
-		linear_bend = hmn_linear_bend(ctx, xc);
+		linear_bend = libxmp_hmn_linear_bend(ctx, xc);
 	else
 		linear_bend = 0;
 
 	return linear_bend;
 }
 
-void extras_process_fx(struct context_data *ctx, struct channel_data *xc,
+void libxmp_extras_process_fx(struct context_data *ctx, struct channel_data *xc,
 			int chn, uint8 note, uint8 fxt, uint8 fxp, int fnum)
 {
 	if (HAS_MED_CHANNEL_EXTRAS(*xc))
-		med_extras_process_fx(ctx, xc, chn, note, fxt, fxp, fnum);
+		libxmp_med_extras_process_fx(ctx, xc, chn, note, fxt, fxp, fnum);
 	else if (HAS_HMN_CHANNEL_EXTRAS(*xc))
-		hmn_extras_process_fx(ctx, xc, chn, note, fxt, fxp, fnum);
+		libxmp_hmn_extras_process_fx(ctx, xc, chn, note, fxt, fxp, fnum);
 }
diff --git a/src/extras.h b/src/extras.h
index 94e3704..b8ef7b2 100644
--- a/src/extras.h
+++ b/src/extras.h
@@ -1,21 +1,18 @@
-#ifndef XMP_EXTRAS_H
-#define XMP_EXTRAS_H
+#ifndef LIBXMP_EXTRAS_H
+#define LIBXMP_EXTRAS_H
 
-void release_module_extras(struct context_data *);
-
-int new_channel_extras(struct context_data *, struct channel_data *);
-void release_channel_extras(struct context_data *, struct channel_data *);
-void reset_channel_extras(struct context_data *, struct channel_data *);
-
-void play_extras(struct context_data *, struct channel_data *, int, int);
-
-int extras_get_volume(struct context_data *, struct channel_data *);
-int extras_get_period(struct context_data *, struct channel_data *);
-int extras_get_linear_bend(struct context_data *, struct channel_data *);
-void extras_process_fx(struct context_data *, struct channel_data *, int, uint8, uint8, uint8, int);
+void libxmp_release_module_extras(struct context_data *);
+int  libxmp_new_channel_extras(struct context_data *, struct channel_data *);
+void libxmp_release_channel_extras(struct context_data *, struct channel_data *);
+void libxmp_reset_channel_extras(struct context_data *, struct channel_data *);
+void libxmp_play_extras(struct context_data *, struct channel_data *, int);
+int  libxmp_extras_get_volume(struct context_data *, struct channel_data *);
+int  libxmp_extras_get_period(struct context_data *, struct channel_data *);
+int  libxmp_extras_get_linear_bend(struct context_data *, struct channel_data *);
+void libxmp_extras_process_fx(struct context_data *, struct channel_data *, int, uint8, uint8, uint8, int);
 
 
 /* FIXME */
-void med_hold_hack(struct context_data *ctx, int, int, int);
+void libxmp_med_hold_hack(struct context_data *ctx, int, int, int);
 
 #endif
diff --git a/src/filter.c b/src/filter.c
index c3437f2..9312d9d 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -24,143 +24,75 @@
  */
 
 #ifndef LIBXMP_CORE_DISABLE_IT
-
+#include 
 #include "xmp.h"
 #include "common.h"
 #include "mixer.h"
 
-static const float filter_cutoff[] = {
-	 130.8127899170F,  132.7154998779F,  134.6458892822F,  136.6043548584F,
-	 138.5913085938F,  140.6071777344F,  142.6523437500F,  144.7272796631F,
-	 146.8323822021F,  148.9681091309F,  151.1349029541F,  153.3332061768F,
-	 155.5634918213F,  157.8262176514F,  160.1218566895F,  162.4508819580F,
-	 164.8137817383F,  167.2110443115F,  169.6431884766F,  172.1107025146F,
-	 174.6141204834F,  177.1539306641F,  179.7306976318F,  182.3449401855F,
-	 184.9972076416F,  187.6880645752F,  190.4180450439F,  193.1877441406F,
-	 195.9977111816F,  198.8485717773F,  201.7408905029F,  204.6752777100F,
-	 207.6523437500F,  210.6727142334F,  213.7370300293F,  216.8459014893F,
-	 220.0000000000F,  223.1999664307F,  226.4464874268F,  229.7402343750F,
-	 233.0818786621F,  236.4721374512F,  239.9116973877F,  243.4012908936F,
-	 246.9416503906F,  250.5334930420F,  254.1775970459F,  257.8746948242F,
-	 261.6255798340F,  265.4309997559F,  269.2917785645F,  273.2087097168F,
-	 277.1826171875F,  281.2143554688F,  285.3046875000F,  289.4545593262F,
-	 293.6647644043F,  297.9362182617F,  302.2698059082F,  306.6664123535F,
-	 311.1269836426F,  315.6524353027F,  320.2437133789F,  324.9017639160F,
-	 329.6275634766F,  334.4220886230F,  339.2863769531F,  344.2214050293F,
-	 349.2282409668F,  354.3078613281F,  359.4613952637F,  364.6898803711F,
-	 369.9944152832F,  375.3761291504F,  380.8360900879F,  386.3754882812F,
-	 391.9954223633F,  397.6971435547F,  403.4817810059F,  409.3505554199F,
-	 415.3046875000F,  421.3454284668F,  427.4740600586F,  433.6918029785F,
-	 440.0000000000F,  446.3999328613F,  452.8929748535F,  459.4804687500F,
-	 466.1637573242F,  472.9442749023F,  479.8233947754F,  486.8025817871F,
-	 493.8833007812F,  501.0669860840F,  508.3551940918F,  515.7493896484F,
-	 523.2511596680F,  530.8619995117F,  538.5835571289F,  546.4174194336F,
-	 554.3652343750F,  562.4287109375F,  570.6093750000F,  578.9091186523F,
-	 587.3295288086F,  595.8724365234F,  604.5396118164F,  613.3328247070F,
-	 622.2539672852F,  631.3048706055F,  640.4874267578F,  649.8035278320F,
-	 659.2551269531F,  668.8441772461F,  678.5727539062F,  688.4428100586F,
-	 698.4564819336F,  708.6157226562F,  718.9227905273F,  729.3797607422F,
-	 739.9888305664F,  750.7522583008F,  761.6721801758F,  772.7509765625F,
-	 783.9908447266F,  795.3942871094F,  806.9635620117F,  818.7011108398F,
-	 830.6093750000F,  842.6908569336F,  854.9481201172F,  867.3836059570F,
-	 880.0000000000F,  892.7998657227F,  905.7859497070F,  918.9609375000F,
-	 932.3275146484F,  945.8885498047F,  959.6467895508F,  973.6051635742F,
-	 987.7666015625F, 1002.1339721680F, 1016.7103881836F, 1031.4987792969F,
-	1046.5023193359F, 1061.7239990234F, 1077.1671142578F, 1092.8348388672F,
-	1108.7304687500F, 1124.8574218750F, 1141.2187500000F, 1157.8182373047F,
-	1174.6590576172F, 1191.7448730469F, 1209.0792236328F, 1226.6656494141F,
-	1244.5079345703F, 1262.6097412109F, 1280.9748535156F, 1299.6070556641F,
-	1318.5102539062F, 1337.6883544922F, 1357.1455078125F, 1376.8856201172F,
-	1396.9129638672F, 1417.2314453125F, 1437.8455810547F, 1458.7595214844F,
-	1479.9776611328F, 1501.5045166016F, 1523.3443603516F, 1545.5019531250F,
-	1567.9816894531F, 1590.7885742188F, 1613.9271240234F, 1637.4022216797F,
-	1661.2187500000F, 1685.3817138672F, 1709.8962402344F, 1734.7672119141F,
-	1760.0000000000F, 1785.5997314453F, 1811.5718994141F, 1837.9218750000F,
-	1864.6550292969F, 1891.7770996094F, 1919.2935791016F, 1947.2103271484F,
-	1975.5332031250F, 2004.2679443359F, 2033.4207763672F, 2062.9975585938F,
-	2093.0046386719F, 2123.4479980469F, 2154.3342285156F, 2185.6696777344F,
-	2217.4609375000F, 2249.7148437500F, 2282.4375000000F, 2315.6364746094F,
-	2349.3181152344F, 2383.4897460938F, 2418.1584472656F, 2453.3312988281F,
-	2489.0158691406F, 2525.2194824219F, 2561.9497070312F, 2599.2141113281F,
-	2637.0205078125F, 2675.3767089844F, 2714.2910156250F, 2753.7712402344F,
-	2793.8259277344F, 2834.4628906250F, 2875.6911621094F, 2917.5190429688F,
-	2959.9553222656F, 3003.0090332031F, 3046.6887207031F, 3091.0039062500F,
-	3135.9633789062F, 3181.5771484375F, 3227.8542480469F, 3274.8044433594F,
-	3322.4375000000F, 3370.7634277344F, 3419.7924804688F, 3469.5344238281F,
-	3520.0000000000F, 3571.1994628906F, 3623.1437988281F, 3675.8437500000F,
-	3729.3100585938F, 3783.5541992188F, 3838.5871582031F, 3894.4206542969F,
-	3951.0664062500F, 4008.5358886719F, 4066.8415527344F, 4125.9951171875F,
-	4186.0092773438F, 4246.8959960938F, 4308.6684570312F, 4371.3393554688F,
-	4434.9218750000F, 4499.4296875000F, 4564.8750000000F, 4631.2729492188F,
-	4698.6362304688F, 4766.9794921875F, 4836.3168945312F, 4906.6625976562F,
-	4978.0317382812F, 5050.4389648438F, 5123.8994140625F, 5198.4282226562F
-};
 
-static const float dmpfac[] = {
-	1.0000000000F, 0.9812888503F, 0.9629278779F, 0.9449104071F,
-	0.9272300601F, 0.9098805189F, 0.8928556442F, 0.8761492968F,
-	0.8597555757F, 0.8436685801F, 0.8278825879F, 0.8123919964F,
-	0.7971912026F, 0.7822748423F, 0.7676376104F, 0.7532742620F,
-	0.7391796708F, 0.7253487706F, 0.7117766738F, 0.6984585524F,
-	0.6853895783F, 0.6725651622F, 0.6599807143F, 0.6476317644F,
-	0.6355138421F, 0.6236226559F, 0.6119539738F, 0.6005036235F,
-	0.5892674923F, 0.5782416463F, 0.5674220920F, 0.5568050146F,
-	0.5463865399F, 0.5361630321F, 0.5261308551F, 0.5162863135F,
-	0.5066260099F, 0.4971464872F, 0.4878443182F, 0.4787161946F,
-	0.4697588682F, 0.4609691501F, 0.4523439109F, 0.4438800514F,
-	0.4355745614F, 0.4274244606F, 0.4194268584F, 0.4115789235F,
-	0.4038778245F, 0.3963208199F, 0.3889051974F, 0.3816283345F,
-	0.3744876385F, 0.3674805760F, 0.3606045842F, 0.3538572788F,
-	0.3472362161F, 0.3407390118F, 0.3343634009F, 0.3281070888F,
-	0.3219678402F, 0.3159434497F, 0.3100318015F, 0.3042307496F,
-	0.2985382676F, 0.2929522693F, 0.2874708176F, 0.2820919156F,
-	0.2768136561F, 0.2716341615F, 0.2665515840F, 0.2615641057F,
-	0.2566699386F, 0.2518673539F, 0.2471546233F, 0.2425300926F,
-	0.2379920781F, 0.2335389853F, 0.2291692048F, 0.2248811871F,
-	0.2206734121F, 0.2165443599F, 0.2124925703F, 0.2085165977F,
-	0.2046150118F, 0.2007864416F, 0.1970295012F, 0.1933428496F,
-	0.1897251904F, 0.1861752123F, 0.1826916784F, 0.1792733073F,
-	0.1759189069F, 0.1726272553F, 0.1693972051F, 0.1662275940F,
-	0.1631172895F, 0.1600651890F, 0.1570701897F, 0.1541312188F,
-	0.1512472481F, 0.1484172493F, 0.1456401944F, 0.1429150999F,
-	0.1402409971F, 0.1376169324F, 0.1350419670F, 0.1325151771F,
-	0.1300356686F, 0.1276025623F, 0.1252149642F, 0.1228720546F,
-	0.1205729842F, 0.1183169261F, 0.1161030829F, 0.1139306650F,
-	0.1117988899F, 0.1097070053F, 0.1076542661F, 0.1056399345F,
-	0.1036632955F, 0.1017236337F, 0.0998202711F, 0.0979525223F,
-	0.0961197242F, 0.0943212137F, 0.0925563574F, 0.0908245221F
+/* LUT for 2 * damping factor */
+static const float resonance_table[128] = {
+        1.0000000000000000f, 0.9786446094512940f, 0.9577452540397644f, 0.9372922182083130f,
+        0.9172759056091309f, 0.8976871371269226f, 0.8785166740417481f, 0.8597555756568909f,
+        0.8413951396942139f, 0.8234267830848694f, 0.8058421611785889f, 0.7886331081390381f,
+        0.7717915177345276f, 0.7553095817565918f, 0.7391796708106995f, 0.7233941555023193f,
+        0.7079457640647888f, 0.6928272843360901f, 0.6780316829681397f, 0.6635520458221436f,
+        0.6493816375732422f, 0.6355138421058655f, 0.6219421625137329f, 0.6086603403091431f,
+        0.5956621170043945f, 0.5829415321350098f, 0.5704925656318665f, 0.5583094954490662f,
+        0.5463865399360657f, 0.5347182154655457f, 0.5232990980148315f, 0.5121238231658936f,
+        0.5011872053146362f, 0.4904841780662537f, 0.4800096750259399f, 0.4697588682174683f,
+        0.4597269892692566f, 0.4499093294143677f, 0.4403013288974762f, 0.4308985173702240f,
+        0.4216965138912201f, 0.4126909971237183f, 0.4038778245449066f, 0.3952528536319733f,
+        0.3868120610713959f, 0.3785515129566193f, 0.3704673945903778f, 0.3625559210777283f,
+        0.3548133969306946f, 0.3472362160682678f, 0.3398208320140839f, 0.3325638175010681f,
+        0.3254617750644684f, 0.3185114264488220f, 0.3117094635963440f, 0.3050527870655060f,
+        0.2985382676124573f, 0.2921628654003143f, 0.2859236001968384f, 0.2798175811767578f,
+        0.2738419771194458f, 0.2679939568042755f, 0.2622708380222321f, 0.2566699385643005f,
+        0.2511886358261108f, 0.2458244115114212f, 0.2405747324228287f, 0.2354371547698975f,
+        0.2304092943668366f, 0.2254888117313385f, 0.2206734120845795f, 0.2159608304500580f,
+        0.2113489061594009f, 0.2068354636430740f, 0.2024184018373489f, 0.1980956792831421f,
+        0.1938652694225311f, 0.1897251904010773f, 0.1856735348701477f, 0.1817083954811096f,
+        0.1778279393911362f, 0.1740303486585617f, 0.1703138649463654f, 0.1666767448186874f,
+        0.1631172895431519f, 0.1596338599920273f, 0.1562248021364212f, 0.1528885662555695f,
+        0.1496235728263855f, 0.1464282870292664f, 0.1433012634515762f, 0.1402409970760346f,
+        0.1372461020946503f, 0.1343151479959488f, 0.1314467936754227f, 0.1286396980285645f,
+        0.1258925348520279f, 0.1232040524482727f, 0.1205729842185974f, 0.1179980933666229f,
+        0.1154781952500343f, 0.1130121126770973f, 0.1105986908078194f, 0.1082368120551109f,
+        0.1059253737330437f, 0.1036632955074310f, 0.1014495193958283f, 0.0992830246686935f,
+        0.0971627980470657f, 0.0950878411531448f, 0.0930572077631950f, 0.0910699293017387f,
+        0.0891250967979431f, 0.0872217938303947f, 0.0853591337800026f, 0.0835362523794174f,
+        0.0817523002624512f, 0.0800064504146576f, 0.0782978758215904f, 0.0766257941722870f,
+        0.0749894231557846f, 0.0733879879117012f, 0.0718207582831383f, 0.0702869966626167f,
+        0.0687859877943993f, 0.0673170387744904f, 0.0658794566988945f, 0.0644725710153580f,
 };
 
 
 /*
  * Simple 2-poles resonant filter
  */
-void filter_setup(int srate, int cutoff, int res, int *a0, int *b0, int *b1)
+#define FREQ_PARAM_MULT (128.0f / (24.0f * 256.0f))
+void libxmp_filter_setup(int srate, int cutoff, int res, int *a0, int *b0, int *b1)
 {
 	float fc, fs = (float)srate;
 	float fg, fb0, fb1;
-	float d2, d, e;
+	float r, d, e;
 
 	/* [0-255] => [100Hz-8000Hz] */
 	CLAMP(cutoff, 0, 255);
-
 	CLAMP(res, 0, 255);
 
-	fc = filter_cutoff[cutoff];
-
-	fc *= 3.14159265358979 * 2 / fs;
-	d2 = dmpfac[res >> 1];
-	d = (1.0 - d2) * fc;
-
-	if (d > 2.0)
-		d = 2.0;
+        fc = 110.0f * powf(2.0f, (float)cutoff * FREQ_PARAM_MULT + 0.25f);
+        if (fc > fs / 2.0f) {
+                fc = fs / 2.0f;
+	}
 
-	e = 1.0 / (fc * fc);
-	d = (d2 - d) / fc + e;
+        r = fs / (2.0 * 3.14159265358979f * fc);
+        d = resonance_table[res >> 1] * (r + 1.0) - 1.0;
+        e = r * r;
 
-	fg  = 1.0 / (1 + d);
-	fb0 = (d + e) / (1 + d);
-	fb1 = -e / (1 + d);
+        fg = 1.0 / (1.0 + d + e);
+        fb0 = (d + e + e) / (1.0 + d + e);
+        fb1 = -e / (1.0 + d + e);
 
 	*a0 = (int)(fg  * (1 << FILTER_SHIFT));
 	*b0 = (int)(fb0 * (1 << FILTER_SHIFT));
diff --git a/src/fmopl.c b/src/fmopl.c
index 735ca72..2a2cb15 100644
--- a/src/fmopl.c
+++ b/src/fmopl.c
@@ -590,7 +590,7 @@ static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
 		OPL->AR_TABLE[i] = rate / ARRATE;
 		OPL->DR_TABLE[i] = rate / DRRATE;
 	}
-	for (i = 60;i < 76;i++)
+	for (i = 60;i < 75;i++)
 	{
 		OPL->AR_TABLE[i] = EG_AED-1;
 		OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
@@ -706,7 +706,7 @@ static void OPLCloseTable( OPL_STATE *ST )
 	free(ST->VIB_TABLE);
 }
 
-#ifndef XMP_OPL_CSM
+#ifdef XMP_OPL_CSM
 /* CSM Key Controll */
 INLINE void CSMKeyControll(OPL_CH *CH)
 {
@@ -1044,7 +1044,7 @@ static void OPL_UnLockTable( OPL_STATE *ST )
 
 /*** Prototype changed to use with xmp ***/
 /* ---------- update one of chip ----------- */
-void YM3812UpdateOne(FM_OPL *OPL, FMSAMPLE *bk, int len, int vl, int vr, int st)
+void YM3812UpdateOne(FM_OPL *OPL, FMSAMPLE *bk, int len, int st)
 {
 	int data;
 	UINT32 amsCnt  = OPL->amsCnt;
@@ -1089,8 +1089,8 @@ void YM3812UpdateOne(FM_OPL *OPL, FMSAMPLE *bk, int len, int vl, int vr, int st)
 
 		/* store to sound buffer - changed to use with xmp */
 		if (st) 
-			*(bk++) += data * vr;
-		*(bk++) += data * vl;
+			*(bk++) += data << 10;
+		*(bk++) += data << 10;
 	}
 
 	OPL->amsCnt = amsCnt;
diff --git a/src/fmopl.h b/src/fmopl.h
index a651d8b..7fa3da0 100644
--- a/src/fmopl.h
+++ b/src/fmopl.h
@@ -200,7 +200,7 @@ unsigned char OPLRead(FM_OPL *OPL,int a);
 int OPLTimerOver(FM_OPL *OPL,int c);
 
 /* YM3626/YM3812 local section - changed to use with xmp */
-void YM3812UpdateOne(FM_OPL *OPL, FMSAMPLE *bk, int len, int st, int vl, int vr);
+void YM3812UpdateOne(FM_OPL *OPL, FMSAMPLE *bk, int len, int st);
 
 void Y8950UpdateOne(FM_OPL *OPL, void *buffer, int length);
 
diff --git a/src/format.c b/src/format.c
index 9426fa3..8632529 100644
--- a/src/format.c
+++ b/src/format.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include 
@@ -11,134 +25,134 @@
 #include "loaders/prowizard/prowiz.h"
 #include "format.h"
 
-extern const struct format_loader xm_loader;
-extern const struct format_loader mod_loader;
-extern const struct format_loader flt_loader;
-extern const struct format_loader st_loader;
-extern const struct format_loader it_loader;
-extern const struct format_loader s3m_loader;
-extern const struct format_loader stm_loader;
-extern const struct format_loader stx_loader;
-extern const struct format_loader mtm_loader;
-extern const struct format_loader ice_loader;
-extern const struct format_loader imf_loader;
-extern const struct format_loader ptm_loader;
-extern const struct format_loader mdl_loader;
-extern const struct format_loader ult_loader;
-extern const struct format_loader liq_loader;
-extern const struct format_loader no_loader;
-extern const struct format_loader masi_loader;
-extern const struct format_loader gal5_loader;
-extern const struct format_loader gal4_loader;
-extern const struct format_loader psm_loader;
-extern const struct format_loader amf_loader;
-extern const struct format_loader asylum_loader;
-extern const struct format_loader gdm_loader;
-extern const struct format_loader mmd1_loader;
-extern const struct format_loader mmd3_loader;
-extern const struct format_loader med2_loader;
-extern const struct format_loader med3_loader;
-extern const struct format_loader med4_loader;
-/* extern const struct format_loader dmf_loader; */
-extern const struct format_loader rtm_loader;
-extern const struct format_loader pt3_loader;
-/* extern const struct format_loader tcb_loader; */
-extern const struct format_loader dt_loader;
-/* extern const struct format_loader gtk_loader; */
-/* extern const struct format_loader dtt_loader; */
-extern const struct format_loader mgt_loader;
-extern const struct format_loader arch_loader;
-extern const struct format_loader sym_loader;
-extern const struct format_loader digi_loader;
-extern const struct format_loader dbm_loader;
-extern const struct format_loader emod_loader;
-extern const struct format_loader okt_loader;
-extern const struct format_loader sfx_loader;
-extern const struct format_loader far_loader;
-extern const struct format_loader umx_loader;
-extern const struct format_loader stim_loader;
-/* extern const struct format_loader coco_loader; */
-/* extern const struct format_loader mtp_loader; */
-extern const struct format_loader ims_loader;
-extern const struct format_loader ssn_loader;
-extern const struct format_loader fnk_loader;
-extern const struct format_loader amd_loader;
-extern const struct format_loader rad_loader;
-extern const struct format_loader hsc_loader;
-extern const struct format_loader mfp_loader;
-/* extern const struct format_loader alm_loader; */
-/* extern const struct format_loader polly_loader; */
-/* extern const struct format_loader stc_loader; */
-extern const struct format_loader pw_loader;
-extern const struct format_loader hmn_loader;
-extern const struct format_loader chip_loader;
-extern const struct format_loader abk_loader;
+extern const struct format_loader libxmp_loader_xm;
+extern const struct format_loader libxmp_loader_mod;
+extern const struct format_loader libxmp_loader_flt;
+extern const struct format_loader libxmp_loader_st;
+extern const struct format_loader libxmp_loader_it;
+extern const struct format_loader libxmp_loader_s3m;
+extern const struct format_loader libxmp_loader_stm;
+extern const struct format_loader libxmp_loader_stx;
+extern const struct format_loader libxmp_loader_mtm;
+extern const struct format_loader libxmp_loader_ice;
+extern const struct format_loader libxmp_loader_imf;
+extern const struct format_loader libxmp_loader_ptm;
+extern const struct format_loader libxmp_loader_mdl;
+extern const struct format_loader libxmp_loader_ult;
+extern const struct format_loader libxmp_loader_liq;
+extern const struct format_loader libxmp_loader_no;
+extern const struct format_loader libxmp_loader_masi;
+extern const struct format_loader libxmp_loader_gal5;
+extern const struct format_loader libxmp_loader_gal4;
+extern const struct format_loader libxmp_loader_psm;
+extern const struct format_loader libxmp_loader_amf;
+extern const struct format_loader libxmp_loader_asylum;
+extern const struct format_loader libxmp_loader_gdm;
+extern const struct format_loader libxmp_loader_mmd1;
+extern const struct format_loader libxmp_loader_mmd3;
+extern const struct format_loader libxmp_loader_med2;
+extern const struct format_loader libxmp_loader_med3;
+extern const struct format_loader libxmp_loader_med4;
+/* extern const struct format_loader libxmp_loader_dmf; */
+extern const struct format_loader libxmp_loader_rtm;
+extern const struct format_loader libxmp_loader_pt3;
+/* extern const struct format_loader libxmp_loader_tcb; */
+extern const struct format_loader libxmp_loader_dt;
+/* extern const struct format_loader libxmp_loader_gtk; */
+/* extern const struct format_loader libxmp_loader_dtt; */
+extern const struct format_loader libxmp_loader_mgt;
+extern const struct format_loader libxmp_loader_arch;
+extern const struct format_loader libxmp_loader_sym;
+extern const struct format_loader libxmp_loader_digi;
+extern const struct format_loader libxmp_loader_dbm;
+extern const struct format_loader libxmp_loader_emod;
+extern const struct format_loader libxmp_loader_okt;
+extern const struct format_loader libxmp_loader_sfx;
+extern const struct format_loader libxmp_loader_far;
+extern const struct format_loader libxmp_loader_umx;
+extern const struct format_loader libxmp_loader_stim;
+/* extern const struct format_loader libxmp_loader_coco; */
+/* extern const struct format_loader libxmp_loader_mtp; */
+extern const struct format_loader libxmp_loader_ims;
+extern const struct format_loader libxmp_loader_669;
+extern const struct format_loader libxmp_loader_fnk;
+/* extern const struct format_loader libxmp_loader_amd; */
+/* extern const struct format_loader libxmp_loader_rad; */
+/* extern const struct format_loader libxmp_loader_hsc; */
+extern const struct format_loader libxmp_loader_mfp;
+/* extern const struct format_loader libxmp_loader_alm; */
+/* extern const struct format_loader libxmp_loader_polly; */
+/* extern const struct format_loader libxmp_loader_stc; */
+extern const struct format_loader libxmp_loader_pw;
+extern const struct format_loader libxmp_loader_hmn;
+extern const struct format_loader libxmp_loader_chip;
+extern const struct format_loader libxmp_loader_abk;
 
 extern const struct pw_format *const pw_format[];
 
 const struct format_loader *const format_loader[NUM_FORMATS + 2] = {
-	&xm_loader,
-	&mod_loader,
-	&flt_loader,
-	&st_loader,
-	&it_loader,
-	&s3m_loader,
-	&stm_loader,
-	&stx_loader,
-	&mtm_loader,
-	&ice_loader,
-	&imf_loader,
-	&ptm_loader,
-	&mdl_loader,
-	&ult_loader,
-	&liq_loader,
-	&no_loader,
-	&masi_loader,
-	&gal5_loader,
-	&gal4_loader,
-	&psm_loader,
-	&amf_loader,
-	&asylum_loader,
-	&gdm_loader,
-	&mmd1_loader,
-	&mmd3_loader,
-	&med2_loader,
-	&med3_loader,
-	&med4_loader,
-	/* &dmf_loader, */
-	&chip_loader,
-	&rtm_loader,
-	&pt3_loader,
-	/* &tcb_loader, */
-	&dt_loader,
-	/* >k_loader, */
-	/* &dtt_loader, */
-	&mgt_loader,
-	&arch_loader,
-	&sym_loader,
-	&digi_loader,
-	&dbm_loader,
-	&emod_loader,
-	&okt_loader,
-	&sfx_loader,
-	&far_loader,
-	&umx_loader,
-	&hmn_loader,
-	&stim_loader,
-	/* &coco_loader, */
-	/* &mtp_loader, */
-	&ims_loader,
-	&ssn_loader,
-	&fnk_loader,
-	&amd_loader,
-	&rad_loader,
-	&hsc_loader,
-	&mfp_loader,
-	&abk_loader,
-	/* &alm_loader, */
-	/* &polly_loader, */
-	/* &stc_loader, */
-	&pw_loader,
+	&libxmp_loader_xm,
+	&libxmp_loader_mod,
+	&libxmp_loader_flt,
+	&libxmp_loader_st,
+	&libxmp_loader_it,
+	&libxmp_loader_s3m,
+	&libxmp_loader_stm,
+	&libxmp_loader_stx,
+	&libxmp_loader_mtm,
+	&libxmp_loader_ice,
+	&libxmp_loader_imf,
+	&libxmp_loader_ptm,
+	&libxmp_loader_mdl,
+	&libxmp_loader_ult,
+	&libxmp_loader_liq,
+	&libxmp_loader_no,
+	&libxmp_loader_masi,
+	&libxmp_loader_gal5,
+	&libxmp_loader_gal4,
+	&libxmp_loader_psm,
+	&libxmp_loader_amf,
+	&libxmp_loader_asylum,
+	&libxmp_loader_gdm,
+	&libxmp_loader_mmd1,
+	&libxmp_loader_mmd3,
+	&libxmp_loader_med2,
+	&libxmp_loader_med3,
+	&libxmp_loader_med4,
+	/* &libxmp_loader_dmf, */
+	&libxmp_loader_chip,
+	&libxmp_loader_rtm,
+	&libxmp_loader_pt3,
+	/* &libxmp_loader_tcb, */
+	&libxmp_loader_dt,
+	/* &libxmp_loader_gtk, */
+	/* &libxmp_loader_dtt, */
+	&libxmp_loader_mgt,
+	&libxmp_loader_arch,
+	&libxmp_loader_sym,
+	&libxmp_loader_digi,
+	&libxmp_loader_dbm,
+	&libxmp_loader_emod,
+	&libxmp_loader_okt,
+	&libxmp_loader_sfx,
+	&libxmp_loader_far,
+	&libxmp_loader_umx,
+	&libxmp_loader_hmn,
+	&libxmp_loader_stim,
+	/* &libxmp_loader_coco, */
+	/* &libxmp_loader_mtp, */
+	&libxmp_loader_ims,
+	&libxmp_loader_669,
+	&libxmp_loader_fnk,
+	/* &libxmp_loader_amd, */
+	/* &libxmp_loader_rad, */
+	/* &libxmp_loader_hsc, */
+	&libxmp_loader_mfp,
+	&libxmp_loader_abk,
+	/* &libxmp_loader_alm, */
+	/* &libxmp_loader_polly, */
+	/* &libxmp_loader_stc, */
+	&libxmp_loader_pw,
 	NULL
 };
 
diff --git a/src/format.h b/src/format.h
index efb9d02..4d90458 100644
--- a/src/format.h
+++ b/src/format.h
@@ -16,9 +16,9 @@ char **format_list(void);
 #ifndef LIBXMP_CORE_PLAYER
 
 #define NUM_FORMATS 52
-#define NUM_PW_FORMATS 39
+#define NUM_PW_FORMATS 43
 
-int pw_test_format(FILE *, char *, const int, struct xmp_test_info *);
+int pw_test_format(HIO_HANDLE *, char *, const int, struct xmp_test_info *);
 #endif
 
 #endif
diff --git a/src/hio.c b/src/hio.c
index 4fc4bf4..2a354aa 100644
--- a/src/hio.c
+++ b/src/hio.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -22,148 +22,258 @@
 
 #include 
 #include 
-#ifndef LIBXMP_CORE_PLAYER
-#include 
-#include 
-#include 
-#endif
 #include 
 #include 
 #include "common.h"
 #include "hio.h"
 #include "mdataio.h"
 
+static long get_size(FILE *f)
+{
+	long size, pos;
+
+	pos = ftell(f);
+	if (pos >= 0) {
+		if (fseek(f, 0, SEEK_END) < 0) {
+			return -1;
+		}
+		size = ftell(f);
+		if (fseek(f, pos, SEEK_SET) < 0) {
+			return -1;
+		}
+		return size;
+	} else {
+		return pos;
+	}
+}
 
 int8 hio_read8s(HIO_HANDLE *h)
 {
+	int err;
+	int8 ret = 0;
+
 	switch (HIO_HANDLE_TYPE(h)) {
 	case HIO_HANDLE_TYPE_FILE:
-		return read8s(h->handle.file);
+		ret = read8s(h->handle.file, &err);
+		if (err != 0) {
+			h->error = err;
+		}
+		break;
 	case HIO_HANDLE_TYPE_MEMORY:
-		return mread8s(h->handle.mem);
-	default:
-		return 0;
+		ret = mread8s(h->handle.mem);
+		break;
 	}
+
+	return ret;
 }
 
 uint8 hio_read8(HIO_HANDLE *h)
 {
+	int err;
+	uint8 ret = 0;
+
 	switch (HIO_HANDLE_TYPE(h)) {
 	case HIO_HANDLE_TYPE_FILE:
-		return read8(h->handle.file);
+		ret = read8(h->handle.file, &err);
+		if (err != 0) {
+			h->error = err;
+		}
+		break;
 	case HIO_HANDLE_TYPE_MEMORY:
-		return mread8(h->handle.mem);
-	default:
-		return 0;
+		ret = mread8(h->handle.mem);
+		break;
 	}
+
+	return ret;
 }
 
 uint16 hio_read16l(HIO_HANDLE *h)
 {
+	int err;
+	uint16 ret = 0;
+
 	switch (HIO_HANDLE_TYPE(h)) {
 	case HIO_HANDLE_TYPE_FILE:
-		return read16l(h->handle.file);
+		ret = read16l(h->handle.file, &err);
+		if (err != 0) {
+			h->error = err;
+		}
+		break;
 	case HIO_HANDLE_TYPE_MEMORY:
-		return mread16l(h->handle.mem);
-	default:
-		return 0;
+		ret = mread16l(h->handle.mem);
+		break;
 	}
+
+	return ret;
 }
 
 uint16 hio_read16b(HIO_HANDLE *h)
 {
+	int err;
+	uint16 ret = 0;
+
 	switch (HIO_HANDLE_TYPE(h)) {
 	case HIO_HANDLE_TYPE_FILE:
-		return read16b(h->handle.file);
+		ret = read16b(h->handle.file, &err);
+		if (err != 0) {
+			h->error = err;
+		}
+		break;
 	case HIO_HANDLE_TYPE_MEMORY:
-		return mread16b(h->handle.mem);
-	default:
-		return 0;
+		ret = mread16b(h->handle.mem);
+		break;
 	}
+
+	return ret;
 }
 
 uint32 hio_read24l(HIO_HANDLE *h)
 {
+	int err;
+	uint32 ret = 0;
+
 	switch (HIO_HANDLE_TYPE(h)) {
 	case HIO_HANDLE_TYPE_FILE:
-		return read24l(h->handle.file); 
+		ret = read24l(h->handle.file, &err); 
+		if (err != 0) {
+			h->error = err;
+		}
+		break;
 	case HIO_HANDLE_TYPE_MEMORY:
-		return mread24l(h->handle.mem); 
-	default:
-		return 0;
+		ret = mread24l(h->handle.mem); 
+		break;
 	}
+
+	return ret;
 }
 
 uint32 hio_read24b(HIO_HANDLE *h)
 {
+	int err;
+	uint32 ret = 0;
+
 	switch (HIO_HANDLE_TYPE(h)) {
 	case HIO_HANDLE_TYPE_FILE:
-		return read24b(h->handle.file);
+		ret = read24b(h->handle.file, &err);
+		if (err != 0) {
+			h->error = err;
+		}
+		break;
 	case HIO_HANDLE_TYPE_MEMORY:
-		return mread24b(h->handle.mem);
-	default:
-		return 0;
+		ret = mread24b(h->handle.mem);
+		break;
 	}
+
+	return ret;
 }
 
 uint32 hio_read32l(HIO_HANDLE *h)
 {
+	int err;
+	uint32 ret = 0;
+
 	switch (HIO_HANDLE_TYPE(h)) {
 	case HIO_HANDLE_TYPE_FILE:
-		return read32l(h->handle.file);
+		ret = read32l(h->handle.file, &err);
+		if (err != 0) {
+			h->error = err;
+		}
+		break;
 	case HIO_HANDLE_TYPE_MEMORY:
-		return mread32l(h->handle.mem);
-	default:
-		return 0;
+		ret = mread32l(h->handle.mem);
+		break;
 	}
+
+	return ret;
 }
 
 uint32 hio_read32b(HIO_HANDLE *h)
 {
+	int err;
+	uint32 ret = 0;
+
 	switch (HIO_HANDLE_TYPE(h)) {
 	case HIO_HANDLE_TYPE_FILE:
-		return read32b(h->handle.file);
+		ret = read32b(h->handle.file, &err);
+		if (err != 0) {
+			h->error = err;
+		}
+		break;
 	case HIO_HANDLE_TYPE_MEMORY:
-		return mread32b(h->handle.mem);
-	default:
-		return 0;
+		ret = mread32b(h->handle.mem);
 	}
+
+	return ret;
 }
 
 size_t hio_read(void *buf, size_t size, size_t num, HIO_HANDLE *h)
 {
+	size_t ret = 0;
+
 	switch (HIO_HANDLE_TYPE(h)) {
 	case HIO_HANDLE_TYPE_FILE:
-		return fread(buf, size, num, h->handle.file);
+		ret = fread(buf, size, num, h->handle.file);
+		if (ret != num) {
+			if (ferror(h->handle.file)) {
+				h->error = errno;
+			} else {
+				h->error = feof(h->handle.file) ? EOF : -2;
+			}
+		}
+		break;
 	case HIO_HANDLE_TYPE_MEMORY:
-		return mread(buf, size, num, h->handle.mem);
-	default:
-		return 0;
+		ret = mread(buf, size, num, h->handle.mem);
+		if (ret != num) {
+			h->error = errno;
+		}
+		break;
 	}
+
+	return ret;
 }
 
 int hio_seek(HIO_HANDLE *h, long offset, int whence)
 {
+	int ret = -1;
+
 	switch (HIO_HANDLE_TYPE(h)) {
 	case HIO_HANDLE_TYPE_FILE:
-		return fseek(h->handle.file, offset, whence);
+		ret = fseek(h->handle.file, offset, whence);
+		if (ret < 0) {
+			h->error = errno;
+		}
+		break;
 	case HIO_HANDLE_TYPE_MEMORY:
-		return mseek(h->handle.mem, offset, whence);
-	default:
-		return -1;
+		ret = mseek(h->handle.mem, offset, whence);
+		if (ret < 0) {
+			h->error = errno;
+		}
+		break;
 	}
+
+	return ret;
 }
 
 long hio_tell(HIO_HANDLE *h)
 {
+	long ret = -1;
+
 	switch (HIO_HANDLE_TYPE(h)) {
 	case HIO_HANDLE_TYPE_FILE:
-		return ftell(h->handle.file);
+		ret = ftell(h->handle.file);
+		if (ret < 0) {
+			h->error = errno;
+		}
+		break;
 	case HIO_HANDLE_TYPE_MEMORY:
-		return mtell(h->handle.mem);
-	default:
-		return -1;
+		ret = mtell(h->handle.mem);
+		if (ret < 0) {
+			h->error = errno;
+		}
+		break;
 	}
+
+	return ret;
 }
 
 int hio_eof(HIO_HANDLE *h)
@@ -178,6 +288,13 @@ int hio_eof(HIO_HANDLE *h)
 	}
 }
 
+int hio_error(HIO_HANDLE *h)
+{
+	int error = h->error;
+	h->error = 0;
+	return error;
+}
+
 HIO_HANDLE *hio_open(void *path, char *mode)
 {
 	HIO_HANDLE *h;
@@ -186,13 +303,20 @@ HIO_HANDLE *hio_open(void *path, char *mode)
 	if (h == NULL)
 		goto err;
 	
+	h->error = 0;
 	h->type = HIO_HANDLE_TYPE_FILE;
 	h->handle.file = fopen(path, mode);
 	if (h->handle.file == NULL)
 		goto err2;
 
+	h->size = get_size(h->handle.file);
+	if (h->size < 0)
+		goto err3;
+
 	return h;
 
+    err3:
+	fclose(h->handle.file);
     err2:
 	free(h);
     err:
@@ -207,8 +331,10 @@ HIO_HANDLE *hio_open_mem(void *ptr, long size)
 	if (h == NULL)
 		return NULL;
 	
+	h->error = 0;
 	h->type = HIO_HANDLE_TYPE_MEMORY;
 	h->handle.mem = mopen(ptr, size);
+	h->size = size;
 
 	return h;
 }
@@ -221,8 +347,10 @@ HIO_HANDLE *hio_open_file(FILE *f)
 	if (h == NULL)
 		return NULL;
 	
+	h->error = 0;
 	h->type = HIO_HANDLE_TYPE_FILE;
-	h->handle.file = fdopen(fileno(f), "rb");
+	h->handle.file = f /*fdopen(fileno(f), "rb")*/;
+	h->size = get_size(f);
 
 	return h;
 }
@@ -246,37 +374,7 @@ int hio_close(HIO_HANDLE *h)
 	return ret;
 }
 
-#ifndef LIBXMP_CORE_PLAYER
-
-HIO_HANDLE *hio_open_fd(int fd, char *mode)
+long hio_size(HIO_HANDLE *h)
 {
-	HIO_HANDLE *h;
-	
-	h = (HIO_HANDLE *)malloc(sizeof (HIO_HANDLE));
-	if (h == NULL)
-		return NULL;
-	
-	h->type = HIO_HANDLE_TYPE_FILE;
-	h->handle.file = fdopen(fd, mode);
-	if (h->handle.file == NULL) {
-		free(h);
-		return NULL;
-	}
-
-	return h;
+	return h->size;
 }
-
-int hio_stat(HIO_HANDLE *h, struct stat *st)
-{
-	switch (HIO_HANDLE_TYPE(h)) {
-	case HIO_HANDLE_TYPE_FILE:
-		return fstat(fileno(h->handle.file), st);
-	case HIO_HANDLE_TYPE_MEMORY:
-		return mstat(h->handle.mem, st);
-	default:
-		return -1;
-	}
-}
-
-#endif
-
diff --git a/src/hio.h b/src/hio.h
index 590d898..1411667 100644
--- a/src/hio.h
+++ b/src/hio.h
@@ -12,10 +12,12 @@ typedef struct {
 #define HIO_HANDLE_TYPE_FILE	0
 #define HIO_HANDLE_TYPE_MEMORY	1
 	int type;
+	long size;
 	union {
 		FILE *file;
 		MFILE *mem;
 	} handle;
+	int error;
 } HIO_HANDLE;
 
 int8	hio_read8s	(HIO_HANDLE *);
@@ -30,11 +32,11 @@ size_t	hio_read	(void *, size_t, size_t, HIO_HANDLE *);
 int	hio_seek	(HIO_HANDLE *, long, int);
 long	hio_tell	(HIO_HANDLE *);
 int	hio_eof		(HIO_HANDLE *);
+int	hio_error	(HIO_HANDLE *);
 HIO_HANDLE *hio_open	(void *, char *);
 HIO_HANDLE *hio_open_mem  (void *, long);
-HIO_HANDLE *hio_open_fd	  (int, char *);
 HIO_HANDLE *hio_open_file (FILE *);
 int	hio_close	(HIO_HANDLE *);
-int	hio_stat	(HIO_HANDLE *, struct stat *);
+long	hio_size	(HIO_HANDLE *);
 
 #endif
diff --git a/src/hmn_extras.c b/src/hmn_extras.c
index bae17b4..711904b 100644
--- a/src/hmn_extras.c
+++ b/src/hmn_extras.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include 
@@ -34,20 +48,20 @@ static uint8 megaarp[16][16] = {
 };
 
 
-int hmn_linear_bend(struct context_data *ctx, struct channel_data *xc)
+int libxmp_hmn_linear_bend(struct context_data *ctx, struct channel_data *xc)
 {
 	return 0;
 }
 
-void hmn_play_extras(struct context_data *ctx, struct channel_data *xc,
-			int chn, int t)
+void libxmp_hmn_play_extras(struct context_data *ctx, struct channel_data *xc, int chn)
 {
+	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
 	struct hmn_channel_extras *ce = xc->extra;
 	struct xmp_instrument *xxi;
 	int pos, waveform, volume;
 
-	if (t == 0 && TEST(NEW_NOTE|NEW_INS)) {
+	if (p->frame == 0 && TEST(NEW_NOTE|NEW_INS)) {
 		ce->datapos = 0;
 	}
 
@@ -58,7 +72,7 @@ void hmn_play_extras(struct context_data *ctx, struct channel_data *xc,
 
 	if (waveform < xxi->nsm && xxi->sub[waveform].sid != xc->smp) {
 		xc->smp = xxi->sub[waveform].sid;
-		virt_setsmp(ctx, chn, xc->smp);
+		libxmp_virt_setsmp(ctx, chn, xc->smp);
 	}
 
 	pos++;
@@ -69,7 +83,7 @@ void hmn_play_extras(struct context_data *ctx, struct channel_data *xc,
 	ce->volume = volume;
 }
 
-int hmn_new_instrument_extras(struct xmp_instrument *xxi)
+int libxmp_hmn_new_instrument_extras(struct xmp_instrument *xxi)
 {
 	xxi->extra = calloc(1, sizeof(struct hmn_instrument_extras));
 	if (xxi->extra == NULL)
@@ -79,7 +93,7 @@ int hmn_new_instrument_extras(struct xmp_instrument *xxi)
 	return 0;
 }
 
-int hmn_new_channel_extras(struct channel_data *xc)
+int libxmp_hmn_new_channel_extras(struct channel_data *xc)
 {
 	xc->extra = calloc(1, sizeof(struct hmn_channel_extras));
 	if (xc->extra == NULL)
@@ -89,17 +103,17 @@ int hmn_new_channel_extras(struct channel_data *xc)
 	return 0;
 }
 
-void hmn_reset_channel_extras(struct channel_data *xc)
+void libxmp_hmn_reset_channel_extras(struct channel_data *xc)
 {
 	memset((char *)xc->extra + 4, 0, sizeof(struct hmn_channel_extras) - 4);
 }
 
-void hmn_release_channel_extras(struct channel_data *xc)
+void libxmp_hmn_release_channel_extras(struct channel_data *xc)
 {
 	free(xc->extra);
 }
 
-int hmn_new_module_extras(struct module_data *m)
+int libxmp_hmn_new_module_extras(struct module_data *m)
 {
 	m->extra = calloc(1, sizeof(struct hmn_module_extras));
 	if (m->extra == NULL)
@@ -109,12 +123,12 @@ int hmn_new_module_extras(struct module_data *m)
 	return 0;
 }
 
-void hmn_release_module_extras(struct module_data *m)
+void libxmp_hmn_release_module_extras(struct module_data *m)
 {
 	free(m->extra);
 }
 
-void hmn_extras_process_fx(struct context_data *ctx, struct channel_data *xc,
+void libxmp_hmn_extras_process_fx(struct context_data *ctx, struct channel_data *xc,
 			   int chn, uint8 note, uint8 fxt, uint8 fxp, int fnum)
 {
 	switch (fxt) {
diff --git a/src/hmn_extras.h b/src/hmn_extras.h
index 379549f..ab739d2 100644
--- a/src/hmn_extras.h
+++ b/src/hmn_extras.h
@@ -36,16 +36,16 @@ struct hmn_module_extras {
 	(HMN_MODULE_EXTRAS(x) != NULL && \
 	 HMN_MODULE_EXTRAS(x)->magic == HMN_EXTRAS_MAGIC)
 
-void hmn_play_extras(struct context_data *, struct channel_data *, int, int);
-void hmn_set_arpeggio(struct channel_data *, int);
-int hmn_linear_bend(struct context_data *, struct channel_data *);
-int hmn_new_instrument_extras(struct xmp_instrument *);
-int hmn_new_channel_extras(struct channel_data *);
-void hmn_reset_channel_extras(struct channel_data *);
-void hmn_release_channel_extras(struct channel_data *);
-int hmn_new_module_extras(struct module_data *);
-void hmn_release_module_extras(struct module_data *);
-void hmn_extras_process_fx(struct context_data *, struct channel_data *, int, uint8, uint8, uint8, int);
+void libxmp_hmn_play_extras(struct context_data *, struct channel_data *, int);
+void libxmp_hmn_set_arpeggio(struct channel_data *, int);
+int  libxmp_hmn_linear_bend(struct context_data *, struct channel_data *);
+int  libxmp_hmn_new_instrument_extras(struct xmp_instrument *);
+int  libxmp_hmn_new_channel_extras(struct channel_data *);
+void libxmp_hmn_reset_channel_extras(struct channel_data *);
+void libxmp_hmn_release_channel_extras(struct channel_data *);
+int  libxmp_hmn_new_module_extras(struct module_data *);
+void libxmp_hmn_release_module_extras(struct module_data *);
+void libxmp_hmn_extras_process_fx(struct context_data *, struct channel_data *, int, uint8, uint8, uint8, int);
 
 #endif
 
diff --git a/src/lfo.c b/src/lfo.c
index 55f072e..5cdf4fb 100644
--- a/src/lfo.c
+++ b/src/lfo.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -36,11 +36,11 @@ static const int sine_wave[WAVEFORM_SIZE] = {
 
 /* LFO */
 
-int get_lfo(struct lfo *lfo, int div)
+static int get_lfo_mod(struct lfo *lfo)
 {
 	int val;
 
-	if (lfo->rate == 0 || div == 0)
+	if (lfo->rate == 0)
 		return 0;
 
 	switch (lfo->type) {
@@ -56,38 +56,109 @@ int get_lfo(struct lfo *lfo, int div)
 	case 3: /* random */
 		val = ((rand() & 0x1ff) - 256);
 		break;
-	case 0x12: /* S3M square */
-		val = lfo->phase < WAVEFORM_SIZE / 2 ? 255 : 0;
+#ifndef LIBXMP_CORE_PLAYER
+	case 669: /* 669 vibrato */
+		val = lfo->phase & 1;
 		break;
+#endif
 	default:
 		return 0;
 	}
 
-	return val * lfo->depth / div;
+	return val * lfo->depth;
 }
 
-void update_lfo(struct lfo *lfo)
+static int get_lfo_st3(struct lfo *lfo)
+{
+	if (lfo->rate == 0) {
+		return 0;
+	}
+
+	/* S3M square */
+	if (lfo->type == 2) {
+		int val = lfo->phase < WAVEFORM_SIZE / 2 ? 255 : 0;
+		return val * lfo->depth;
+	}
+
+	return get_lfo_mod(lfo);
+}
+
+/* From OpenMPT VibratoWaveforms.xm:
+ * "Generally the vibrato and tremolo tables are identical to those that
+ *  ProTracker uses, but the vibrato’s “ramp down” table is upside down."
+ */
+static int get_lfo_ft2(struct lfo *lfo)
+{
+	if (lfo->rate == 0)
+		return 0;
+
+	/* FT2 ramp */
+	if (lfo->type == 1) {
+		int phase = (lfo->phase + (WAVEFORM_SIZE >> 1)) % WAVEFORM_SIZE;
+		int val = (phase << 3) - 255;
+		return val * lfo->depth;
+	}
+
+	return get_lfo_mod(lfo);
+}
+
+#ifndef LIBXMP_CORE_DISABLE_IT
+
+static int get_lfo_it(struct lfo *lfo)
+{
+	if (lfo->rate == 0)
+		return 0;
+
+	return get_lfo_st3(lfo);
+}
+
+#endif
+
+int libxmp_lfo_get(struct context_data *ctx, struct lfo *lfo, int is_vibrato)
+{
+	struct module_data *m = &ctx->m;
+
+	switch (m->read_event_type) {
+	case READ_EVENT_ST3:
+		return get_lfo_st3(lfo);
+	case READ_EVENT_FT2:
+		if (is_vibrato) {
+			return get_lfo_ft2(lfo);
+		} else {
+			return get_lfo_mod(lfo);
+		}
+#ifndef LIBXMP_CORE_DISABLE_IT
+	case READ_EVENT_IT:
+		return get_lfo_it(lfo);
+#endif
+	default:
+		return get_lfo_mod(lfo);
+	}
+}
+
+
+void libxmp_lfo_update(struct lfo *lfo)
 {
 	lfo->phase += lfo->rate;
 	lfo->phase %= WAVEFORM_SIZE;
 }
 
-void set_lfo_phase(struct lfo *lfo, int phase)
+void libxmp_lfo_set_phase(struct lfo *lfo, int phase)
 {
 	lfo->phase = phase;
 }
 
-void set_lfo_depth(struct lfo *lfo, int depth)
+void libxmp_lfo_set_depth(struct lfo *lfo, int depth)
 {
 	lfo->depth = depth;
 }
 
-void set_lfo_rate(struct lfo *lfo, int rate)
+void libxmp_lfo_set_rate(struct lfo *lfo, int rate)
 {
 	lfo->rate = rate;
 }
 
-void set_lfo_waveform(struct lfo *lfo, int type)
+void libxmp_lfo_set_waveform(struct lfo *lfo, int type)
 {
 	lfo->type = type;
 }
diff --git a/src/lfo.h b/src/lfo.h
index 364608b..a269ac3 100644
--- a/src/lfo.h
+++ b/src/lfo.h
@@ -1,6 +1,8 @@
 #ifndef LIBXMP_LFO_H
 #define LIBXMP_LFO_H
 
+#include "common.h"
+
 struct lfo {
 	int type;
 	int rate;
@@ -8,12 +10,11 @@ struct lfo {
 	int phase;
 };
 
-
-int get_lfo(struct lfo *, int);
-void update_lfo(struct lfo *);
-void set_lfo_phase(struct lfo *, int);
-void set_lfo_depth(struct lfo *, int);
-void set_lfo_rate(struct lfo *, int);
-void set_lfo_waveform(struct lfo *, int);
+int  libxmp_lfo_get(struct context_data *, struct lfo *, int);
+void libxmp_lfo_update(struct lfo *);
+void libxmp_lfo_set_phase(struct lfo *, int);
+void libxmp_lfo_set_depth(struct lfo *, int);
+void libxmp_lfo_set_rate(struct lfo *, int);
+void libxmp_lfo_set_waveform(struct lfo *, int);
 
 #endif
diff --git a/src/load.c b/src/load.c
index 3c04d54..523c3c9 100644
--- a/src/load.c
+++ b/src/load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -24,11 +24,6 @@
 #include 
 #include 
 #include 
-#ifndef LIBXMP_CORE_PLAYER
-#include 
-#include 
-#include 
-#endif
 #include 
 #ifdef __native_client__
 #include 
@@ -39,6 +34,7 @@
 #include "format.h"
 #include "list.h"
 #include "hio.h"
+#include "tempfile.h"
 
 #ifndef LIBXMP_CORE_PLAYER
 #if !defined(HAVE_POPEN) && defined(WIN32)
@@ -51,219 +47,46 @@
 
 extern struct format_loader *format_loader[];
 
-void load_prologue(struct context_data *);
-void load_epilogue(struct context_data *);
-int prepare_scan(struct context_data *);
-
+void libxmp_load_prologue(struct context_data *);
+void libxmp_load_epilogue(struct context_data *);
+int  libxmp_prepare_scan(struct context_data *);
 
 #ifndef LIBXMP_CORE_PLAYER
 
-int decrunch_arc	(FILE *, FILE *);
-int decrunch_arcfs	(FILE *, FILE *);
-int decrunch_sqsh	(FILE *, FILE *);
-int decrunch_pp		(FILE *, FILE *);
-int decrunch_mmcmp	(FILE *, FILE *);
-int decrunch_muse	(FILE *, FILE *);
-int decrunch_lzx	(FILE *, FILE *);
-int decrunch_oxm	(FILE *, FILE *);
-int decrunch_xfd	(FILE *, FILE *);
-int decrunch_s404	(FILE *, FILE *);
-int decrunch_zip	(FILE *, FILE *);
-int decrunch_gzip	(FILE *, FILE *);
-int decrunch_compress	(FILE *, FILE *);
-int decrunch_bzip2	(FILE *, FILE *);
-int decrunch_xz		(FILE *, FILE *);
-int decrunch_lha	(FILE *, FILE *);
-/* int decrunch_zoo	(FILE *, FILE *); */
-int test_oxm		(FILE *);
-char *test_xfd		(unsigned char *, int);
-
-enum {
-	BUILTIN_PP = 0x01,
-	BUILTIN_SQSH,
-	BUILTIN_MMCMP,
-	BUILTIN_ARC,
-	BUILTIN_ARCFS,
-	BUILTIN_S404,
-	BUILTIN_OXM,
-	BUILTIN_XFD,
-	BUILTIN_MUSE,
-	BUILTIN_LZX,
-	BUILTIN_ZIP,
-	BUILTIN_GZIP,
-	BUILTIN_COMPRESS,
-	BUILTIN_BZIP2,
-	BUILTIN_XZ,
-	BUILTIN_LHA
-};
-
+#include "depacker.h"
 
-#if defined __EMX__ || defined WIN32
-#define REDIR_STDERR "2>NUL"
-#elif defined unix || defined __unix__
-#define REDIR_STDERR "2>/dev/null"
-#else
-#define REDIR_STDERR
+static struct depacker *depacker_list[] = {
+#if defined __AMIGA__ && !defined __AROS__
+	&libxmp_depacker_xfd,
 #endif
+	&libxmp_depacker_zip,
+	&libxmp_depacker_lha,
+	&libxmp_depacker_gzip,
+	&libxmp_depacker_bzip2,
+	&libxmp_depacker_xz,
+	&libxmp_depacker_compress,
+	&libxmp_depacker_pp,
+	&libxmp_depacker_sqsh,
+	&libxmp_depacker_arcfs,
+	&libxmp_depacker_mmcmp,
+	&libxmp_depacker_muse,
+	&libxmp_depacker_lzx,
+	&libxmp_depacker_s404,
+	&libxmp_depacker_arc,
+	NULL
+};
 
+int test_oxm		(FILE *);
 
 #define BUFLEN 16384
 
-
-static int decrunch(FILE **f, char *s, char **temp)
+static int execute_command(char *cmd, char *filename, FILE *t)
 {
-    unsigned char b[1024];
-    char *cmd;
-    FILE *t;
-    int fd, builtin, res;
-    char tmp[PATH_MAX];
-    int headersize;
-
-    cmd = NULL;
-    builtin = res = 0;
-    *temp = NULL;
-
-    if (get_temp_dir(tmp, PATH_MAX) < 0)
-	return 0;
-
-    strncat(tmp, "xmp_XXXXXX", PATH_MAX - 10);
-
-    fseek(*f, 0, SEEK_SET);
-    if ((headersize = fread(b, 1, 1024, *f)) < 100)	/* minimum valid file size */
-	return 0;
-
-#if defined __AMIGA__ && !defined __AROS__
-    if (test_xfd(b, 1024)) {
-	builtin = BUILTIN_XFD;
-    } else
-#endif
-
-    if (b[0] == 'P' && b[1] == 'K' &&
-	((b[2] == 3 && b[3] == 4) || (b[2] == '0' && b[3] == '0' &&
-	b[4] == 'P' && b[5] == 'K' && b[6] == 3 && b[7] == 4))) {
-
-	/* Zip */
-	builtin = BUILTIN_ZIP;
-    } else if (b[2] == '-' && b[3] == 'l' && b[4] == 'h') {
-	/* LHa */
-	builtin = BUILTIN_LHA;
-    } else if (b[0] == 31 && b[1] == 139) {
-	/* gzip */
-	builtin = BUILTIN_GZIP;
-    } else if (b[0] == 'B' && b[1] == 'Z' && b[2] == 'h') {
-	/* bzip2 */
-	builtin = BUILTIN_BZIP2;
-    } else if (b[0] == 0xfd && b[3] == 'X' && b[4] == 'Z' && b[5] == 0x00) {
-	/* xz */
-	builtin = BUILTIN_XZ;
-#if 0
-    } else if (b[0] == 'Z' && b[1] == 'O' && b[2] == 'O' && b[3] == ' ') {
-	/* zoo */
-	builtin = BUILTIN_ZOO;
-#endif
-    } else if (b[0] == 'M' && b[1] == 'O' && b[2] == '3') {
-	/* MO3 */
-	cmd = "unmo3 -s \"%s\" STDOUT";
-    } else if (b[0] == 31 && b[1] == 157) {
-	/* compress */
-	builtin = BUILTIN_COMPRESS;
-    } else if (memcmp(b, "PP20", 4) == 0) {
-	/* PowerPack */
-	builtin = BUILTIN_PP;
-    } else if (memcmp(b, "XPKF", 4) == 0 && memcmp(b + 8, "SQSH", 4) == 0) {
-	/* SQSH */
-	builtin = BUILTIN_SQSH;
-    } else if (!memcmp(b, "Archive\0", 8)) {
-	/* ArcFS */
-	builtin = BUILTIN_ARCFS;
-    } else if (memcmp(b, "ziRCONia", 8) == 0) {
-	/* MMCMP */
-	builtin = BUILTIN_MMCMP;
-    } else if (memcmp(b, "MUSE", 4) == 0 && readmem32b(b + 4) == 0xdeadbeaf) {
-	/* J2B MUSE */
-	builtin = BUILTIN_MUSE;
-    } else if (memcmp(b, "MUSE", 4) == 0 && readmem32b(b + 4) == 0xdeadbabe) {
-	/* MOD2J2B MUSE */
-	builtin = BUILTIN_MUSE;
-    } else if (memcmp(b, "LZX", 3) == 0) {
-	/* LZX */
-	builtin = BUILTIN_LZX;
-    } else if (memcmp(b, "Rar", 3) == 0) {
-	/* rar */
-	cmd = "unrar p -inul -xreadme -x*.diz -x*.nfo -x*.txt "
-	    "-x*.exe -x*.com \"%s\"";
-    } else if (memcmp(b, "S404", 4) == 0) {
-	/* Stonecracker */
-	builtin = BUILTIN_S404;
-    } else if (test_oxm(*f) == 0) {
-	/* oggmod */
-	builtin = BUILTIN_OXM;
-    }
-
-    if (builtin == 0 && cmd == NULL && b[0] == 0x1a) {
-	int x = b[1] & 0x7f;
-	int i, flag = 0;
-	long size;
-	
-	/* check file name */
-	for (i = 0; i < 13; i++) {
-	    if (b[2 + i] == 0) {
-		if (i == 0)		/* name can't be empty */
-		    flag = 1;
-		break;
-	    }
-	    if (!isprint(b[2 + i])) {	/* name must be printable */
-		flag = 1;
-		break;
-	    }
-	}
-
-	size = readmem32l(b + 15);	/* max file size is 512KB */
-	if (size < 0 || size > 512 * 1024)
-		flag = 1;
-
-        if (flag == 0) {
-	    if (x >= 1 && x <= 9 && x != 7) {
-		/* Arc */
-		builtin = BUILTIN_ARC;
-	    } else if (x == 0x7f) {
-		/* !Spark */
-		builtin = BUILTIN_ARC;
-	    }
-	}
-    }
-
-    fseek(*f, 0, SEEK_SET);
-
-    if (builtin == 0 && cmd == NULL)
-	return 0;
-
-#if defined ANDROID || defined __native_client__
-    /* Don't use external helpers in android */
-    if (cmd)
-	return 0;
-#endif
-
-    D_(D_WARN "Depacking file... ");
-
-    *temp = strdup(tmp);
-    if (*temp == NULL || (fd = mkstemp(*temp)) < 0) {
-	D_(D_CRIT "failed");
-	return -1;
-    }
-
-    if ((t = fdopen(fd, "w+b")) == NULL) {
-	D_(D_CRIT "failed");
-	return -1;
-    }
-
-    if (cmd) {
-#define BSIZE 0x4000
-	int n;
-	char line[1024], buf[BSIZE];
+	char line[1024], buf[BUFLEN];
 	FILE *p;
+	int n;
 
-	snprintf(line, 1024, cmd, s);
+	snprintf(line, 1024, cmd, filename);
 
 #ifdef WIN32
 	/* Note: The _popen function returns an invalid file opaque, if
@@ -273,99 +96,125 @@ static int decrunch(FILE **f, char *s, char **temp)
 	 * read the section "Creating a Child Process with Redirected Input
 	 * and Output" in the Win32 SDK. -- Mirko 
 	 */
-	if ((p = popen(line, "rb")) == NULL) {
+	p = popen(line, "rb");
 #else
 	/* Linux popen fails with "rb" */
-	if ((p = popen(line, "r")) == NULL) {
+	p = popen(line, "r");
 #endif
-	    D_(D_CRIT "failed");
-	    fclose(t);
+
+	if (p == NULL) {
 	    return -1;
 	}
-	while ((n = fread(buf, 1, BSIZE, p)) > 0) {
+
+	while ((n = fread(buf, 1, BUFLEN, p)) > 0) {
 	    fwrite(buf, 1, n, t);
 	}
+
 	pclose (p);
-    } else {
-	switch (builtin) {
-	case BUILTIN_PP:    
-	    res = decrunch_pp(*f, t);
-	    break;
-	case BUILTIN_ARC:
-	    res = decrunch_arc(*f, t);
-	    break;
-	case BUILTIN_ARCFS:
-	    res = decrunch_arcfs(*f, t);
-	    break;
-	case BUILTIN_SQSH:    
-	    res = decrunch_sqsh(*f, t);
-	    break;
-	case BUILTIN_MMCMP:    
-	    res = decrunch_mmcmp(*f, t);
-	    break;
-	case BUILTIN_MUSE:    
-	    res = decrunch_muse(*f, t);
-	    break;
-	case BUILTIN_LZX:    
-	    res = decrunch_lzx(*f, t);
-	    break;
-	case BUILTIN_S404:
-	    res = decrunch_s404(*f, t);
-	    break;
-	case BUILTIN_ZIP:
-	    res = decrunch_zip(*f, t);
-	    break;
-	case BUILTIN_GZIP:
-	    res = decrunch_gzip(*f, t);
-	    break;
-	case BUILTIN_COMPRESS:
-	    res = decrunch_compress(*f, t);
-	    break;
-	case BUILTIN_BZIP2:
-	    res = decrunch_bzip2(*f, t);
-	    break;
-	case BUILTIN_XZ:
-	    res = decrunch_xz(*f, t);
-	    break;
-	case BUILTIN_LHA:
-	    res = decrunch_lha(*f, t);
-	    break;
-	case BUILTIN_OXM:
-	    res = decrunch_oxm(*f, t);
-	    break;
-#ifdef AMIGA
-	case BUILTIN_XFD:
-	    res = decrunch_xfd(*f, t);
-	    break;
-#endif
+
+	return 0;
+}
+
+static int decrunch(HIO_HANDLE **h, char *filename, char **temp)
+{
+	unsigned char b[1024];
+	char *cmd;
+	FILE *f, *t;
+	int res;
+	int headersize;
+	int i;
+	struct depacker *depacker = NULL;
+
+	cmd = NULL;
+	res = 0;
+	*temp = NULL;
+	f = (*h)->handle.file;
+
+	headersize = fread(b, 1, 1024, f);
+	if (headersize < 100) {	/* minimum valid file size */
+		return 0;
 	}
-    }
 
-    if (res < 0) {
-	D_(D_CRIT "failed");
-	fclose(t);
-	return -1;
-    }
+	/* Check built-in depackers */
+	for (i = 0; depacker_list[i] != NULL; i++) {
+		if (depacker_list[i]->test(b)) {
+			depacker = depacker_list[i];
+			D_(D_INFO "Use depacker %d", i);
+			break;
+		}
+	}
 
-    D_(D_INFO "done");
+	/* Check external commands */
+	if (depacker == NULL) {
+		if (b[0] == 'M' && b[1] == 'O' && b[2] == '3') {
+			/* MO3 */
+			D_(D_INFO "mo3");
+			cmd = "unmo3 -s \"%s\" STDOUT";
+		} else if (memcmp(b, "Rar", 3) == 0) {
+			/* rar */
+			D_(D_INFO "rar");
+			cmd = "unrar p -inul -xreadme -x*.diz -x*.nfo -x*.txt "
+			    "-x*.exe -x*.com \"%s\"";
+		} else if (test_oxm(f) == 0) {
+			/* oggmod */
+			D_(D_INFO "oggmod");
+			depacker = &libxmp_depacker_oxm;
+		}
+	}
 
-    fseek(t, 0, SEEK_SET);
-    fclose(*f);
-    *f = t;
+	if (fseek(f, 0, SEEK_SET) < 0) {
+		goto err;
+	}
 
-    return res;
-}
+	if (depacker == NULL && cmd == NULL) {
+		D_(D_INFO "Not packed");
+		return 0;
+	}
 
-/*
- * Windows doesn't allow you to unlink an open file, so we changed the
- * temp file cleanup system to remove temporary files after we close it
- */
-static void unlink_tempfile(char *temp)
-{
-	if (temp) {
-		unlink(temp);
-		free(temp);
+#if defined __ANDROID__ || defined __native_client__
+	/* Don't use external helpers in android */
+	if (cmd) {
+		return 0;
+	}
+#endif
+
+	D_(D_WARN "Depacking file... ");
+
+	if ((t = make_temp_file(temp)) == NULL) {
+		goto err;
+	}
+
+	/* Depack file */
+	if (cmd) {
+		D_(D_INFO "External depacker: %s", cmd);
+		if (execute_command(cmd, filename, t) < 0) {
+			D_(D_CRIT "failed");
+			goto err2;
+		}
+	} else if (depacker) {
+		D_(D_INFO "Internal depacker");
+		if (depacker->depack(f, t) < 0) {
+			D_(D_CRIT "failed");
+			goto err2;
+		}
 	}
+
+	D_(D_INFO "done");
+
+	if (fseek(t, 0, SEEK_SET) < 0) {
+		D_(D_CRIT "fseek error");
+		goto err2;
+	}
+
+	hio_close(*h);
+	*h = hio_open_file(t);
+
+	return res;
+
+    err2:
+	fclose(t);
+    err:
+	return -1;
 }
 
 static void set_md5sum(HIO_HANDLE *f, unsigned char *digest)
@@ -373,12 +222,8 @@ static void set_md5sum(HIO_HANDLE *f, unsigned char *digest)
 	unsigned char buf[BUFLEN];
 	MD5_CTX ctx;
 	int bytes_read;
-	struct stat st;
-
-	if (hio_stat(f, &st) < 0)
-		return;
 
-	if (st.st_size <= 0) {
+	if (hio_size(f) <= 0) {
 		memset(digest, 0, 16);
 		return;
 	}
@@ -431,9 +276,9 @@ int xmp_test_module(char *path, struct xmp_test_info *info)
 	struct stat st;
 	char buf[XMP_NAME_SIZE];
 	int i;
-	int ret = -XMP_ERROR_FORMAT;;
+	int ret = -XMP_ERROR_FORMAT;
 #ifndef LIBXMP_CORE_PLAYER
-	char *temp;
+	char *temp = NULL;
 #endif
 
 	if (stat(path, &st) < 0)
@@ -450,21 +295,17 @@ int xmp_test_module(char *path, struct xmp_test_info *info)
 		return -XMP_ERROR_SYSTEM;
 
 #ifndef LIBXMP_CORE_PLAYER
-	if (decrunch(&h->handle.file, path, &temp) < 0) {
-		ret = -XMP_ERROR_DEPACK;
-		goto err;
-	}
-
-	if (hio_stat(h, &st) < 0) {	/* get size after decrunch */
+	if (decrunch(&h, path, &temp) < 0) {
 		ret = -XMP_ERROR_DEPACK;
 		goto err;
 	}
-#endif
 
-	if (st.st_size < 256) {		/* set minimum valid module size */
+	/* get size after decrunch */
+	if (hio_size(h) < 256) {	/* set minimum valid module size */
 		ret = -XMP_ERROR_FORMAT;
 		goto err;
 	}
+#endif
 
 	if (info != NULL) {
 		*info->name = 0;	/* reset name prior to testing */
@@ -472,14 +313,14 @@ int xmp_test_module(char *path, struct xmp_test_info *info)
 	}
 
 	for (i = 0; format_loader[i] != NULL; i++) {
-		fseek(h->handle.file, 0, SEEK_SET);
+		hio_seek(h, 0, SEEK_SET);
 		if (format_loader[i]->test(h, buf, 0) == 0) {
 			int is_prowizard = 0;
 
 #ifndef LIBXMP_CORE_PLAYER
 			if (strcmp(format_loader[i]->name, "prowizard") == 0) {
-				fseek(h->handle.file, 0, SEEK_SET);
-				pw_test_format(h->handle.file, buf, 0, info);
+				hio_seek(h, 0, SEEK_SET);
+				pw_test_format(h, buf, 0, info);
 				is_prowizard = 1;
 			}
 #endif
@@ -487,39 +328,48 @@ int xmp_test_module(char *path, struct xmp_test_info *info)
 			fclose(h->handle.file);
 
 #ifndef LIBXMP_CORE_PLAYER
-			unlink_tempfile(temp);
+			unlink_temp_file(temp);
 #endif
 
 			if (info != NULL && !is_prowizard) {
-				strncpy(info->name, buf, XMP_NAME_SIZE);
+				strncpy(info->name, buf, XMP_NAME_SIZE - 1);
 				strncpy(info->type, format_loader[i]->name,
-							XMP_NAME_SIZE);
+							XMP_NAME_SIZE - 1);
 			}
 			return 0;
 		}
 	}
 
+#ifndef LIBXMP_CORE_PLAYER
     err:
 	hio_close(h);
-#ifndef LIBXMP_CORE_PLAYER
-	unlink_tempfile(temp);
+	unlink_temp_file(temp);
+#else
+	hio_close(h);
 #endif
 	return ret;
 }
 
-static int load_module(xmp_context opaque, HIO_HANDLE *h, char *tmpfile)
+static int load_module(xmp_context opaque, HIO_HANDLE *h)
 {
 	struct context_data *ctx = (struct context_data *)opaque;
 	struct module_data *m = &ctx->m;
-	int i, ret;
+	struct xmp_module *mod = &m->mod;
+	int i, j, ret;
 	int test_result, load_result;
 
-	load_prologue(ctx);
+	libxmp_load_prologue(ctx);
 
 	D_(D_WARN "load");
 	test_result = load_result = -1;
 	for (i = 0; format_loader[i] != NULL; i++) {
 		hio_seek(h, 0, SEEK_SET);
+
+		if (hio_error(h)) {
+			/* reset error flag */
+		}
+
+		D_(D_WARN "test %s", format_loader[i]->name);
 		test_result = format_loader[i]->test(h, NULL, 0);
 		if (test_result == 0) {
 			hio_seek(h, 0, SEEK_SET);
@@ -534,12 +384,6 @@ static int load_module(xmp_context opaque, HIO_HANDLE *h, char *tmpfile)
 		set_md5sum(h, m->md5);
 #endif
 
-	hio_close(h);
-
-#ifndef LIBXMP_CORE_PLAYER
-	unlink_tempfile(tmpfile);
-#endif
-
 	if (test_result < 0) {
 		free(m->basename);
 		free(m->dirname);
@@ -547,36 +391,84 @@ static int load_module(xmp_context opaque, HIO_HANDLE *h, char *tmpfile)
 	}
 
 	if (load_result < 0) {
-		xmp_release_module(opaque);
-		return -XMP_ERROR_LOAD;
+		goto err_load;
 	}
 
-	adjust_string(m->mod.name);
-	load_epilogue(ctx);
+	/* Sanity check: number of channels, module length */
+	if (mod->chn > XMP_MAX_CHANNELS || mod->len > XMP_MAX_MOD_LENGTH) {
+		goto err_load;
+	}
 
-	ret = prepare_scan(ctx);
-	if (ret < 0)
+	/* Sanity check: channel pan */
+	for (i = 0; i < mod->chn; i++) {
+		if (mod->xxc[i].vol < 0 || mod->xxc[i].vol > 0xff) {
+			goto err_load;
+		}
+		if (mod->xxc[i].pan < 0 || mod->xxc[i].pan > 0xff) {
+			goto err_load;
+		}
+	}
+
+	/* Sanity check: patterns */
+	if (mod->xxp == NULL) {
+		goto err_load;
+	}
+	for (i = 0; i < mod->pat; i++) {
+		if (mod->xxp[i] == NULL) {
+			goto err_load;
+		}
+		for (j = 0; j < mod->chn; j++) {
+			int t = mod->xxp[i]->index[j];
+			if (t < 0 || t >= mod->trk || mod->xxt[t] == NULL) {
+				goto err_load;
+			}
+		}
+	}
+
+	libxmp_adjust_string(mod->name);
+	for (i = 0; i < mod->ins; i++) {
+		libxmp_adjust_string(mod->xxi[i].name);
+	}
+	for (i = 0; i < mod->smp; i++) {
+		libxmp_adjust_string(mod->xxs[i].name);
+	}
+
+	libxmp_load_epilogue(ctx);
+
+	ret = libxmp_prepare_scan(ctx);
+	if (ret < 0) {
+		xmp_release_module(opaque);
 		return ret;
+	}
 
-	scan_sequences(ctx);
+	libxmp_scan_sequences(ctx);
 
 	ctx->state = XMP_STATE_LOADED;
 
 	return 0;
+
+    err_load:
+	xmp_release_module(opaque);
+	return -XMP_ERROR_LOAD;
 }
 
 int xmp_load_module(xmp_context opaque, char *path)
 {
 	struct context_data *ctx = (struct context_data *)opaque;
+#ifndef LIBXMP_CORE_PLAYER
 	struct module_data *m = &ctx->m;
+	long size;
+	char *temp_name;
+#endif
 	HIO_HANDLE *h;
 	struct stat st;
-	char *temp;
+	int ret;
 
 	D_(D_WARN "path = %s", path);
 
-	if (stat(path, &st) < 0)
+	if (stat(path, &st) < 0) {
 		return -XMP_ERROR_SYSTEM;
+	}
 
 #ifndef _MSC_VER
 	if (S_ISDIR(st.st_mode)) {
@@ -585,21 +477,21 @@ int xmp_load_module(xmp_context opaque, char *path)
 	}
 #endif
 
-	if ((h = hio_open(path, "rb")) == NULL)
+	if ((h = hio_open(path, "rb")) == NULL) {
 		return -XMP_ERROR_SYSTEM;
+	}
 
 #ifndef LIBXMP_CORE_PLAYER
 	D_(D_INFO "decrunch");
-	if (decrunch(&h->handle.file, path, &temp) < 0)
-		goto err_depack;
-
-	if (hio_stat(h, &st) < 0)
-		goto err_depack;
+	if (decrunch(&h, path, &temp_name) < 0) {
+		ret = -XMP_ERROR_DEPACK;
+		goto err;
+	}
 
-	if (st.st_size < 256) {		/* get size after decrunch */
-		hio_close(h);
-		unlink_tempfile(temp);
-		return -XMP_ERROR_FORMAT;
+	size = hio_size(h);
+	if (size < 256) {		/* get size after decrunch */
+		ret = -XMP_ERROR_FORMAT;
+		goto err;
 	}
 #endif
 
@@ -608,24 +500,35 @@ int xmp_load_module(xmp_context opaque, char *path)
 
 #ifndef LIBXMP_CORE_PLAYER
 	m->dirname = get_dirname(path);
-	if (m->dirname == NULL)
-		return -XMP_ERROR_SYSTEM;
+	if (m->dirname == NULL) {
+		ret = -XMP_ERROR_SYSTEM;
+		goto err;
+	}
 
 	m->basename = get_basename(path);
-	if (m->basename == NULL)
-		return -XMP_ERROR_SYSTEM;
+	if (m->basename == NULL) {
+		ret = -XMP_ERROR_SYSTEM;
+		goto err;
+	}
 
 	m->filename = path;	/* For ALM, SSMT, etc */
+	m->size = size;
+#endif
+
+	ret = load_module(opaque, h);
+	hio_close(h);
+
+#ifndef LIBXMP_CORE_PLAYER
+	unlink_temp_file(temp_name);
 #endif
-	m->size = st.st_size;
 
-	return load_module(opaque, h, temp);
+	return ret;
 
 #ifndef LIBXMP_CORE_PLAYER
-    err_depack:
+    err:
 	hio_close(h);
-	unlink_tempfile(temp);
-	return -XMP_ERROR_DEPACK;
+	unlink_temp_file(temp_name);
+	return ret;
 #endif
 }
 
@@ -634,6 +537,7 @@ int xmp_load_module_from_memory(xmp_context opaque, void *mem, long size)
 	struct context_data *ctx = (struct context_data *)opaque;
 	struct module_data *m = &ctx->m;
 	HIO_HANDLE *h;
+	int ret;
 
 	/* Use size < 0 for unknown/undetermined size */
 	if (size == 0)
@@ -648,9 +552,13 @@ int xmp_load_module_from_memory(xmp_context opaque, void *mem, long size)
 	m->filename = NULL;
 	m->basename = NULL;
 	m->dirname = NULL;
-	m->size = 0;
+	m->size = size;
+
+	ret = load_module(opaque, h);
+
+	hio_close(h);
 
-	return load_module(opaque, h, NULL);
+	return ret;
 }
 
 int xmp_load_module_from_file(xmp_context opaque, void *file, long size)
@@ -658,11 +566,8 @@ int xmp_load_module_from_file(xmp_context opaque, void *file, long size)
 	struct context_data *ctx = (struct context_data *)opaque;
 	struct module_data *m = &ctx->m;
 	HIO_HANDLE *h;
-	FILE *f = (FILE *)file;
-	struct stat st;
-
-	if (fstat(fileno(f), &st) < 0)
-		return -XMP_ERROR_SYSTEM;
+	FILE *f = fdopen(fileno((FILE *)file), "rb");
+	int ret;
 
 	if ((h = hio_open_file(f)) == NULL)
 		return -XMP_ERROR_SYSTEM;
@@ -673,9 +578,13 @@ int xmp_load_module_from_file(xmp_context opaque, void *file, long size)
 	m->filename = NULL;
 	m->basename = NULL;
 	m->dirname = NULL;
-	m->size = st.st_size;
+	m->size = hio_size(h);
+
+	ret = load_module(opaque, h);
 
-	return load_module(opaque, h, NULL);
+	hio_close(h);
+
+	return ret;
 }
 
 void xmp_release_module(xmp_context opaque)
@@ -699,32 +608,51 @@ void xmp_release_module(xmp_context opaque)
 	D_(D_INFO "Freeing memory");
 
 #ifndef LIBXMP_CORE_PLAYER
-	release_module_extras(ctx);
+	libxmp_release_module_extras(ctx);
 #endif
 
-	for (i = 0; i < mod->trk; i++)
-		free(mod->xxt[i]);
-	if (mod->trk > 0)
+	if (mod->xxt != NULL) {
+		for (i = 0; i < mod->trk; i++) {
+			free(mod->xxt[i]);
+		}
 		free(mod->xxt);
+	}
 
-	for (i = 0; i < mod->pat; i++)
-		free(mod->xxp[i]);
-	if (mod->pat > 0)
+	if (mod->xxp != NULL) {
+		for (i = 0; i < mod->pat; i++) {
+			free(mod->xxp[i]);
+		}
 		free(mod->xxp);
-
-	for (i = 0; i < mod->ins; i++) {
-		free(mod->xxi[i].sub);
-		free(mod->xxi[i].extra);
 	}
-	if (mod->ins > 0)
-		free(mod->xxi);
 
-	for (i = 0; i < mod->smp; i++) {
-		if (mod->xxs[i].data != NULL)
-			free(mod->xxs[i].data - 4);
+	if (mod->xxi != NULL) {
+		for (i = 0; i < mod->ins; i++) {
+			free(mod->xxi[i].sub);
+			free(mod->xxi[i].extra);
+		}
+		free(mod->xxi);
 	}
-	if (mod->smp > 0)
+
+	if (mod->xxs != NULL) {
+		for (i = 0; i < mod->smp; i++) {
+			if (mod->xxs[i].data != NULL) {
+				free(mod->xxs[i].data - 4);
+			}
+		}
 		free(mod->xxs);
+		free(m->xtra);
+	}
+
+#ifndef LIBXMP_CORE_DISABLE_IT
+	if (m->xsmp != NULL) {
+		for (i = 0; i < mod->smp; i++) {
+			if (m->xsmp[i].data != NULL) {
+				free(m->xsmp[i].data - 4);
+			}
+		}
+		free(m->xsmp);
+	}
+#endif
 
 	if (m->scan_cnt) {
 		for (i = 0; i < mod->len; i++)
@@ -737,7 +665,6 @@ void xmp_release_module(xmp_context opaque)
 	D_("free dirname/basename");
 	free(m->dirname);
 	free(m->basename);
-
 }
 
 void xmp_scan_module(xmp_context opaque)
@@ -747,5 +674,5 @@ void xmp_scan_module(xmp_context opaque)
 	if (ctx->state < XMP_STATE_LOADED)
 		return;
 
-	scan_sequences(ctx);
+	libxmp_scan_sequences(ctx);
 }
diff --git a/src/load_helpers.c b/src/load_helpers.c
index 381a25d..9bc3734 100644
--- a/src/load_helpers.c
+++ b/src/load_helpers.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -30,14 +30,13 @@
 
 #ifndef LIBXMP_CORE_PLAYER
 
-#ifdef ANDROID
+#ifdef __ANDROID__
 #include 
 #include 
 #include 
 #endif
 
 #include 
-#include "synth.h"
 
 /*
  * Handle special "module quirks" that can't be detected automatically
@@ -47,6 +46,7 @@
 struct module_quirk {
 	uint8 md5[16];
 	int flags;
+	int mode;
 };
 
 const struct module_quirk mq[] = {
@@ -54,34 +54,66 @@ const struct module_quirk mq[] = {
 	{
 		{ 0x36, 0x6e, 0xc0, 0xfa, 0x96, 0x2a, 0xeb, 0xee,
 	  	  0x03, 0x4a, 0xa2, 0xdb, 0xaa, 0x49, 0xaa, 0xea },
-		XMP_FLAGS_FX9BUG
+		0, XMP_MODE_PROTRACKER
 	},
 
 	/* mod.souvenir of china */
 	{
 		{ 0x93, 0xf1, 0x46, 0xae, 0xb7, 0x58, 0xc3, 0x9d,
 		  0x8b, 0x5f, 0xbc, 0x98, 0xbf, 0x23, 0x7a, 0x43 },
-		XMP_FLAGS_FIXLOOP
+		XMP_FLAGS_FIXLOOP, XMP_MODE_AUTO
 	},
 
 	/* "siedler ii" (added by Daniel Åkerud) */
 	{
 		{ 0x70, 0xaa, 0x03, 0x4d, 0xfb, 0x2f, 0x1f, 0x73,
 		  0xd9, 0xfd, 0xba, 0xfe, 0x13, 0x1b, 0xb7, 0x01 },
-		XMP_FLAGS_VBLANK
+		XMP_FLAGS_VBLANK, XMP_MODE_AUTO
 	},
 
 	/* "Klisje paa klisje" (added by Kjetil Torgrim Homme) */
 	{
 		{ 0xe9, 0x98, 0x01, 0x2c, 0x70, 0x0e, 0xb4, 0x3a,
 		  0xf0, 0x32, 0x17, 0x11, 0x30, 0x58, 0x29, 0xb2 },
+		0, XMP_MODE_NOISETRACKER
+	},
+
+#if 0
+	/* -- Already covered by Noisetracker fingerprinting -- */
+
+	/* Another version of Klisje paa klisje sent by Steve Fernandez */
+	{
+		{ 0x12, 0x19, 0x1c, 0x90, 0x41, 0xe3, 0xfd, 0x70,
+		  0xb7, 0xe6, 0xb3, 0x94, 0x8b, 0x21, 0x07, 0x63 },
 		XMP_FLAGS_VBLANK
 	},
+#endif
+
+	/* "((((( nebulos )))))" sent by Tero Auvinen (AMP version) */
+	{
+		{ 0x51, 0x6e, 0x8d, 0xcc, 0x35, 0x7d, 0x50, 0xde,
+		  0xa9, 0x85, 0xbe, 0xbf, 0x90, 0x2e, 0x42, 0xdc },
+		0, XMP_MODE_NOISETRACKER
+	},
+
+	/* Purple Motion's Sundance.mod, Music Channel BBS edit */
+	{
+		{ 0x5d, 0x3e, 0x1e, 0x08, 0x28, 0x52, 0x12, 0xc7,
+		  0x17, 0x64, 0x95, 0x75, 0x98, 0xe6, 0x95, 0xc1 },
+		0, XMP_MODE_ST3
+	},
+
+	/* Asle's Ode to Protracker */
+	{
+		{ 0x97, 0xa3, 0x7d, 0x30, 0xd7, 0xae, 0x6d, 0x50,
+		  0xc9, 0x62, 0xe9, 0xd8, 0x87, 0x1b, 0x7e, 0x8a },
+		0, XMP_MODE_PROTRACKER
+	},
 
 	{
 		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-		0
+		0, 0
 	}
 };
 
@@ -91,9 +123,10 @@ static void module_quirks(struct context_data *ctx)
 	struct module_data *m = &ctx->m;
 	int i;
 
-	for (i = 0; mq[i].flags != 0; i++) {
+	for (i = 0; mq[i].flags != 0 || mq[i].mode != 0; i++) {
 		if (!memcmp(m->md5, mq[i].md5, 16)) {
 			p->flags |= mq[i].flags;
+			p->mode = mq[i].mode;
 		}
 	}
 }
@@ -102,7 +135,7 @@ static void module_quirks(struct context_data *ctx)
  * Check whether the given string matches one of the blacklisted glob
  * patterns. Used to filter file names stored in archive files.
  */
-int exclude_match(char *name)
+int libxmp_exclude_match(char *name)
 {
 	int i;
 
@@ -128,76 +161,57 @@ int exclude_match(char *name)
 	return 0;
 }
 
-int get_temp_dir(char *buf, int size)
-{
-#if defined WIN32
-	const char def[] = "C:\\WINDOWS\\TEMP";
-	char *tmp = getenv("TEMP");
-
-	strncpy(buf, tmp ? tmp : def, size);
-	strncat(buf, "\\", size);
-#elif defined __AMIGA__
-	strncpy(buf, "T:", size);
-#elif defined ANDROID
-#define APPDIR "/sdcard/Xmp for Android"
-	struct stat st;
-	if (stat(APPDIR, &st) < 0) {
-		if (mkdir(APPDIR, 0777) < 0)
-			return -1;
-	}
-	if (stat(APPDIR "/tmp", &st) < 0) {
-		if (mkdir(APPDIR "/tmp", 0777) < 0)
-			return -1;
-	}
-	strncpy(buf, APPDIR "/tmp/", size);
-#else
-	const char def[] = "/tmp";
-	char *tmp = getenv("TMPDIR");
-
-	strncpy(buf, tmp ? tmp : def, size);
-	strncat(buf, "/", size);
-#endif
-
-	return 0;
-}
-
 #endif /* LIBXMP_CORE_PLAYER */
 
-char *adjust_string(char *s)
+char *libxmp_adjust_string(char *s)
 {
 	int i;
 
-	for (i = 0; i < strlen(s); i++)
+	for (i = 0; i < strlen(s); i++) {
 		if (!isprint((int)s[i]) || ((uint8) s[i] > 127))
 			s[i] = ' ';
+	}
 
-	while (*s && (s[strlen(s) - 1] == ' '))
+	while (*s && (s[strlen(s) - 1] == ' ')) {
 		s[strlen(s) - 1] = 0;
+	}
 
 	return s;
 }
 
 static void check_envelope(struct xmp_envelope *env)
 {
-	if (env->npt <= 0 || env->lps >= env->npt || env->lpe >= env->npt)
+	/* Disable envelope if invalid number of points */
+	if (env->npt <= 0 || env->npt > XMP_MAX_ENV_POINTS) {
+		env->flg &= ~XMP_ENVELOPE_ON;
+	}
+
+	/* Disable envelope loop if invalid loop parameters */
+	if (env->lps >= env->npt || env->lpe >= env->npt) {
 		env->flg &= ~XMP_ENVELOPE_LOOP;
+	}
+
+	/* Disable envelope loop if invalid sustain */
+	if (env->sus >= env->npt) {
+		env->flg &= ~XMP_ENVELOPE_ON;
+	}
 }
 
-void load_prologue(struct context_data *ctx)
+void libxmp_load_prologue(struct context_data *ctx)
 {
 	struct module_data *m = &ctx->m;
 	int i;
 
 	/* Reset variables */
-	memset(m->mod.name, 0, XMP_NAME_SIZE);
-	memset(m->mod.type, 0, XMP_NAME_SIZE);
+	memset(&m->mod, 0, sizeof (struct xmp_module));
 	m->rrate = PAL_RATE;
 	m->c4rate = C4_PAL_RATE;
 	m->volbase = 0x40;
-	m->gvolbase = 0x40;
+	m->gvol = m->gvolbase = 0x40;
 	m->vol_table = NULL;
 	m->quirk = 0;
 	m->read_event_type = READ_EVENT_MOD;
+	m->period_type = PERIOD_AMIGA;
 	m->comment = NULL;
 	m->scan_cnt = NULL;
 
@@ -213,9 +227,12 @@ void load_prologue(struct context_data *ctx)
     	m->mod.rst = 0;
 
 #ifndef LIBXMP_CORE_PLAYER
-	m->synth = &synth_null;
 	m->extra = NULL;
 #endif
+#ifndef LIBXMP_CORE_DISABLE_IT
+	m->xsmp = NULL;
+#endif
+
 	m->time_factor = DEFAULT_TIME_FACTOR;
 
 	for (i = 0; i < 64; i++) {
@@ -226,14 +243,21 @@ void load_prologue(struct context_data *ctx)
 	}
 }
 
-void load_epilogue(struct context_data *ctx)
+void libxmp_load_epilogue(struct context_data *ctx)
 {
 	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
 	struct xmp_module *mod = &m->mod;
 	int i, j;
 
-    	mod->gvl = m->gvolbase;
+    	mod->gvl = m->gvol;
+
+	/* Sanity check for module parameters */
+	CLAMP(mod->len, 0, XMP_MAX_MOD_LENGTH);
+	CLAMP(mod->pat, 0, 257);   /* some formats have an extra pattern */
+	CLAMP(mod->ins, 0, 255);
+	CLAMP(mod->smp, 0, MAX_SAMPLES);
+	CLAMP(mod->chn, 0, XMP_MAX_CHANNELS);
 
 	/* Fix cases where the restart value is invalid e.g. kc_fall8.xm
 	 * from http://aminet.net/mods/mvp/mvp_0002.lha (reported by
@@ -243,13 +267,11 @@ void load_epilogue(struct context_data *ctx)
 		mod->rst = 0;
 	}
 
-	/* Sanity check */
-	if (mod->spd == 0) {
+	/* Sanity check for tempo and BPM */
+	if (mod->spd <= 0 || mod->spd > 255) {
 		mod->spd = 6;
 	}
-	if (mod->bpm == 0) {
-		mod->bpm = 125;
-	}
+	CLAMP(mod->bpm, XMP_MIN_BPM, 255);
 
 	/* Set appropriate values for instrument volumes and subinstrument
 	 * global volumes when QUIRK_INSVOL is not set, to keep volume values
@@ -275,19 +297,22 @@ void load_epilogue(struct context_data *ctx)
 		check_envelope(&mod->xxi[i].pei);
 	}
 
+	p->filter = 0;
+	p->mode = XMP_MODE_AUTO;
 	p->flags = p->player_flags;
 #ifndef LIBXMP_CORE_PLAYER
 	module_quirks(ctx);
 #endif
+	libxmp_set_player_mode(ctx);
 }
 
-int prepare_scan(struct context_data *ctx)
+int libxmp_prepare_scan(struct context_data *ctx)
 {
 	struct module_data *m = &ctx->m;
 	struct xmp_module *mod = &m->mod;
 	int i, ord;
 
-	if (mod->xxo == NULL || mod->xxp == NULL || mod->xxt == NULL)
+	if (mod->xxp == NULL || mod->xxt == NULL)
 		return -XMP_ERROR_LOAD;
 	ord = 0;
 	while (ord < mod->len && mod->xxo[ord] >= mod->pat) {
@@ -309,8 +334,9 @@ int prepare_scan(struct context_data *ctx)
 
 		/* Add pattern if referenced in orders */
 		if (pat_idx < mod->pat && !mod->xxp[pat_idx]) {
-			if (pattern_alloc(mod, pat_idx) < 0)
+			if (libxmp_alloc_pattern(mod, pat_idx) < 0) {
 				return -XMP_ERROR_SYSTEM;
+			}
 		}
 
 		pat = pat_idx >= mod->pat ? NULL : mod->xxp[pat_idx];
@@ -321,3 +347,79 @@ int prepare_scan(struct context_data *ctx)
  
 	return 0;
 }
+
+/* Process player personality flags */
+int libxmp_set_player_mode(struct context_data *ctx)
+{
+	struct player_data *p = &ctx->p;
+	struct module_data *m = &ctx->m;
+	int q;
+
+	switch (p->mode) {
+	case XMP_MODE_AUTO:
+		break;
+	case XMP_MODE_MOD:
+		m->c4rate = C4_PAL_RATE;
+		m->quirk = 0;
+		m->read_event_type = READ_EVENT_MOD;
+		m->period_type = PERIOD_AMIGA;
+		break;
+	case XMP_MODE_NOISETRACKER:
+		m->c4rate = C4_PAL_RATE;
+		m->quirk = QUIRK_NOBPM;
+		m->read_event_type = READ_EVENT_MOD;
+		m->period_type = PERIOD_MODRNG;
+		break;
+	case XMP_MODE_PROTRACKER:
+		m->c4rate = C4_PAL_RATE;
+		m->quirk = QUIRK_PROTRACK;
+		m->read_event_type = READ_EVENT_MOD;
+		m->period_type = PERIOD_MODRNG;
+		break;
+	case XMP_MODE_S3M:
+		q = m->quirk & (QUIRK_VSALL | QUIRK_ARPMEM);
+		m->c4rate = C4_NTSC_RATE;
+		m->quirk = QUIRKS_ST3 | q;
+		m->read_event_type = READ_EVENT_ST3;
+		break;
+	case XMP_MODE_ST3:
+		q = m->quirk & (QUIRK_VSALL | QUIRK_ARPMEM);
+		m->c4rate = C4_NTSC_RATE;
+		m->quirk = QUIRKS_ST3 | QUIRK_ST3BUGS | q;
+		m->read_event_type = READ_EVENT_ST3;
+		break;
+	case XMP_MODE_ST3GUS:
+		q = m->quirk & (QUIRK_VSALL | QUIRK_ARPMEM);
+		m->c4rate = C4_NTSC_RATE;
+		m->quirk = QUIRKS_ST3 | QUIRK_ST3BUGS | q;
+		m->quirk &= ~QUIRK_RSTCHN;
+		m->read_event_type = READ_EVENT_ST3;
+		break;
+	case XMP_MODE_XM:
+		m->c4rate = C4_NTSC_RATE;
+		m->quirk = QUIRKS_FT2;
+		m->read_event_type = READ_EVENT_FT2;
+		break;
+	case XMP_MODE_FT2:
+		m->c4rate = C4_NTSC_RATE;
+		m->quirk = QUIRKS_FT2 | QUIRK_FT2BUGS;
+		m->read_event_type = READ_EVENT_FT2;
+		break;
+	case XMP_MODE_IT:
+		m->c4rate = C4_NTSC_RATE;
+		m->quirk = QUIRKS_IT | QUIRK_VIBHALF | QUIRK_VIBINV;
+		m->read_event_type = READ_EVENT_IT;
+		break;
+	case XMP_MODE_ITSMP:
+		m->c4rate = C4_NTSC_RATE;
+		m->quirk = QUIRKS_IT | QUIRK_VIBHALF | QUIRK_VIBINV;
+		m->quirk &= ~(QUIRK_VIRTUAL | QUIRK_RSTCHN);
+		m->read_event_type = READ_EVENT_IT;
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
diff --git a/src/loaders/669_load.c b/src/loaders/669_load.c
index 506c5fa..0d0706c 100644
--- a/src/loaders/669_load.c
+++ b/src/loaders/669_load.c
@@ -1,24 +1,38 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
 
 
-static int ssn_test (HIO_HANDLE *, char *, const int);
-static int ssn_load (struct module_data *, HIO_HANDLE *, const int);
+static int c669_test (HIO_HANDLE *, char *, const int);
+static int c669_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader ssn_loader = {
+const struct format_loader libxmp_loader_669 = {
     "Composer 669",
-    ssn_test,
-    ssn_load
+    c669_test,
+    c669_load
 };
 
-static int ssn_test(HIO_HANDLE *f, char *t, const int start)
+static int c669_test(HIO_HANDLE *f, char *t, const int start)
 {
     uint16 id;
 
@@ -26,18 +40,24 @@ static int ssn_test(HIO_HANDLE *f, char *t, const int start)
     if (id != 0x6966 && id != 0x4a4e)
 	return -1;
 
-    hio_seek(f, 238, SEEK_CUR);
+    hio_seek(f, 110, SEEK_SET);
+    if (hio_read8(f) > 64)
+	return -1;
+    if (hio_read8(f) > 128)
+	return -1;
+
+    hio_seek(f, 240, SEEK_SET);
     if (hio_read8(f) != 0xff)
 	return -1;
 
     hio_seek(f, start + 2, SEEK_SET);
-    read_title(f, t, 36);
+    libxmp_read_title(f, t, 36);
 
     return 0;
 }
 
 
-struct ssn_file_header {
+struct c669_file_header {
     uint8 marker[2];		/* 'if'=standard, 'JN'=extended */
     uint8 message[108];		/* Song message */
     uint8 nos;			/* Number of samples (0-64) */
@@ -48,7 +68,7 @@ struct ssn_file_header {
     uint8 pbrk[128];		/* Break list for patterns */
 };
 
-struct ssn_instrument_header {
+struct c669_instrument_header {
     uint8 name[13];		/* ASCIIZ instrument name */
     uint32 length;		/* Instrument length */
     uint32 loop_start;		/* Instrument loop start */
@@ -61,22 +81,22 @@ struct ssn_instrument_header {
 /* Effects bug fixed by Miod Vallat  */
 
 static const uint8 fx[] = {
-    FX_PER_PORTA_UP,
-    FX_PER_PORTA_DN,
-    FX_PER_TPORTA,
-    FX_FINETUNE,
-    FX_PER_VIBRATO,
+    FX_669_PORTA_UP,
+    FX_669_PORTA_DN,
+    FX_669_TPORTA,
+    FX_669_FINETUNE,
+    FX_669_VIBRATO,
     FX_SPEED_CP
 };
 
 
-static int ssn_load(struct module_data *m, HIO_HANDLE *f, const int start)
+static int c669_load(struct module_data *m, HIO_HANDLE *f, const int start)
 {
     struct xmp_module *mod = &m->mod;
     int i, j;
     struct xmp_event *event;
-    struct ssn_file_header sfh;
-    struct ssn_instrument_header sih;
+    struct c669_file_header sfh;
+    struct c669_instrument_header sih;
     uint8 ev[3];
 
     LOAD_INIT();
@@ -85,28 +105,38 @@ static int ssn_load(struct module_data *m, HIO_HANDLE *f, const int start)
     hio_read(&sfh.message, 108, 1, f);	/* Song message */
     sfh.nos = hio_read8(f);		/* Number of samples (0-64) */
     sfh.nop = hio_read8(f);		/* Number of patterns (0-128) */
+
+    /* Sanity check */
+    if (sfh.nos > 64 || sfh.nop > 128)
+	return -1;
+
     sfh.loop = hio_read8(f);		/* Loop order number */
-    hio_read(&sfh.order, 128, 1, f);	/* Order list */
-    hio_read(&sfh.speed, 128, 1, f);	/* Tempo list for patterns */
-    hio_read(&sfh.pbrk, 128, 1, f);	/* Break list for patterns */
+    if (hio_read(&sfh.order, 1, 128, f) != 128)	/* Order list */
+	return -1;
+    if (hio_read(&sfh.speed, 1, 128, f) != 128)	/* Tempo list for patterns */
+	return -1;
+    if (hio_read(&sfh.pbrk, 1, 128, f) != 128) 	/* Break list for patterns */
+	return -1;
 
     mod->chn = 8;
     mod->ins = sfh.nos;
     mod->pat = sfh.nop;
     mod->trk = mod->chn * mod->pat;
-    for (i = 0; i < 128; i++)
+    for (i = 0; i < 128; i++) {
 	if (sfh.order[i] > sfh.nop)
 	    break;
+    }
     mod->len = i;
     memcpy (mod->xxo, sfh.order, mod->len);
     mod->spd = 6;
-    mod->bpm = 76;		/* adjusted using Flux/sober.669 */
+    mod->bpm = 78;
     mod->smp = mod->ins;
 
-    m->quirk |= QUIRK_LINEAR;
+    m->period_type = PERIOD_CSPD;
+    m->c4rate = C4_NTSC_RATE;
 
-    copy_adjust(mod->name, sfh.message, 36);
-    set_type(m, strncmp((char *)sfh.marker, "if", 2) ?
+    libxmp_copy_adjust(mod->name, sfh.message, 36);
+    libxmp_set_type(m, strncmp((char *)sfh.marker, "if", 2) ?
 				"UNIS 669" : "Composer 669");
 
     MODULE_INFO();
@@ -117,51 +147,71 @@ static int ssn_load(struct module_data *m, HIO_HANDLE *f, const int start)
     
     /* Read and convert instruments and samples */
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     D_(D_INFO "Instruments: %d", mod->pat);
 
     for (i = 0; i < mod->ins; i++) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	struct xmp_instrument *xxi = &mod->xxi[i];
+	struct xmp_sample *xxs = &mod->xxs[i];
+	struct xmp_subinstrument *sub;
+
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 	    return -1;
 
+	sub = &xxi->sub[0];
+
 	hio_read (&sih.name, 13, 1, f);		/* ASCIIZ instrument name */
 	sih.length = hio_read32l(f);		/* Instrument size */
 	sih.loop_start = hio_read32l(f);	/* Instrument loop start */
 	sih.loopend = hio_read32l(f);		/* Instrument loop end */
 
-	mod->xxs[i].len = sih.length;
-	mod->xxs[i].lps = sih.loop_start;
-	mod->xxs[i].lpe = sih.loopend >= 0xfffff ? 0 : sih.loopend;
-	mod->xxs[i].flg = mod->xxs[i].lpe ? XMP_SAMPLE_LOOP : 0;	/* 1 == Forward loop */
-	mod->xxi[i].sub[0].vol = 0x40;
-	mod->xxi[i].sub[0].pan = 0x80;
-	mod->xxi[i].sub[0].sid = i;
+	/* Sanity check */
+	if (sih.length > MAX_SAMPLE_SIZE)
+	    return -1;
+
+	xxs->len = sih.length;
+	xxs->lps = sih.loop_start;
+	xxs->lpe = sih.loopend >= 0xfffff ? 0 : sih.loopend;
+	xxs->flg = xxs->lpe ? XMP_SAMPLE_LOOP : 0;	/* 1 == Forward loop */
+
+	sub->vol = 0x40;
+	sub->pan = 0x80;
+	sub->sid = i;
 
-	if (mod->xxs[i].len > 0)
-		mod->xxi[i].nsm = 1;
+	if (xxs->len > 0)
+		xxi->nsm = 1;
 
-	instrument_name(mod, i, sih.name, 13);
+	libxmp_instrument_name(mod, i, sih.name, 13);
 
 	D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c", i,
-		mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
-		mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ');
+		xxi->name, xxs->len, xxs->lps, xxs->lpe,
+		xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ');
     }
 
-    if (pattern_init(mod) < 0)
+    if (libxmp_init_pattern(mod) < 0)
 	return -1;
 
     /* Read and convert patterns */
     D_(D_INFO "Stored patterns: %d", mod->pat);
     for (i = 0; i < mod->pat; i++) {
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
+	int pbrk;
+
+	if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 	    return -1;
 
-	EVENT(i, 0, 0).f2t = FX_SPEED_CP;
-	EVENT(i, 0, 0).f2p = sfh.speed[i];
-	EVENT(i, 1, sfh.pbrk[i]).f2t = FX_BREAK;
-	EVENT(i, 1, sfh.pbrk[i]).f2p = 0;
+	event = &EVENT(i, 0, 0);
+	event->f2t = FX_SPEED_CP;
+	event->f2p = sfh.speed[i];
+
+	pbrk = sfh.pbrk[i];
+	if (pbrk >= 64)
+	    return -1;
+
+	event = &EVENT(i, 1, pbrk);
+	event->f2t = FX_BREAK;
+	event->f2p = 0;
 
 	for (j = 0; j < 64 * 8; j++) {
 	    event = &EVENT(i, j % 8, j / 8);
@@ -179,31 +229,11 @@ static int ssn_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		if (MSN(ev[2]) > 5)
 		    continue;
 
-		/* If no instrument is playing on the channel where the
-		 * command was encountered, there will be no effect (except
-		 * for command 'f', it always changes the speed). 
-		 */
-		if (MSN(ev[2] < 5) && !event->ins)
-		    continue;
-
 		event->fxt = fx[MSN(ev[2])];
+		event->fxp = LSN(ev[2]);
 
-		switch (event->fxt) {
-		case FX_PER_PORTA_UP:
-		case FX_PER_PORTA_DN:
-		case FX_PER_TPORTA:
-		    event->fxp = LSN(ev[2]);
-		    break;
-		case FX_PER_VIBRATO:
-		    event->fxp = 0x40 || LSN(ev[2]);
-		    break;
-		case FX_FINETUNE:
-		    event->fxp = 0x80 + (LSN(ev[2]) << 4);
-		    break;
-		case FX_SPEED_CP:
-		    event->fxp = LSN(ev[2]);
+		if (event->fxt == FX_SPEED_CP) {
 		    event->f2t = FX_PER_CANCEL;
-		    break;
 		}
 	    }
 	}
@@ -215,14 +245,15 @@ static int ssn_load(struct module_data *m, HIO_HANDLE *f, const int start)
     for (i = 0; i < mod->ins; i++) {
 	if (mod->xxs[i].len <= 2)
 	    continue;
-	if (load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
+	if (libxmp_load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
 	    return -1;
     }
 
-    for (i = 0; i < mod->chn; i++)
-	mod->xxc[i].pan = (i % 2) * 0xff;
+    for (i = 0; i < mod->chn; i++) {
+	mod->xxc[i].pan = DEFPAN((i % 2) * 0xff);
+    }
 
-    m->quirk |= QUIRK_PERPAT;	    /* Cancel persistent fx at each new pat */
+    m->quirk |= QUIRK_PBALL|QUIRK_PERPAT;
 
     return 0;
 }
diff --git a/src/loaders/Makefile b/src/loaders/Makefile
deleted file mode 100644
index bff3ef0..0000000
--- a/src/loaders/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-
-LOADERS	= xm_load.o mod_load.o s3m_load.o stm_load.o 669_load.o far_load.o \
-	  mtm_load.o ptm_load.o okt_load.o amd_load.o rad_load.o \
-	  ult_load.o mdl_load.o it_load.o stx_load.o pt3_load.o sfx_load.o \
-	  flt_load.o st_load.o emod_load.o imf_load.o digi_load.o fnk_load.o \
-	  ice_load.o hsc_load.o liq_load.o ims_load.o masi_load.o amf_load.o \
-	  psm_load.o stim_load.o mmd_common.o mmd1_load.o mmd3_load.o \
-	  rtm_load.o dt_load.o no_load.o arch_load.o sym_load.o med2_load.o \
-	  med3_load.o med4_load.o dbm_load.o umx_load.o gdm_load.o pw_load.o \
-	  gal5_load.o gal4_load.o mfp_load.o asylum_load.o hmn_load.o \
-	  mgt_load.o chip_load.o abk_load.o
-
-LOADERS_OBJS	= common.o iff.o itsex.o asif.o voltable.o sample.o $(LOADERS)
-LOADERS_DFILES	= Makefile $(LOADERS_OBJS:.o=.c) \
-		  asif.h iff.h it.h loader.h med.h mod.h s3m.h xm.h
-LOADERS_PATH	= src/loaders
-
-OBJS += $(addprefix $(LOADERS_PATH)/,$(LOADERS_OBJS))
-
-default:
-
-dist-loaders::
-	mkdir -p $(DIST)/$(LOADERS_PATH)
-	cp -RPp $(addprefix $(LOADERS_PATH)/,$(LOADERS_DFILES)) $(DIST)/$(LOADERS_PATH)
diff --git a/src/loaders/abk_load.c b/src/loaders/abk_load.c
index 70a7d83..303699a 100644
--- a/src/loaders/abk_load.c
+++ b/src/loaders/abk_load.c
@@ -1,11 +1,24 @@
 /* Extended Module Player
  * AMOS/STOS Music Bank Loader
- *
  * Copyright (C) 2014 Stephen J Leary and Claudio Matsuoka
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU General Public License. See doc/COPYING
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -14,13 +27,12 @@
 
 #include 
 
+#include "loader.h"
 #include "effects.h"
 #include "period.h"
-#include "loader.h"
 
 #define AMOS_BANK 0x416d426b
 #define AMOS_MUSIC_TYPE 0x0003
-#define AMOS_MUSIC_TEXT 0x4D75736963202020
 #define AMOS_MAIN_HEADER 0x14L
 #define AMOS_STRING_LEN 0x10
 #define AMOS_BASE_FREQ 8192
@@ -30,7 +42,7 @@
 static int abk_test (HIO_HANDLE *, char *, const int);
 static int abk_load (struct module_data *, HIO_HANDLE *, const int);
 
-struct format_loader abk_loader =
+struct format_loader libxmp_loader_abk =
 {
     "AMOS Music Bank",
     abk_test,
@@ -87,17 +99,6 @@ struct abk_instrument
 };
 
 
-static void free_abk_playlist(struct abk_playlist *playlist)
-{
-    if (playlist->pattern != NULL)
-    {
-        free(playlist->pattern);
-    }
-
-    playlist->length = 0;
-}
-
-
 /**
  * @brief read the ABK playlist out from the file stream. This method malloc's some memory for the playlist
  * and can realloc if the playlist is very long.
@@ -143,7 +144,7 @@ static int read_abk_song(HIO_HANDLE *f, struct abk_song *song, uint32 songs_sect
     int i;
     uint32 song_section;
 
-    /* move to the start of the songs data sectio */
+    /* move to the start of the songs data section */
     hio_seek(f, songs_section_offset, SEEK_SET);
 
     if (hio_read16b(f) != 1)
@@ -155,7 +156,9 @@ static int read_abk_song(HIO_HANDLE *f, struct abk_song *song, uint32 songs_sect
 
     song_section = hio_read32b(f);
 
-    hio_seek(f, songs_section_offset + song_section, SEEK_SET);
+    if (hio_seek(f, songs_section_offset + song_section, SEEK_SET) < 0) {
+        return -1;
+    }
 
     for (i=0; isong_name, 1, AMOS_STRING_LEN, f);
+    if (hio_read(song->song_name, 1, AMOS_STRING_LEN, f) != AMOS_STRING_LEN) {
+        return -1;
+    }
 
     return 0;
 }
@@ -179,7 +184,7 @@ static int read_abk_song(HIO_HANDLE *f, struct abk_song *song, uint32 songs_sect
  * @param pattern_offset_abs the absolute file offset to the start of the patter to read.
  * @return returns the size of the pattern.
  */
-static uint16 read_abk_pattern(HIO_HANDLE *f, struct xmp_event *events, uint32 pattern_offset_abs)
+static int read_abk_pattern(HIO_HANDLE *f, struct xmp_event *events, uint32 pattern_offset_abs)
 {
     uint8 position;
     uint8 command;
@@ -192,8 +197,10 @@ static uint16 read_abk_pattern(HIO_HANDLE *f, struct xmp_event *events, uint32 p
     uint16 delay;
     uint16 patdata;
 
-    uint32 storepos;
-    storepos = hio_tell(f);
+    int storepos;
+    if ((storepos = hio_tell(f)) < 0) {
+        return -1;
+    }
 
     /* count how many abk positions are used in this pattern */
     position = 0;
@@ -306,9 +313,13 @@ static uint16 read_abk_pattern(HIO_HANDLE *f, struct xmp_event *events, uint32 p
                 jumped = 1;
                 break;
             default:
+#if 0
                 /* write out an error for any unprocessed commands.*/
                 D_(D_WARN "ABK UNPROCESSED COMMAND: %x,%x\n", command, param);
                 break;
+#else
+		return -1;
+#endif
             }
         }
         else
@@ -332,7 +343,7 @@ static uint16 read_abk_pattern(HIO_HANDLE *f, struct xmp_event *events, uint32 p
                 if (patdata != 0)
                 {
                     /* convert the note from amiga period format to xmp's internal format.*/
-                    events[position].note = period_to_note(patdata & 0x0fff);
+                    events[position].note = libxmp_period_to_note(patdata & 0x0fff);
                     events[position].ins = inst;
                 }
 
@@ -345,7 +356,7 @@ static uint16 read_abk_pattern(HIO_HANDLE *f, struct xmp_event *events, uint32 p
             else /* new note format */
             {
                 /* convert the note from amiga period format to xmp's internal format.*/
-                events[position].note = period_to_note(patdata & 0x0fff);
+                events[position].note = libxmp_period_to_note(patdata & 0x0fff);
                 events[position].ins = inst;
             }
         }
@@ -393,7 +404,10 @@ static struct abk_instrument* read_abk_insts(HIO_HANDLE *f, uint32 inst_section_
             inst[i].sample_length = sampleLength;
         }
     
-        hio_read(inst[i].sample_name, 1, 16, f);
+        if (hio_read(inst[i].sample_name, 1, 16, f) != 16) {
+            free(inst);
+            return NULL;
+	}
     }
 
     return inst;
@@ -401,7 +415,7 @@ static struct abk_instrument* read_abk_insts(HIO_HANDLE *f, uint32 inst_section_
 
 static int abk_test(HIO_HANDLE *f, char *t, const int start)
 {
-    uint64 music;
+    char music[8];
 
     if (hio_read32b(f) != AMOS_BANK)
     {
@@ -416,11 +430,9 @@ static int abk_test(HIO_HANDLE *f, char *t, const int start)
     /* skip over length and chip/fastmem.*/
     hio_seek(f, 6, SEEK_CUR);
 
-    music = hio_read32b(f); /* get the "Music   " */
-    music = music << 32;
-    music |= hio_read32b(f);
+    hio_read(music, 1, 8, f);	/* get the "Music   " */
 
-    if (music != (unsigned long long)AMOS_MUSIC_TEXT)
+    if (memcmp(music, "Music   ", 8))
     {
         return -1;
     }
@@ -434,7 +446,6 @@ static int abk_load(struct module_data *m, HIO_HANDLE *f, const int start)
     uint16 pattern;
     uint32 first_sample_offset;
     uint32 inst_section_size;
-    uint32 file_size;
 
     struct xmp_module *mod = &m->mod;
 
@@ -443,32 +454,32 @@ static int abk_load(struct module_data *m, HIO_HANDLE *f, const int start)
     struct abk_song song;
     struct abk_playlist playlist;
 
-    ci = NULL;
-    pattern = 0;
-    first_sample_offset = 0;
-
-    hio_seek(f, 0, SEEK_END);
-    file_size = hio_tell(f);
-
     hio_seek(f, AMOS_MAIN_HEADER, SEEK_SET);
 
     main_header.instruments_offset = hio_read32b(f);
     main_header.songs_offset = hio_read32b(f);
     main_header.patterns_offset = hio_read32b(f);
 
+    /* Sanity check */
+    if (main_header.instruments_offset > 0x00100000 ||
+        main_header.songs_offset > 0x00100000 ||
+        main_header.patterns_offset > 0x00100000) {
+            return -1;
+    }
+
     inst_section_size = main_header.instruments_offset;
     D_(D_INFO "Sample Bytes: %d", inst_section_size);
 
     LOAD_INIT();
 
-    set_type(m, "AMOS Music Bank");
+    libxmp_set_type(m, "AMOS Music Bank");
 
     if (read_abk_song(f, &song, AMOS_MAIN_HEADER + main_header.songs_offset) < 0)
     {
         return -1;
     }
 
-    copy_adjust(mod->name, (uint8*) song.song_name, AMOS_STRING_LEN);
+    libxmp_copy_adjust(mod->name, (uint8*) song.song_name, AMOS_STRING_LEN);
 
     MODULE_INFO();
 
@@ -476,16 +487,28 @@ static int abk_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     mod->chn = AMOS_ABK_CHANNELS;
     mod->pat = hio_read16b(f);
+
+    /* Sanity check */
+    if (mod->pat > 256) {
+        return -1;
+    }
+
     mod->trk = mod->chn * mod->pat;
 
     /* move to the start of the instruments section. */
     hio_seek(f, AMOS_MAIN_HEADER + main_header.instruments_offset, SEEK_SET);
     mod->ins = hio_read16b(f);
+
+    /* Sanity check */
+    if (mod->ins > 255) {
+	return -1;
+    }
+
     mod->smp = mod->ins;
 
     /* Read and convert instruments and samples */
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
     {
         return -1;
     }
@@ -494,14 +517,18 @@ static int abk_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     /* read all the instruments in */
     ci = read_abk_insts(f, inst_section_size, mod->ins);
+    if (ci == NULL) {
+        return -1;
+    }
 
     /* store the location of the first sample so we can read them later. */
     first_sample_offset = AMOS_MAIN_HEADER + main_header.instruments_offset + ci[0].sample_offset;
 
     for (i = 0; i < mod->ins; i++)
     {
-        if (subinstrument_alloc(mod, i, 1) < 0)
+        if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
         {
+            free(ci);
             return -1;
         }
 
@@ -532,14 +559,16 @@ static int abk_load(struct module_data *m, HIO_HANDLE *f, const int start)
         mod->xxi[i].sub[0].pan = 0x80;
         mod->xxi[i].sub[0].sid = i;
 
-        instrument_name(mod, i, (uint8*)ci[i].sample_name, 16);
+        libxmp_instrument_name(mod, i, (uint8*)ci[i].sample_name, 16);
 
         D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c", i,
            mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
            mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ');
     }
 
-    if (pattern_init(mod) < 0)
+    free(ci);
+
+    if (libxmp_init_pattern(mod) < 0)
     {
         return -1;
     }
@@ -559,33 +588,40 @@ static int abk_load(struct module_data *m, HIO_HANDLE *f, const int start)
     i = 0;
     for (j = 0; j < mod->pat; j++)
     {
-        if (pattern_tracks_alloc(mod, i, 64) < 0)
+        if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
         {
+            free(playlist.pattern);
             return -1;
         }
 
-        for (k = 0; k  < mod->chn; k++)
+        for (k = 0; k < mod->chn; k++)
         {
             pattern = hio_read16b(f);
-            read_abk_pattern(f,  mod->xxt[(i*mod->chn)+k]->event, AMOS_MAIN_HEADER + main_header.patterns_offset + pattern);
+            if (read_abk_pattern(f,  mod->xxt[(i*mod->chn)+k]->event, AMOS_MAIN_HEADER + main_header.patterns_offset + pattern) < 0) {
+    		free(playlist.pattern);
+		return -1;
+	    }
         }
 
         i++;
     }
 
-    /* now push all the patterns into the module and set the length */
-    i = 0;
+    /* Sanity check */
+    if (playlist.length > 256) {
+    	free(playlist.pattern);
+	return -1;
+    }
 	
-    for (j=0; j< playlist.length; j++)
+    mod->len = playlist.length;
+
+    /* now push all the patterns into the module and set the length */
+    for (i = 0; i < playlist.length; i++)
     {
-        /* increment the length */
-        mod->len++;
-        mod->xxo[i++] = playlist.pattern[j];
+        mod->xxo[i] = playlist.pattern[i];
     }
 
     /* free up some memory here */
-    free(ci);
-    free_abk_playlist(&playlist);
+    free(playlist.pattern);
 
     D_(D_INFO "Stored patterns: %d", mod->pat);
     D_(D_INFO "Stored tracks: %d", mod->trk);
@@ -600,7 +636,7 @@ static int abk_load(struct module_data *m, HIO_HANDLE *f, const int start)
         if (mod->xxs[i].len <= 2)
             continue;
 
-        if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+        if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
         {
             return -1;
         }
diff --git a/src/loaders/alm_load.c b/src/loaders/alm_load.c
new file mode 100644
index 0000000..be7c651
--- /dev/null
+++ b/src/loaders/alm_load.c
@@ -0,0 +1,194 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* ALM (Aley's Module) is a module format used on 8bit computers. It was
+ * designed to be usable on Sam Coupe (CPU Z80 6MHz) and PC XT. The ALM file
+ * format is very simple and it have no special effects, so every computer
+ * can play the ALMs.
+ *
+ * Note: xmp's module loading mechanism was not designed to load samples
+ * from different files. Using *module into a global variable is a hack.
+ */
+
+#include "loader.h"
+#include 
+#include 
+#include 
+
+
+static int alm_test (HIO_HANDLE *, char *, const int);
+static int alm_load (struct module_data *, HIO_HANDLE *, const int);
+
+const struct format_loader libxmp_loader_alm = {
+    "Aley Keptr (ALM)",
+    alm_test,
+    alm_load
+};
+
+static int alm_test(HIO_HANDLE *f, char *t, const int start)
+{
+    char buf[7];
+
+    if (HIO_HANDLE_TYPE(f) != HIO_HANDLE_TYPE_FILE)
+	return -1;
+
+    if (hio_read(buf, 1, 7, f) < 7)
+	return -1;
+
+    if (memcmp(buf, "ALEYMOD", 7) && memcmp(buf, "ALEY MO", 7))
+	return -1;
+
+    libxmp_read_title(f, t, 0);
+
+    return 0;
+}
+
+
+
+struct alm_file_header {
+    uint8 id[7];		/* "ALEY MO" or "ALEYMOD" */
+    uint8 speed;		/* Only in versions 1.1 and 1.2 */
+    uint8 length;		/* Length of module */
+    uint8 restart;		/* Restart position */
+    uint8 order[128];		/* Pattern sequence */
+};
+
+#define NAME_SIZE 255
+
+static int alm_load(struct module_data *m, HIO_HANDLE *f, const int start)
+{
+    struct xmp_module *mod = &m->mod;
+    int i, j;
+    struct alm_file_header afh;
+    struct xmp_event *event;
+    struct stat stat;
+    uint8 b;
+    char *basename;
+    char filename[NAME_SIZE];
+    char modulename[NAME_SIZE];
+
+    LOAD_INIT();
+
+    hio_read(&afh.id, 7, 1, f);
+
+    if (!strncmp((char *)afh.id, "ALEYMOD", 7))		/* Version 1.0 */
+	mod->spd = afh.speed / 2;
+
+    strncpy(modulename, m->filename, NAME_SIZE);
+    basename = strtok (modulename, ".");
+
+    afh.speed = hio_read8(f);
+    afh.length = hio_read8(f);
+    afh.restart = hio_read8(f);
+    hio_read(&afh.order, 128, 1, f);
+
+    mod->len = afh.length;
+    mod->rst = afh.restart;
+    memcpy (mod->xxo, afh.order, mod->len);
+
+    for (mod->pat = i = 0; i < mod->len; i++)
+	if (mod->pat < afh.order[i])
+	    mod->pat = afh.order[i];
+    mod->pat++;
+
+    mod->ins = 31;
+    mod->trk = mod->pat * mod->chn;
+    mod->smp = mod->ins;
+    m->c4rate = C4_NTSC_RATE;
+
+    libxmp_set_type(m, "Aley's Module");
+
+    MODULE_INFO();
+
+    if (libxmp_init_pattern(mod) < 0)
+	return -1;
+
+    /* Read and convert patterns */
+    D_(D_INFO "Stored patterns: %d", mod->pat);
+
+    for (i = 0; i < mod->pat; i++) {
+	if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
+		return -1;
+
+	for (j = 0; j < 64 * mod->chn; j++) {
+	    event = &EVENT (i, j % mod->chn, j / mod->chn);
+	    b = hio_read8(f);
+	    if (b)
+		event->note = (b == 37) ? 0x61 : b + 48;
+	    event->ins = hio_read8(f);
+	}
+    }
+
+    if (libxmp_init_instrument(m) < 0)
+	return -1;
+
+    /* Read and convert instruments and samples */
+
+    D_(D_INFO "Loading samples: %d", mod->ins);
+
+    for (i = 0; i < mod->ins; i++) {
+	HIO_HANDLE *s;
+
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+	    return -1;
+
+	mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1);
+	snprintf(filename, NAME_SIZE, "%s.%d", basename, i + 1);
+	s = hio_open_file(filename, "rb");
+
+	if (s == NULL)
+	    continue;
+
+	mod->xxi[i].nsm = 1;
+
+	hio_stat(s, &stat);
+	b = hio_read8(s);		/* Get first octet */
+	mod->xxs[i].len = stat.st_size - 5 * !b;
+
+	if (!b) {		/* Instrument with header */
+	    mod->xxs[i].lps = hio_read16l(f);
+	    mod->xxs[i].lpe = hio_read16l(f);
+	    mod->xxs[i].flg = mod->xxs[i].lpe > mod->xxs[i].lps ? XMP_SAMPLE_LOOP : 0;
+	} else {
+	    hio_seek(s, 0, SEEK_SET);
+	}
+
+	mod->xxi[i].sub[0].pan = 0x80;
+	mod->xxi[i].sub[0].vol = 0x40;
+	mod->xxi[i].sub[0].sid = i;
+
+	D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x", i,
+		filename, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
+		mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol);
+
+	if (libxmp_load_sample(m, s, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
+	    return -1;
+
+	hio_close(s);
+    }
+
+    /* ALM is LRLR, not LRRL */
+    for (i = 0; i < mod->chn; i++)
+	mod->xxc[i].pan = DEFPAN((i % 2) * 0xff);
+
+    return 0;
+}
diff --git a/src/loaders/amd_load.c b/src/loaders/amd_load.c
index eba83eb..acb8e62 100644
--- a/src/loaders/amd_load.c
+++ b/src/loaders/amd_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -12,7 +26,7 @@
 static int amd_test(HIO_HANDLE *, char *, const int);
 static int amd_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader amd_loader = {
+const struct format_loader libxmp_loader_amd = {
 	"Amusic Adlib Tracker",
 	amd_test,
 	amd_load
@@ -30,7 +44,7 @@ static int amd_test(HIO_HANDLE *f, char *t, const int start)
 		return -1;
 
 	hio_seek(f, start + 0, SEEK_SET);
-	read_title(f, t, 24);
+	libxmp_read_title(f, t, 24);
 
 	return 0;
 }
@@ -104,11 +118,11 @@ static int load_unpacked_patterns(struct module_data *m, HIO_HANDLE *f)
 	struct xmp_event *event;
 
 	mod->trk = mod->pat * 9;
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 			return -1;
 
 		for (j = 0; j < (64 * mod->chn); j++) {
@@ -140,7 +154,7 @@ static int load_packed_patterns(struct module_data *m, HIO_HANDLE *f)
 		return -1;
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_alloc(mod, i) < 0)
+		if (libxmp_alloc_pattern(mod, i) < 0)
 			return -1;
 
 		for (j = 0; j < 9; j++) {
@@ -153,9 +167,20 @@ static int load_packed_patterns(struct module_data *m, HIO_HANDLE *f)
 	}
 	mod->trk++;
 
+	/* Sanity check */
+	if (mod->trk > mod->pat * 9) {
+		return -1;
+	}
+
 	stored_tracks = hio_read16l(f);
+	
+	/* Sanity check */
+	if (hio_error(f) || stored_tracks <= 0) {
+		return -1;
+	}
 
-	D_(D_INFO "Stored tracks: %d", w);
+	D_(D_INFO "Tracks: %d", mod->trk);
+	D_(D_INFO "Stored tracks: %d", stored_tracks);
 
 	mod->xxt = calloc(sizeof(struct xmp_track *), mod->trk);
 	if (mod->xxt == NULL)
@@ -163,14 +188,27 @@ static int load_packed_patterns(struct module_data *m, HIO_HANDLE *f)
 
 	for (i = 0; i < stored_tracks; i++) {
 		w = hio_read16l(f);
-		if (track_alloc(mod, w, 64) < 0)
+		if (hio_error(f)) {
 			return -1;
+		}
+
+		/* Sanity check */
+		if (w >= mod->trk || mod->xxt[w] != NULL) {
+			return -1;
+		}
+
+		if (libxmp_alloc_track(mod, w, 64) < 0) {
+			return -1;
+		}
 
 		for (r = 0; r < 64; r++) {
 			event = &mod->xxt[w]->event[r];
 
 			/* check event packing */
 			b = hio_read8(f);	/* Effect parameter */
+			if (hio_error(f)) {
+				return -1;
+			}
 			if (b & 0x80) {
 				r += (b & 0x7f) - 1;
 				continue;
@@ -202,6 +240,9 @@ static int amd_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		hio_read(&afh.ins[i].reg, 11, 1, f);
 	}
 	afh.len = hio_read8(f);
+	if (afh.len >= 128) {
+		return -1;
+	}
 	afh.pat = hio_read8(f);
 	hio_read(&afh.order, 128, 1, f);
 	hio_read(&afh.magic, 9, 1, f);
@@ -219,21 +260,21 @@ static int amd_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->smp = mod->ins;
 	memcpy(mod->xxo, afh.order, mod->len);
 
-	set_type(m, "Amusic Adlib Tracker");
+	libxmp_set_type(m, "Amusic Adlib Tracker");
 	strncpy(mod->name, (char *)afh.name, 24);
 
 	MODULE_INFO();
 	D_(D_INFO "Instruments: %d", mod->ins);
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	/* Load instruments */
 	for (i = 0; i < mod->ins; i++) {
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 
-		instrument_name(mod, i, afh.ins[i].name, 23);
+		libxmp_instrument_name(mod, i, afh.ins[i].name, 23);
 
 		mod->xxi[i].sub[0].vol = 0x40;
 		mod->xxi[i].sub[0].pan = 0x80;
@@ -245,7 +286,7 @@ static int amd_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		D_(D_INFO "\n[%2X] %-23.23s", i, mod->xxi[i].name);
 
-		if (load_sample(m, f, SAMPLE_FLAG_ADLIB, &mod->xxs[i],regs) < 0)
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_ADLIB, &mod->xxs[i],regs) < 0)
 			return -1;
 	}
 
diff --git a/src/loaders/amf_load.c b/src/loaders/amf_load.c
index 4bc4c7d..b39b4a3 100644
--- a/src/loaders/amf_load.c
+++ b/src/loaders/amf_load.c
@@ -1,13 +1,27 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 /* AMF loader written based on the format specs by Miodrag Vallat with
- * fixes by Andre Timmermans
+ * fixes by Andre Timmermans.
  *
  * The AMF format is the internal format used by DSMI, the DOS Sound and Music
  * Interface, which is the engine of DMP. As DMP was able to play more and more
@@ -22,7 +36,7 @@
 static int amf_test(HIO_HANDLE *, char *, const int);
 static int amf_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader amf_loader = {
+const struct format_loader libxmp_loader_amf = {
 	"DSMI Advanced Module Format",
 	amf_test,
 	amf_load
@@ -43,7 +57,7 @@ static int amf_test(HIO_HANDLE * f, char *t, const int start)
 	if (ver < 0x0a || ver > 0x0e)
 		return -1;
 
-	read_title(f, t, 32);
+	libxmp_read_title(f, t, 32);
 
 	return 0;
 }
@@ -65,13 +79,19 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	hio_read(buf, 1, 32, f);
 	strncpy(mod->name, (char *)buf, 32);
-	set_type(m, "DSMI %d.%d AMF", ver / 10, ver % 10);
+	libxmp_set_type(m, "DSMI %d.%d AMF", ver / 10, ver % 10);
 
 	mod->ins = hio_read8(f);
 	mod->len = hio_read8(f);
 	mod->trk = hio_read16l(f);
 	mod->chn = hio_read8(f);
 
+	/* Sanity check */
+	if (mod->ins == 0 || mod->len == 0 || mod->trk == 0
+		|| mod->chn == 0 || mod->chn > XMP_MAX_CHANNELS) {
+		return -1;
+	}
+
 	mod->smp = mod->ins;
 	mod->pat = mod->len;
 
@@ -89,6 +109,8 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		hio_read(buf, 1, 16, f);
 	}
 
+	m->c4rate = C4_NTSC_RATE;
+
 	MODULE_INFO();
  
 
@@ -108,16 +130,19 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	D_(D_INFO "Stored patterns: %d", mod->pat);
 
-	mod->xxp = calloc(sizeof(struct xmp_pattern *), mod->pat + 1);
+	mod->xxp = calloc(sizeof(struct xmp_pattern *), mod->pat);
 	if (mod->xxp == NULL)
 		return -1;
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_alloc(mod, i) < 0)
+		if (libxmp_alloc_pattern(mod, i) < 0)
 			return -1;
 
 		mod->xxp[i]->rows = ver >= 0x0e ? hio_read16l(f) : 64;
 
+		if (mod->xxp[i]->rows > 256)
+			return -1;
+
 		for (j = 0; j < mod->chn; j++) {
 			uint16 t = hio_read16l(f);
 			mod->xxp[i]->index[j] = t;
@@ -126,7 +151,7 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	/* Instruments */
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	/* Probe for 2-byte loop start 1.0 format
@@ -137,6 +162,9 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		uint8 b;
 		uint32 len, start, end;
 		long pos = hio_tell(f);
+		if (pos < 0) {
+			return -1;
+		}
 		for (i = 0; i < mod->ins; i++) {
 			b = hio_read8(f);
 			if (b != 0 && b != 1) {
@@ -179,13 +207,13 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		/*uint8 b;*/
 		int c2spd;
 
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 
 		/*b =*/ hio_read8(f);
 
 		hio_read(buf, 1, 32, f);
-		instrument_name(mod, i, buf, 32);
+		libxmp_instrument_name(mod, i, buf, 32);
 
 		hio_read(buf, 1, 13, f);	/* sample name */
 		hio_read32l(f);			/* sample index */
@@ -195,7 +223,7 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		mod->xxi[i].sub[0].pan = 0x80;
 		mod->xxs[i].len = hio_read32l(f);
 		c2spd = hio_read16l(f);
-		c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
+		libxmp_c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
 		mod->xxi[i].sub[0].vol = hio_read8(f);
 
 		/*
@@ -243,7 +271,6 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		t = hio_read16l(f);
 		trkmap[i] = t;
 		if (t > newtrk) newtrk = t;
-/*printf("%d -> %d\n", i, t);*/
 	}
 
 	for (i = 0; i < mod->pat; i++) {		/* read track table */
@@ -256,7 +283,6 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			if (k < 0 || k >= mod->trk)
 				k = 0;
 			mod->xxp[i]->index[j] = trkmap[k];
-/*printf("mod->xxp[%d]->info[%d].index = %d (k = %d)\n", i, j, trkmap[k], k);*/
 		}
 	}
 
@@ -271,7 +297,7 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		return -1;
 
 	/* Alloc track 0 as empty track */
-	if (track_alloc(mod, 0, 64) < 0)
+	if (libxmp_alloc_track(mod, 0, 64) < 0)
 		return -1;
 
 	/* Alloc rest of the tracks */
@@ -279,21 +305,23 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		uint8 t1, t2, t3;
 		int size;
 
-		if (track_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_track(mod, i, 64) < 0)	/* FIXME! */
 			return -1;
 
 		size = hio_read24l(f);
-/*printf("TRACK %d SIZE %d\n", i, size);*/
 
 		for (j = 0; j < size; j++) {
 			t1 = hio_read8(f);			/* row */
 			t2 = hio_read8(f);			/* type */
 			t3 = hio_read8(f);			/* parameter */
-/*printf("track %d row %d: %02x %02x %02x\n", i, t1, t1, t2, t3);*/
 
 			if (t1 == 0xff && t2 == 0xff && t3 == 0xff)
 				break;
 
+			/* Sanity check */
+			if (t1 >= mod->xxt[i]->rows)
+				return -1;
+
 			event = &mod->xxt[i]->event[t1];
 
 			if (t2 < 0x7f) {		/* note */
@@ -301,6 +329,12 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 					event->note = t2 + 1;
 				event->vol = t3;
 			} else if (t2 == 0x7f) {	/* copy previous */
+
+				/* Sanity check */
+				if (t1 == 0) {
+					return -1;
+				}
+
 				memcpy(event, &mod->xxt[i]->event[t1 - 1],
 					sizeof(struct xmp_event));
 			} else if (t2 == 0x80) {	/* instrument */
@@ -458,7 +492,6 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				event->fxt = fxt;
 				event->fxp = fxp;
 			}
-
 		}
 	}
 
@@ -468,7 +501,7 @@ static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	D_(D_INFO "Stored samples: %d", mod->smp);
 
 	for (i = 0; i < mod->ins; i++) {
-		if (load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
 			return -1;
 	}
 
diff --git a/src/loaders/arch_load.c b/src/loaders/arch_load.c
index 442b880..a43055e 100644
--- a/src/loaders/arch_load.c
+++ b/src/loaders/arch_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -11,13 +25,19 @@
 
 #define MAGIC_MUSX	MAGIC4('M','U','S','X')
 #define MAGIC_MNAM	MAGIC4('M','N','A','M')
+#define MAGIC_SNAM	MAGIC4('S','N','A','M')
+#define MAGIC_SVOL	MAGIC4('S','V','O','L')
+#define MAGIC_SLEN	MAGIC4('S','L','E','N')
+#define MAGIC_ROFS	MAGIC4('R','O','F','S')
+#define MAGIC_RLEN	MAGIC4('R','L','E','N')
+#define MAGIC_SDAT	MAGIC4('S','D','A','T')
 
 
 static int arch_test (HIO_HANDLE *, char *, const int);
 static int arch_load (struct module_data *, HIO_HANDLE *, const int);
 
 
-const struct format_loader arch_loader = {
+const struct format_loader libxmp_loader_arch = {
 	"Archimedes Tracker",
 	arch_test,
 	arch_load
@@ -50,8 +70,9 @@ static uint8 convert_vol(uint8 vol) {
 
 static int arch_test(HIO_HANDLE *f, char *t, const int start)
 {
-	if (hio_read32b(f) != MAGIC_MUSX)
+	if (hio_read32b(f) != MAGIC_MUSX) {
 		return -1;
+	}
 
 	hio_read32l(f);
 
@@ -59,15 +80,20 @@ static int arch_test(HIO_HANDLE *f, char *t, const int start)
 		uint32 id = hio_read32b(f);
 		uint32 len = hio_read32l(f);
 
+		/* Sanity check */
+		if (len > 0x100000) {
+			return -1;
+		}
+
 		if (id == MAGIC_MNAM) {
-			read_title(f, t, 32);
+			libxmp_read_title(f, t, 32);
 			return 0;
 		}
 
 		hio_seek(f, len, SEEK_CUR);
 	}
 
-	read_title(f, t, 0);
+	libxmp_read_title(f, t, 0);
 
 	return 0;
 }
@@ -172,6 +198,11 @@ static int get_mvox(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 
 	mod->chn = hio_read32l(f);
 
+	/* Sanity check */
+	if (mod->chn < 1 || mod->chn > 8) {
+		return -1;
+	}
+
 	return 0;
 }
 
@@ -181,9 +212,11 @@ static int get_ster(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	struct local_data *data = (struct local_data *)parm;
 	int i;
 
-	hio_read(data->ster, 1, 8, f);
+	if (hio_read(data->ster, 1, 8, f) != 8) {
+		return -1;
+	}
 	
-	for (i=0; i < mod->chn; i++) {
+	for (i = 0; i < mod->chn; i++) {
 		if (data->ster[i] > 0 && data->ster[i] < 8) {
 			mod->xxc[i].pan = 42 * data->ster[i] - 40;
 		}
@@ -196,7 +229,8 @@ static int get_mnam(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 {
 	struct xmp_module *mod = &m->mod;
 
-	hio_read(mod->name, 1, 32, f);
+	if (hio_read(mod->name, 1, 32, f) != 32)
+		return -1;
 
 	return 0;
 }
@@ -214,6 +248,10 @@ static int get_mlen(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 
 	mod->len = hio_read32l(f);
 
+	/* Sanity check */
+	if (mod->len > 0xff)
+		return -1;
+
 	return 0;
 }
 
@@ -223,6 +261,10 @@ static int get_pnum(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 
 	mod->pat = hio_read32l(f);
 
+	/* Sanity check */
+	if (mod->pat > 64 )
+		return -1;
+
 	return 0;
 }
 
@@ -230,7 +272,8 @@ static int get_plen(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 {
 	struct local_data *data = (struct local_data *)parm;
 
-	hio_read(data->rows, 1, 64, f);
+	if (hio_read(data->rows, 1, 64, f) != 64)
+		return -1;
 
 	return 0;
 }
@@ -240,7 +283,7 @@ static int get_sequ(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	struct xmp_module *mod = &m->mod;
 
 	hio_read(mod->xxo, 1, 128, f);
-	set_type(m, "Archimedes Tracker");
+	libxmp_set_type(m, "Archimedes Tracker");
 	MODULE_INFO();
 
 	return 0;
@@ -259,13 +302,17 @@ static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 		data->max_pat = 0;
 		mod->trk = mod->pat * mod->chn;
 
-		if (pattern_init(mod) < 0)
+		if (libxmp_init_pattern(mod) < 0)
 			return -1;
 	}
 
+	/* Sanity check */
+	if (data->max_pat >= mod->pat || data->max_pat >= 64)
+		return -1;
+
         i = data->max_pat;
 
-	if (pattern_tracks_alloc(mod, i, data->rows[i]) < 0)
+	if (libxmp_alloc_pattern_tracks(mod, i, data->rows[i]) < 0)
 		return -1;
 
 	for (j = 0; j < data->rows[i]; j++) {
@@ -297,7 +344,7 @@ static int get_samp(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 
 	if (!data->sflag) {
 		mod->smp = mod->ins = 36;
-		if (instrument_init(mod) < 0)
+		if (libxmp_init_instrument(m) < 0)
 			return -1;
 
 		D_(D_INFO "Instruments: %d", mod->ins);
@@ -316,38 +363,53 @@ static int get_samp(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	i = data->max_ins;
 
 	mod->xxi[i].nsm = 1;
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+		return -1;
+
+	if (hio_read32b(f) != MAGIC_SNAM)	/* SNAM */
 		return -1;
 
-	hio_read32l(f);	/* SNAM */
 	{
 		/* should usually be 0x14 but zero is not unknown */
 		int name_len = hio_read32l(f);
-		if (name_len < 32)
-			hio_read(mod->xxi[i].name, 1, name_len, f);
+
+		/* Sanity check */
+		if (name_len < 0 || name_len > 32)
+			return -1;
+
+		hio_read(mod->xxi[i].name, 1, name_len, f);
 	}
-	hio_read32l(f);	/* SVOL */
+
+	if (hio_read32b(f) != MAGIC_SVOL)	/* SVOL */
+		return -1;
 	hio_read32l(f);
 	/* mod->xxi[i].sub[0].vol = convert_vol(hio_read32l(f)); */
 	mod->xxi[i].sub[0].vol = hio_read32l(f) & 0xff;
-	hio_read32l(f);	/* SLEN */
+
+	if (hio_read32b(f) != MAGIC_SLEN)	/* SLEN */
+		return -1;
 	hio_read32l(f);
 	mod->xxs[i].len = hio_read32l(f);
-	hio_read32l(f);	/* ROFS */
+
+	if (hio_read32b(f) != MAGIC_ROFS)	/* ROFS */
+		return -1;
 	hio_read32l(f);
 	mod->xxs[i].lps = hio_read32l(f);
-	hio_read32l(f);	/* RLEN */
+
+	if (hio_read32b(f) != MAGIC_RLEN)	/* RLEN */
+		return -1;
 	hio_read32l(f);
 	mod->xxs[i].lpe = hio_read32l(f);
 
-	hio_read32l(f);	/* SDAT */
+	if (hio_read32b(f) != MAGIC_SDAT)	/* SDAT */
+		return -1;
 	hio_read32l(f);
 	hio_read32l(f);	/* 0x00000000 */
 
 	mod->xxi[i].sub[0].sid = i;
 	mod->xxi[i].sub[0].pan = 0x80;
 
-	m->vol_table = (int *)arch_vol_table;
+	m->vol_table = (int *)libxmp_arch_vol_table;
 	m->volbase = 0xff;
 
 	if (mod->xxs[i].lpe > 2) {
@@ -360,7 +422,7 @@ static int get_samp(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 		mod->xxs[i].lpe = mod->xxs[i].len;
 	}
 
-	if (load_sample(m, f, SAMPLE_FLAG_VIDC, &mod->xxs[i], NULL) < 0)
+	if (libxmp_load_sample(m, f, SAMPLE_FLAG_VIDC, &mod->xxs[i], NULL) < 0)
 		return -1;
 
 	D_(D_INFO "[%2X] %-20.20s %05x %05x %05x %c V%02x",
@@ -391,35 +453,36 @@ static int arch_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	data.pflag = data.sflag = 0;
 	data.year = data.month = data.day = 0;
 
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		return -1;
 
 	/* IFF chunk IDs */
-	iff_register(handle, "TINF", get_tinf);
-	iff_register(handle, "MVOX", get_mvox);
-	iff_register(handle, "STER", get_ster);
-	iff_register(handle, "MNAM", get_mnam);
-	iff_register(handle, "ANAM", get_anam);
-	iff_register(handle, "MLEN", get_mlen);
-	iff_register(handle, "PNUM", get_pnum);
-	iff_register(handle, "PLEN", get_plen);
-	iff_register(handle, "SEQU", get_sequ);
-	iff_register(handle, "PATT", get_patt);
-	iff_register(handle, "SAMP", get_samp);
-
-	iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
+	libxmp_iff_register(handle, "TINF", get_tinf);
+	libxmp_iff_register(handle, "MVOX", get_mvox);
+	libxmp_iff_register(handle, "STER", get_ster);
+	libxmp_iff_register(handle, "MNAM", get_mnam);
+	libxmp_iff_register(handle, "ANAM", get_anam);
+	libxmp_iff_register(handle, "MLEN", get_mlen);
+	libxmp_iff_register(handle, "PNUM", get_pnum);
+	libxmp_iff_register(handle, "PLEN", get_plen);
+	libxmp_iff_register(handle, "SEQU", get_sequ);
+	libxmp_iff_register(handle, "PATT", get_patt);
+	libxmp_iff_register(handle, "SAMP", get_samp);
+
+	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
 
 	/* Load IFF chunks */
-	if (iff_load(handle, m, f, &data) < 0) {
-		iff_release(handle);
+	if (libxmp_iff_load(handle, m, f, &data) < 0) {
+		libxmp_iff_release(handle);
 		return -1;
 	}
 
-	iff_release(handle);
+	libxmp_iff_release(handle);
 
-	for (i = 0; i < mod->chn; i++)
-		mod->xxc[i].pan = (((i + 3) / 2) % 2) * 0xff;
+	for (i = 0; i < mod->chn; i++) {
+		mod->xxc[i].pan = DEFPAN((((i + 3) / 2) % 2) * 0xff);
+	}
 
 	return 0;
 }
diff --git a/src/loaders/asif.c b/src/loaders/asif.c
index 40bbd82..d095cd6 100644
--- a/src/loaders/asif.c
+++ b/src/loaders/asif.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include 
@@ -55,7 +69,7 @@ int asif_load(struct module_data *m, HIO_HANDLE *f, int i)
 				hio_read16l(f);		/* SampRate */
 			}
 		
-			if (load_sample(m, f, SAMPLE_FLAG_UNS,
+			if (libxmp_load_sample(m, f, SAMPLE_FLAG_UNS,
 						&mod->xxs[i], NULL) < 0) {
 				return -1;
 			}
diff --git a/src/loaders/asylum_load.c b/src/loaders/asylum_load.c
index e9bd2f5..cbcd0ea 100644
--- a/src/loaders/asylum_load.c
+++ b/src/loaders/asylum_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -30,7 +30,7 @@
 static int asylum_test(HIO_HANDLE *, char *, const int);
 static int asylum_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader asylum_loader = {
+const struct format_loader libxmp_loader_asylum = {
 	"Asylum Music Format v1.0",
 	asylum_test,
 	asylum_load
@@ -46,7 +46,7 @@ static int asylum_test(HIO_HANDLE *f, char *t, const int start)
 	if (memcmp(buf, "ASYLUM Music Format V1.0\0\0\0\0\0\0\0\0", 32))
 		return -1;
 
-	read_title(f, t, 0);
+	libxmp_read_title(f, t, 0);
 
 	return 0;
 }
@@ -78,18 +78,22 @@ static int asylum_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	MODULE_INFO();
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	/* Read and convert instruments and samples */
 	for (i = 0; i < mod->ins; i++) {
 		uint8 insbuf[37];
 
-		if (subinstrument_alloc(mod, i, 1) < 0)	
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)	{
 			return -1;
+		}
+
+		if (hio_read(insbuf, 1, 37, f) != 37) {
+			return -1;
+		}
 
-		hio_read(insbuf, 1, 37, f);
-		instrument_name(mod, i, insbuf, 22);
+		libxmp_instrument_name(mod, i, insbuf, 22);
 		mod->xxi[i].sub[0].fin = (int8)(insbuf[22] << 4);
 		mod->xxi[i].sub[0].vol = insbuf[23];
 		mod->xxi[i].sub[0].xpo = (int8)insbuf[24];
@@ -113,14 +117,14 @@ static int asylum_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	D_(D_INFO "Module length: %d", mod->len);
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	/* Read and convert patterns */
 	D_(D_INFO "Stored patterns: %d", mod->pat);
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 			return -1;
 
 		for (j = 0; j < 64 * mod->chn; j++) {
@@ -137,6 +141,9 @@ static int asylum_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			event->ins = hio_read8(f);
 			event->fxt = hio_read8(f);
 			event->fxp = hio_read8(f);
+			if (hio_error(f)) {
+				return -1;
+			}
 		}
 	}
 
@@ -145,7 +152,7 @@ static int asylum_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	for (i = 0; i < mod->ins; i++) {
 		if (mod->xxs[i].len > 1) {
-			if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+			if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
 				return -1;
 			mod->xxi[i].nsm = 1;
 		}
diff --git a/src/loaders/chip_load.c b/src/loaders/chip_load.c
index 4524afa..04c8806 100644
--- a/src/loaders/chip_load.c
+++ b/src/loaders/chip_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -27,7 +27,7 @@
 static int chip_test(HIO_HANDLE *, char *, const int);
 static int chip_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader chip_loader = {
+const struct format_loader libxmp_loader_chip = {
 	"Chiptracker",
 	chip_test,
 	chip_load
@@ -46,7 +46,7 @@ static int chip_test(HIO_HANDLE *f, char *t, const int start)
 		return -1;
 
 	hio_seek(f, start + 0, SEEK_SET);
-	read_title(f, t, 20);
+	libxmp_read_title(f, t, 20);
 
 	return 0;
 }
@@ -60,8 +60,9 @@ static int chip_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	LOAD_INIT();
 
-	if ((tidx = calloc(1, 1024)) == NULL)
+	if ((tidx = calloc(1, 1024)) == NULL) {
 		goto err;
+	}
 
 	hio_read(&mh.name, 20, 1, f);
 	hio_read16b(f);
@@ -77,6 +78,12 @@ static int chip_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	hio_read(&mh.magic, 4, 1, f);
 	mh.len = hio_read8(f);
+
+	/* Sanity check */
+	if (mh.len > 128) {
+		goto err2;
+	}
+
 	mh.restart = hio_read8(f);
 	hio_read(tidx, 1024, 1, f);
 	hio_read16b(f);
@@ -102,10 +109,10 @@ static int chip_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->trk = tnum + 1;
 
 	strncpy(mod->name, (char *)mh.name, 20);
-	set_type(m, "Chiptracker");
+	libxmp_set_type(m, "Chiptracker");
 	MODULE_INFO();
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		goto err2;
 
 	for (i = 0; i < mod->ins; i++) {
@@ -113,8 +120,8 @@ static int chip_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		struct xmp_sample *xxs = &mod->xxs[i];
 		struct xmp_subinstrument *sub;
 
-		if (subinstrument_alloc(mod, i, 1) < 0)
-			goto err;
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			goto err2;
 
 		sub = &xxi->sub[0];
 
@@ -130,14 +137,14 @@ static int chip_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		if (xxs->len > 0)
 			xxi->nsm = 1;
 
-		instrument_name(mod, i, mh.ins[i].name, 22);
+		libxmp_instrument_name(mod, i, mh.ins[i].name, 22);
 	}
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		goto err2;
 
 	for (i = 0; i < mod->len; i++) {
-		if (pattern_alloc(mod, i) < 0)
+		if (libxmp_alloc_pattern(mod, i) < 0)
 			goto err2;
 		mod->xxp[i]->rows = 64;
 
@@ -151,7 +158,7 @@ static int chip_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	D_(D_INFO "Stored tracks: %d", mod->trk);
 
 	for (i = 0; i < mod->trk; i++) {
-		if (track_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_track(mod, i, 64) < 0)
 			goto err2;
 
 		for (j = 0; j < 64; j++) {
@@ -167,7 +174,7 @@ static int chip_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		}
 	}
 
-	m->quirk |= QUIRK_MODRNG;
+	m->period_type = PERIOD_MODRNG;
 
 	/* Load samples */
 
@@ -177,7 +184,7 @@ static int chip_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		if (mod->xxs[i].len == 0)
 			continue;
 
-		if (load_sample(m, f, SAMPLE_FLAG_FULLREP, &mod->xxs[i], NULL) < 0)
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_FULLREP, &mod->xxs[i], NULL) < 0)
 			goto err2;
 	}
 
diff --git a/src/loaders/coco_load.c b/src/loaders/coco_load.c
new file mode 100644
index 0000000..eb270ac
--- /dev/null
+++ b/src/loaders/coco_load.c
@@ -0,0 +1,298 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "loader.h"
+
+static int coco_test (HIO_HANDLE *, char *, const int);
+static int coco_load (struct module_data *, HIO_HANDLE *, const int);
+
+const struct format_loader libxmp_loader_coco = {
+	"Coconizer",
+	coco_test,
+	coco_load
+};
+
+static int check_cr(uint8 *s, int n)
+{
+	while (n--) {
+		if (*s++ == 0x0d)
+			return 0;
+	}
+
+	return -1;
+}
+
+static int coco_test(HIO_HANDLE *f, char *t, const int start)
+{
+	uint8 x, buf[20];
+	uint32 y;
+	int n, i;
+
+	x = hio_read8(f);
+
+	/* check number of channels */
+	if (x != 0x84 && x != 0x88)
+		return -1;
+
+	hio_read(buf, 1, 20, f);		/* read title */
+	if (check_cr(buf, 20) != 0)
+		return -1;
+
+	n = hio_read8(f);			/* instruments */
+	if (n > 100)
+		return -1;
+
+	hio_read8(f);			/* sequences */
+	hio_read8(f);			/* patterns */
+
+	y = hio_read32l(f);
+	if (y < 64 || y > 0x00100000)	/* offset of sequence table */
+		return -1;
+
+	y = hio_read32l(f);			/* offset of patterns */
+	if (y < 64 || y > 0x00100000)
+		return -1;
+
+	for (i = 0; i < n; i++) {
+		int ofs = hio_read32l(f);
+		int len = hio_read32l(f);
+		int vol = hio_read32l(f);
+		int lps = hio_read32l(f);
+		int lsz = hio_read32l(f);
+
+		if (ofs < 64 || ofs > 0x00100000)
+			return -1;
+
+		if (vol > 0xff)
+			return -1;
+
+		if (len > 0x00100000 || lps > 0x00100000 || lsz > 0x00100000)
+			return -1;
+
+		if (lps + lsz - 1 > len)
+			return -1;
+
+		hio_read(buf, 1, 11, f);
+		if (check_cr(buf, 11) != 0)
+			return -1;
+
+		hio_read8(f);	/* unused */
+	}
+
+	hio_seek(f, start + 1, SEEK_SET);
+	libxmp_read_title(f, t, 20);
+
+#if 0
+	for (i = 0; i < 20; i++) {
+		if (t[i] == 0x0d)
+			t[i] = 0;
+	}
+#endif
+	
+	return 0;
+}
+
+
+static void fix_effect(struct xmp_event *e)
+{
+	switch (e->fxt) {
+	case 0x00:			/* 00 xy Normal play or Arpeggio */
+		e->fxt = FX_ARPEGGIO;
+		/* x: first halfnote to add
+		   y: second halftone to subtract */
+		break;
+	case 0x01:			/* 01 xx Slide Up */
+	case 0x05:
+		e->fxt = FX_PORTA_UP;
+		break;
+	case 0x02:			/* 02 xx Slide Down */
+	case 0x06:
+		e->fxt = FX_PORTA_DN;
+		break;
+	case 0x03:
+		e->fxt = FX_VOLSLIDE_UP;	/* FIXME: it's fine */
+		break;
+	case 0x04:
+		e->fxt = FX_VOLSLIDE_DN;	/* FIXME: it's fine */
+		break;
+	case 0x07:
+		e->fxt = FX_SETPAN;
+		break;
+	case 0x08:			/* FIXME */
+	case 0x09:
+	case 0x0a:
+	case 0x0b:
+		e->fxt = e->fxp = 0;
+		break;
+	case 0x0c:
+		e->fxt = FX_VOLSET;
+		e->fxp = 0xff - e->fxp;
+		break;
+	case 0x0d:
+		e->fxt = FX_BREAK;
+		break;
+	case 0x0e:
+		e->fxt = FX_JUMP;
+		break;
+	case 0x0f:
+		e->fxt = FX_SPEED;
+		break;
+	case 0x10:			/* unused */
+		e->fxt = e->fxp = 0;
+		break;
+	case 0x11:
+	case 0x12:			/* FIXME */
+		e->fxt = e->fxp = 0;
+		break;
+	case 0x13:
+		e->fxt = FX_VOLSLIDE_UP;
+		break;
+	case 0x14:
+		e->fxt = FX_VOLSLIDE_DN;
+		break;
+	default:
+		e->fxt = e->fxp = 0;
+	}
+}
+
+static int coco_load(struct module_data *m, HIO_HANDLE *f, const int start)
+{
+	struct xmp_module *mod = &m->mod;
+	struct xmp_event *event;
+	int i, j;
+	int seq_ptr, pat_ptr, smp_ptr[100];
+
+	LOAD_INIT();
+
+	mod->chn = hio_read8(f) & 0x3f;
+	libxmp_read_title(f, mod->name, 20);
+
+	for (i = 0; i < 20; i++) {
+		if (mod->name[i] == 0x0d)
+			mod->name[i] = 0;
+	}
+
+	libxmp_set_type(m, "Coconizer");
+
+	mod->ins = mod->smp = hio_read8(f);
+	mod->len = hio_read8(f);
+	mod->pat = hio_read8(f);
+	mod->trk = mod->pat * mod->chn;
+
+	seq_ptr = hio_read32l(f);
+	pat_ptr = hio_read32l(f);
+
+	MODULE_INFO();
+
+	if (libxmp_init_instrument(m) < 0)
+		return -1;
+
+	m->vol_table = (int *)arch_vol_table;
+	m->volbase = 0xff;
+
+	for (i = 0; i < mod->ins; i++) {
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+
+		smp_ptr[i] = hio_read32l(f);
+		mod->xxs[i].len = hio_read32l(f);
+		mod->xxi[i].sub[0].vol = 0xff - hio_read32l(f);
+		mod->xxi[i].sub[0].pan = 0x80;
+		mod->xxs[i].lps = hio_read32l(f);
+                mod->xxs[i].lpe = mod->xxs[i].lps + hio_read32l(f);
+		if (mod->xxs[i].lpe)
+			mod->xxs[i].lpe -= 1;
+		mod->xxs[i].flg = mod->xxs[i].lps > 0 ?  XMP_SAMPLE_LOOP : 0;
+		hio_read(mod->xxi[i].name, 1, 11, f);
+		for (j = 0; j < 11; j++) {
+			if (mod->xxi[i].name[j] == 0x0d)
+				mod->xxi[i].name[j] = 0;
+		}
+		hio_read8(f);	/* unused */
+		mod->xxi[i].sub[0].sid = i;
+
+		if (mod->xxs[i].len > 0)
+			mod->xxi[i].nsm = 1;
+
+		D_(D_INFO "[%2X] %-10.10s  %05x %05x %05x %c V%02x",
+				i, mod->xxi[i].name,
+				mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
+				mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
+				mod->xxi[i].sub[0].vol);
+	}
+
+	/* Sequence */
+
+	hio_seek(f, start + seq_ptr, SEEK_SET);
+	for (i = 0; ; i++) {
+		uint8 x = hio_read8(f);
+		if (x == 0xff)
+			break;
+		mod->xxo[i] = x;
+	}
+	for (i++; i % 4; i++)	/* for alignment */
+		hio_read8(f);
+
+
+	/* Patterns */
+
+	if (libxmp_init_pattern(mod) < 0)
+		return -1;
+
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
+			return -1;
+
+		for (j = 0; j < (64 * mod->chn); j++) {
+			event = &EVENT (i, j % mod->chn, j / mod->chn);
+			event->fxp = hio_read8(f);
+			event->fxt = hio_read8(f);
+			event->ins = hio_read8(f);
+			event->note = hio_read8(f);
+			if (event->note)
+				event->note += 12;
+
+			fix_effect(event);
+		}
+	}
+
+	/* Read samples */
+
+	D_(D_INFO "Stored samples : %d", mod->smp);
+
+	for (i = 0; i < mod->ins; i++) {
+		if (mod->xxi[i].nsm == 0)
+			continue;
+
+		hio_seek(f, start + smp_ptr[i], SEEK_SET);
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_VIDC, &mod->xxs[i], NULL) < 0)
+			return -1;
+	}
+
+	for (i = 0; i < mod->chn; i++) {
+		mod->xxc[i].pan = DEFPAN((((i + 3) / 2) % 2) * 0xff);
+	}
+
+	return 0;
+}
diff --git a/src/loaders/common.c b/src/loaders/common.c
index 11b10cd..d543d6b 100644
--- a/src/loaders/common.c
+++ b/src/loaders/common.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -32,22 +32,35 @@
 #include "period.h"
 #include "loader.h"
 
-int instrument_init(struct xmp_module *mod)
+int libxmp_init_instrument(struct module_data *m)
 {
-	mod->xxi = calloc(sizeof (struct xmp_instrument), mod->ins);
-	if (mod->xxi == NULL)
-		return -1;
+	struct xmp_module *mod = &m->mod;
+
+	if (mod->ins > 0) {
+		mod->xxi = calloc(sizeof (struct xmp_instrument), mod->ins);
+		if (mod->xxi == NULL)
+			return -1;
+	}
 
-	if (mod->smp) {
-		mod->xxs = calloc (sizeof (struct xmp_sample), mod->smp);
+	if (mod->smp > 0) {
+		int i;
+
+		mod->xxs = calloc(sizeof (struct xmp_sample), mod->smp);
 		if (mod->xxs == NULL)
 			return -1;
+		m->xtra = calloc(sizeof (struct extra_sample_data), mod->smp);
+		if (m->xtra == NULL)
+			return -1;
+
+		for (i = 0; i < mod->smp; i++) {
+			m->xtra[i].c5spd = m->c4rate;
+		}
 	}
 
 	return 0;
 }
 
-int subinstrument_alloc(struct xmp_module *mod, int i, int num)
+int libxmp_alloc_subinstrument(struct xmp_module *mod, int i, int num)
 {
 	if (num == 0)
 		return 0;
@@ -59,7 +72,7 @@ int subinstrument_alloc(struct xmp_module *mod, int i, int num)
 	return 0;
 }
 
-int pattern_init(struct xmp_module *mod)
+int libxmp_init_pattern(struct xmp_module *mod)
 {
 	mod->xxt = calloc(sizeof (struct xmp_track *), mod->trk);
 	if (mod->xxt == NULL)
@@ -72,8 +85,12 @@ int pattern_init(struct xmp_module *mod)
 	return 0;
 }
 
-int pattern_alloc(struct xmp_module *mod, int num)
+int libxmp_alloc_pattern(struct xmp_module *mod, int num)
 {
+	/* Sanity check */
+	if (num < 0 || num >= mod->pat || mod->xxp[num] != NULL)
+		return -1;
+
 	mod->xxp[num] = calloc(1, sizeof (struct xmp_pattern) +
         				sizeof (int) * (mod->chn - 1));
 	if (mod->xxp[num] == NULL)
@@ -82,10 +99,14 @@ int pattern_alloc(struct xmp_module *mod, int num)
 	return 0;
 }
 
-int track_alloc(struct xmp_module *mod, int num, int rows)
+int libxmp_alloc_track(struct xmp_module *mod, int num, int rows)
 {
-	mod->xxt[num] = calloc (sizeof (struct xmp_track) +
-				sizeof (struct xmp_event) * (rows - 1), 1);
+	/* Sanity check */
+	if (num < 0 || num >= mod->trk || mod->xxt[num] != NULL || rows <= 0)
+		return -1;
+
+	mod->xxt[num] = calloc(sizeof (struct xmp_track) +
+			       sizeof (struct xmp_event) * (rows - 1), 1);
 	if (mod->xxt[num] == NULL)
 		return -1;
 
@@ -94,15 +115,16 @@ int track_alloc(struct xmp_module *mod, int num, int rows)
 	return 0;
 }
 
-int tracks_in_pattern_alloc(struct xmp_module *mod, int num)
+int libxmp_alloc_tracks_in_pattern(struct xmp_module *mod, int num)
 {
 	int i;
 
+	D_(D_INFO "Alloc %d tracks of %d rows", mod->chn, mod->xxp[num]->rows);
 	for (i = 0; i < mod->chn; i++) {
 		int t = num * mod->chn + i;
 		int rows = mod->xxp[num]->rows;
 
-		if (track_alloc(mod, t, rows) < 0)
+		if (libxmp_alloc_track(mod, t, rows) < 0)
 			return -1;
 
 		mod->xxp[num]->index[i] = t;
@@ -111,20 +133,25 @@ int tracks_in_pattern_alloc(struct xmp_module *mod, int num)
 	return 0;
 }
 
-int pattern_tracks_alloc(struct xmp_module *mod, int num, int rows)
+int libxmp_alloc_pattern_tracks(struct xmp_module *mod, int num, int rows)
 {
-	if (pattern_alloc(mod, num) < 0)
+	/* Sanity check */
+	if (rows < 0 || rows > 256)
 		return -1;
+
+	if (libxmp_alloc_pattern(mod, num) < 0)
+		return -1;
+
 	mod->xxp[num]->rows = rows;
 
-	if (tracks_in_pattern_alloc(mod, num) < 0)
+	if (libxmp_alloc_tracks_in_pattern(mod, num) < 0)
 		return -1;
 
 	return 0;
 }
 
 /* Sample number adjustment by Vitamin/CAIG */
-struct xmp_sample *realloc_samples(struct xmp_sample *buf, int *size, int new_size)
+struct xmp_sample *libxmp_realloc_samples(struct xmp_sample *buf, int *size, int new_size)
 {
 	buf = realloc(buf, sizeof (struct xmp_sample) * new_size);
 	if (buf == NULL)
@@ -136,14 +163,14 @@ struct xmp_sample *realloc_samples(struct xmp_sample *buf, int *size, int new_si
 	return buf;
 }
 
-char *instrument_name(struct xmp_module *mod, int i, uint8 *r, int n)
+char *libxmp_instrument_name(struct xmp_module *mod, int i, uint8 *r, int n)
 {
 	CLAMP(n, 0, 31);
 
-	return copy_adjust(mod->xxi[i].name, r, n);
+	return libxmp_copy_adjust(mod->xxi[i].name, r, n);
 }
 
-char *copy_adjust(char *s, uint8 *r, int n)
+char *libxmp_copy_adjust(char *s, uint8 *r, int n)
 {
 	int i;
 
@@ -161,7 +188,7 @@ char *copy_adjust(char *s, uint8 *r, int n)
 	return s;
 }
 
-void read_title(HIO_HANDLE *f, char *t, int s)
+void libxmp_read_title(HIO_HANDLE *f, char *t, int s)
 {
 	uint8 buf[XMP_NAME_SIZE];
 
@@ -173,14 +200,14 @@ void read_title(HIO_HANDLE *f, char *t, int s)
 
 	memset(t, 0, s + 1);
 
-	hio_read(buf, 1, s, f);
+	hio_read(buf, 1, s, f);		/* coverity[check_return] */
 	buf[s] = 0;
-	copy_adjust(t, buf, s);
+	libxmp_copy_adjust(t, buf, s);
 }
 
 #ifndef LIBXMP_CORE_PLAYER
 
-int test_name(uint8 *s, int n)
+int libxmp_test_name(uint8 *s, int n)
 {
 	int i;
 
@@ -218,12 +245,12 @@ int test_name(uint8 *s, int n)
  * module players erroneously interpret as "newer-version-trackers commands".
  * Which they aren't.
  */
-void decode_noisetracker_event(struct xmp_event *event, uint8 *mod_event)
+void libxmp_decode_noisetracker_event(struct xmp_event *event, uint8 *mod_event)
 {
 	int fxt;
 
 	memset(event, 0, sizeof (struct xmp_event));
-	event->note = period_to_note((LSN(mod_event[0]) << 8) + mod_event[1]);
+	event->note = libxmp_period_to_note((LSN(mod_event[0]) << 8) + mod_event[1]);
 	event->ins = ((MSN(mod_event[0]) << 4) | MSN(mod_event[2]));
 	fxt = LSN(mod_event[2]);
 
@@ -232,16 +259,16 @@ void decode_noisetracker_event(struct xmp_event *event, uint8 *mod_event)
 		event->fxp = mod_event[3];
 	}
 
-	disable_continue_fx(event);
+	libxmp_disable_continue_fx(event);
 }
 #endif
 
-void decode_protracker_event(struct xmp_event *event, uint8 *mod_event)
+void libxmp_decode_protracker_event(struct xmp_event *event, uint8 *mod_event)
 {
 	int fxt = LSN(mod_event[2]);
 
 	memset(event, 0, sizeof (struct xmp_event));
-	event->note = period_to_note((LSN(mod_event[0]) << 8) + mod_event[1]);
+	event->note = libxmp_period_to_note((LSN(mod_event[0]) << 8) + mod_event[1]);
 	event->ins = ((MSN(mod_event[0]) << 4) | MSN(mod_event[2]));
 
 	if (fxt != 0x08) {
@@ -249,12 +276,12 @@ void decode_protracker_event(struct xmp_event *event, uint8 *mod_event)
 		event->fxp = mod_event[3];
 	}
 
-	disable_continue_fx(event);
+	libxmp_disable_continue_fx(event);
 }
 
-void disable_continue_fx(struct xmp_event *event)
+void libxmp_disable_continue_fx(struct xmp_event *event)
 {
-	if (!event->fxp) {
+	if (event->fxp == 0) {
 		switch (event->fxt) {
 		case 0x05:
 			event->fxt = 0x03;
@@ -267,6 +294,10 @@ void disable_continue_fx(struct xmp_event *event)
 		case 0x0a:
 			event->fxt = 0x00;
 		}
+	} else if (event->fxt == 0x0e) {
+		if (event->fxp == 0xa0 || event->fxp == 0xb0) {
+			event->fxt = event->fxp = 0;
+		}
 	}
 }
 
@@ -275,7 +306,7 @@ void disable_continue_fx(struct xmp_event *event)
 
 /* Given a directory, see if file exists there, ignoring case */
 
-int check_filename_case(char *dir, char *name, char *new_name, int size)
+int libxmp_check_filename_case(char *dir, char *name, char *new_name, int size)
 {
 	int found = 0;
 	DIR *dirfd;
@@ -304,14 +335,14 @@ int check_filename_case(char *dir, char *name, char *new_name, int size)
 
 /* FIXME: implement functionality for Win32 */
 
-int check_filename_case(char *dir, char *name, char *new_name, int size)
+int libxmp_check_filename_case(char *dir, char *name, char *new_name, int size)
 {
 	return 0;
 }
 
 #endif
 
-void get_instrument_path(struct module_data *m, char *path, int size)
+void libxmp_get_instrument_path(struct module_data *m, char *path, int size)
 {
 	if (m->instrument_path) {
 		strncpy(path, m->instrument_path, size);
@@ -323,7 +354,7 @@ void get_instrument_path(struct module_data *m, char *path, int size)
 }
 #endif /* LIBXMP_CORE_PLAYER */
 
-void set_type(struct module_data *m, char *fmt, ...)
+void libxmp_set_type(struct module_data *m, char *fmt, ...)
 {
 	va_list ap;
 	va_start(ap, fmt);
diff --git a/src/loaders/dbm_load.c b/src/loaders/dbm_load.c
index c5f0539..cbef747 100644
--- a/src/loaders/dbm_load.c
+++ b/src/loaders/dbm_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 /* Based on DigiBooster_E.guide from the DigiBoosterPro 2.20 package.
@@ -20,7 +34,7 @@
 static int dbm_test(HIO_HANDLE *, char *, const int);
 static int dbm_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader dbm_loader = {
+const struct format_loader libxmp_loader_dbm = {
 	"DigiBooster Pro",
 	dbm_test,
 	dbm_load
@@ -32,7 +46,7 @@ static int dbm_test(HIO_HANDLE * f, char *t, const int start)
 		return -1;
 
 	hio_seek(f, 12, SEEK_CUR);
-	read_title(f, t, 44);
+	libxmp_read_title(f, t, 44);
 
 	return 0;
 }
@@ -46,19 +60,58 @@ struct local_data {
 static int get_info(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 {
 	struct xmp_module *mod = &m->mod;
+	int val;
+
+	/* Sanity check */
+	if (mod->ins != 0) {
+		return -1;
+	}
+ 
+	val = hio_read16b(f);
+	if (val < 0 || val > 255) {
+		D_(D_CRIT "Invalid number of instruments: %d", val);
+		goto err;
+	}
+	mod->ins = val;
+
+	val = hio_read16b(f);
+	if (val < 0) {
+		D_(D_CRIT "Invalid number of samples: %d", val);
+		goto err2;
+	}
+	mod->smp = val;
 
-	mod->ins = hio_read16b(f);
-	mod->smp = hio_read16b(f);
 	hio_read16b(f);			/* Songs */
-	mod->pat = hio_read16b(f);
-	mod->chn = hio_read16b(f);
+
+	val = hio_read16b(f);
+	if (val < 0 || val > 256) {
+		D_(D_CRIT "Invalid number of patterns: %d", val);
+		goto err3;
+	}
+	mod->pat = val;
+
+	val = hio_read16b(f);
+	if (val < 0 || val > XMP_MAX_CHANNELS) {
+		D_(D_CRIT "Invalid number of channels: %d", val);
+		goto err4;
+	}
+	mod->chn = val;
 
 	mod->trk = mod->pat * mod->chn;
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	return 0;
+
+    err4:
+	mod->pat = 0;
+    err3:
+	mod->smp = 0;
+    err2:
+	mod->ins = 0;
+    err:
+	return -1;
 }
 
 static int get_song(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
@@ -79,6 +132,11 @@ static int get_song(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	mod->len = hio_read16b(f);
 	D_(D_INFO "Song length: %d patterns", mod->len);
 
+	/* Sanity check */
+	if (mod->len > 256) {
+		return -1;
+	}
+
 	for (i = 0; i < mod->len; i++)
 		mod->xxo[i] = hio_read16b(f);
 
@@ -96,11 +154,11 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 
 	for (i = 0; i < mod->ins; i++) {
 		mod->xxi[i].nsm = 1;
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 
 		hio_read(buffer, 30, 1, f);
-		instrument_name(mod, i, buffer, 30);
+		libxmp_instrument_name(mod, i, buffer, 30);
 		snum = hio_read16b(f);
 		if (snum == 0 || snum > mod->smp)
 			continue;
@@ -117,7 +175,7 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 		mod->xxs[snum].flg = flags & 0x03 ? XMP_SAMPLE_LOOP : 0;
 		mod->xxs[snum].flg |= flags & 0x02 ? XMP_SAMPLE_LOOP_BIDIR : 0;
 
-		c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
+		libxmp_c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
 
 		D_(D_INFO "[%2X] %-30.30s #%02X V%02x P%02x %5d",
 			i, mod->xxi[i].name, snum,
@@ -134,7 +192,7 @@ static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	struct xmp_event *event, dummy;
 	uint8 x;
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	D_(D_INFO "Stored patterns: %d ", mod->pat);
@@ -145,14 +203,14 @@ static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	 */
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, hio_read16b(f)) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, hio_read16b(f)) < 0)
 			return -1;
 
 		sz = hio_read32b(f);
 		//printf("rows = %d, size = %d\n", mod->xxp[i]->rows, sz);
 
 		r = 0;
-		c = -1;
+		/*c = -1;*/
 
 		while (sz > 0) {
 			//printf("  offset=%x,  sz = %d, ", hio_tell(f), sz);
@@ -162,7 +220,6 @@ static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 
 			if (c == 0) {
 				r++;
-				c = -1;
 				continue;
 			}
 			c--;
@@ -171,10 +228,13 @@ static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 			if (--sz <= 0) break;
 			//printf("    n = %d\n", n);
 
-			if (c >= mod->chn || r >= mod->xxp[i]->rows)
+			if (c >= mod->chn || r >= mod->xxp[i]->rows) {
 				event = &dummy;
-			else
+			} else {
 				event = &EVENT(i, c, r);
+			}
+
+			memset(event, 0, sizeof (struct xmp_event));
 
 			if (n & 0x01) {
 				x = hio_read8(f);
@@ -240,7 +300,7 @@ static int get_smpl(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 			continue;
 		}
 		
-		if (load_sample(m, f, SAMPLE_FLAG_BIGEND, &mod->xxs[i], NULL) < 0)
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_BIGEND, &mod->xxs[i], NULL) < 0)
 			return -1;
 
 		if (mod->xxs[i].len == 0)
@@ -305,17 +365,19 @@ static int dbm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	hio_seek(f, 10, SEEK_CUR);
 	hio_read(name, 1, 44, f);
 
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		return -1;
 
+	m->c4rate = C4_NTSC_RATE;
+
 	/* IFF chunk IDs */
-	ret = iff_register(handle, "INFO", get_info);
-	ret |= iff_register(handle, "SONG", get_song);
-	ret |= iff_register(handle, "INST", get_inst);
-	ret |= iff_register(handle, "PATT", get_patt);
-	ret |= iff_register(handle, "SMPL", get_smpl);
-	ret |= iff_register(handle, "VENV", get_venv);
+	ret = libxmp_iff_register(handle, "INFO", get_info);
+	ret |= libxmp_iff_register(handle, "SONG", get_song);
+	ret |= libxmp_iff_register(handle, "INST", get_inst);
+	ret |= libxmp_iff_register(handle, "PATT", get_patt);
+	ret |= libxmp_iff_register(handle, "SMPL", get_smpl);
+	ret |= libxmp_iff_register(handle, "VENV", get_venv);
 
 	if (ret != 0)
 		return -1;
@@ -323,15 +385,16 @@ static int dbm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	strncpy(mod->name, name, XMP_NAME_SIZE);
 	snprintf(mod->type, XMP_NAME_SIZE, "DigiBooster Pro %d.%02x DBM0",
 					version >> 8, version & 0xff);
+
 	MODULE_INFO();
 
 	/* Load IFF chunks */
-	if (iff_load(handle, m, f, &data) < 0) {
-		iff_release(handle);
+	if (libxmp_iff_load(handle, m, f, &data) < 0) {
+		libxmp_iff_release(handle);
 		return -1;
 	}
 
-	iff_release(handle);
+	libxmp_iff_release(handle);
 
 	for (i = 0; i < mod->chn; i++)
 		mod->xxc[i].pan = 0x80;
diff --git a/src/loaders/digi_load.c b/src/loaders/digi_load.c
index b20f251..e427dcc 100644
--- a/src/loaders/digi_load.c
+++ b/src/loaders/digi_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -41,7 +41,7 @@
 static int digi_test (HIO_HANDLE *, char *, const int);
 static int digi_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader digi_loader = {
+const struct format_loader libxmp_loader_digi = {
     "DIGI Booster",
     digi_test,
     digi_load
@@ -61,7 +61,7 @@ static int digi_test(HIO_HANDLE *f, char *t, const int start)
     hio_seek(f, 3 * 4 * 32, SEEK_CUR);
     hio_seek(f, 2 * 1 * 32, SEEK_CUR);
 
-    read_title(f, t, 32);
+    libxmp_read_title(f, t, 32);
 
     return 0;
 }
@@ -107,6 +107,12 @@ static int digi_load(struct module_data *m, HIO_HANDLE *f, const int start)
     hio_read(&dh.unknown, 19, 1, f);
     dh.pat = hio_read8(f);
     dh.len = hio_read8(f);
+
+    /* Sanity check */
+    if (dh.len > 127) {
+        return -1;
+    }
+
     hio_read(&dh.ord, 128, 1, f);
 
     for (i = 0; i < 31; i++)
@@ -132,23 +138,23 @@ static int digi_load(struct module_data *m, HIO_HANDLE *f, const int start)
     mod->trk = mod->pat * mod->chn;
     mod->len = dh.len + 1;
 
-    m->quirk |= QUIRK_MODRNG;
+    m->period_type = PERIOD_MODRNG;
 
-    copy_adjust(mod->name, dh.title, 32);
-    set_type(m, "DIGI Booster %-4.4s", dh.vstr);
+    libxmp_copy_adjust(mod->name, dh.title, 32);
+    libxmp_set_type(m, "DIGI Booster %-4.4s", dh.vstr);
 
     MODULE_INFO();
  
     for (i = 0; i < mod->len; i++)
 	mod->xxo[i] = dh.ord[i];
  
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     /* Read and convert instruments and samples */
 
     for (i = 0; i < mod->ins; i++) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 	    return -1;
 
 	mod->xxs[i].len = dh.slen[i];
@@ -163,21 +169,21 @@ static int digi_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	if (mod->xxs[i].len > 0)
 	    mod->xxi[i].nsm = 1;
 
-	instrument_name(mod, i, dh.insname[i], 30);
+	libxmp_instrument_name(mod, i, dh.insname[i], 30);
 
 	D_(D_INFO "[%2X] %-30.30s %04x %04x %04x %c V%02x", i,
 		mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
 		mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol);
     }
 
-    if (pattern_init(mod) < 0)
+    if (libxmp_init_pattern(mod) < 0)
 	return -1;
 
     /* Read and convert patterns */
     D_(D_INFO "Stored patterns: %d", mod->pat);
 
     for (i = 0; i < mod->pat; i++) {
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
+	if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 	    return -1;
 
 	if (dh.pack) {
@@ -193,7 +199,7 @@ static int digi_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	        if (chn_table[j] & k) {
 		    hio_read (digi_event, 4, 1, f);
 		    event = &EVENT (i, c, j);
-	            decode_protracker_event(event, digi_event);
+	            libxmp_decode_protracker_event(event, digi_event);
 		    switch (event->fxt) {
 		    case 0x08:		/* Robot */
 			event->fxt = event->fxp = 0;
@@ -225,7 +231,7 @@ static int digi_load(struct module_data *m, HIO_HANDLE *f, const int start)
     /* Read samples */
     D_(D_INFO "Stored samples: %d", mod->smp);
     for (i = 0; i < mod->ins; i++) {
-	if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+	if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
 	    return -1;
     }
 
diff --git a/src/loaders/dmf_load.c b/src/loaders/dmf_load.c
new file mode 100644
index 0000000..4549dbc
--- /dev/null
+++ b/src/loaders/dmf_load.c
@@ -0,0 +1,461 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * Public domain DMF sample decompressor by Olivier Lapicque
+ */
+
+#include 
+
+#include "loader.h"
+#include "iff.h"
+#include "period.h"
+
+#define MAGIC_DDMF	MAGIC4('D','D','M','F')
+
+
+static int dmf_test(HIO_HANDLE *, char *, const int);
+static int dmf_load (struct module_data *, HIO_HANDLE *, const int);
+
+const struct format_loader libxmp_loader_dmf = {
+	"X-Tracker",
+	dmf_test,
+	dmf_load
+};
+
+static int dmf_test(HIO_HANDLE * f, char *t, const int start)
+{
+	if (hio_read32b(f) != MAGIC_DDMF)
+		return -1;
+
+	hio_seek(f, 9, SEEK_CUR);
+	libxmp_read_title(f, t, 30);
+
+	return 0;
+}
+
+
+struct local_data {
+	int ver;
+	uint8 packtype[256];
+};
+
+
+struct hnode {
+	short int left, right;
+	uint8 value;
+};
+
+struct htree {
+	uint8 *ibuf, *ibufmax;
+	uint32 bitbuf;
+	int bitnum;
+	int lastnode, nodecount;
+	struct hnode nodes[256];
+};
+
+
+static uint8 read_bits(struct htree *tree, int nbits)
+{
+	uint8 x = 0, bitv = 1;
+	while (nbits--) {
+		if (tree->bitnum) {
+			tree->bitnum--;
+		} else {
+			tree->bitbuf = (tree->ibuf < tree->ibufmax) ?
+							*(tree->ibuf++) : 0;
+			tree->bitnum = 7;
+		}
+		if (tree->bitbuf & 1) x |= bitv;
+		bitv <<= 1;
+		tree->bitbuf >>= 1;
+	}
+	return x;
+}
+
+/* tree: [8-bit value][12-bit index][12-bit index] = 32-bit */
+static void new_node(struct htree *tree)
+{
+	uint8 isleft, isright;
+	int actnode;
+
+	actnode = tree->nodecount;
+
+	if (actnode > 255)
+		return;
+
+	tree->nodes[actnode].value = read_bits(tree, 7);
+	isleft = read_bits(tree, 1);
+	isright = read_bits(tree, 1);
+	actnode = tree->lastnode;
+
+	if (actnode > 255)
+		return;
+
+	tree->nodecount++;
+	tree->lastnode = tree->nodecount;
+
+	if (isleft) {
+		tree->nodes[actnode].left = tree->lastnode;
+		new_node(tree);
+	} else {
+		tree->nodes[actnode].left = -1;
+	}
+
+	tree->lastnode = tree->nodecount;
+
+	if (isright) {
+		tree->nodes[actnode].right = tree->lastnode;
+		new_node(tree);
+	} else {
+		tree->nodes[actnode].right = -1;
+	}
+}
+
+static int unpack(uint8 *psample, uint8 *ibuf, uint8 *ibufmax, uint32 maxlen)
+{
+	struct htree tree;
+	int i, actnode;
+	uint8 value, sign, delta = 0;
+	
+	memset(&tree, 0, sizeof(tree));
+	tree.ibuf = ibuf;
+	tree.ibufmax = ibufmax;
+	new_node(&tree);
+	value = 0;
+
+	for (i = 0; i < maxlen; i++) {
+		actnode = 0;
+		sign = read_bits(&tree, 1);
+
+		do {
+			if (read_bits(&tree, 1))
+				actnode = tree.nodes[actnode].right;
+			else
+				actnode = tree.nodes[actnode].left;
+			if (actnode > 255) break;
+			delta = tree.nodes[actnode].value;
+			if ((tree.ibuf >= tree.ibufmax) && (!tree.bitnum)) break;
+		} while ((tree.nodes[actnode].left >= 0) &&
+					(tree.nodes[actnode].right >= 0));
+
+		if (sign)
+			delta ^= 0xff;
+		value += delta;
+		psample[i] = i ? value : 0;
+	}
+
+	return tree.ibuf - ibuf;
+}
+
+
+/*
+ * IFF chunk handlers
+ */
+
+static int get_sequ(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
+{
+	struct xmp_module *mod = &m->mod;
+	int i;
+
+	hio_read16l(f);	/* sequencer loop start */
+	hio_read16l(f);	/* sequencer loop end */
+
+	mod->len = (size - 4) / 2;
+	if (mod->len > 255)
+		mod->len = 255;
+
+	for (i = 0; i < mod->len; i++)
+		mod->xxo[i] = hio_read16l(f);
+
+	return 0;
+}
+
+static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
+{
+	struct xmp_module *mod = &m->mod;
+	int i, j, r, chn;
+	int patsize;
+	int info, counter, data;
+	int track_counter[32];
+	struct xmp_event *event;
+
+	mod->pat = hio_read16l(f);
+	mod->chn = hio_read8(f);
+	mod->trk = mod->chn * mod->pat;
+
+	if (libxmp_init_pattern(mod) < 0)
+		return -1;
+
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	for (i = 0; i < mod->pat; i++) {
+		chn = hio_read8(f);
+		hio_read8(f);		/* beat */
+
+		if (libxmp_alloc_pattern_tracks(mod, i, hio_read16l(f)) < 0)
+			return -1;
+
+		patsize = hio_read32l(f);
+
+		for (j = 0; j < chn; j++)
+			track_counter[j] = 0;
+
+		for (counter = r = 0; r < mod->xxp[i]->rows; r++) {
+			if (counter == 0) {
+				/* global track */
+				info = hio_read8(f);
+				counter = info & 0x80 ? hio_read8(f) : 0;
+				data = info & 0x3f ? hio_read8(f) : 0;
+			} else {
+				counter--;
+			}
+
+			for (j = 0; j < chn; j++) {
+				int b, fxt, fxp;
+
+				event = &EVENT(i, j, r);
+
+				if (track_counter[j] == 0) {
+					b = hio_read8(f);
+		
+					if (b & 0x80)
+						track_counter[j] = hio_read8(f);
+					if (b & 0x40)
+						event->ins = hio_read8(f);
+					if (b & 0x20)
+						event->note = 24 + hio_read8(f);
+					if (b & 0x10)
+						event->vol = hio_read8(f);
+					if (b & 0x08) {	/* instrument effect */
+						fxt = hio_read8(f);
+						fxp = hio_read8(f);
+					}
+					if (b & 0x04) {	/* note effect */
+						fxt = hio_read8(f);
+						fxp = hio_read8(f);
+					}
+					if (b & 0x02) {	/* volume effect */
+						fxt = hio_read8(f);
+						fxp = hio_read8(f);
+						switch (fxt) {
+						case 0x02:
+							event->fxt = FX_VOLSLIDE_DN;
+							event->fxp = fxp;
+							break;
+						}
+					}
+				} else {
+					track_counter[j]--;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int get_smpi(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
+{
+	struct xmp_module *mod = &m->mod;
+	struct local_data *data = (struct local_data *)parm;
+	int i, namelen, c3spd, flag;
+	uint8 name[30];
+
+	mod->ins = mod->smp = hio_read8(f);
+
+	if (libxmp_init_instrument(m) < 0)
+		return -1;
+
+	D_(D_INFO "Instruments: %d", mod->ins);
+
+	for (i = 0; i < mod->ins; i++) {
+		int x;
+
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+		
+		namelen = hio_read8(f);
+		x = namelen - hio_read(name, 1, namelen > 30 ? 30 : namelen, f);
+		libxmp_instrument_name(mod, i, name, namelen);
+		name[namelen] = 0;
+		while (x--)
+			hio_read8(f);
+
+		mod->xxs[i].len = hio_read32l(f);
+		mod->xxs[i].lps = hio_read32l(f);
+		mod->xxs[i].lpe = hio_read32l(f);
+		mod->xxi[i].nsm = !!mod->xxs[i].len;
+		c3spd = hio_read16l(f);
+		libxmp_c2spd_to_note(c3spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
+		mod->xxi[i].sub[0].vol = hio_read8(f);
+		mod->xxi[i].sub[0].pan = 0x80;
+		mod->xxi[i].sub[0].sid = i;
+		flag = hio_read8(f);
+		mod->xxs[i].flg = flag & 0x01 ? XMP_SAMPLE_LOOP : 0;
+		if (data->ver >= 8)
+			hio_seek(f, 8, SEEK_CUR);	/* library name */
+		hio_read16l(f);	/* reserved -- specs say 1 byte only*/
+		hio_read32l(f);	/* sampledata crc32 */
+
+		data->packtype[i] = (flag & 0x0c) >> 2;
+		D_(D_INFO "[%2X] %-30.30s %05x %05x %05x %c P%c %5d V%02x",
+				i, name, mod->xxs[i].len, mod->xxs[i].lps & 0xfffff,
+				mod->xxs[i].lpe & 0xfffff,
+				mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
+				'0' + data->packtype[i],
+				c3spd, mod->xxi[i].sub[0].vol);
+	}
+
+	return 0;
+}
+
+struct dynamic_buffer
+{
+	uint32 size;
+	uint8* data;
+};
+
+static int dynamic_buffer_alloc(struct dynamic_buffer* buf, uint32 size)
+{
+	uint8* data;
+	if (buf->size >= size)
+	  return 0;
+	if (!buf->data)
+	  data = malloc(size);
+	else
+	  data = realloc(buf->data, size);
+	if (data) {
+	  buf->data = data;
+	  buf->size = size;
+	  return 0;
+	} else {
+	  return -1;
+	}
+}
+
+static void dynamic_buffer_free(struct dynamic_buffer* buf)
+{
+	free(buf->data);
+}
+
+static int get_smpd(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
+{
+	struct xmp_module *mod = &m->mod;
+	struct local_data *data = (struct local_data *)parm;
+	int i;
+	struct dynamic_buffer sbuf = {0}, ibuf = {0};
+
+	D_(D_INFO "Stored samples: %d", mod->smp);
+
+	for (i = 0; i < mod->smp; i++) {
+		uint32 samplesize = mod->xxs[i].len;
+		uint32 datasize = hio_read32l(f);
+		if (datasize == 0)
+			continue;
+
+		switch (data->packtype[i]) {
+		case 0:
+      if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+				goto error;
+			break;
+		case 1:
+      if (dynamic_buffer_alloc(&ibuf, datasize) < 0)
+				goto error;
+      if (hio_read(ibuf.data, 1, datasize, f) != datasize)
+				goto error;
+      if (dynamic_buffer_alloc(&sbuf, samplesize) < 0)
+				goto error;
+			unpack(sbuf.data, ibuf.data, ibuf.data + datasize, samplesize);
+			if (libxmp_load_sample(m, NULL, SAMPLE_FLAG_NOLOAD,
+        &mod->xxs[i], (char *)sbuf.data) < 0)
+        goto error;
+			break;
+		default:
+			hio_seek(f, datasize, SEEK_CUR);
+		}
+	}
+	dynamic_buffer_free(&ibuf);
+	dynamic_buffer_free(&sbuf);
+	return 0;
+error:
+	dynamic_buffer_free(&ibuf);
+	dynamic_buffer_free(&sbuf);
+	return -1;
+}
+
+static int dmf_load(struct module_data *m, HIO_HANDLE *f, const int start)
+{
+	struct xmp_module *mod = &m->mod;
+	iff_handle handle;
+	uint8 date[3];
+	char tracker_name[10];
+	struct local_data data;
+	int ret;
+
+	LOAD_INIT();
+
+	hio_read32b(f);		/* DDMF */
+
+	data.ver = hio_read8(f);
+	hio_read(tracker_name, 8, 1, f);
+	tracker_name[8] = 0;
+	snprintf(mod->type, XMP_NAME_SIZE, "%s DMF v%d",
+				tracker_name, data.ver);
+	tracker_name[8] = 0;
+	hio_read(mod->name, 30, 1, f);
+	hio_seek(f, 20, SEEK_CUR);
+	hio_read(date, 3, 1, f);
+
+	m->c4rate = C4_NTSC_RATE;
+	
+	MODULE_INFO();
+	D_(D_INFO "Creation date: %02d/%02d/%04d", date[0],
+						date[1], 1900 + date[2]);
+	
+	handle = libxmp_iff_new();
+	if (handle == NULL)
+		return -1;
+
+	/* IFF chunk IDs */
+	ret = libxmp_iff_register(handle, "SEQU", get_sequ);
+	ret |= libxmp_iff_register(handle, "PATT", get_patt);
+	ret |= libxmp_iff_register(handle, "SMPI", get_smpi);
+	ret |= libxmp_iff_register(handle, "SMPD", get_smpd);
+
+	if (ret != 0)
+		return -1;
+
+	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
+
+	/* Load IFF chunks */
+	if (libxmp_iff_load(handle, m, f, &data) < 0) {
+		libxmp_iff_release(handle);
+		return -1;
+	}
+
+	m->volbase = 0xff;
+
+	libxmp_iff_release(handle);
+
+	return 0;
+}
diff --git a/src/loaders/dt_load.c b/src/loaders/dt_load.c
index b21f7fc..1a49d31 100644
--- a/src/loaders/dt_load.c
+++ b/src/loaders/dt_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include 
@@ -18,7 +32,7 @@
 static int dt_test(HIO_HANDLE *, char *, const int);
 static int dt_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader dt_loader = {
+const struct format_loader libxmp_loader_dt = {
 	"Digital Tracker",
 	dt_test,
 	dt_load
@@ -37,7 +51,7 @@ static int dt_test(HIO_HANDLE *f, char *t, const int start)
 	hio_read16b(f);			/* bpm */
 	hio_read32b(f);			/* undocumented */
 
-	read_title(f, t, 32);
+	libxmp_read_title(f, t, 32);
 
 	return 0;
 }
@@ -65,7 +79,7 @@ static int get_d_t_(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	hio_read32b(f);			/* undocumented */
 
 	hio_read(mod->name, 32, 1, f);
-	set_type(m, "Digital Tracker DTM");
+	libxmp_set_type(m, "Digital Tracker DTM");
 
 	MODULE_INFO();
 
@@ -77,8 +91,19 @@ static int get_s_q_(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	struct xmp_module *mod = &m->mod;
 	int i, maxpat;
 
+	/* Sanity check */
+	if (mod->pat != 0) {
+		return -1;
+	}
+
 	mod->len = hio_read16b(f);
 	mod->rst = hio_read16b(f);
+
+	/* Sanity check */
+	if (mod->len > 256 || mod->rst > 255) {
+		return -1;
+	}
+
 	hio_read32b(f);	/* reserved */
 
 	for (maxpat = i = 0; i < 128; i++) {
@@ -113,13 +138,13 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 
 	D_(D_INFO "Instruments    : %d ", mod->ins);
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	for (i = 0; i < mod->ins; i++) {
 		int fine, replen, flag;
 
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 
 		hio_read32b(f);		/* reserved */
@@ -134,7 +159,7 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 		mod->xxs[i].flg = replen > 2 ?  XMP_SAMPLE_LOOP : 0;
 
 		hio_read(name, 22, 1, f);
-		instrument_name(mod, i, name, 22);
+		libxmp_instrument_name(mod, i, name, 22);
 
 		flag = hio_read16b(f);	/* bit 0-7:resol 8:stereo */
 		if ((flag & 0xff) > 8) {
@@ -146,7 +171,7 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 
 		hio_read32b(f);		/* midi note (0x00300000) */
 		c2spd = hio_read32b(f);	/* frequency */
-		c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
+		libxmp_c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
 
 		/* It's strange that we have both c2spd and finetune */
 		mod->xxi[i].sub[0].fin += fine;
@@ -183,16 +208,24 @@ static int get_dapt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 		data->pflag = 1;
 		data->last_pat = 0;
 
-		if (pattern_init(mod) < 0)
+		if (libxmp_init_pattern(mod) < 0)
 			return -1;
 	}
 
 	hio_read32b(f);	/* 0xffffffff */
-	i = pat = hio_read16b(f);
+	pat = hio_read16b(f);
 	rows = hio_read16b(f);
 
+	/* Sanity check */
+	if (pat < 0 || pat >= mod->pat || rows < 0 || rows > 256) {
+		return -1;
+	}
+	if (pat < data->last_pat) {
+		return -1;
+	}
+
 	for (i = data->last_pat; i <= pat; i++) {
-		if (pattern_tracks_alloc(mod, i, rows) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
 			return -1;
 	}
 	data->last_pat = pat + 1;
@@ -232,7 +265,14 @@ static int get_dait(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	}
 
 	if (size > 2) {
-		int ret = load_sample(m, f, SAMPLE_FLAG_BIGEND,
+		int ret;
+
+		/* Sanity check */
+		if (data->insnum >= mod->ins) {
+			return -1;
+		}
+
+		ret = libxmp_load_sample(m, f, SAMPLE_FLAG_BIGEND,
 			&mod->xxs[mod->xxi[data->insnum].sub[0].sid], NULL);
 
 		if (ret < 0)
@@ -248,37 +288,43 @@ static int dt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 {
 	iff_handle handle;
 	struct local_data data;
+	struct xmp_module *mod = &m->mod;
 	int ret, i;
 
 	LOAD_INIT();
 
-	data.pflag = data.sflag = 0;
+	memset(&data, 0, sizeof (struct local_data));
 	
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		return -1;
 
+	m->c4rate = C4_NTSC_RATE;
+
 	/* IFF chunk IDs */
-	ret = iff_register(handle, "D.T.", get_d_t_);
-	ret |= iff_register(handle, "S.Q.", get_s_q_);
-	ret |= iff_register(handle, "PATT", get_patt);
-	ret |= iff_register(handle, "INST", get_inst);
-	ret |= iff_register(handle, "DAPT", get_dapt);
-	ret |= iff_register(handle, "DAIT", get_dait);
+	ret = libxmp_iff_register(handle, "D.T.", get_d_t_);
+	ret |= libxmp_iff_register(handle, "S.Q.", get_s_q_);
+	ret |= libxmp_iff_register(handle, "PATT", get_patt);
+	ret |= libxmp_iff_register(handle, "INST", get_inst);
+	ret |= libxmp_iff_register(handle, "DAPT", get_dapt);
+	ret |= libxmp_iff_register(handle, "DAIT", get_dait);
 
 	if (ret != 0)
 		return -1;
 
 	/* Load IFF chunks */
-	ret = iff_load(handle, m, f , &data);
-	iff_release(handle);
+	ret = libxmp_iff_load(handle, m, f , &data);
+	libxmp_iff_release(handle);
 	if (ret < 0)
 		return -1;
 
-	//fix rest patterns
-	for (i = data.last_pat; i < m->mod.pat; i++) {
-		if (pattern_tracks_alloc(&m->mod, i, 64) < 0)
-			return -1;
+	/* alloc remaining patterns */
+	if (mod->xxp != NULL) {
+		for (i = data.last_pat; i < mod->pat; i++) {
+			if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0) {
+				return -1;
+			}
+		}
 	}
 
 	return 0;
diff --git a/src/loaders/dtt_load.c b/src/loaders/dtt_load.c
new file mode 100644
index 0000000..d6e93f9
--- /dev/null
+++ b/src/loaders/dtt_load.c
@@ -0,0 +1,185 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "loader.h"
+
+#define MAGIC_DskT	MAGIC4('D','s','k','T')
+#define MAGIC_DskS	MAGIC4('D','s','k','S')
+
+
+static int dtt_test(HIO_HANDLE *, char *, const int);
+static int dtt_load (struct module_data *, HIO_HANDLE *, const int);
+
+const struct format_loader libxmp_loader_dtt = {
+	"Desktop Tracker",
+	dtt_test,
+	dtt_load
+};
+
+static int dtt_test(HIO_HANDLE *f, char *t, const int start)
+{
+	if (hio_read32b(f) != MAGIC_DskT)
+		return -1;
+
+	libxmp_read_title(f, t, 64);
+
+	return 0;
+}
+
+static int dtt_load(struct module_data *m, HIO_HANDLE *f, const int start)
+{
+	struct xmp_module *mod = &m->mod;
+	struct xmp_event *event;
+	int i, j, k;
+	int n;
+	uint8 buf[100];
+	uint32 flags;
+	uint32 pofs[256];
+	uint8 plen[256];
+	int sdata[64];
+
+	LOAD_INIT();
+
+	hio_read32b(f);
+
+	libxmp_set_type(m, "Desktop Tracker");
+
+	hio_read(buf, 1, 64, f);
+	strncpy(mod->name, (char *)buf, XMP_NAME_SIZE);
+	hio_read(buf, 1, 64, f);
+	/* strncpy(m->author, (char *)buf, XMP_NAME_SIZE); */
+	
+	flags = hio_read32l(f);
+	mod->chn = hio_read32l(f);
+	mod->len = hio_read32l(f);
+	hio_read(buf, 1, 8, f);
+	mod->spd = hio_read32l(f);
+	mod->rst = hio_read32l(f);
+	mod->pat = hio_read32l(f);
+	mod->ins = mod->smp = hio_read32l(f);
+	mod->trk = mod->pat * mod->chn;
+	
+	hio_read(mod->xxo, 1, (mod->len + 3) & ~3L, f);
+
+	m->c4rate = C4_NTSC_RATE;
+
+	MODULE_INFO();
+
+	for (i = 0; i < mod->pat; i++) {
+		int x = hio_read32l(f);
+		if (i < 256)
+			pofs[i] = x;
+	}
+
+	n = (mod->pat + 3) & ~3L;
+	for (i = 0; i < n; i++) {
+		int x = hio_read8(f);
+		if (i < 256)
+			plen[i] = x;
+	}
+
+	if (libxmp_init_instrument(m) < 0)
+		return -1;
+
+	/* Read instrument names */
+
+	for (i = 0; i < mod->ins; i++) {
+		int c2spd, looplen;
+
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+
+		hio_read8(f);			/* note */
+		mod->xxi[i].sub[0].vol = hio_read8(f) >> 1;
+		mod->xxi[i].sub[0].pan = 0x80;
+		hio_read16l(f);			/* not used */
+		c2spd = hio_read32l(f);		/* period? */
+		hio_read32l(f);			/* sustain start */
+		hio_read32l(f);			/* sustain length */
+		mod->xxs[i].lps = hio_read32l(f);
+		looplen = hio_read32l(f);
+		mod->xxs[i].flg = looplen > 0 ? XMP_SAMPLE_LOOP : 0;
+		mod->xxs[i].lpe = mod->xxs[i].lps + looplen;
+		mod->xxs[i].len = hio_read32l(f);
+		hio_read(buf, 1, 32, f);
+		libxmp_instrument_name(mod, i, (uint8 *)buf, 32);
+		sdata[i] = hio_read32l(f);
+
+		mod->xxi[i].nsm = !!(mod->xxs[i].len);
+		mod->xxi[i].sub[0].sid = i;
+
+		D_(D_INFO "[%2X] %-32.32s  %04x %04x %04x %c V%02x %d\n",
+				i, mod->xxi[i].name, mod->xxs[i].len,
+				mod->xxs[i].lps, mod->xxs[i].lpe,
+				mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
+				mod->xxi[i].sub[0].vol, c2spd);
+	}
+
+	if (libxmp_init_pattern(mod) < 0)
+		return -1;
+
+	/* Read and convert patterns */
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern_tracks(mod, i, plen[i]) < 0)
+			return -1;
+
+		hio_seek(f, start + pofs[i], SEEK_SET);
+
+		for (j = 0; j < mod->xxp[i]->rows; j++) {
+			for (k = 0; k < mod->chn; k++) {
+				uint32 x;
+
+				event = &EVENT (i, k, j);
+				x = hio_read32l(f);
+
+				event->ins  = (x & 0x0000003f);
+				event->note = (x & 0x00000fc0) >> 6;
+				event->fxt  = (x & 0x0001f000) >> 12;
+
+				if (event->note)
+					event->note += 48;
+
+				/* sorry, we only have room for two effects */
+				if (x & (0x1f << 17)) {
+					event->f2p = (x & 0x003e0000) >> 17;
+					x = hio_read32l(f);
+					event->fxp = (x & 0x000000ff);
+					event->f2p = (x & 0x0000ff00) >> 8;
+				} else {
+					event->fxp = (x & 0xfc000000) >> 18;
+				}
+			}
+		}
+	}
+
+	/* Read samples */
+	D_(D_INFO "Stored samples: %d", mod->smp);
+	for (i = 0; i < mod->ins; i++) {
+		hio_seek(f, start + sdata[i], SEEK_SET);
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_VIDC, &mod->xxs[i], NULL) < 0)
+			return -1;
+	}
+
+	return 0;
+}
diff --git a/src/loaders/emod_load.c b/src/loaders/emod_load.c
index 7a9bde1..983360a 100644
--- a/src/loaders/emod_load.c
+++ b/src/loaders/emod_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include 
@@ -17,7 +31,7 @@
 static int emod_test(HIO_HANDLE *, char *, const int);
 static int emod_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader emod_loader = {
+const struct format_loader libxmp_loader_emod = {
 	"Quadra Composer",
 	emod_test,
 	emod_load
@@ -36,9 +50,9 @@ static int emod_test(HIO_HANDLE * f, char *t, const int start)
 	if (hio_read32b(f) == MAGIC_EMIC) {
 		hio_read32b(f);	/* skip size */
 		hio_read16b(f);	/* skip version */
-		read_title(f, t, 20);
+		libxmp_read_title(f, t, 20);
 	} else {
-		read_title(f, t, 0);
+		libxmp_read_title(f, t, 0);
 	}
 
 	return 0;
@@ -57,12 +71,12 @@ static int get_emic(struct module_data *m, int size, HIO_HANDLE * f, void *parm)
 	mod->ins = hio_read8(f);
 	mod->smp = mod->ins;
 
-	m->quirk |= QUIRK_MODRNG;
+	m->period_type = PERIOD_MODRNG;
 
 	snprintf(mod->type, XMP_NAME_SIZE, "Quadra Composer EMOD v%d", ver);
 	MODULE_INFO();
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	for (i = 0; i < mod->ins; i++) {
@@ -70,7 +84,7 @@ static int get_emic(struct module_data *m, int size, HIO_HANDLE * f, void *parm)
 		struct xmp_sample *xxs = &mod->xxs[i];
 		struct xmp_subinstrument *sub;
 
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 
 		sub = &xxi->sub[0];
@@ -80,7 +94,7 @@ static int get_emic(struct module_data *m, int size, HIO_HANDLE * f, void *parm)
 		xxs->len = 2 * hio_read16b(f);
 		hio_read(xxi->name, 1, 20, f);
 		xxs->flg = hio_read8(f) & 1 ? XMP_SAMPLE_LOOP : 0;
-		sub->fin = hio_read8(f);
+		sub->fin = hio_read8s(f) << 4;
 		xxs->lps = 2 * hio_read16b(f);
 		xxs->lpe = xxs->lps + 2 * hio_read16b(f);
 		hio_read32b(f);	/* ptr */
@@ -99,7 +113,7 @@ static int get_emic(struct module_data *m, int size, HIO_HANDLE * f, void *parm)
 	mod->pat = hio_read8(f);
 	mod->trk = mod->pat * mod->chn;
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	memset(reorder, 0, 256);
@@ -107,7 +121,7 @@ static int get_emic(struct module_data *m, int size, HIO_HANDLE * f, void *parm)
 	for (i = 0; i < mod->pat; i++) {
 		reorder[hio_read8(f)] = i;
 
-		if (pattern_tracks_alloc(mod, i, hio_read8(f) + 1) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, hio_read8(f) + 1) < 0)
 			return -1;
 
 		hio_seek(f, 20, SEEK_CUR);	/* skip name */
@@ -174,7 +188,7 @@ static int get_8smp(struct module_data *m, int size, HIO_HANDLE * f, void *parm)
 	D_(D_INFO "Stored samples : %d ", mod->smp);
 
 	for (i = 0; i < mod->smp; i++) {
-		if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
 			return -1;
 	}
 
@@ -192,25 +206,25 @@ static int emod_load(struct module_data *m, HIO_HANDLE * f, const int start)
 	hio_read32b(f);
 	hio_read32b(f);		/* EMOD */
 
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		return -1;
 
 	/* IFF chunk IDs */
-	ret = iff_register(handle, "EMIC", get_emic);
-	ret |= iff_register(handle, "PATT", get_patt);
-	ret |= iff_register(handle, "8SMP", get_8smp);
+	ret = libxmp_iff_register(handle, "EMIC", get_emic);
+	ret |= libxmp_iff_register(handle, "PATT", get_patt);
+	ret |= libxmp_iff_register(handle, "8SMP", get_8smp);
 
 	if (ret != 0)
 		return -1;
 
 	/* Load IFF chunks */
-	if (iff_load(handle, m, f, NULL) < 0) {
-		iff_release(handle);
+	if (libxmp_iff_load(handle, m, f, NULL) < 0) {
+		libxmp_iff_release(handle);
 		return -1;
 	}
 
-	iff_release(handle);
+	libxmp_iff_release(handle);
 
 	return 0;
 }
diff --git a/src/loaders/far_load.c b/src/loaders/far_load.c
index 8ad7736..86bd86e 100644
--- a/src/loaders/far_load.c
+++ b/src/loaders/far_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 /* Based on the Farandole Composer format specifications by Daniel Potter.
@@ -61,7 +75,7 @@ struct far_event {
 static int far_test (HIO_HANDLE *, char *, const int);
 static int far_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader far_loader = {
+const struct format_loader libxmp_loader_far = {
     "Farandole Composer",
     far_test,
     far_load
@@ -72,7 +86,7 @@ static int far_test(HIO_HANDLE *f, char *t, const int start)
     if (hio_read32b(f) != MAGIC_FAR)
 	return -1;
 
-    read_title(f, t, 40);
+    libxmp_read_title(f, t, 40);
 
     return 0;
 }
@@ -119,26 +133,36 @@ static int far_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     LOAD_INIT();
 
-    hio_read32b(f);				/* File magic: 'FAR\xfe' */
-    hio_read(&ffh.name, 40, 1, f);		/* Song name */
-    hio_read(&ffh.crlf, 3, 1, f);		/* 0x0d 0x0a 0x1A */
+    hio_read32b(f);			/* File magic: 'FAR\xfe' */
+    hio_read(&ffh.name, 40, 1, f);	/* Song name */
+    hio_read(&ffh.crlf, 3, 1, f);	/* 0x0d 0x0a 0x1A */
     ffh.headersize = hio_read16l(f);	/* Remaining header size in bytes */
     ffh.version = hio_read8(f);		/* Version MSN=major, LSN=minor */
     hio_read(&ffh.ch_on, 16, 1, f);	/* Channel on/off switches */
     hio_seek(f, 9, SEEK_CUR);		/* Current editing values */
     ffh.tempo = hio_read8(f);		/* Default tempo */
-    hio_read(&ffh.pan, 16, 1, f);		/* Channel pan definitions */
-    hio_read32l(f);				/* Grid, mode (for editor) */
-    ffh.textlen = hio_read16l(f);		/* Length of embedded text */
+    hio_read(&ffh.pan, 16, 1, f);	/* Channel pan definitions */
+    hio_read32l(f);			/* Grid, mode (for editor) */
+    ffh.textlen = hio_read16l(f);	/* Length of embedded text */
+
+    /* Sanity check */
+    if (ffh.tempo == 0) {
+	return -1;
+    }
 
     hio_seek(f, ffh.textlen, SEEK_CUR);	/* Skip song text */
 
     hio_read(&ffh2.order, 256, 1, f);	/* Orders */
-    ffh2.patterns = hio_read8(f);		/* Number of stored patterns (?) */
-    ffh2.songlen = hio_read8(f);		/* Song length in patterns */
-    ffh2.restart = hio_read8(f);		/* Restart pos */
-    for (i = 0; i < 256; i++)
-	ffh2.patsize[i] = hio_read16l(f);	/* Size of each pattern in bytes */
+    ffh2.patterns = hio_read8(f);	/* Number of stored patterns (?) */
+    ffh2.songlen = hio_read8(f);	/* Song length in patterns */
+    ffh2.restart = hio_read8(f);	/* Restart pos */
+    for (i = 0; i < 256; i++) {
+	ffh2.patsize[i] = hio_read16l(f); /* Size of each pattern in bytes */
+    }
+
+    if (hio_error(f)) {
+        return -1;
+    }
 
     mod->chn = 16;
     /*mod->pat=ffh2.patterns; (Error in specs? --claudio) */
@@ -155,11 +179,11 @@ static int far_load(struct module_data *m, HIO_HANDLE *f, const int start)
     mod->trk = mod->chn * mod->pat;
 
     strncpy(mod->name, (char *)ffh.name, 40);
-    set_type(m, "Farandole Composer %d.%d", MSN(ffh.version), LSN(ffh.version));
+    libxmp_set_type(m, "Farandole Composer %d.%d", MSN(ffh.version), LSN(ffh.version));
 
     MODULE_INFO();
 
-    if (pattern_init(mod) < 0)
+    if (libxmp_init_pattern(mod) < 0)
 	return -1;
 
     /* Read and convert patterns */
@@ -168,16 +192,24 @@ static int far_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     for (i = 0; i < mod->pat; i++) {
 	uint8 brk, note, ins, vol, fxb;
+	int rows;
 
-	if (pattern_alloc(mod, i) < 0)
+	if (libxmp_alloc_pattern(mod, i) < 0)
 	    return -1;
 
 	if (!ffh2.patsize[i])
 	    continue;
 
-	mod->xxp[i]->rows = (ffh2.patsize[i] - 2) / 64;
+	rows = (ffh2.patsize[i] - 2) / 64;
 
-	if (tracks_in_pattern_alloc(mod, i) < 0)
+	/* Sanity check */
+	if (rows <= 0 || rows > 256) {
+	    return -1;
+	}
+
+	mod->xxp[i]->rows = rows;
+
+	if (libxmp_alloc_tracks_in_pattern(mod, i) < 0)
 	    return -1;
 
 	brk = hio_read8(f) + 1;
@@ -246,7 +278,11 @@ static int far_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		event->fxp |= (EX_F_VSLIDE_DN << 4);
 		break;
 	    case FX_SPEED:
-		event->fxp = 8 * 60 / event->fxp;
+		if (event->fxp != 0) {
+			event->fxp = 8 * 60 / event->fxp;
+		} else {
+			event->fxt = 0;
+		}
 		break;
 	    }
 	}
@@ -262,7 +298,7 @@ static int far_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     mod->smp = mod->ins;
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     /* Read and convert instruments and samples */
@@ -271,21 +307,24 @@ static int far_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	if (!(sample_map[i / 8] & (1 << (i % 8))))
 		continue;
 
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 	    return -1;
 
 	hio_read(&fih.name, 32, 1, f);	/* Instrument name */
 	fih.length = hio_read32l(f);	/* Length of sample (up to 64Kb) */
 	fih.finetune = hio_read8(f);	/* Finetune (unsuported) */
-	fih.volume = hio_read8(f);		/* Volume (unsuported?) */
-	fih.loop_start = hio_read32l(f);	/* Loop start */
+	fih.volume = hio_read8(f);	/* Volume (unsuported?) */
+	fih.loop_start = hio_read32l(f);/* Loop start */
 	fih.loopend = hio_read32l(f);	/* Loop end */
 	fih.sampletype = hio_read8(f);	/* 1=16 bit sample */
 	fih.loopmode = hio_read8(f);
 
-	fih.length &= 0xffff;
-	fih.loop_start &= 0xffff;
-	fih.loopend &= 0xffff;
+	/* Sanity check */
+	if (fih.length > 0x10000 || fih.loop_start > 0x10000 ||
+            fih.loopend > 0x10000) {
+		return -1;
+	}
+
 	mod->xxs[i].len = fih.length;
 	mod->xxs[i].lps = fih.loop_start;
 	mod->xxs[i].lpe = fih.loopend;
@@ -305,13 +344,13 @@ static int far_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->xxi[i].sub[0].vol = 0xff; /* fih.volume; */
 	mod->xxi[i].sub[0].sid = i;
 
-	instrument_name(mod, i, fih.name, 32);
+	libxmp_instrument_name(mod, i, fih.name, 32);
 
 	D_(D_INFO "[%2X] %-32.32s %04x %04x %04x %c V%02x",
 		i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
 		mod->xxs[i].lpe, fih.loopmode ? 'L' : ' ', mod->xxi[i].sub[0].vol);
 
-	if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+	if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
 		return -1;
     }
 
diff --git a/src/loaders/fcm_load.c b/src/loaders/fcm_load.c
new file mode 100644
index 0000000..108729c
--- /dev/null
+++ b/src/loaders/fcm_load.c
@@ -0,0 +1,146 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * This file is part of the Extended Module Player and is distributed
+ * under the terms of the GNU Lesser General Public License. See COPYING.LIB
+ * for more information.
+ */
+
+/* Loader for FC-M Packer modules based on the format description
+ * written by Sylvain Chipaux (Asle/ReDoX). Modules sent by Sylvain
+ * Chipaux.
+ */
+
+#include "loader.h"
+#include "period.h"
+
+
+struct fcm_instrument {
+    uint16 size;
+    uint8 finetune;
+    uint8 volume;
+    uint16 loop_start;
+    uint16 loop_size;
+};
+
+struct fcm_header {
+    uint8 magic[4];		/* 'FC-M' magic ID */
+    uint8 vmaj;
+    uint8 vmin;
+    uint8 name_id[4];		/* 'NAME' pseudo chunk ID */
+    uint8 name[20];
+    uint8 inst_id[4];		/* 'INST' pseudo chunk ID */
+    struct fcm_instrument ins[31];
+    uint8 long_id[4];		/* 'LONG' pseudo chunk ID */
+    uint8 len;
+    uint8 rst;
+    uint8 patt_id[4];		/* 'PATT' pseudo chunk ID */
+};
+    
+
+int fcm_load(struct module_data *m, HIO_HANDLE *f)
+{
+    int i, j, k;
+    struct xmp_event *event;
+    struct fcm_header fh;
+    uint8 fe[4];
+
+    LOAD_INIT();
+
+    hio_read (&fh, 1, sizeof (struct fcm_header), f);
+
+    if (fh.magic[0] != 'F' || fh.magic[1] != 'C' || fh.magic[2] != '-' ||
+	fh.magic[3] != 'M' || fh.name_id[0] != 'N')
+	return -1;
+
+    strncpy (mod->name, fh.name, 20);
+    libxmp_set_type(m, "FC-M %d.%d", fh.vmaj, fh.vmin);
+
+    MODULE_INFO();
+
+    mod->len = fh.len;
+
+    hio_read (mod->xxo, 1, mod->len, f);
+
+    for (mod->pat = i = 0; i < mod->len; i++) {
+	if (mod->xxo[i] > mod->pat)
+	    mod->pat = mod->xxo[i];
+    }
+    mod->pat++;
+
+    mod->trk = mod->pat * mod->chn;
+
+    INSTRUMENT_INIT();
+
+    for (i = 0; i < mod->ins; i++) {
+	B_ENDIAN16 (fh.ins[i].size);
+	B_ENDIAN16 (fh.ins[i].loop_start);
+	B_ENDIAN16 (fh.ins[i].loop_size);
+	mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1);
+	mod->xxs[i].len = 2 * fh.ins[i].size;
+	mod->xxs[i].lps = 2 * fh.ins[i].loop_start;
+	mod->xxs[i].lpe = mod->xxs[i].lps + 2 * fh.ins[i].loop_size;
+	mod->xxs[i].flg = fh.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0;
+	mod->xxi[i].sub[0].fin = (int8)fh.ins[i].finetune << 4;
+	mod->xxi[i].sub[0].vol = fh.ins[i].volume;
+	mod->xxi[i].sub[0].pan = 0x80;
+	mod->xxi[i].sub[0].sid = i;
+	mod->xxi[i].nsm = !!(mod->xxs[i].len);
+	mod->xxi[i].rls = 0xfff;
+	if (mod->xxi[i].sub[0].fin > 48)
+	    mod->xxi[i].sub[0].xpo = -1;
+	if (mod->xxi[i].sub[0].fin < -48)
+	    mod->xxi[i].sub[0].xpo = 1;
+
+	if (V(1) && (strlen(mod->xxi[i].name) || mod->xxs[i].len > 2)) {
+	    report ("[%2X] %04x %04x %04x %c V%02x %+d\n",
+		i, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
+		fh.ins[i].loop_size > 1 ? 'L' : ' ',
+		mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4);
+	}
+    }
+
+    PATTERN_INIT();
+
+    /* Load and convert patterns */
+    if (V(0))
+	report ("Stored patterns: %d ", mod->pat);
+
+    hio_read (fe, 4, 1, f);	/* Skip 'SONG' pseudo chunk ID */
+
+    for (i = 0; i < mod->pat; i++) {
+	PATTERN_ALLOC (i);
+	mod->xxp[i]->rows = 64;
+	TRACK_ALLOC (i);
+	for (j = 0; j < 64; j++) {
+	    for (k = 0; k < 4; k++) {
+		event = &EVENT (i, k, j);
+		hio_read (fe, 4, 1, f);
+		cvt_pt_event (event, fe);
+	    }
+	}
+
+	if (V(0))
+	    report (".");
+    }
+
+    mod->flg |= XXM_FLG_MODRNG;
+
+    /* Load samples */
+
+    hio_read (fe, 4, 1, f);	/* Skip 'SAMP' pseudo chunk ID */
+
+    if (V(0))
+	report ("\nStored samples : %d ", mod->smp);
+    for (i = 0; i < mod->smp; i++) {
+	if (!mod->xxs[i].len)
+	    continue;
+	libxmp_load_sample(m, f, 0, &mod->xxs[mod->xxi[i].sub[0].sid], NULL);
+	if (V(0))
+	    report (".");
+    }
+    if (V(0))
+	report ("\n");
+
+    return 0;
+}
diff --git a/src/loaders/flt_load.c b/src/loaders/flt_load.c
index aee5895..8bb3485 100644
--- a/src/loaders/flt_load.c
+++ b/src/loaders/flt_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -27,7 +27,7 @@
 static int flt_test(HIO_HANDLE *, char *, const int);
 static int flt_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader flt_loader = {
+const struct format_loader libxmp_loader_flt = {
 	"Startrekker",
 	flt_test,
 	flt_load
@@ -49,7 +49,7 @@ static int flt_test(HIO_HANDLE * f, char *t, const int start)
 		return -1;
 
 	hio_seek(f, start + 0, SEEK_SET);
-	read_title(f, t, 20);
+	libxmp_read_title(f, t, 20);
 
 	return 0;
 }
@@ -93,28 +93,24 @@ struct am_instrument {
 	int16 fq;		/* base frequency */
 };
 
-static int is_am_instrument(FILE * nt, int i)
+static int is_am_instrument(HIO_HANDLE *nt, int i)
 {
 	char buf[2];
 	int16 wf;
 
-	fseek(nt, 144 + i * 120, SEEK_SET);
-
-	if (fread(buf, 1, 2, nt) < 2)
-		return 0;
-
+	hio_seek(nt, 144 + i * 120, SEEK_SET);
+	hio_read(buf, 1, 2, nt);
 	if (memcmp(buf, "AM", 2))
 		return 0;
-
-	fseek(nt, 24, SEEK_CUR);
-	wf = read16b(nt);
-	if (wf < 0 || wf > 3)
+	hio_seek(nt, 24, SEEK_CUR);
+	wf = hio_read16b(nt);
+	if (hio_error(nt) || wf < 0 || wf > 3)
 		return 0;
 
 	return 1;
 }
 
-static int read_am_instrument(struct module_data *m, FILE * nt, int i)
+static int read_am_instrument(struct module_data *m, HIO_HANDLE *nt, int i)
 {
 	struct xmp_module *mod = &m->mod;
 	struct xmp_instrument *xxi = &mod->xxi[i];
@@ -126,22 +122,26 @@ static int read_am_instrument(struct module_data *m, FILE * nt, int i)
 	int a, b;
 	int8 am_noise[1024];
 
-	fseek(nt, 144 + i * 120 + 2 + 4, SEEK_SET);
-	am.l0 = read16b(nt);
-	am.a1l = read16b(nt);
-	am.a1s = read16b(nt);
-	am.a2l = read16b(nt);
-	am.a2s = read16b(nt);
-	am.sl = read16b(nt);
-	am.ds = read16b(nt);
-	am.st = read16b(nt);
-	read16b(nt);
-	am.rs = read16b(nt);
-	am.wf = read16b(nt);
-	am.p_fall = -(int16) read16b(nt);
-	am.v_amp = read16b(nt);
-	am.v_spd = read16b(nt);
-	am.fq = read16b(nt);
+	hio_seek(nt, 144 + i * 120 + 2 + 4, SEEK_SET);
+	am.l0  = hio_read16b(nt);
+	am.a1l = hio_read16b(nt);
+	am.a1s = hio_read16b(nt);
+	am.a2l = hio_read16b(nt);
+	am.a2s = hio_read16b(nt);
+	am.sl  = hio_read16b(nt);
+	am.ds  = hio_read16b(nt);
+	am.st  = hio_read16b(nt);
+	hio_read16b(nt);
+	am.rs  = hio_read16b(nt);
+	am.wf  = hio_read16b(nt);
+	am.p_fall = -(int16) hio_read16b(nt);
+	am.v_amp = hio_read16b(nt);
+	am.v_spd = hio_read16b(nt);
+	am.fq  = hio_read16b(nt);
+
+	if (hio_error(nt)) {
+		return -1;
+	}
 
 #if 0
 	printf
@@ -173,7 +173,7 @@ static int read_am_instrument(struct module_data *m, FILE * nt, int i)
 	xxi->nsm = 1;
 	xxi->sub[0].xpo = -12 * am.fq;
 	xxi->sub[0].vwf = 0;
-	xxi->sub[0].vde = am.v_amp;
+	xxi->sub[0].vde = am.v_amp << 2;
 	xxi->sub[0].vra = am.v_spd;
 
 	/*
@@ -281,7 +281,7 @@ static int read_am_instrument(struct module_data *m, FILE * nt, int i)
 		freq_env->data[3] = 10 * (am.p_fall < 0 ? -256 : 256);
 	}
 
-	if (load_sample(m, NULL, SAMPLE_FLAG_NOLOAD, xxs, wave))
+	if (libxmp_load_sample(m, NULL, SAMPLE_FLAG_NOLOAD, xxs, wave))
 		return -1;
 
 	return 0;
@@ -297,7 +297,7 @@ static int flt_load(struct module_data *m, HIO_HANDLE * f, const int start)
 	char *tracker;
 	char filename[1024];
 	char buf[16];
-	FILE *nt;
+	HIO_HANDLE *nt;
 	int am_synth;
 
 	LOAD_INIT();
@@ -305,15 +305,15 @@ static int flt_load(struct module_data *m, HIO_HANDLE * f, const int start)
 	/* See if we have the synth parameters file */
 	am_synth = 0;
 	snprintf(filename, 1024, "%s%s.NT", m->dirname, m->basename);
-	if ((nt = fopen(filename, "rb")) == NULL) {
+	if ((nt = hio_open(filename, "rb")) == NULL) {
 		snprintf(filename, 1024, "%s%s.nt", m->dirname, m->basename);
-		if ((nt = fopen(filename, "rb")) == NULL) {
+		if ((nt = hio_open(filename, "rb")) == NULL) {
 			snprintf(filename, 1024, "%s%s.AS", m->dirname,
 				 m->basename);
-			if ((nt = fopen(filename, "rb")) == NULL) {
+			if ((nt = hio_open(filename, "rb")) == NULL) {
 				snprintf(filename, 1024, "%s%s.as", m->dirname,
 					 m->basename);
-				nt = fopen(filename, "rb");
+				nt = hio_open(filename, "rb");
 			}
 		}
 	}
@@ -321,7 +321,9 @@ static int flt_load(struct module_data *m, HIO_HANDLE * f, const int start)
 	tracker = "Startrekker";
 
 	if (nt) {
-		fread(buf, 1, 16, nt);
+		if (hio_read(buf, 1, 16, nt) != 16) {
+			goto err;
+		}
 		if (memcmp(buf, "ST1.2 ModuleINFO", 16) == 0) {
 			am_synth = 1;
 			tracker = "Startrekker 1.2";
@@ -348,10 +350,11 @@ static int flt_load(struct module_data *m, HIO_HANDLE * f, const int start)
 	hio_read(&mh.order, 128, 1, f);
 	hio_read(&mh.magic, 4, 1, f);
 
-	if (mh.magic[3] == '4')
+	if (mh.magic[3] == '4') {
 		mod->chn = 4;
-	else
+	} else {
 		mod->chn = 8;
+	}
 
 	mod->ins = 31;
 	mod->smp = mod->ins;
@@ -371,18 +374,18 @@ static int flt_load(struct module_data *m, HIO_HANDLE * f, const int start)
 	mod->trk = mod->chn * mod->pat;
 
 	strncpy(mod->name, (char *)mh.name, 20);
-	set_type(m, "%s %4.4s", tracker, mh.magic);
+	libxmp_set_type(m, "%s %4.4s", tracker, mh.magic);
 	MODULE_INFO();
 
-	if (instrument_init(mod) < 0)
-		return -1;
+	if (libxmp_init_instrument(m) < 0)
+		goto err;
 
 	for (i = 0; i < mod->ins; i++) {
 		struct xmp_instrument *xxi = &mod->xxi[i];
 		struct xmp_sample *xxs = &mod->xxs[i];
 		struct xmp_subinstrument *sub;
 
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			goto err;
 
 		sub = &xxi->sub[0];
@@ -400,10 +403,10 @@ static int flt_load(struct module_data *m, HIO_HANDLE * f, const int start)
 		if (xxs->len > 0)
 			xxi->nsm = 1;
 
-		instrument_name(mod, i, mh.ins[i].name, 22);
+		libxmp_instrument_name(mod, i, mh.ins[i].name, 22);
 	}
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		goto err;
 
 	/* Load and convert patterns */
@@ -422,19 +425,19 @@ static int flt_load(struct module_data *m, HIO_HANDLE * f, const int start)
 	 *  the normal portamento command, that would be hard to patch).
 	 */
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 			goto err;
 
 		for (j = 0; j < (64 * 4); j++) {
 			event = &EVENT(i, j % 4, j / 4);
 			hio_read(mod_event, 1, 4, f);
-			decode_noisetracker_event(event, mod_event);
+			libxmp_decode_noisetracker_event(event, mod_event);
 		}
 		if (mod->chn > 4) {
 			for (j = 0; j < (64 * 4); j++) {
 				event = &EVENT(i, (j % 4) + 4, j / 4);
 				hio_read(mod_event, 1, 4, f);
-				decode_noisetracker_event(event, mod_event);
+				libxmp_decode_noisetracker_event(event, mod_event);
 
 				/* no macros */
 				if (event->fxt == 0x0e)
@@ -454,26 +457,28 @@ static int flt_load(struct module_data *m, HIO_HANDLE * f, const int start)
 	for (i = 0; i < mod->smp; i++) {
 		if (mod->xxs[i].len == 0) {
 			if (am_synth && is_am_instrument(nt, i)) {
-				if (read_am_instrument(m, nt, i) < 0)
+				if (read_am_instrument(m, nt, i) < 0) {
+					D_(D_CRIT "Missing nt file");
 					goto err;
+				}
 			}
 			continue;
 		}
-		if (load_sample(m, f, SAMPLE_FLAG_FULLREP, &mod->xxs[i], NULL) <
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_FULLREP, &mod->xxs[i], NULL) <
 		    0) {
 			goto err;
 		}
 	}
 
 	if (nt) {
-		fclose(nt);
+		hio_close(nt);
 	}
 
 	return 0;
 
       err:
 	if (nt) {
-		fclose(nt);
+		hio_close(nt);
 	}
 
 	return -1;
diff --git a/src/loaders/fnk_load.c b/src/loaders/fnk_load.c
index c11312d..f2cb751 100644
--- a/src/loaders/fnk_load.c
+++ b/src/loaders/fnk_load.c
@@ -1,13 +1,25 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
-#include 
-#include 
 #include "loader.h"
 
 #define MAGIC_Funk	MAGIC4('F','u','n','k')
@@ -16,7 +28,7 @@
 static int fnk_test (HIO_HANDLE *, char *, const int);
 static int fnk_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader fnk_loader = {
+const struct format_loader libxmp_loader_fnk = {
     "Funktracker",
     fnk_test,
     fnk_load
@@ -26,7 +38,6 @@ static int fnk_test(HIO_HANDLE *f, char *t, const int start)
 {
     uint8 a, b;
     int size;
-    struct stat st;
 
     if (hio_read32b(f) != MAGIC_Funk)
 	return -1;
@@ -46,11 +57,10 @@ static int fnk_test(HIO_HANDLE *f, char *t, const int start)
     if (size < 1024)
 	return -1;
 
-    hio_stat(f, &st);
-    if (size != st.st_size)
+    if (hio_size(f) != size)
         return -1;
 
-    read_title(f, t, 0);
+    libxmp_read_title(f, t, 0);
 
     return 0;
 }
@@ -98,6 +108,12 @@ static int fnk_load(struct module_data *m, HIO_HANDLE *f, const int start)
     hio_read(&ffh.order, 256, 1, f);
     hio_read(&ffh.pbrk, 128, 1, f);
 
+    for (i = 0; i < 128; i++) {
+        if (ffh.pbrk[i] >= 64) {
+            return -1;
+        }
+    }
+
     for (i = 0; i < 64; i++) {
 	hio_read(&ffh.fih[i].name, 19, 1, f);
 	ffh.fih[i].loop_start = hio_read32l(f);
@@ -138,12 +154,12 @@ static int fnk_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	else
 	    mod->bpm += (ffh.info[3] >> 1) & 0x3f;
 
-	set_type(m, "FunktrackerGOLD");
+	libxmp_set_type(m, "FunktrackerGOLD");
     } else if (ffh.fmt[0] == 'F' && (ffh.fmt[1] == 'v' || ffh.fmt[1] == 'k')) {
-	set_type(m, "Funktracker");
+	libxmp_set_type(m, "Funktracker");
     } else {
 	mod->chn = 8;
-	set_type(m, "Funktracker DOS32");
+	libxmp_set_type(m, "Funktracker DOS32");
     }
 
     if (mod->chn == 0) {
@@ -155,18 +171,18 @@ static int fnk_load(struct module_data *m, HIO_HANDLE *f, const int start)
     mod->bpm = 4 * mod->bpm / 5;
     mod->trk = mod->chn * mod->pat;
 
-    /* FNK allows mode per instrument but we don't, so use linear like 669 */
-    m->quirk |= QUIRK_LINEAR;
+    /* FNK allows mode per instrument but we don't, so use linear for all */
+    m->period_type = PERIOD_LINEAR;
 
     MODULE_INFO();
     /* D_(D_INFO "Creation date: %02d/%02d/%04d", day, month, year); */
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     /* Convert instruments */
     for (i = 0; i < mod->ins; i++) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 	    return -1;
 
 	mod->xxs[i].len = ffh.fih[i].length;
@@ -182,7 +198,7 @@ static int fnk_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	if (mod->xxs[i].len > 0)
 	     mod->xxi[i].nsm = 1;
 
-	instrument_name(mod, i, ffh.fih[i].name, 19);
+	libxmp_instrument_name(mod, i, ffh.fih[i].name, 19);
 
 	D_(D_INFO "[%2X] %-20.20s %04x %04x %04x %c V%02x P%02x", i,
 		mod->xxi[i].name,
@@ -191,14 +207,14 @@ static int fnk_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].pan);
     }
 
-    if (pattern_init(mod) < 0)
+    if (libxmp_init_pattern(mod) < 0)
 	return -1;
 
     /* Read and convert patterns */
     D_(D_INFO "Stored patterns: %d", mod->pat);
 
     for (i = 0; i < mod->pat; i++) {
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
+	if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 	    return -1;
 
 	EVENT(i, 1, ffh.pbrk[i]).f2t = FX_BREAK;
@@ -290,7 +306,7 @@ static int fnk_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	if (mod->xxs[i].len <= 2)
 	    continue;
 
-	if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+	if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
 	    return -1;
     }
 
diff --git a/src/loaders/ftm_load.c b/src/loaders/ftm_load.c
new file mode 100644
index 0000000..d4f1f13
--- /dev/null
+++ b/src/loaders/ftm_load.c
@@ -0,0 +1,91 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * This file is part of the Extended Module Player and is distributed
+ * under the terms of the GNU Lesser General Public License. See COPYING.LIB
+ * for more information.
+ */
+
+/*
+ * From http://amp.dascene.net/faq.php:
+ * [Face The Music is an] Amiga tracker created by Jörg W. Schmidt in 1990
+ * for Maxon Computer GmbH. Face the Music delivers: 8 channels, line-based
+ * editor with S.E.L. (Sound Effect Language).
+ */
+#include "loader.h"
+
+struct ftm_instrument {
+	uint8 name[30];		/* Instrument name */
+	uint8 unknown[2];
+};
+
+struct ftm_header {
+	uint8 id[4];		/* "FTMN" ID string */
+	uint8 ver;		/* Version ?!? (0x03) */
+	uint8 nos;		/* Number of samples (?) */
+	uint8 unknown[10];
+	uint8 title[32];	/* Module title */
+	uint8 author[32];	/* Module author */
+	uint8 unknown2[2];
+};
+
+int ftm_load(HIO_HANDLE * f)
+{
+	int i, j, k;
+	struct xmp_event *event;
+	struct ftm_header fh;
+	struct ftm_instrument si;
+	uint8 b1, b2, b3;
+
+	LOAD_INIT();
+
+	hio_read(&fh.id, 4, 1, f);
+	if (memcmp(fh.id, "FTMN", 4))
+		return -1;
+
+	fh.ver = hio_read8(f);
+	fh.nos = hio_read8(f);
+	hio_read16b(f);
+	hio_read32b(f);
+	hio_read32b(f);
+	hio_read(&fh.title, 32, 1, f);
+	hio_read(&fh.author, 32, 1, f);
+	hio_read16b(f);
+
+	//mod->len = fh.len;
+	//mod->pat = fh.pat;
+	mod->ins = fh.nos;
+	mod->smp = mod->ins;
+	mod->trk = mod->pat * mod->chn;
+	for (i = 0; i < mod->len; i++)
+		mod->xxo[i] = fh.order[i];
+
+	libxmp_set_type(m, "Face The Music");
+	MODULE_INFO();
+	PATTERN_INIT();
+
+	/* Load and convert patterns */
+	if (V(0))
+		report("Stored patterns: %d ", mod->pat);
+	for (i = 0; i < mod->pat; i++) {
+		PATTERN_ALLOC(i);
+		mod->xxp[i]->rows = 64;
+		TRACK_ALLOC(i);
+		for (j = 0; j < 4; j++) {
+		}
+
+		reportv(ctx, 0, ".");
+	}
+
+	INSTRUMENT_INIT();
+	reportv(ctx, 0, "\nStored samples : %d ", mod->smp);
+
+	for (i = 0; i < mod->smp; i++) {
+		reportv(ctx, 0, ".");
+	}
+
+	reportv(ctx, 0, "\n");
+	mod->flg |= XXM_FLG_MODRNG;
+
+	return 0;
+}
diff --git a/src/loaders/gal4_load.c b/src/loaders/gal4_load.c
index 09a59a3..9a05b6b 100644
--- a/src/loaders/gal4_load.c
+++ b/src/loaders/gal4_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -34,7 +34,7 @@
 static int gal4_test(HIO_HANDLE *, char *, const int);
 static int gal4_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader gal4_loader = {
+const struct format_loader libxmp_loader_gal4 = {
 	"Galaxy Music System 4.0",
 	gal4_test,
 	gal4_load
@@ -54,7 +54,7 @@ static int gal4_test(HIO_HANDLE *f, char *t, const int start)
 		return -1;
 
 	hio_read32b(f);		/* skip size */
-	read_title(f, t, 64);
+	libxmp_read_title(f, t, 64);
 
 	return 0;
 }
@@ -70,12 +70,12 @@ static int get_main(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	int flags;
 	
 	hio_read(buf, 1, 64, f);
-	strncpy(mod->name, buf, 64);
-	set_type(m, "Galaxy Music System 4.0");
+	strncpy(mod->name, buf, 63);	/* ensure string terminator */
+	libxmp_set_type(m, "Galaxy Music System 4.0");
 
 	flags = hio_read8(f);
 	if (~flags & 0x01)
-		m->quirk = QUIRK_LINEAR;
+		m->period_type = PERIOD_LINEAR;
 	mod->chn = hio_read8(f);
 	mod->spd = hio_read8(f);
 	mod->bpm = hio_read8(f);
@@ -83,6 +83,11 @@ static int get_main(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	hio_read16l(f);		/* unknown - 0xff00 */
 	hio_read8(f);		/* unknown - 0x80 */
 
+	/* Sanity check */
+	if (mod->chn > 32) {
+		return -1;
+	}
+
 	return 0;
 }
 
@@ -91,10 +96,14 @@ static int get_ordr(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	struct xmp_module *mod = &m->mod;
 	int i;
 
-	mod->len = hio_read8(f);
+	mod->len = hio_read8(f) + 1;
+	if (hio_error(f)) {
+		return -1;
+	}
 
-	for (i = 0; i < mod->len; i++)
+	for (i = 0; i < mod->len; i++) {
 		mod->xxo[i] = hio_read8(f);
+	}
 
 	return 0;
 }
@@ -141,9 +150,14 @@ static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	i = hio_read8(f);	/* pattern number */
 	len = hio_read32l(f);
 	
+	/* Sanity check */
+	if (i >= mod->pat || len <= 0) {
+		return -1;
+	}
+
 	rows = hio_read8(f) + 1;
 
-	if (pattern_tracks_alloc(mod, i, rows) < 0)
+	if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
 		return -1;
 
 	for (r = 0; r < rows; ) {
@@ -205,8 +219,6 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	i = hio_read8(f);		/* instrument number */
 
 	hio_read(&mod->xxi[i].name, 1, 28, f);
-	adjust_string((char *)mod->xxi[i].name);
-
 	mod->xxi[i].nsm = hio_read8(f);
 
 	for (j = 0; j < 108; j++) {
@@ -218,7 +230,7 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	vsw = hio_read8(f);			/* vibrato sweep */
 	hio_read8(f);			/* unknown */
 	hio_read8(f);			/* unknown */
-	vde = hio_read8(f) / 4;		/* vibrato depth */
+	vde = hio_read8(f);		/* vibrato depth */
 	vra = hio_read16l(f) / 16;		/* vibrato speed */
 	hio_read8(f);			/* unknown */
 
@@ -278,7 +290,7 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	if (mod->xxi[i].nsm == 0)
 		return 0;
 
-	if (subinstrument_alloc(mod, i, mod->xxi[i].nsm) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, mod->xxi[i].nsm) < 0)
 		return -1;
 
 	for (j = 0; j < mod->xxi[i].nsm; j++, data->snum++) {
@@ -286,7 +298,6 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 		hio_read32b(f);	/* size */
 	
 		hio_read(&mod->xxs[data->snum].name, 1, 28, f);
-		adjust_string((char *)mod->xxs[data->snum].name);
 	
 		mod->xxi[i].sub[j].pan = hio_read8(f) * 4;
 		if (mod->xxi[i].sub[j].pan == 0)	/* not sure about this */
@@ -318,7 +329,7 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	
 		srate = hio_read32l(f);
 		finetune = 0;
-		c2spd_to_note(srate, &mod->xxi[i].sub[j].xpo, &mod->xxi[i].sub[j].fin);
+		libxmp_c2spd_to_note(srate, &mod->xxi[i].sub[j].xpo, &mod->xxi[i].sub[j].fin);
 		mod->xxi[i].sub[j].fin += finetune;
 	
 		hio_read32l(f);			/* 0x00000000 */
@@ -337,7 +348,7 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	
 		if (mod->xxs[data->snum].len > 1) {
 			int snum = data->snum;
-			if (load_sample(m, f, 0, &mod->xxs[snum], NULL) < 0)
+			if (libxmp_load_sample(m, f, 0, &mod->xxs[snum], NULL) < 0)
 				return -1;
 		}
 	}
@@ -362,38 +373,40 @@ static int gal4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	mod->smp = mod->ins = 0;
 
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		return -1;
 
+	m->c4rate = C4_NTSC_RATE;
+
 	/* IFF chunk IDs */
-	ret = iff_register(handle, "MAIN", get_main);
-	ret |= iff_register(handle, "ORDR", get_ordr);
-	ret |= iff_register(handle, "PATT", get_patt_cnt);
-	ret |= iff_register(handle, "INST", get_inst_cnt);
+	ret = libxmp_iff_register(handle, "MAIN", get_main);
+	ret |= libxmp_iff_register(handle, "ORDR", get_ordr);
+	ret |= libxmp_iff_register(handle, "PATT", get_patt_cnt);
+	ret |= libxmp_iff_register(handle, "INST", get_inst_cnt);
 
 	if (ret != 0)
 		return -1;
 
-	iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
-	iff_set_quirk(handle, IFF_CHUNK_TRUNC4);
+	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
+	libxmp_iff_set_quirk(handle, IFF_CHUNK_TRUNC4);
 
 	/* Load IFF chunks */
-	if (iff_load(handle, m, f, &data) < 0) {
-		iff_release(handle);
+	if (libxmp_iff_load(handle, m, f, &data) < 0) {
+		libxmp_iff_release(handle);
 		return -1;
 	}
 
-	iff_release(handle);
+	libxmp_iff_release(handle);
 
 	mod->trk = mod->pat * mod->chn;
 
 	MODULE_INFO();
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	D_(D_INFO "Stored patterns: %d\n", mod->pat);
@@ -402,30 +415,40 @@ static int gal4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	hio_seek(f, start + offset, SEEK_SET);
 	data.snum = 0;
 
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		return -1;
 
 	/* IFF chunk IDs */
-	ret = iff_register(handle, "PATT", get_patt);
-	ret |= iff_register(handle, "INST", get_inst);
+	ret = libxmp_iff_register(handle, "PATT", get_patt);
+	ret |= libxmp_iff_register(handle, "INST", get_inst);
 
 	if (ret != 0)
 		return -1;
 
-	iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
-	iff_set_quirk(handle, IFF_CHUNK_TRUNC4);
+	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
+	libxmp_iff_set_quirk(handle, IFF_CHUNK_TRUNC4);
 
 	/* Load IFF chunks */
-	if (iff_load(handle, m, f, &data) < 0) {
-		iff_release(handle);
+	if (libxmp_iff_load(handle, m, f, &data) < 0) {
+		libxmp_iff_release(handle);
 		return -1;
 	}
 
-	iff_release(handle);
+	libxmp_iff_release(handle);
+
+	/* Alloc missing patterns */
+	for (i = 0; i < mod->pat; i++) {
+		if (mod->xxp[i] == NULL) {
+			if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0) {
+				return -1;
+			}
+		}
+	}
 
-	for (i = 0; i < mod->chn; i++)
+	for (i = 0; i < mod->chn; i++) {
 		mod->xxc[i].pan = 0x80;
+	}
 
 	m->quirk |= QUIRKS_FT2;
 	m->read_event_type = READ_EVENT_FT2;
diff --git a/src/loaders/gal5_load.c b/src/loaders/gal5_load.c
index 3f2af90..7d32f5e 100644
--- a/src/loaders/gal5_load.c
+++ b/src/loaders/gal5_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -37,7 +37,7 @@
 static int gal5_test(HIO_HANDLE *, char *, const int);
 static int gal5_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader gal5_loader = {
+const struct format_loader libxmp_loader_gal5 = {
 	"Galaxy Music System 5.0 (J2B)",
 	gal5_test,
 	gal5_load
@@ -62,7 +62,7 @@ static int gal5_test(HIO_HANDLE *f, char *t, const int start)
 		return -1;
 
 	hio_read32b(f);		/* skip size */
-	read_title(f, t, 64);
+	libxmp_read_title(f, t, 64);
 
 	return 0;
 }
@@ -75,11 +75,11 @@ static int get_init(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	int flags;
 	
 	hio_read(buf, 1, 64, f);
-	strncpy(mod->name, buf, 64);
-	set_type(m, "Galaxy Music System 5.0");
+	strncpy(mod->name, buf, 63);	/* ensure string terminator */
+	libxmp_set_type(m, "Galaxy Music System 5.0");
 	flags = hio_read8(f);	/* bit 0: Amiga period */
 	if (~flags & 0x01)
-		m->quirk |= QUIRK_LINEAR;
+		m->period_type = PERIOD_LINEAR;
 	mod->chn = hio_read8(f);
 	mod->spd = hio_read8(f);
 	mod->bpm = hio_read8(f);
@@ -146,7 +146,7 @@ static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	
 	rows = hio_read8(f) + 1;
 
-	if (pattern_tracks_alloc(mod, i, rows) < 0)
+	if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
 		return -1;
 
 	for (r = 0; r < rows; ) {
@@ -206,8 +206,6 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	i = hio_read8(f);		/* instrument number */
 	
 	hio_read(&mod->xxi[i].name, 1, 28, f);
-	adjust_string((char *)mod->xxi[i].name);
-
 	hio_seek(f, 290, SEEK_CUR);	/* Sample/note map, envelopes */
 	mod->xxi[i].nsm = hio_read16l(f);
 
@@ -216,7 +214,7 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	if (mod->xxi[i].nsm == 0)
 		return 0;
 
-	if (subinstrument_alloc(mod, i, mod->xxi[i].nsm) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, mod->xxi[i].nsm) < 0)
 		return -1;
 
 	/* FIXME: Currently reading only the first sample */
@@ -229,7 +227,6 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	hio_read32b(f);	/* unknown - usually 0x40000000 */
 
 	hio_read(&mod->xxs[i].name, 1, 28, f);
-	adjust_string((char *)mod->xxs[i].name);
 
 	hio_read32b(f);	/* unknown - 0x0000 */
 	hio_read8(f);	/* unknown - 0x00 */
@@ -257,7 +254,7 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 
 	srate = hio_read32l(f);
 	finetune = 0;
-	c2spd_to_note(srate, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
+	libxmp_c2spd_to_note(srate, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
 	mod->xxi[i].sub[0].fin += finetune;
 
 	hio_read32l(f);			/* 0x00000000 */
@@ -273,7 +270,7 @@ static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 		mod->xxi[i].sub[0].vol, flags, srate);
 
 	if (mod->xxs[i].len > 1) {
-		if (load_sample(m, f, has_unsigned_sample ?
+		if (libxmp_load_sample(m, f, has_unsigned_sample ?
 				SAMPLE_FLAG_UNS : 0, &mod->xxs[i], NULL) < 0)
 			return -1;
 	}
@@ -298,40 +295,42 @@ static int gal5_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	mod->smp = mod->ins = 0;
 
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		return -1;
 
+	m->c4rate = C4_NTSC_RATE;
+
 	/* IFF chunk IDs */
-	ret = iff_register(handle, "INIT", get_init);		/* Galaxy 5.0 */
-	ret |= iff_register(handle, "ORDR", get_ordr);
-	ret |= iff_register(handle, "PATT", get_patt_cnt);
-	ret |= iff_register(handle, "INST", get_inst_cnt);
+	ret = libxmp_iff_register(handle, "INIT", get_init);		/* Galaxy 5.0 */
+	ret |= libxmp_iff_register(handle, "ORDR", get_ordr);
+	ret |= libxmp_iff_register(handle, "PATT", get_patt_cnt);
+	ret |= libxmp_iff_register(handle, "INST", get_inst_cnt);
 
 	if (ret != 0)
 		return -1;
 
-	iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
-	iff_set_quirk(handle, IFF_SKIP_EMBEDDED);
-	iff_set_quirk(handle, IFF_CHUNK_ALIGN2);
+	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
+	libxmp_iff_set_quirk(handle, IFF_SKIP_EMBEDDED);
+	libxmp_iff_set_quirk(handle, IFF_CHUNK_ALIGN2);
 
 	/* Load IFF chunks */
-	if (iff_load(handle, m, f, &data) < 0) {
-		iff_release(handle);
+	if (libxmp_iff_load(handle, m, f, &data) < 0) {
+		libxmp_iff_release(handle);
 		return -1;
 	}
 
-	iff_release(handle);
+	libxmp_iff_release(handle);
 
 	mod->trk = mod->pat * mod->chn;
 	mod->smp = mod->ins;
 
 	MODULE_INFO();
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	D_(D_INFO "Stored patterns: %d", mod->pat);
@@ -339,28 +338,37 @@ static int gal5_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	hio_seek(f, start + offset, SEEK_SET);
 
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		return -1;
 
 	/* IFF chunk IDs */
-	ret = iff_register(handle, "PATT", get_patt);
-	ret |= iff_register(handle, "INST", get_inst);
+	ret = libxmp_iff_register(handle, "PATT", get_patt);
+	ret |= libxmp_iff_register(handle, "INST", get_inst);
 
 	if (ret != 0)
 		return -1;
 
-	iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
-	iff_set_quirk(handle, IFF_SKIP_EMBEDDED);
-	iff_set_quirk(handle, IFF_CHUNK_ALIGN2);
+	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
+	libxmp_iff_set_quirk(handle, IFF_SKIP_EMBEDDED);
+	libxmp_iff_set_quirk(handle, IFF_CHUNK_ALIGN2);
 
 	/* Load IFF chunks */
-	if (iff_load(handle, m, f, &data) < 0) {
-		iff_release(handle);
+	if (libxmp_iff_load(handle, m, f, &data) < 0) {
+		libxmp_iff_release(handle);
 		return -1;
 	}
 
-	iff_release(handle);
+	libxmp_iff_release(handle);
+
+	/* Alloc missing patterns */
+	for (i = 0; i < mod->pat; i++) {
+		if (mod->xxp[i] == NULL) {
+			if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0) {
+				return -1;
+			}
+		}
+	}
 
 	for (i = 0; i < mod->chn; i++) {
 		mod->xxc[i].pan = data.chn_pan[i] * 2;
diff --git a/src/loaders/gdm_load.c b/src/loaders/gdm_load.c
index a8dd43f..5b83ebe 100644
--- a/src/loaders/gdm_load.c
+++ b/src/loaders/gdm_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 /*
@@ -21,7 +35,7 @@
 static int gdm_test(HIO_HANDLE *, char *, const int);
 static int gdm_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader gdm_loader = {
+const struct format_loader libxmp_loader_gdm = {
 	"Generic Digital Music",
 	gdm_test,
 	gdm_load
@@ -37,7 +51,7 @@ static int gdm_test(HIO_HANDLE *f, char *t, const int start)
 		return -1;
 
 	hio_seek(f, start + 4, SEEK_SET);
-	read_title(f, t, 32);
+	libxmp_read_title(f, t, 32);
 
 	return 0;
 }
@@ -120,10 +134,10 @@ static int gdm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	tvmin = hio_read8(f);
 
 	if (tracker == 0) {
-		set_type(m, "GDM %d.%02d (2GDM %d.%02d)",
+		libxmp_set_type(m, "GDM %d.%02d (2GDM %d.%02d)",
 					vermaj, vermin, tvmaj, tvmin);
 	} else {
-		set_type(m, "GDM %d.%02d (unknown tracker %d.%02d)",
+		libxmp_set_type(m, "GDM %d.%02d (unknown tracker %d.%02d)",
 					vermaj, vermin, tvmaj, tvmin);
 	}
 
@@ -151,6 +165,8 @@ static int gdm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	smp_ofs = hio_read32l(f);
 	mod->ins = mod->smp = hio_read8(f) + 1;
 	
+	m->c4rate = C4_NTSC_RATE;
+
 	MODULE_INFO();
 
 	hio_seek(f, start + ord_ofs, SEEK_SET);
@@ -162,17 +178,19 @@ static int gdm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	hio_seek(f, start + ins_ofs, SEEK_SET);
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	for (i = 0; i < mod->ins; i++) {
 		int flg, c4spd, vol, pan;
 
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+
+		if (hio_read(buffer, 1, 32, f) != 32)
 			return -1;
 
-		hio_read(buffer, 32, 1, f);
-		instrument_name(mod, i, buffer, 32);
+		libxmp_instrument_name(mod, i, buffer, 32);
 		hio_seek(f, 12, SEEK_CUR);		/* skip filename */
 		hio_read8(f);			/* skip EMS handle */
 		mod->xxs[i].len = hio_read32l(f);
@@ -185,7 +203,7 @@ static int gdm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		
 		mod->xxi[i].sub[0].vol = vol > 0x40 ? 0x40 : vol;
 		mod->xxi[i].sub[0].pan = pan > 15 ? 0x80 : 0x80 + (pan - 8) * 16;
-		c2spd_to_note(c4spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
+		libxmp_c2spd_to_note(c4spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
 
 		mod->xxi[i].sub[0].sid = i;
 		mod->xxs[i].flg = 0;
@@ -236,6 +254,16 @@ static int gdm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 			if (c == 0) {
 				r++;
+
+				/* Sanity check */
+				if (len == 0) {
+					if  (r > 64)
+						return -1;
+				} else {
+					if (r >= 64)
+						return -1;
+				}
+
 				continue;
 			}
 
@@ -263,7 +291,7 @@ static int gdm_load(struct module_data *m, HIO_HANDLE *f, const int start)
  
 	mod->trk = mod->pat * mod->chn;
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	hio_seek(f, start + pat_ofs, SEEK_SET);
@@ -272,7 +300,7 @@ static int gdm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	for (i = 0; i < mod->pat; i++) {
 		int len, c, r, k;
 
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 			return -1;
 
 		len = hio_read16l(f);
@@ -287,6 +315,11 @@ static int gdm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				continue;
 			}
 
+			/* Sanity check */
+			if ((c & 0x1f) >= mod->chn || r >= 64) {
+				return -1;
+			}
+
 			event = &EVENT(i, c & 0x1f, r);
 
 			if (c & 0x20) {		/* note and sample follows */
@@ -329,9 +362,11 @@ static int gdm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	D_(D_INFO "Stored samples: %d", mod->smp);
 
 	for (i = 0; i < mod->ins; i++) {
-		if (load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
 			return -1;
 	}
 
+	m->quirk |= QUIRK_ARPMEM;
+
 	return 0;
 }
diff --git a/src/loaders/gtk_load.c b/src/loaders/gtk_load.c
new file mode 100644
index 0000000..230638b
--- /dev/null
+++ b/src/loaders/gtk_load.c
@@ -0,0 +1,285 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "loader.h"
+#include "period.h"
+
+
+static int gtk_test(HIO_HANDLE *, char *, const int);
+static int gtk_load (struct module_data *, HIO_HANDLE *, const int);
+
+const struct format_loader libxmp_loader_gtk = {
+	"Graoumf Tracker",
+	gtk_test,
+	gtk_load
+};
+
+static int gtk_test(HIO_HANDLE * f, char *t, const int start)
+{
+	char buf[4];
+
+	if (hio_read(buf, 1, 4, f) < 4)
+		return -1;
+
+	if (memcmp(buf, "GTK", 3) || buf[3] > 4)
+		return -1;
+
+	libxmp_read_title(f, t, 32);
+
+	return 0;
+}
+
+static void translate_effects(struct xmp_event *event)
+{
+	/* Ignore extended effects */
+	if (event->fxt == 0x0e || event->fxt == 0x0c) {
+		event->fxt = 0;
+		event->fxp = 0;
+	}
+
+	/* handle high-numbered effects */
+	if (event->fxt >= 0x40 && event->fxt <= 0x4f) {
+		event->fxp = (event->fxt << 4) | (event->fxp >> 4);
+		event->fxt = FX_SETPAN;
+	} else if (event->fxt >= 0x80 && event->fxt <= 0x8f) {
+		event->fxt = FX_MULTI_RETRIG;
+	} else if (event->fxt >= 0x08) {
+		switch (event->fxt) {
+		case 0x08:	/* detune */
+			event->fxt = event->fxp = 0;
+			break;
+		case 0x09:	/* delay */
+			event->fxt = FX_EXTENDED;
+			event->fxp = 0xd0 | (event->fxp & 0x0f);
+			break;
+		case 0x0a:	/* cut / note release */
+			event->fxt = FX_EXTENDED;
+			event->fxp = 0xc0 | (event->fxp & 0x0f);
+			break;
+		case 0x0b:	/* position jump */
+		case 0x0d:	/* break pattern */
+		case 0x0f:	/* set global speed/tempo */
+			/* same as ptk */
+			break;
+		case 0x0c:	/* set vibrato waveform */
+			event->fxt = FX_EXTENDED;
+			event->fxp = 0x40 | (event->fxp & 0x0f);
+			break;
+		case 0x0e:	/* set tremolo waveform */
+			event->fxt = FX_EXTENDED;
+			event->fxp = 0x70 | (event->fxp & 0x0f);
+			break;
+		case 0x10:	/* arpeggio */
+			event->fxt = FX_ARPEGGIO;
+			break;
+		case 0x11:	/* fine portamento up */
+			event->fxt = FX_F_PORTA_UP;
+			break;
+		case 0x12:	/* fine portamento down */
+			event->fxt = FX_F_PORTA_DN;
+			break;
+		case 0x13:	/* roll + volume slide */
+			event->fxt = FX_MULTI_RETRIG;
+			break;
+		case 0x16:	/* exp. volume slide up */
+		case 0x14:	/* linear volume slide up */
+			event->fxt = FX_VOLSLIDE_UP;
+			break;
+		case 0x17:	/* exp. volume slide down */
+		case 0x15:	/* linear volume slide down */
+			event->fxt = FX_VOLSLIDE_DN;
+			break;
+		case 0x20:	/* set volume */
+			event->fxt = FX_VOLSET;
+			break;
+		case 0x21:	/* set volume to 0x100 */
+			event->fxt = FX_VOLSET;
+			event->fxp = 0xff;
+			break;
+		case 0xa4:	/* fine volume slide up */
+			event->fxt = FX_F_VSLIDE;
+			if (event->fxp > 0x0f)
+				event->fxp = 0x0f;
+			event->fxp <<= 4;
+			break;
+		case 0xa5:	/* fine volume slide down */
+			event->fxt = FX_F_VSLIDE;
+			if (event->fxp > 0x0f)
+				event->fxp = 0x0f;
+			break;
+		case 0xa8:	/* set number of frames */
+			event->fxt = FX_S3M_SPEED;
+			break;
+		default:
+			event->fxt = event->fxp = 0;
+		}
+	}
+}
+
+static int gtk_load(struct module_data *m, HIO_HANDLE *f, const int start)
+{
+	struct xmp_module *mod = &m->mod;
+	struct xmp_event *event;
+	int i, j, k;
+	uint8 buffer[40];
+	int rows, bits, c2spd, size;
+	int ver, patmax;
+
+	LOAD_INIT();
+
+	hio_read(buffer, 4, 1, f);
+	ver = buffer[3];
+	hio_read(mod->name, 32, 1, f);
+	libxmp_set_type(m, "Graoumf Tracker GTK v%d", ver);
+	hio_seek(f, 160, SEEK_CUR);	/* skip comments */
+
+	mod->ins = hio_read16b(f);
+	mod->smp = mod->ins;
+	rows = hio_read16b(f);
+	mod->chn = hio_read16b(f);
+	mod->len = hio_read16b(f);
+	mod->rst = hio_read16b(f);
+	m->volbase = 0x100;
+	m->c4rate = C4_NTSC_RATE;
+
+	MODULE_INFO();
+
+	D_(D_INFO "Instruments    : %d ", mod->ins);
+
+	if (libxmp_init_instrument(m) < 0)
+		return -1;
+
+	for (i = 0; i < mod->ins; i++) {
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+
+		hio_read(buffer, 28, 1, f);
+		libxmp_instrument_name(mod, i, buffer, 28);
+
+		if (ver == 1) {
+			hio_read32b(f);
+			mod->xxs[i].len = hio_read32b(f);
+			mod->xxs[i].lps = hio_read32b(f);
+			size = hio_read32b(f);
+			mod->xxs[i].lpe = mod->xxs[i].lps + size - 1;
+			hio_read16b(f);
+			hio_read16b(f);
+			mod->xxi[i].sub[0].vol = 0xff;
+			mod->xxi[i].sub[0].pan = 0x80;
+			bits = 1;
+			c2spd = 8363;
+		} else {
+			hio_seek(f, 14, SEEK_CUR);
+			hio_read16b(f);		/* autobal */
+			bits = hio_read16b(f);	/* 1 = 8 bits, 2 = 16 bits */
+			c2spd = hio_read16b(f);
+			libxmp_c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
+			mod->xxs[i].len = hio_read32b(f);
+			mod->xxs[i].lps = hio_read32b(f);
+			size = hio_read32b(f);
+			mod->xxs[i].lpe = mod->xxs[i].lps + size - 1;
+			mod->xxi[i].sub[0].vol = hio_read16b(f);
+			hio_read8(f);
+			mod->xxi[i].sub[0].fin = hio_read8s(f);
+		}
+
+		if (mod->xxs[i].len > 0)
+			mod->xxi[i].nsm = 1;
+
+		mod->xxi[i].sub[0].sid = i;
+		mod->xxs[i].flg = size > 2 ? XMP_SAMPLE_LOOP : 0;
+
+		if (bits > 1) {
+			mod->xxs[i].flg |= XMP_SAMPLE_16BIT;
+			mod->xxs[i].len >>= 1;
+			mod->xxs[i].lps >>= 1;
+			mod->xxs[i].lpe >>= 1;
+		}
+
+		D_(D_INFO "[%2X] %-28.28s  %05x%c%05x %05x %c "
+						"V%02x F%+03d %5d", i,
+			 	mod->xxi[i].name,
+				mod->xxs[i].len,
+				bits > 1 ? '+' : ' ',
+				mod->xxs[i].lps,
+				size,
+				mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
+				mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin,
+				c2spd);
+	}
+
+	for (i = 0; i < 256; i++)
+		mod->xxo[i] = hio_read16b(f);
+
+	for (patmax = i = 0; i < mod->len; i++) {
+		if (mod->xxo[i] > patmax)
+			patmax = mod->xxo[i];
+	}
+
+	mod->pat = patmax + 1;
+	mod->trk = mod->pat * mod->chn;
+
+	if (libxmp_init_pattern(mod) < 0)
+		return -1;
+
+	/* Read and convert patterns */
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
+			return -1;
+
+		for (j = 0; j < mod->xxp[i]->rows; j++) {
+			for (k = 0; k < mod->chn; k++) {
+				event = &EVENT (i, k, j);
+
+				event->note = hio_read8(f);
+				if (event->note) {
+					event->note += 13;
+				}
+				event->ins = hio_read8(f);
+
+				event->fxt = hio_read8(f);
+				event->fxp = hio_read8(f);
+				if (ver >= 4) {
+					event->vol = hio_read8(f);
+				}
+
+				translate_effects(event);
+
+			}
+		}
+	}
+
+	/* Read samples */
+	D_(D_INFO "Stored samples: %d", mod->smp);
+
+	for (i = 0; i < mod->ins; i++) {
+		if (mod->xxs[i].len == 0)
+			continue;
+
+		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+			return -1;
+	}
+
+	return 0;
+}
diff --git a/src/loaders/hmn_load.c b/src/loaders/hmn_load.c
index 618a077..b05edf7 100644
--- a/src/loaders/hmn_load.c
+++ b/src/loaders/hmn_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -64,7 +78,7 @@
 static int hmn_test(HIO_HANDLE *, char *, const int);
 static int hmn_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader hmn_loader = {
+const struct format_loader libxmp_loader_hmn = {
 	"His Master's Noise",
 	hmn_test,
 	hmn_load
@@ -87,7 +101,7 @@ static int hmn_test(HIO_HANDLE * f, char *t, const int start)
 		return -1;
 
 	hio_seek(f, start + 0, SEEK_SET);
-	read_title(f, t, 20);
+	libxmp_read_title(f, t, 20);
 
 	return 0;
 }
@@ -186,14 +200,14 @@ static int hmn_load(struct module_data *m, HIO_HANDLE * f, const int start)
 	mod->pat++;
 	mod->trk = mod->chn * mod->pat;
 
-	if (hmn_new_module_extras(m) != 0)
+	if (libxmp_hmn_new_module_extras(m) != 0)
 		return -1;
 
 	strncpy(mod->name, (char *)mh.name, 20);
-	set_type(m, "%s (%4.4s)", "His Master's Noise", mh.magic);
+	libxmp_set_type(m, "%s (%4.4s)", "His Master's Noise", mh.magic);
 	MODULE_INFO();
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	for (i = 0; i < mod->ins; i++) {
@@ -202,11 +216,11 @@ static int hmn_load(struct module_data *m, HIO_HANDLE * f, const int start)
 			snprintf(mod->xxi[i].name, 32,
 				"Mupp %02x %02x %02x", mupp[i].pattno,
 				mupp[i].dataloopstart, mupp[i].dataloopend);
-			if (hmn_new_instrument_extras(&mod->xxi[i]) != 0)
+			if (libxmp_hmn_new_instrument_extras(&mod->xxi[i]) != 0)
 				return -1;
 		} else {
 			mod->xxi[i].nsm = 1;
-			instrument_name(mod, i, mh.ins[i].name, 22);
+			libxmp_instrument_name(mod, i, mh.ins[i].name, 22);
 
 			mod->xxs[i].len = 2 * mh.ins[i].size;
 			mod->xxs[i].lps = 2 * mh.ins[i].loop_start;
@@ -216,7 +230,7 @@ static int hmn_load(struct module_data *m, HIO_HANDLE * f, const int start)
 						XMP_SAMPLE_LOOP : 0;
 		}
 
-		if (subinstrument_alloc(mod, i, mod->xxi[i].nsm) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, mod->xxi[i].nsm) < 0)
 			return -1;
 
 		for (j = 0; j < mod->xxi[i].nsm; j++) {
@@ -228,20 +242,20 @@ static int hmn_load(struct module_data *m, HIO_HANDLE * f, const int start)
 		}
 	}
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	/* Load and convert patterns */
 	D_(D_INFO "Stored patterns: %d", mod->pat);
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 			return -1;
 
 		for (j = 0; j < (64 * 4); j++) {
 			event = &EVENT(i, j % 4, j / 4);
 			hio_read(mod_event, 1, 4, f);
-			decode_protracker_event(event, mod_event);
+			libxmp_decode_protracker_event(event, mod_event);
 
 			switch (event->fxt) {
 			case 0x07:
@@ -256,14 +270,14 @@ static int hmn_load(struct module_data *m, HIO_HANDLE * f, const int start)
 		}
 	}
 
-	m->quirk |= QUIRK_MODRNG;
+	m->period_type = PERIOD_MODRNG;
 
 	/* Load samples */
 
 	D_(D_INFO "Stored samples: %d", mod->smp);
 
 	for (i = 0; i < 31; i++) {
-		if (load_sample(m, f, SAMPLE_FLAG_FULLREP,
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_FULLREP,
 						&mod->xxs[i], NULL) < 0) {
 			return -1;
 		}
@@ -288,7 +302,7 @@ static int hmn_load(struct module_data *m, HIO_HANDLE * f, const int start)
 			mod->xxs[k].lps = 0;
 			mod->xxs[k].lpe = 32;
 			mod->xxs[k].flg = XMP_SAMPLE_LOOP;
-			if (load_sample(m, f, 0, &mod->xxs[k], NULL) < 0)
+			if (libxmp_load_sample(m, f, 0, &mod->xxs[k], NULL) < 0)
 				return -1;
 		}
 
diff --git a/src/loaders/hsc_load.c b/src/loaders/hsc_load.c
index 5302a7b..0a122af 100644
--- a/src/loaders/hsc_load.c
+++ b/src/loaders/hsc_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -21,7 +35,7 @@
 static int hsc_test (HIO_HANDLE *, char *, const int);
 static int hsc_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader hsc_loader = {
+const struct format_loader libxmp_loader_hsc = {
     "HSC-Tracker",
     hsc_test,
     hsc_load
@@ -60,7 +74,7 @@ static int hsc_test(HIO_HANDLE *f, char *t, const int start)
 	}
     }
 
-    read_title(f, t, 0);
+    libxmp_read_title(f, t, 0);
 
     return 0;
 }
@@ -95,18 +109,18 @@ static int hsc_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     m->quirk |= QUIRK_LINEAR;
 
-    set_type(m, "HSC-Tracker");
+    libxmp_set_type(m, "HSC-Tracker");
 
     MODULE_INFO();
 
     /* Read instruments */
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
-    hio_read (buf, 1, 128 * 12, f);
+    hio_read(buf, 1, 128 * 12, f);
     sid = buf;
     for (i = 0; i < mod->ins; i++, sid += 12) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 	    return -1;
 
 	mod->xxi[i].nsm = 1;
@@ -117,15 +131,15 @@ static int hsc_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->xxi[i].sub[0].sid = i;
 	mod->xxi[i].rls = LSN(sid[7]) * 32;	/* carrier release */
 
-	if (load_sample(m, f, SAMPLE_FLAG_ADLIB | SAMPLE_FLAG_HSC,
+	if (libxmp_load_sample(m, f, SAMPLE_FLAG_ADLIB | SAMPLE_FLAG_HSC,
 					&mod->xxs[i], (char *)sid) < 0)
 		return -1;
     }
 
     /* Read orders */
     for (pat = i = 0; i < 51; i++) {
-	hio_read (&mod->xxo[i], 1, 1, f);
-	if (mod->xxo[i] & 0x80)
+	mod->xxo[i] = hio_read8(f);
+	if (mod->xxo[i] > 127)
 	    break;			/* FIXME: jump line */
 	if (mod->xxo[i] > pat)
 	    pat = mod->xxo[i];
@@ -139,19 +153,19 @@ static int hsc_load(struct module_data *m, HIO_HANDLE *f, const int start)
     D_(D_INFO "Instruments: %d", mod->ins);
     D_(D_INFO "Stored patterns: %d", mod->pat);
 
-    if (pattern_init(mod) < 0)
+    if (libxmp_init_pattern(mod) < 0)
 	return -1;
 
     /* Read and convert patterns */
     for (i = 0; i < mod->pat; i++) {
 	int ins[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
+	if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 	    return -1;
 
         for (r = 0; r < mod->xxp[i]->rows; r++) {
             for (c = 0; c < 9; c++) {
-	        hio_read (e, 1, 2, f);
+	        hio_read(e, 1, 2, f);
 	        event = &EVENT (i, c, r);
 		if (e[0] & 0x80) {
 		    ins[c] = e[1] + 1;
diff --git a/src/loaders/hvl_load.c b/src/loaders/hvl_load.c
new file mode 100644
index 0000000..c6e777e
--- /dev/null
+++ b/src/loaders/hvl_load.c
@@ -0,0 +1,531 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * This file is part of the Extended Module Player and is distributed
+ * under the terms of the GNU Lesser General Public License. See COPYING.LIB
+ * for more information.
+ */
+
+#define D_EBUG
+
+#include "loader.h"
+
+#define MAGIC_HVL	MAGIC4('H','V','L', 0)
+
+static int hvl_test (HIO_HANDLE *, char *, const int);
+static int hvl_load (struct module_data *, HIO_HANDLE *, const int);
+
+
+const struct format_loader libxmp_loader_hvl = {
+	"HVL",
+	"Hively Tracker",
+	hvl_test,
+	hvl_load
+};
+
+static int hvl_test(HIO_HANDLE *f, char *t, const int start)
+{
+	if (hio_read32b(f) != MAGIC_HVL)
+		return -1;
+
+	uint16 off = hio_read16b(f);
+	if (hio_seek(f, off + 1, SEEK_SET))
+		return -1;
+
+	libxmp_read_title(f, t, 32);
+
+	return 0;
+}
+
+
+static void hvl_GenSawtooth(int8 * buf, uint32 len)
+{
+	uint32 i;
+	int32 val, add;
+
+	add = 256 / (len - 1);
+	val = -128;
+
+	for (i = 0; i < len; i++, val += add)
+		*buf++ = (int8) val;
+}
+
+static void hvl_GenTriangle(int8 * buf, uint32 len)
+{
+	uint32 i;
+	int32 d2, d5, d1, d4;
+	int32 val;
+	int8 *buf2;
+
+	d2 = len;
+	d5 = len >> 2;
+	d1 = 128 / d5;
+	d4 = -(d2 >> 1);
+	val = 0;
+
+	for (i = 0; i < d5; i++) {
+		*buf++ = val;
+		val += d1;
+	}
+	*buf++ = 0x7f;
+
+	if (d5 != 1) {
+		val = 128;
+		for (i = 0; i < d5 - 1; i++) {
+			val -= d1;
+			*buf++ = val;
+		}
+	}
+
+	buf2 = buf + d4;
+	for (i = 0; i < d5 * 2; i++) {
+		int8 c;
+
+		c = *buf2++;
+		if (c == 0x7f)
+			c = 0x80;
+		else
+			c = -c;
+
+		*buf++ = c;
+	}
+}
+
+static void hvl_GenSquare(int8 * buf)
+{
+	uint32 i, j;
+
+	for (i = 1; i <= 0x20; i++) {
+		for (j = 0; j < (0x40 - i) * 2; j++)
+			*buf++ = 0x80;
+		for (j = 0; j < i * 2; j++)
+			*buf++ = 0x7f;
+	}
+}
+
+static void hvl_GenWhiteNoise(int8 * buf, uint32 len)
+{
+	uint32 ays;
+
+	ays = 0x41595321;
+
+	do {
+		uint16 ax, bx;
+		int8 s;
+
+		s = ays;
+
+		if (ays & 0x100) {
+			s = 0x80;
+
+			if ((int32) (ays & 0xffff) >= 0)
+				s = 0x7f;
+		}
+
+		*buf++ = s;
+		len--;
+
+		ays = (ays >> 5) | (ays << 27);
+		ays = (ays & 0xffffff00) | ((ays & 0xff) ^ 0x9a);
+		bx = ays;
+		ays = (ays << 2) | (ays >> 30);
+		ax = ays;
+		bx += ax;
+		ax ^= bx;
+		ays = (ays & 0xffff0000) | ax;
+		ays = (ays >> 3) | (ays << 29);
+	} while (len);
+}
+
+static void fix_effect (uint8 *fx, uint8 *param) {
+	switch (*fx) {
+	case 0:
+		if (*param)
+			*fx = FX_AHX_FILTER;
+		break;
+	case 3: /* init square */
+		*fx = FX_AHX_SQUARE;
+		break;
+	case 4: /* set filter */
+		*fx = FX_AHX_MODULATE;
+		break;
+	case 6: /* unused */
+	case 8: /* unused */
+		*fx = *param = 0;
+		break;
+	case 7:
+		*fx = FX_MASTER_PAN;
+		*param ^= 0x80;
+//		printf ("pan %02x\n", *param);
+		break;
+	case 9:
+		D_(D_INFO "square %02x", *param);
+		break;
+	case 12:
+		if (*param >= 0x50 && *param <= 0x90) {
+			*param -= 0x50;
+			*fx = FX_GLOBALVOL;
+		} else if (*param >= 0xa0 && *param <= 0xe0) {
+			*param -= 0xa0;
+			*fx = FX_TRK_VOL;
+		}
+		break;
+	case 15:
+		*fx = FX_S3M_SPEED;
+		break;
+	}
+}
+
+static int hvl_load(struct module_data *m, HIO_HANDLE *f, const int start)
+{
+	struct player_data *p = &ctx->p;
+	struct xmp_module *mod = &m->mod;
+	int i, j, tmp, blank;
+
+	LOAD_INIT();
+
+	hio_read32b(f);
+
+	uint16 title_offset = hio_read16b(f);
+	tmp = hio_read16b(f);
+	mod->len = tmp & 0xfff;
+	blank = tmp & 0x8000;
+		
+	tmp = hio_read16b(f);
+	mod->chn = (tmp >> 10) + 4;
+	mod->rst = tmp & 1023;
+
+	int pattlen = hio_read8(f);
+	mod->trk = hio_read8(f) + 1;
+	mod->ins = hio_read8(f);
+	int subsongs = hio_read8(f);
+	int gain = hio_read8(f);
+	int stereo = hio_read8(f);
+
+	D_(D_WARN "pattlen=%d npatts=%d nins=%d seqlen=%d stereo=%02x",
+		pattlen, mod->trk, mod->ins, mod->len, stereo);
+
+	libxmp_set_type(m, "HVL (Hively Tracker)");
+	MODULE_INFO();
+
+	mod->pat = mod->len;
+	mod->smp = 20;
+	PATTERN_INIT();
+	INSTRUMENT_INIT();
+
+	hio_seek (f, subsongs*2, SEEK_CUR);
+
+	uint8 *seqbuf = malloc(mod->len * mod->chn * 2);
+	uint8 *seqptr = seqbuf;
+	hio_read (seqbuf, 1, mod->len * mod->chn * 2, f);
+
+	uint8 **transbuf = malloc (mod->len * mod->chn * sizeof(uint8 *));
+	int transposed = 0;
+
+	reportv(ctx, 0, "Stored patterns: %d ", mod->len);
+
+	for (i = 0; i < mod->len; i++) {
+		PATTERN_ALLOC(i);
+		mod->xxp[i]->rows = pattlen;
+		for (j = 0; j < mod->chn; j++) {
+			if (seqptr[1]) {
+//				printf ("%d: transpose %02x by %d\n", i, seqptr[0], seqptr[1]);
+				mod->xxp[i]->info[j].index = mod->trk + transposed;
+				transbuf[transposed] = seqptr;
+				transposed++;
+			} else {
+				mod->xxp[i]->info[j].index = seqptr[0];
+			}
+			seqptr += 2;
+//			printf ("%02x ", mod->xxp[i]->info[j].index);
+		}
+//		printf ("\n");
+		mod->xxo[i] = i;
+		reportv(ctx, 0, ".");
+	}
+	reportv(ctx, 0, "\n");
+	
+
+	/*
+	 * tracks
+	 */
+
+	if (transposed) {
+		mod->trk += transposed;
+		mod->xxt = realloc(mod->xxt, mod->trk * sizeof (struct xmp_track *));
+	}
+	
+	reportv(ctx, 0, "Stored tracks  : %d ", mod->trk);
+
+	for (i = 0; i < mod->trk; i++) {
+		mod->xxt[i] = calloc(sizeof(struct xmp_track) +
+				   sizeof(struct xmp_event) * pattlen - 1, 1);
+                mod->xxt[i]->rows = pattlen;
+
+		if (!i && blank)
+			continue;
+
+		if (i >= mod->trk-transposed) {
+			int n=i-(mod->trk - transposed);
+			int o=transbuf[n][1];
+			if (o>127)
+				o-=256;
+//			printf ("pattern %02x: source %02x offset %d\n", i, n, o);
+			memcpy (mod->xxt[i], mod->xxt[transbuf[n][0]],
+				sizeof(struct xmp_track) +
+				sizeof(struct xmp_event) * pattlen - 1);
+			for (j = 0; j < mod->xxt[i]->rows; j++) {
+				struct xmp_event *event = &mod->xxt[i]->event[j];
+				if (event->note)
+					event->note+=o;
+			}
+			continue;
+		}
+
+		for (j = 0; j < mod->xxt[i]->rows; j++) {
+			struct xmp_event *event = &mod->xxt[i]->event[j];
+			int note = hio_read8(f);			
+
+			if (note != 0x3f) {
+				uint32 b = hio_read32b(f);
+				event->note = note?note+24:0;
+				event->ins = b >> 24;
+				event->fxt = (b & 0xf00000) >> 20;
+				event->f2t = (b & 0x0f0000) >> 16;
+				event->fxp = (b & 0xff00) >> 8;
+				event->f2p = b & 0xff;
+				fix_effect (&event->fxt, &event->fxp);
+				fix_effect (&event->f2t, &event->f2p);
+				//	printf ("#");
+			} //else 
+			//	printf (".");
+		}
+		if (V(0) && !(i % mod->chn))
+			report (".");
+	}
+	reportv(ctx, 0, "\n");
+
+	free(seqbuf);
+	free(transbuf);
+
+	/*
+	 * Instruments
+	 */
+
+	for (i = 0; i < mod->ins; i++) {
+		uint8 buf[22];
+		int vol, fspd, wavelen, flow, vibdel, hclen, hc;
+		int vibdep, vibspd, sqmin, sqmax, sqspd, fmax, plen, pspd;
+		int Alen, Avol, Dlen, Dvol, Slen, Rlen, Rvol;
+                mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1);
+
+		hio_read(buf, 22, 1, f);
+
+		vol = buf[0];		/* Master volume (0 to 64) */
+		fspd = ((buf[1] >> 3) & 0x1f) | ((buf[12] >> 2) & 0x20);
+					/* Filter speed */
+		wavelen = buf[1] & 7;	/* Wave length */
+
+		Alen = buf[2];		/* attack length, 1 to 255 */
+		Avol = buf[3];		/* attack volume, 0 to 64 */
+		Dlen = buf[4];		/* decay length, 1 to 255 */
+		Dvol = buf[5];		/* decay volume, 0 to 64 */
+		Slen = buf[6];		/* sustain length, 1 to 255 */
+		Rlen = buf[7];		/* release length, 1 to 255 */
+		Rvol = buf[8];		/* release volume, 0 to 64 */
+
+		flow = buf[12] & 0x7f;	/* filter modulation lower limit */
+		vibdel = buf[13];	/* vibrato delay */
+		hclen = (buf[14] >> 4) & 0x07;
+					/* Hardcut length */
+		hc = buf[14] & 0x80 ? 1 : 0;
+					/* Hardcut release */
+		vibdep = buf[14] & 15;	/* vibrato depth, 0 to 15 */
+		vibspd = buf[15];	/* vibrato speed, 0 to 63 */
+		sqmin = buf[16];	/* square modulation lower limit */
+		sqmax = buf[17];	/* square modulation upper limit */
+		sqspd = buf[18];	/* square modulation speed */
+		fmax = buf[19] & 0x3f;	/* filter modulation upper limit */
+		pspd = buf[20];		/* playlist default speed */	
+		plen = buf[21];		/* playlist length */
+
+		if (!pspd)
+			pspd=1;
+		int poff = 0;
+
+		D_(D_WARN "I: %02x plen %02x pspd %02x vibdep=%d vibspd=%d sqmin=%d sqmax=%d", i, plen, pspd, vibdep, vibspd, sqmin, sqmax);
+		int j;
+		int wave=0;
+
+		mod->xxi[i].fei.flg = XMP_ENVELOPE_ON; /* | XMP_ENVELOPE_LOOP;*/
+		mod->xxi[i].fei.npt = plen*2;
+		mod->xxfe[i] = calloc (4, mod->xxi[i].fei.npt);
+
+		int note=0;
+		int jump = -1;
+		int dosq = -1;
+
+		for (j = 0; j < plen; j++) {
+			uint8 tmp[5];
+			hio_read (tmp, 1, 5, f);
+
+			int fx1 = tmp[0] & 15;
+			int fx2 = (tmp[1] >> 3) & 15;
+
+			/* non-zero waveform means change to wf[waveform-1] */
+			/* 0: triangle
+			   1: sawtooth
+			   2: square
+			   3: white noise
+			*/
+
+			int fixed = (tmp[2] >> 6) & 0x01;
+
+			if (tmp[2] & 0x3f) {
+				note = tmp[2] & 0x3f;
+				if (fixed)
+					note-=60;
+			}
+
+			if (fx1 == 15)
+				pspd = tmp[3];
+			else if (fx2 == 15)
+				pspd = tmp[4];
+
+			mod->xxfe[i][j*4] = poff;
+			mod->xxfe[i][j*4+1] = note * 100;
+			poff += pspd;
+			mod->xxfe[i][j*4+2] = poff;
+			mod->xxfe[i][j*4+3] = note * 100;
+
+			if (jump >= 0) 
+				continue;
+
+			if ((fx1 == 4 && tmp[3] & 0xf) ||
+			    (fx2 == 4 && tmp[4] & 0xf))
+				dosq = sqmax;
+
+			if (fx1 == 3)
+				dosq = tmp[3] & 0x3f;
+			else if (fx2 == 3)
+				dosq = tmp[4] & 0x3f;
+
+			if ((tmp[1] & 7))
+				wave = tmp[1] & 7;
+			
+			if (fx1 == 5)
+				jump = tmp[3];
+			else if (fx2 == 5)
+				jump = tmp[4];
+			
+			if (jump >= 0) {
+				printf ("jump %d-%d\n", jump,j);
+				mod->xxi[i].fei.flg |= XMP_ENVELOPE_LOOP;
+				mod->xxi[i].fei.lps = jump*2;
+				mod->xxi[i].fei.lpe = j*2+1;
+			}
+
+			D_(D_INFO "[%d W:%x 1:%x%02x 2:%x%02x n:%02x]", j, tmp[1] &7, tmp[0]&15, tmp[3], (tmp[1]>>3)&15, tmp[4], tmp[2]);
+		}
+
+		if (!wave)
+			wave = 2;
+		else if (dosq >= 0)
+			wave = ((dosq>>2)&15)+4;
+		else
+			wave--;
+
+		D_(D_INFO "I: %02x V: %02x A: %02x %02x D: %02x %02x S:  %02x R: %02x %02x wave %02x",
+			i, vol, Alen, Avol, Dlen, Dvol, Slen, Rlen, Rvol, wave);
+		mod->xxi[i].aei.flg = XMP_ENVELOPE_ON;
+		mod->xxi[i].aei.npt = 5;
+		mod->xxae[i] = calloc (4, mod->xxi[i].aei.npt);
+		mod->xxae[i][0] = 0;
+		mod->xxae[i][1] = vol;
+		mod->xxae[i][2] = Alen; /* these are *not* multiplied by pspd */
+		mod->xxae[i][3] = Avol;
+		mod->xxae[i][4] = (Alen+Dlen);
+		mod->xxae[i][5] = Dvol;
+		mod->xxae[i][6] = (Alen+Dlen+Slen);
+		mod->xxae[i][7] = Dvol;
+		mod->xxae[i][8] = (Alen+Dlen+Slen+Rlen);
+		mod->xxae[i][9] = Rvol;
+
+		mod->xxi[i].sub[0].vol = 64;
+		mod->xxi[i].sub[0].sid = wave;
+		mod->xxi[i].sub[0].pan = 128;
+		mod->xxi[i].sub[0].xpo = (3-wavelen) * 12 - 1;
+		/*mod->xxi[i].sub[0].vde = vibdep;
+		  mod->xxi[i].sub[0].vra = vibspd; */
+		mod->xxi[i].nsm = 1;
+        }
+
+#define LEN 64
+	int8 b[16384];
+
+	for (i=0; i<20; i++) {
+		mod->xxs[i].len = LEN;
+		mod->xxs[i].lps = 0;
+		mod->xxs[i].lpe = LEN;
+		mod->xxs[i].flg |= XMP_SAMPLE_LOOP;
+
+		switch (i) {
+		case 0:
+			hvl_GenTriangle (b, LEN);
+			break;
+		case 1:
+			hvl_GenSawtooth (b, LEN);
+			break;
+		case 2:
+			memset (b, 0x80, LEN/2);
+			memset (b+LEN/2, 0x7f, LEN/2);
+			break;
+		case 3:
+			mod->xxs[i].len = mod->xxs[i].lpe = 16384;
+			hvl_GenWhiteNoise (b, 16384);
+			break;
+		default:
+			memset (b, 0x7f, LEN);
+			memset (b, 0x80, LEN*(20-i)/32);
+			break;
+		}
+
+		libxmp_load_sample(m, NULL, SAMPLE_FLAG_NOLOAD, &mod->xxs[i], (char *)b);
+	}
+
+
+	{
+		int len, i;
+		uint8 *namebuf, *nameptr;
+
+		hio_seek (f, 0, SEEK_END);
+		len = hio_tell(f) - title_offset;
+		hio_seek (f, title_offset, SEEK_SET);
+
+		nameptr = namebuf = malloc (len+1);
+		hio_read (namebuf, 1, len, f);
+		namebuf[len]=0;
+
+		libxmp_copy_adjust ((uint8 *)mod->name, namebuf, 32);
+		mod->name[31]=0;
+//		printf ("len=%d, name=%s\n", len, mod->name);
+		
+		for (i=0; nameptr < namebuf+len && i < mod->ins; i++) {
+			nameptr += strlen((char *)nameptr)+1;
+			libxmp_instrument_name(mod, i, nameptr, 32);
+
+			printf ("%02x: %s\n", i, nameptr);
+		}
+
+		free (namebuf);
+	}
+
+	for (i = 0; i < mod->chn; i++)
+                mod->xxc[i].pan = ((i&3)%3) ? 128+stereo*31 : 128-stereo*31;
+
+
+/*	m->quirk |= XMP_CTL_VBLANK;*/
+/*	m->quirk |= QUIRK_UNISLD;*/
+	return 0;
+}
+
diff --git a/src/loaders/ice_load.c b/src/loaders/ice_load.c
index 813c0dc..5a1c732 100644
--- a/src/loaders/ice_load.c
+++ b/src/loaders/ice_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 /* Loader for Soundtracker 2.6/Ice Tracker modules */
@@ -13,158 +27,177 @@
 #define MAGIC_MTN_	MAGIC4('M','T','N',0)
 #define MAGIC_IT10	MAGIC4('I','T','1','0')
 
+static int ice_test(HIO_HANDLE *, char *, const int);
+static int ice_load(struct module_data *, HIO_HANDLE *, const int);
 
-static int ice_test (HIO_HANDLE *, char *, const int);
-static int ice_load (struct module_data *, HIO_HANDLE *, const int);
-
-const struct format_loader ice_loader = {
-    "Soundtracker 2.6/Ice Tracker",
-    ice_test,
-    ice_load
+const struct format_loader libxmp_loader_ice = {
+	"Soundtracker 2.6/Ice Tracker",
+	ice_test,
+	ice_load
 };
 
-static int ice_test(HIO_HANDLE *f, char *t, const int start)
+static int ice_test(HIO_HANDLE * f, char *t, const int start)
 {
-    uint32 magic;
+	uint32 magic;
 
-    hio_seek(f, start + 1464, SEEK_SET);
-    magic = hio_read32b(f);
-    if (magic != MAGIC_MTN_ && magic != MAGIC_IT10)
-	return -1;
+	hio_seek(f, start + 1464, SEEK_SET);
+	magic = hio_read32b(f);
+	if (magic != MAGIC_MTN_ && magic != MAGIC_IT10)
+		return -1;
 
-    hio_seek(f, start + 0, SEEK_SET);
-    read_title(f, t, 28);
+	hio_seek(f, start + 0, SEEK_SET);
+	libxmp_read_title(f, t, 28);
 
-    return 0;
+	return 0;
 }
 
-
 struct ice_ins {
-    char name[22];		/* Instrument name */
-    uint16 len;			/* Sample length / 2 */
-    uint8 finetune;		/* Finetune */
-    uint8 volume;		/* Volume (0-63) */
-    uint16 loop_start;		/* Sample loop start in file */
-    uint16 loop_size;		/* Loop size / 2 */
+	char name[22];		/* Instrument name */
+	uint16 len;		/* Sample length / 2 */
+	uint8 finetune;		/* Finetune */
+	uint8 volume;		/* Volume (0-63) */
+	uint16 loop_start;	/* Sample loop start in file */
+	uint16 loop_size;	/* Loop size / 2 */
 };
 
 struct ice_header {
-    char title[20];
-    struct ice_ins ins[31];	/* Instruments */
-    uint8 len;			/* Size of the pattern list */
-    uint8 trk;			/* Number of tracks */
-    uint8 ord[128][4];
-    uint32 magic;		/* 'MTN\0', 'IT10' */
+	char title[20];
+	struct ice_ins ins[31];	/* Instruments */
+	uint8 len;		/* Size of the pattern list */
+	uint8 trk;		/* Number of tracks */
+	uint8 ord[128][4];
+	uint32 magic;		/* 'MTN\0', 'IT10' */
 };
 
-
-static int ice_load(struct module_data *m, HIO_HANDLE *f, const int start)
+static int ice_load(struct module_data *m, HIO_HANDLE * f, const int start)
 {
-    struct xmp_module *mod = &m->mod;
-    int i, j;
-    struct xmp_event *event;
-    struct ice_header ih;
-    uint8 ev[4];
-
-    LOAD_INIT();
-
-    hio_read(&ih.title, 20, 1, f);
-    for (i = 0; i < 31; i++) {
-	hio_read(&ih.ins[i].name, 22, 1, f);
-	ih.ins[i].len = hio_read16b(f);
-	ih.ins[i].finetune = hio_read8(f);
-	ih.ins[i].volume = hio_read8(f);
-	ih.ins[i].loop_start = hio_read16b(f);
-	ih.ins[i].loop_size = hio_read16b(f);
-    }
-    ih.len = hio_read8(f);
-    ih.trk = hio_read8(f);
-    hio_read(&ih.ord, 128 * 4, 1, f);
-    ih.magic = hio_read32b(f);
-
-    if (ih.magic == MAGIC_IT10)
-        set_type(m, "Ice Tracker IT10");
-    else if (ih.magic == MAGIC_MTN_)
-        set_type(m, "Soundtracker 2.6 MTN");
-    else
-	return -1;
-
-    mod->ins = 31;
-    mod->smp = mod->ins;
-    mod->pat = ih.len;
-    mod->len = ih.len;
-    mod->trk = ih.trk;
-
-    strncpy (mod->name, (char *) ih.title, 20);
-    MODULE_INFO();
-
-    if (instrument_init(mod) < 0)
-	return -1;
-
-    for (i = 0; i < mod->ins; i++) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
-	    return -1;
-
-	mod->xxs[i].len = 2 * ih.ins[i].len;
-	mod->xxs[i].lps = 2 * ih.ins[i].loop_start;
-	mod->xxs[i].lpe = mod->xxs[i].lps + 2 * ih.ins[i].loop_size;
-	mod->xxs[i].flg = ih.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0;
-	mod->xxi[i].sub[0].vol = ih.ins[i].volume;
-	mod->xxi[i].sub[0].fin = ((int16)ih.ins[i].finetune / 0x48) << 4;
-	mod->xxi[i].sub[0].pan = 0x80;
-	mod->xxi[i].sub[0].sid = i;
-
-	if (mod->xxs[i].len > 0)
-		mod->xxi[i].nsm = 1;
-
-	D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c %02x %01x",
-		i, ih.ins[i].name, mod->xxs[i].len, mod->xxs[i].lps,
-		mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
-		mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4);
-    }
-
-    if (pattern_init(mod) < 0)
-	return -1;
-
-    D_(D_INFO "Stored patterns: %d", mod->pat);
-
-    for (i = 0; i < mod->pat; i++) {
-	if (pattern_alloc(mod, i) < 0)
-	    return -1;
-	mod->xxp[i]->rows = 64;
-
-	for (j = 0; j < mod->chn; j++) {
-	    mod->xxp[i]->index[j] = ih.ord[i][j];
+	struct xmp_module *mod = &m->mod;
+	int i, j;
+	struct xmp_event *event;
+	struct ice_header ih;
+	uint8 ev[4];
+
+	LOAD_INIT();
+
+	hio_read(&ih.title, 20, 1, f);
+	for (i = 0; i < 31; i++) {
+		hio_read(&ih.ins[i].name, 22, 1, f);
+		ih.ins[i].len = hio_read16b(f);
+		ih.ins[i].finetune = hio_read8(f);
+		ih.ins[i].volume = hio_read8(f);
+		ih.ins[i].loop_start = hio_read16b(f);
+		ih.ins[i].loop_size = hio_read16b(f);
+	}
+	ih.len = hio_read8(f);
+	ih.trk = hio_read8(f);
+	hio_read(&ih.ord, 128 * 4, 1, f);
+	ih.magic = hio_read32b(f);
+
+	/* Sanity check */
+	if (ih.len > 128) {
+		return -1;
+	}
+	for (i = 0; i < ih.len; i++) {
+		for (j = 0; j < 4; j++) {
+			if (ih.ord[i][j] >= ih.trk)
+				return -1;
+		}
+	}
+
+	if (ih.magic == MAGIC_IT10)
+		libxmp_set_type(m, "Ice Tracker");
+	else if (ih.magic == MAGIC_MTN_)
+		libxmp_set_type(m, "Soundtracker 2.6");
+	else
+		return -1;
+
+	mod->ins = 31;
+	mod->smp = mod->ins;
+	mod->pat = ih.len;
+	mod->len = ih.len;
+	mod->trk = ih.trk;
+
+	strncpy(mod->name, (char *)ih.title, 20);
+	MODULE_INFO();
+
+	if (libxmp_init_instrument(m) < 0)
+		return -1;
+
+	for (i = 0; i < mod->ins; i++) {
+		struct xmp_instrument *xxi;
+		struct xmp_sample *xxs;
+
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+
+		xxi = &mod->xxi[i];
+		xxs = &mod->xxs[i];
+
+		xxs->len = 2 * ih.ins[i].len;
+		xxs->lps = 2 * ih.ins[i].loop_start;
+		xxs->lpe = xxs->lps + 2 * ih.ins[i].loop_size;
+		xxs->flg = ih.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0;
+		xxi->sub[0].vol = ih.ins[i].volume;
+		/* xxi->sub[0].fin = (int8)(ih.ins[i].finetune << 4); */
+		xxi->sub[0].pan = 0x80;
+		xxi->sub[0].sid = i;
+
+		if (xxs->len > 0)
+			xxi->nsm = 1;
+
+		D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c %02x %01x",
+		   i, ih.ins[i].name, xxs->len, xxs->lps,
+		   xxs->lpe, xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
+		   xxi->sub[0].vol, xxi->sub[0].fin >> 4);
 	}
-	mod->xxo[i] = i;
-    }
 
-    D_(D_INFO "Stored tracks: %d", mod->trk);
+	if (libxmp_init_pattern(mod) < 0)
+		return -1;
 
-    for (i = 0; i < mod->trk; i++) {
-	if (track_alloc(mod, i, 64) < 0)
-	    return -1;
+	D_(D_INFO "Stored patterns: %d", mod->pat);
 
-	for (j = 0; j < mod->xxt[i]->rows; j++) {
-	    event = &mod->xxt[i]->event[j];
-	    hio_read (ev, 1, 4, f);
-	    decode_protracker_event(event, ev);
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern(mod, i) < 0)
+			return -1;
+		mod->xxp[i]->rows = 64;
+
+		for (j = 0; j < mod->chn; j++) {
+			mod->xxp[i]->index[j] = ih.ord[i][j];
+		}
+		mod->xxo[i] = i;
 	}
-    }
 
-    m->quirk |= QUIRK_MODRNG;
+	D_(D_INFO "Stored tracks: %d", mod->trk);
+
+	for (i = 0; i < mod->trk; i++) {
+		if (libxmp_alloc_track(mod, i, 64) < 0)
+			return -1;
 
-    /* Read samples */
+		for (j = 0; j < mod->xxt[i]->rows; j++) {
+			event = &mod->xxt[i]->event[j];
+			hio_read(ev, 1, 4, f);
+			libxmp_decode_protracker_event(event, ev);
 
-    D_(D_INFO "Stored samples: %d", mod->smp);
+			if (event->fxt == FX_SPEED) {
+				if (MSN(event->fxp) && LSN(event->fxp)) {
+					event->fxt = FX_ICE_SPEED;
+				}
+			}
+		}
+	}
 
-    for (i = 0; i < mod->ins; i++) {
-	if (mod->xxs[i].len <= 4)
-	    continue;
-	if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
-	    return -1;
-    }
+	m->period_type = PERIOD_MODRNG;
 
-    return 0;
-}
+	/* Read samples */
 
+	D_(D_INFO "Stored samples: %d", mod->smp);
+
+	for (i = 0; i < mod->ins; i++) {
+		if (mod->xxs[i].len <= 4)
+			continue;
+		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+			return -1;
+	}
+
+	return 0;
+}
diff --git a/src/loaders/iff.c b/src/loaders/iff.c
index 816cbc9..056f97d 100644
--- a/src/loaders/iff.c
+++ b/src/loaders/iff.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -31,33 +31,53 @@
 
 struct iff_data {
 	struct list_head iff_list;
-	int id_size;
-	int flags;
+	unsigned id_size;
+	unsigned flags;
 };
 
-iff_handle iff_new()
+static int iff_process(iff_handle opaque, struct module_data *m, char *id, long size,
+		HIO_HANDLE *f, void *parm)
 {
-	struct iff_data *data;
+	struct iff_data *data = (struct iff_data *)opaque;
+	struct list_head *tmp;
+	struct iff_info *i;
+	int pos;
 
-	data = malloc(sizeof(struct iff_data));
-	if (data == NULL)
-		return NULL;
+	pos = hio_tell(f);
 
-	INIT_LIST_HEAD(&data->iff_list);
-	data->id_size = 4;
-	data->flags = 0;
+	list_for_each(tmp, &data->iff_list) {
+		i = list_entry(tmp, struct iff_info, list);
+		if (id && !memcmp(id, i->id, data->id_size)) {
+			D_(D_WARN "Load IFF chunk %s (%ld) @%d", id, size, pos);
+			if (size > IFF_MAX_CHUNK_SIZE) {
+				return -1;
+			}
+			if (i->loader(m, size, f, parm) < 0) {
+				return -1;
+			}
+			break;
+		}
+	}
 
-	return (iff_handle) data;
+	if (hio_seek(f, pos + size, SEEK_SET) < 0) {
+		return -1;
+	}
+
+	return 0;
 }
 
 static int iff_chunk(iff_handle opaque, struct module_data *m, HIO_HANDLE *f, void *parm)
 {
 	struct iff_data *data = (struct iff_data *)opaque;
-	long size;
+	unsigned size;
 	char id[17] = "";
 
-	if (hio_read(id, 1, data->id_size, f) != data->id_size)
+	D_(D_INFO "chunk id size: %d", data->id_size);
+	if (hio_read(id, 1, data->id_size, f) != data->id_size) {
+		(void)hio_error(f);	/* clear error flag */
 		return 1;
+	}
+	D_(D_INFO "chunk id: [%s]", id);
 
 	if (data->flags & IFF_SKIP_EMBEDDED) {
 		/* embedded RIFF hack */
@@ -65,28 +85,65 @@ static int iff_chunk(iff_handle opaque, struct module_data *m, HIO_HANDLE *f, vo
 			hio_read32b(f);
 			hio_read32b(f);
 			/* read first chunk ID instead */
-			hio_read(id, 1, data->id_size, f);
+			if (hio_read(id, 1, data->id_size, f) != data->id_size){
+				return 1;
+			}
 		}
 	}
 
-	size = (data->flags & IFF_LITTLE_ENDIAN) ? hio_read32l(f) : hio_read32b(f);
+	if (data->flags & IFF_LITTLE_ENDIAN) {
+		size = hio_read32l(f);
+	} else {
+		size = hio_read32b(f);
+	}
+	D_(D_INFO "size: %d", size);
+
+	if (hio_error(f)) {
+		return -1;
+	}
 
-	if (data->flags & IFF_CHUNK_ALIGN2)
+	if (data->flags & IFF_CHUNK_ALIGN2) {
+		/* Sanity check */
+		if (size > 0xfffffffe) {
+			return -1;
+		}
 		size = (size + 1) & ~1;
+	}
 
-	if (data->flags & IFF_CHUNK_ALIGN4)
+	if (data->flags & IFF_CHUNK_ALIGN4) {
+		/* Sanity check */
+		if (size > 0xfffffffc) {
+			return -1;
+		}
 		size = (size + 3) & ~3;
+	}
 
-	if (data->flags & IFF_FULL_CHUNK_SIZE)
+	if (data->flags & IFF_FULL_CHUNK_SIZE) {
+		if (size < data->id_size + 4)
+			return -1;
 		size -= data->id_size + 4;
-
-	if (size < 0)
-		return 1;
+	}
 
 	return iff_process(opaque, m, id, size, f, parm);
 }
 
-int iff_load(iff_handle opaque, struct module_data *m, HIO_HANDLE *f, void *parm)
+iff_handle libxmp_iff_new()
+{
+	struct iff_data *data;
+
+	data = malloc(sizeof(struct iff_data));
+	if (data == NULL) {
+		return NULL;
+	}
+
+	INIT_LIST_HEAD(&data->iff_list);
+	data->id_size = 4;
+	data->flags = 0;
+
+	return (iff_handle)data;
+}
+
+int libxmp_iff_load(iff_handle opaque, struct module_data *m, HIO_HANDLE *f, void *parm)
 {
 	int ret;
 
@@ -103,7 +160,7 @@ int iff_load(iff_handle opaque, struct module_data *m, HIO_HANDLE *f, void *parm
 	return 0;
 }
 
-int iff_register(iff_handle opaque, char *id,
+int libxmp_iff_register(iff_handle opaque, char *id,
 	int (*loader)(struct module_data *, int, HIO_HANDLE *, void *))
 {
 	struct iff_data *data = (struct iff_data *)opaque;
@@ -113,7 +170,7 @@ int iff_register(iff_handle opaque, char *id,
 	if (f == NULL)
 		return -1;
 
-	strncpy(f->id, id, 5);
+	strncpy(f->id, id, 4);
 	f->loader = loader;
 
 	list_add_tail(&f->list, &data->iff_list);
@@ -121,7 +178,7 @@ int iff_register(iff_handle opaque, char *id,
 	return 0;
 }
 
-void iff_release(iff_handle opaque)
+void libxmp_iff_release(iff_handle opaque)
 {
 	struct iff_data *data = (struct iff_data *)opaque;
 	struct list_head *tmp;
@@ -138,40 +195,16 @@ void iff_release(iff_handle opaque)
 	free(data);
 }
 
-int iff_process(iff_handle opaque, struct module_data *m, char *id, long size,
-		HIO_HANDLE *f, void *parm)
-{
-	struct iff_data *data = (struct iff_data *)opaque;
-	struct list_head *tmp;
-	struct iff_info *i;
-	int pos;
-
-	pos = hio_tell(f);
-
-	list_for_each(tmp, &data->iff_list) {
-		i = list_entry(tmp, struct iff_info, list);
-		if (id && !strncmp(id, i->id, data->id_size)) {
-			if (i->loader(m, size, f, parm) < 0)
-				return -1;
-			break;
-		}
-	}
-
-	hio_seek(f, pos + size, SEEK_SET);
-
-	return 0;
-}
-
 /* Functions to tune IFF mutations */
 
-void iff_id_size(iff_handle opaque, int n)
+void libxmp_iff_id_size(iff_handle opaque, int n)
 {
 	struct iff_data *data = (struct iff_data *)opaque;
 
 	data->id_size = n;
 }
 
-void iff_set_quirk(iff_handle opaque, int i)
+void libxmp_iff_set_quirk(iff_handle opaque, int i)
 {
 	struct iff_data *data = (struct iff_data *)opaque;
 
diff --git a/src/loaders/iff.h b/src/loaders/iff.h
index c9a343b..2c36a9f 100644
--- a/src/loaders/iff.h
+++ b/src/loaders/iff.h
@@ -1,5 +1,5 @@
-#ifndef __IFF_H
-#define __IFF_H
+#ifndef LIBXMP_IFF_H
+#define LIBXMP_IFF_H
 
 #include "list.h"
 #include "hio.h"
@@ -13,6 +13,8 @@
 #define IFF_SKIP_EMBEDDED	0x10
 #define IFF_CHUNK_TRUNC4	0x20
 
+#define IFF_MAX_CHUNK_SIZE	0x400000
+
 typedef void *iff_handle;
 
 struct iff_header {
@@ -22,19 +24,20 @@ struct iff_header {
 };
 
 struct iff_info {
-	char id[5];
+	char id[4];
 	int (*loader)(struct module_data *, int, HIO_HANDLE *, void *);
 	struct list_head list;
 };
 
-iff_handle iff_new(void);
-int iff_load(iff_handle, struct module_data *, HIO_HANDLE *, void *);
-/* int iff_chunk(iff_handle, struct module_data *, HIO_HANDLE *, void *); */
-int iff_register(iff_handle, char *,
+iff_handle libxmp_iff_new(void);
+int	libxmp_iff_load(iff_handle, struct module_data *, HIO_HANDLE *, void *);
+/* int libxmp_iff_chunk(iff_handle, struct module_data *, HIO_HANDLE *, void *); */
+int 	libxmp_iff_register(iff_handle, char *,
 	int (*loader)(struct module_data *, int, HIO_HANDLE *, void *));
-void iff_id_size(iff_handle, int);
-void iff_set_quirk(iff_handle, int);
-void iff_release(iff_handle);
-int iff_process(iff_handle, struct module_data *, char *, long, HIO_HANDLE *, void *);
+void 	libxmp_iff_id_size(iff_handle, int);
+void 	libxmp_iff_set_quirk(iff_handle, int);
+void 	libxmp_iff_release(iff_handle);
+/* int 	libxmp_iff_process(iff_handle, struct module_data *, char *, long,
+	HIO_HANDLE *, void *); */
 
-#endif /* __IFF_H */
+#endif /* LIBXMP_IFF_H */
diff --git a/src/loaders/imf_load.c b/src/loaders/imf_load.c
index a9a5518..a801000 100644
--- a/src/loaders/imf_load.c
+++ b/src/loaders/imf_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 /* Loader for Imago Orpheus modules based on the format description
@@ -91,7 +105,7 @@ struct imf_sample {
 static int imf_test (HIO_HANDLE *, char *, const int);
 static int imf_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader imf_loader = {
+const struct format_loader libxmp_loader_imf = {
     "Imago Orpheus v1.0",
     imf_test,
     imf_load
@@ -104,7 +118,7 @@ static int imf_test(HIO_HANDLE *f, char *t, const int start)
 	return -1;
 
     hio_seek(f, start, SEEK_SET);
-    read_title(f, t, 32);
+    libxmp_read_title(f, t, 32);
 
     return 0;
 }
@@ -241,6 +255,11 @@ static int imf_load(struct module_data *m, HIO_HANDLE *f, const int start)
     hio_read(&ih.unused2, 8, 1, f);
     ih.magic = hio_read32b(f);
 
+    /* Sanity check */
+    if (ih.len > 256 || ih.pat > 256 || ih.ins > 255) {
+	return -1;
+    }
+
     for (i = 0; i < 32; i++) {
 	hio_read(&ih.chn[i].name, 12, 1, f);
 	ih.chn[i].status = hio_read8(f);
@@ -251,12 +270,11 @@ static int imf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     hio_read(&ih.pos, 256, 1, f);
 
-#if 0
-    if (ih.magic != MAGIC_IM10)
+    if (ih.magic != MAGIC_IM10) {
 	return -1;
-#endif
+    }
 
-    copy_adjust(mod->name, (uint8 *)ih.name, 32);
+    libxmp_copy_adjust(mod->name, (uint8 *)ih.name, 32);
 
     mod->len = ih.len;
     mod->ins = ih.ins;
@@ -264,20 +282,21 @@ static int imf_load(struct module_data *m, HIO_HANDLE *f, const int start)
     mod->pat = ih.pat;
 
     if (ih.flg & 0x01)
-	m->quirk |= QUIRK_LINEAR;
+	m->period_type = PERIOD_LINEAR;
 
     mod->spd = ih.tpo;
     mod->bpm = ih.bpm;
 
-    set_type(m, "Imago Orpheus 1.0 IMF");
+    libxmp_set_type(m, "Imago Orpheus 1.0 IMF");
 
     MODULE_INFO();
 
-    for (mod->chn = i = 0; i < 32; i++) {
-	if (ih.chn[i].status != 0x00)
-	    mod->chn = i + 1;
-	else
+    mod->chn = 0;
+    for (i = 0; i < 32; i++) {
+	if (ih.chn[i].status == 0x00)
 	    continue;
+
+	mod->chn = i + 1;
 	mod->xxc[i].pan = ih.chn[i].pan;
 #if 0
 	/* FIXME */
@@ -286,16 +305,18 @@ static int imf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->xxc[i].flg |= XMP_CHANNEL_FX;
 #endif
     }
+
     mod->trk = mod->pat * mod->chn;
  
     memcpy(mod->xxo, ih.pos, mod->len);
-    for (i = 0; i < mod->len; i++)
+    for (i = 0; i < mod->len; i++) {
 	if (mod->xxo[i] == 0xff)
 	    mod->xxo[i]--;
+    }
 
     m->c4rate = C4_NTSC_RATE;
 
-    if (pattern_init(mod) < 0)
+    if (libxmp_init_pattern(mod) < 0)
 	return -1;
 
     /* Read patterns */
@@ -303,9 +324,18 @@ static int imf_load(struct module_data *m, HIO_HANDLE *f, const int start)
     D_(D_INFO "Stored patterns: %d", mod->pat);
 
     for (i = 0; i < mod->pat; i++) {
+        int rows;
+
 	pat_len = hio_read16l(f) - 4;
 
-	if (pattern_tracks_alloc(mod, i, hio_read16l(f)) < 0)
+        rows = hio_read16l(f);
+
+	/* Sanity check */
+	if (rows > 256) {
+	    return -1;
+	}
+
+	if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
 	    return -1;
 
 	r = 0;
@@ -318,8 +348,13 @@ static int imf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		continue;
 	    }
 
+	    /* Sanity check */
+	    if (r >= rows) {
+		return -1;
+	    }
+
 	    c = b & IMF_CH_MASK;
-	    event = c >= mod->chn ? &dummy : &EVENT (i, c, r);
+	    event = c >= mod->chn ? &dummy : &EVENT(i, c, r);
 
 	    if (b & IMF_NI_FOLLOW) {
 		n = hio_read8(f);
@@ -351,7 +386,7 @@ static int imf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	}
     }
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     /* Read and convert instruments and samples */
@@ -359,7 +394,10 @@ static int imf_load(struct module_data *m, HIO_HANDLE *f, const int start)
     D_(D_INFO "Instruments: %d", mod->ins);
 
     for (smp_num = i = 0; i < mod->ins; i++) {
+	struct xmp_instrument *xxi = &mod->xxi[i];
+
 	hio_read(&ii.name, 32, 1, f);
+	ii.name[31] = 0;
 	hio_read(&ii.map, 120, 1, f);
 	hio_read(&ii.unused, 8, 1, f);
 	for (j = 0; j < 32; j++)
@@ -380,40 +418,50 @@ static int imf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	ii.nsm = hio_read16l(f);
 	ii.magic = hio_read32b(f);
 
+	/* Sanity check */
+	if (ii.nsm > 255)
+	    return -1;
+
 	if (ii.magic != MAGIC_II10)
 	    return -2;
 
-	mod->xxi[i].nsm = ii.nsm;
+	xxi->nsm = ii.nsm;
 
-        if (mod->xxi[i].nsm) {
-	    if (subinstrument_alloc(mod, i, mod->xxi[i].nsm) < 0)
+        if (xxi->nsm > 0) {
+	    if (libxmp_alloc_subinstrument(mod, i, xxi->nsm) < 0)
 		return -1;
 	}
 
-	adjust_string ((char *) ii.name);
-	strncpy ((char *) mod->xxi[i].name, ii.name, 24);
+	strncpy((char *)xxi->name, ii.name, 24);
 
 	for (j = 0; j < 108; j++) {
-		mod->xxi[i].map[j + 12].ins = ii.map[j];
+		xxi->map[j + 12].ins = ii.map[j];
 	}
 
 	D_(D_INFO "[%2X] %-31.31s %2d %4x %c", i, ii.name, ii.nsm,
 		ii.fadeout, ii.env[0].flg & 0x01 ? 'V' : '-');
 
-	mod->xxi[i].aei.npt = ii.env[0].npt;
-	mod->xxi[i].aei.sus = ii.env[0].sus;
-	mod->xxi[i].aei.lps = ii.env[0].lps;
-	mod->xxi[i].aei.lpe = ii.env[0].lpe;
-	mod->xxi[i].aei.flg = ii.env[0].flg & 0x01 ? XMP_ENVELOPE_ON : 0;
-	mod->xxi[i].aei.flg |= ii.env[0].flg & 0x02 ? XMP_ENVELOPE_SUS : 0;
-	mod->xxi[i].aei.flg |= ii.env[0].flg & 0x04 ?  XMP_ENVELOPE_LOOP : 0;
-
-	for (j = 0; j < mod->xxi[i].aei.npt; j++) {
-	    mod->xxi[i].aei.data[j * 2] = ii.vol_env[j * 2];
-	    mod->xxi[i].aei.data[j * 2 + 1] = ii.vol_env[j * 2 + 1];
+	xxi->aei.npt = ii.env[0].npt;
+	xxi->aei.sus = ii.env[0].sus;
+	xxi->aei.lps = ii.env[0].lps;
+	xxi->aei.lpe = ii.env[0].lpe;
+	xxi->aei.flg = ii.env[0].flg & 0x01 ? XMP_ENVELOPE_ON : 0;
+	xxi->aei.flg |= ii.env[0].flg & 0x02 ? XMP_ENVELOPE_SUS : 0;
+	xxi->aei.flg |= ii.env[0].flg & 0x04 ?  XMP_ENVELOPE_LOOP : 0;
+
+	/* Sanity check */
+	if (xxi->aei.npt >= 16) {
+	    return -1;
+	}
+
+	for (j = 0; j < xxi->aei.npt; j++) {
+	    xxi->aei.data[j * 2] = ii.vol_env[j * 2];
+	    xxi->aei.data[j * 2 + 1] = ii.vol_env[j * 2 + 1];
 	}
 
 	for (j = 0; j < ii.nsm; j++, smp_num++) {
+            struct xmp_subinstrument *sub = &xxi->sub[j];
+            struct xmp_sample *xxs = &mod->xxs[smp_num];
 	    int sid;
 
 	    hio_read(&is.name, 13, 1, f);
@@ -431,39 +479,51 @@ static int imf_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	    is.dram = hio_read32l(f);
 	    is.magic = hio_read32b(f);
 
-	    mod->xxi[i].sub[j].sid = smp_num;
-	    mod->xxi[i].sub[j].vol = is.vol;
-	    mod->xxi[i].sub[j].pan = is.pan;
-	    mod->xxs[smp_num].len = is.len;
-	    mod->xxs[smp_num].lps = is.lps;
-	    mod->xxs[smp_num].lpe = is.lpe;
-	    mod->xxs[smp_num].flg = is.flg & 1 ? XMP_SAMPLE_LOOP : 0;
+            /* Sanity check */
+            if (is.len > 0x100000 || is.lps > 0x100000 || is.lpe > 0x100000)
+		return -1;
+
+	    sub->sid = smp_num;
+	    sub->vol = is.vol;
+	    sub->pan = is.pan;
+	    xxs->len = is.len;
+	    xxs->lps = is.lps;
+	    xxs->lpe = is.lpe;
+	    xxs->flg = is.flg & 1 ? XMP_SAMPLE_LOOP : 0;
 
 	    if (is.flg & 4) {
-	        mod->xxs[smp_num].flg |= XMP_SAMPLE_16BIT;
-	        mod->xxs[smp_num].len >>= 1;
-	        mod->xxs[smp_num].lps >>= 1;
-	        mod->xxs[smp_num].lpe >>= 1;
+	        xxs->flg |= XMP_SAMPLE_16BIT;
+	        xxs->len >>= 1;
+	        xxs->lps >>= 1;
+	        xxs->lpe >>= 1;
 	    }
 
 	    D_(D_INFO "  %02x: %05x %05x %05x %5d",
 		    j, is.len, is.lps, is.lpe, is.rate);
 
-	    c2spd_to_note (is.rate, &mod->xxi[i].sub[j].xpo, &mod->xxi[i].sub[j].fin);
+	    libxmp_c2spd_to_note(is.rate, &sub->xpo, &sub->fin);
 
-	    if (!mod->xxs[smp_num].len)
+	    if (xxs->len <= 0)
 		continue;
 
-	    sid = mod->xxi[i].sub[j].sid;
-	    if (load_sample(m, f, 0, &mod->xxs[sid], NULL) < 0)
+	    sid = sub->sid;
+	    if (libxmp_load_sample(m, f, 0, &mod->xxs[sid], NULL) < 0)
 		return -1;
 	}
     }
 
     mod->smp = smp_num;
     mod->xxs = realloc(mod->xxs, sizeof (struct xmp_sample) * mod->smp);
+    if (mod->xxs == NULL) {
+        return -1;
+    }
+    m->xtra = realloc(m->xtra, sizeof (struct extra_sample_data) * mod->smp);
+    if (m->xtra == NULL) {
+        return -1;
+    }
 
-    m->quirk |= QUIRK_FILTER | QUIRKS_ST3;
+    m->c4rate = C4_NTSC_RATE;
+    m->quirk |= QUIRK_FILTER | QUIRKS_ST3 | QUIRK_ARPMEM;
     m->read_event_type = READ_EVENT_ST3;
 
     return 0;
diff --git a/src/loaders/ims_load.c b/src/loaders/ims_load.c
index e7172e9..d8a79dc 100644
--- a/src/loaders/ims_load.c
+++ b/src/loaders/ims_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 /* Loader for Images Music System modules based on the EP replayer.
@@ -54,7 +68,7 @@ struct ims_header {
 static int ims_test (HIO_HANDLE *, char *, const int);
 static int ims_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader ims_loader = {
+const struct format_loader libxmp_loader_ims = {
     "Images Music System",
     ims_test,
     ims_load
@@ -83,7 +97,7 @@ static int ims_test(HIO_HANDLE *f, char *t, const int start)
 
 	smp_size += ih.ins[i].size * 2;
 
-	if (test_name(ih.ins[i].name, 20) < 0)
+	if (libxmp_test_name(ih.ins[i].name, 20) < 0)
 	    return -1;
 
 	if (ih.ins[i].volume > 0x40)
@@ -104,8 +118,8 @@ static int ims_test(HIO_HANDLE *f, char *t, const int start)
 
     ih.len = hio_read8(f);
     ih.zero = hio_read8(f);
-    hio_read (&ih.orders, 128, 1, f);
-    hio_read (&ih.magic, 4, 1, f);
+    hio_read(&ih.orders, 128, 1, f);
+    hio_read(&ih.magic, 4, 1, f);
   
     if (ih.zero > 1)		/* not sure what this is */
 	return -1;
@@ -125,7 +139,7 @@ static int ims_test(HIO_HANDLE *f, char *t, const int start)
 	return -1;
    
     hio_seek(f, start + 0, SEEK_SET);
-    read_title(f, t, 20);
+    libxmp_read_title(f, t, 20);
 
     return 0;
 }
@@ -143,6 +157,7 @@ static int ims_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     LOAD_INIT();
 
+    mod->chn = 4;
     mod->ins = 31;
     mod->smp = mod->ins;
     smp_size = 0;
@@ -162,6 +177,9 @@ static int ims_load(struct module_data *m, HIO_HANDLE *f, const int start)
     }
 
     ih.len = hio_read8(f);
+    if (ih.len > 128) {
+        return -1;
+    }
     ih.zero = hio_read8(f);
     hio_read (&ih.orders, 128, 1, f);
     hio_read (&ih.magic, 4, 1, f);
@@ -177,50 +195,60 @@ static int ims_load(struct module_data *m, HIO_HANDLE *f, const int start)
     mod->trk = mod->chn * mod->pat;
 
     strncpy(mod->name, (char *)ih.title, 20);
-    set_type(m, "Images Music System");
+    libxmp_set_type(m, "Images Music System");
 
     MODULE_INFO();
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     for (i = 0; i < mod->ins; i++) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
-	    return -1;
+	struct xmp_instrument *xxi;
+	struct xmp_subinstrument *sub;
+	struct xmp_sample *xxs;
 
-	mod->xxs[i].len = 2 * ih.ins[i].size;
-	mod->xxs[i].lpe = mod->xxs[i].lps + 2 * ih.ins[i].loop_size;
-	mod->xxs[i].flg = ih.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0;
-	mod->xxi[i].sub[0].fin = 0; /* ih.ins[i].finetune; */
-	mod->xxi[i].sub[0].vol = ih.ins[i].volume;
-	mod->xxi[i].sub[0].pan = 0x80;
-	mod->xxi[i].sub[0].sid = i;
-	mod->xxi[i].rls = 0xfff;
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+	    return -1;
 
-	if (mod->xxs[i].len > 0)
-		mod->xxi[i].nsm = 1;
+	xxi = &mod->xxi[i];
+	sub = &xxi->sub[0];
+	xxs = &mod->xxs[i];
+
+	xxs->len = 2 * ih.ins[i].size;
+	xxs->lps = 2 * ih.ins[i].loop_start;
+	xxs->lpe = xxs->lps + 2 * ih.ins[i].loop_size;
+	xxs->flg = ih.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0;
+	sub->fin = 0; /* ih.ins[i].finetune; */
+	sub->vol = ih.ins[i].volume;
+	sub->pan = 0x80;
+	sub->sid = i;
+	//mod->xxi[i].rls = 0xfff;
+
+	if (xxs->len > 0) {
+		xxi->nsm = 1;
+	}
 
-	instrument_name(mod, i, ih.ins[i].name, 20);
+	libxmp_instrument_name(mod, i, ih.ins[i].name, 20);
 
 	D_(D_INFO "[%2X] %-20.20s %04x %04x %04x %c V%02x %+d",
-		i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
-		mod->xxs[i].lpe, ih.ins[i].loop_size > 1 ? 'L' : ' ',
-		mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4);
+		i, xxi->name, xxs->len, xxs->lps, xxs->lpe,
+		ih.ins[i].loop_size > 1 ? 'L' : ' ', sub->vol, sub->fin >> 4);
     }
 
-    if (pattern_init(mod) < 0)
+    if (libxmp_init_pattern(mod) < 0) {
 	return -1;
+    }
 
     /* Load and convert patterns */
     D_(D_INFO "Stored patterns: %d", mod->pat);
 
     for (i = 0; i < mod->pat; i++) {
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
+	if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 	    return -1;
 
 	for (j = 0; j < 0x100; j++) {
 	    event = &EVENT (i, j & 0x3, j >> 2);
-	    hio_read (ims_event, 1, 3, f);
+	    hio_read(ims_event, 1, 3, f);
 
 	    /* Event format:
 	     *
@@ -240,7 +268,7 @@ static int ims_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	    event->fxt = LSN(ims_event[1]);
 	    event->fxp = ims_event[2];
 
-	    disable_continue_fx (event);
+	    libxmp_disable_continue_fx (event);
 
 	    /* According to Asle:
 	     * ``Just note that pattern break effect command (D**) uses
@@ -254,7 +282,7 @@ static int ims_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	}
     }
 
-    m->quirk |= QUIRK_MODRNG;
+    m->period_type = PERIOD_MODRNG;
 
     /* Load samples */
 
@@ -263,7 +291,7 @@ static int ims_load(struct module_data *m, HIO_HANDLE *f, const int start)
     for (i = 0; i < mod->smp; i++) {
 	if (!mod->xxs[i].len)
 	    continue;
-	if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+	if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
 	    return -1;
     }
 
diff --git a/src/loaders/it.h b/src/loaders/it.h
index 14c8929..b574c67 100644
--- a/src/loaders/it.h
+++ b/src/loaders/it.h
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -161,7 +161,7 @@ struct it_sample_header {
 	uint8 dosname[12];	/* DOS filename */
 	uint8 zero;		/* Always zero */
 	uint8 gvl;		/* Global volume for instrument */
-	uint8 flags;		/* Instrument flags */
+	uint8 flags;		/* Sample flags */
 	uint8 vol;		/* Volume */
 	uint8 name[26];		/* ASCIIZ sample name */
 	uint8 convert;		/* Sample flags */
diff --git a/src/loaders/it_load.c b/src/loaders/it_load.c
index b1f4464..1009557 100644
--- a/src/loaders/it_load.c
+++ b/src/loaders/it_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -28,35 +28,36 @@
 #include "period.h"
 
 #define MAGIC_IMPM	MAGIC4('I','M','P','M')
+#define MAGIC_IMPI	MAGIC4('I','M','P','I')
 #define MAGIC_IMPS	MAGIC4('I','M','P','S')
 
 
-static int it_test (HIO_HANDLE *, char *, const int);
-static int it_load (struct module_data *, HIO_HANDLE *, const int);
+static int it_test(HIO_HANDLE *, char *, const int);
+static int it_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader it_loader = {
-    "Impulse Tracker",
-    it_test,
-    it_load
+const struct format_loader libxmp_loader_it = {
+	"Impulse Tracker",
+	it_test,
+	it_load
 };
 
 #ifdef WIN32
-struct tm *localtime_r(const time_t *timep, struct tm *result)
+struct tm *localtime_r(const time_t * timep, struct tm *result)
 {
-    /* Note: Win32 localtime() is thread-safe */
-    memcpy(result, localtime(timep), sizeof(struct tm));
-    return result;
+	/* Note: Win32 localtime() is thread-safe */
+	memcpy(result, localtime(timep), sizeof(struct tm));
+	return result;
 }
 #endif
 
-static int it_test(HIO_HANDLE *f, char *t, const int start)
+static int it_test(HIO_HANDLE * f, char *t, const int start)
 {
-    if (hio_read32b(f) != MAGIC_IMPM)
-	return -1;
+	if (hio_read32b(f) != MAGIC_IMPM)
+		return -1;
 
-    read_title(f, t, 26);
+	libxmp_read_title(f, t, 26);
 
-    return 0;
+	return 0;
 }
 
 
@@ -69,7 +70,7 @@ static const uint8 fx[] = {
 	/*   */ FX_NONE,
 	/* A */ FX_S3M_SPEED,
 	/* B */ FX_JUMP,
-	/* C */ FX_BREAK,
+	/* C */ FX_IT_BREAK,
 	/* D */ FX_VOLSLIDE,
 	/* E */ FX_PORTA_DN,
 	/* F */ FX_PORTA_UP,
@@ -102,700 +103,631 @@ int itsex_decompress16 (HIO_HANDLE *, void *, int, int);
 
 static void xlat_fx(int c, struct xmp_event *e, uint8 *last_fxp, int new_fx)
 {
-    uint8 h = MSN(e->fxp), l = LSN(e->fxp);
+	uint8 h = MSN(e->fxp), l = LSN(e->fxp);
 
-    switch (e->fxt = fx[e->fxt]) {
-    case FX_XTND:		/* Extended effect */
-	e->fxt = FX_EXTENDED;
+	switch (e->fxt = fx[e->fxt]) {
+	case FX_XTND:		/* Extended effect */
+		e->fxt = FX_EXTENDED;
 
-	if (h == 0 && e->fxp == 0) {
-	    e->fxp = last_fxp[c];
-	    h = MSN(e->fxp);
-	    l = LSN(e->fxp);
-	} else {
-	    last_fxp[c] = e->fxp;
-	}
+		if (h == 0 && e->fxp == 0) {
+			e->fxp = last_fxp[c];
+			h = MSN(e->fxp);
+			l = LSN(e->fxp);
+		} else {
+			last_fxp[c] = e->fxp;
+		}
 
-	switch (h) {
-	case 0x1:		/* Glissando */
-	    e->fxp = 0x30 | l;
-	    break;
-	case 0x2:		/* Finetune */
-	    e->fxp = 0x50 | l;
-	    break;
-	case 0x3:		/* Vibrato wave */
-	    e->fxp = 0x40 | l;
-	    break;
-	case 0x4:		/* Tremolo wave */
-	    e->fxp = 0x70 | l;
-	    break;
-	case 0x5:		/* Panbrello wave */
-	    if (l <= 3) {
-	    	e->fxt = FX_PANBRELLO_WF;
-	    	e->fxp = l;
-	    } else {
-		e->fxt = e->fxp = 0;
-	    }
-	    break;
-	case 0x6:		/* Pattern delay */
-	    e->fxp = 0xe0 | l;
-	    break;
-	case 0x7:		/* Instrument functions */
-	    e->fxt = FX_IT_INSTFUNC;
-	    e->fxp &= 0x0f;
-	    break;
-	case 0x8:		/* Set pan position */
-	    e->fxt = FX_SETPAN;
-	    e->fxp = l << 4;
-	    break;
-	case 0x9:		/* 0x91 = set surround -- NOT IMPLEMENTED */
-	    e->fxt = e->fxp = 0;
-	    break;
-	case 0xb:		/* Pattern loop */
-	    e->fxp = 0x60 | l;
-	    break;
-	case 0xc:		/* Note cut */
-	case 0xd:		/* Note delay */
-	    if ((e->fxp = l) == 0)
-		e->fxp++;	/* SD0 and SC0 become SD1 and SC1 */
-	    e->fxp |= h << 4;
-	    break;
-	case 0xe:		/* Pattern row delay */
-	    e->fxt = FX_IT_ROWDELAY;
-	    e->fxp = l;
-	    break;
-	default:
-	    e->fxt = e->fxp = 0;
-	}
-	break;
-    case FX_FLT_CUTOFF:
-	if (e->fxp > 0x7f && e->fxp < 0x90) {	/* Resonance */
-	    e->fxt = FX_FLT_RESN;
-	    e->fxp = (e->fxp - 0x80) * 16;
-	} else {		/* Cutoff */
-	    e->fxp *= 2;
-	}
-	break;
-    case FX_TREMOR:
-	if (!new_fx && e->fxp != 0) {
-	   e->fxp = ((MSN(e->fxp) + 1) << 4) | (LSN(e->fxp) + 1);
-	}
-	break;
-    case FX_GLOBALVOL:
-	if (e->fxp > 0x80) {	/* See storlek test 16 */
+		switch (h) {
+		case 0x1:	/* Glissando */
+			e->fxp = 0x30 | l;
+			break;
+		case 0x2:	/* Finetune -- not supported */
+			e->fxt = e->fxp = 0;
+			break;
+		case 0x3:	/* Vibrato wave */
+			e->fxp = 0x40 | l;
+			break;
+		case 0x4:	/* Tremolo wave */
+			e->fxp = 0x70 | l;
+			break;
+		case 0x5:	/* Panbrello wave */
+			if (l <= 3) {
+				e->fxt = FX_PANBRELLO_WF;
+				e->fxp = l;
+			} else {
+				e->fxt = e->fxp = 0;
+			}
+			break;
+		case 0x6:	/* Pattern delay */
+			e->fxp = 0xe0 | l;
+			break;
+		case 0x7:	/* Instrument functions */
+			e->fxt = FX_IT_INSTFUNC;
+			e->fxp &= 0x0f;
+			break;
+		case 0x8:	/* Set pan position */
+			e->fxt = FX_SETPAN;
+			e->fxp = l << 4;
+			break;
+		case 0x9:	/* 0x91 = set surround */
+			e->fxt = FX_SURROUND;
+			e->fxp = l;
+			break;
+		case 0xa:	/* High offset */
+			e->fxt = FX_HIOFFSET;
+			e->fxp = l;
+			break;
+		case 0xb:	/* Pattern loop */
+			e->fxp = 0x60 | l;
+			break;
+		case 0xc:	/* Note cut */
+		case 0xd:	/* Note delay */
+			if ((e->fxp = l) == 0)
+				e->fxp++;  /* SD0 and SC0 become SD1 and SC1 */
+			e->fxp |= h << 4;
+			break;
+		case 0xe:	/* Pattern row delay */
+			e->fxt = FX_IT_ROWDELAY;
+			e->fxp = l;
+			break;
+		default:
+			e->fxt = e->fxp = 0;
+		}
+		break;
+	case FX_FLT_CUTOFF:
+		if (e->fxp > 0x7f && e->fxp < 0x90) {	/* Resonance */
+			e->fxt = FX_FLT_RESN;
+			e->fxp = (e->fxp - 0x80) * 16;
+		} else {	/* Cutoff */
+			e->fxp *= 2;
+		}
+		break;
+	case FX_TREMOR:
+		if (!new_fx && e->fxp != 0) {
+			e->fxp = ((MSN(e->fxp) + 1) << 4) | (LSN(e->fxp) + 1);
+		}
+		break;
+	case FX_GLOBALVOL:
+		if (e->fxp > 0x80) {	/* See storlek test 16 */
+			e->fxt = e->fxp = 0;
+		}
+		break;
+	case FX_NONE:		/* No effect */
 		e->fxt = e->fxp = 0;
+		break;
 	}
-	break;
-    case FX_NONE:		/* No effect */
-	e->fxt = e->fxp = 0;
-	break;
-    }
-
-    /* Impulse Tracker ignores the portamento command if there is an
-     * portamento command next to an offset command
-     */
-    if (e->fxt == FX_OFFSET && e->f2t == FX_TONEPORTA) {
-        e->f2t = e->f2p = 0;
-    }
-
 }
 
 
 static void xlat_volfx(struct xmp_event *event)
 {
-    int b;
-
-    b = event->vol;
-    event->vol = 0;
-
-    if (b <= 0x40) {
-	event->vol = b + 1;
-    } else if (b >= 65 && b <= 74) {	/* A */
-	event->f2t = FX_EXTENDED;
-	event->f2p = (EX_F_VSLIDE_UP << 4) | (b - 65);
-    } else if (b >= 75 && b <= 84) {	/* B */
-	event->f2t = FX_EXTENDED;
-	event->f2p = (EX_F_VSLIDE_DN << 4) | (b - 75);
-    } else if (b >= 85 && b <= 94) {	/* C */
-	event->f2t = FX_VOLSLIDE_2;
-	event->f2p = (b - 85) << 4;
-    } else if (b >= 95 && b <= 104) {	/* D */
-	event->f2t = FX_VOLSLIDE_2;
-	event->f2p = b - 95;
-    } else if (b >= 105 && b <= 114) {	/* E */
-	event->f2t = FX_PORTA_DN;
-	event->f2p = (b - 105) << 2;
-    } else if (b >= 115 && b <= 124) {	/* F */
-	event->f2t = FX_PORTA_UP;
-	event->f2p = (b - 115) << 2;
-    } else if (b >= 128 && b <= 192) {	/* pan */
-	if (b == 192)
-	    b = 191;
-	event->f2t = FX_SETPAN;
-	event->f2p = (b - 128) << 2;
-    } else if (b >= 193 && b <= 202) {	/* G */
-	event->f2t = FX_TONEPORTA;
-	event->f2p = (b - 193) << 2;
-    } else if (b >= 203 && b <= 212) {	/* H */
-	event->f2t = FX_VIBRATO;
-	event->f2p = b - 203;
-    }
+	int b;
+
+	b = event->vol;
+	event->vol = 0;
+
+	if (b <= 0x40) {
+		event->vol = b + 1;
+	} else if (b >= 65 && b <= 74) {	/* A */
+		event->f2t = FX_F_VSLIDE_UP_2;
+		event->f2p = b - 65;
+	} else if (b >= 75 && b <= 84) {	/* B */
+		event->f2t = FX_F_VSLIDE_DN_2;
+		event->f2p = b - 75;
+	} else if (b >= 85 && b <= 94) {	/* C */
+		event->f2t = FX_VSLIDE_UP_2;
+		event->f2p = b - 85;
+	} else if (b >= 95 && b <= 104) {	/* D */
+		event->f2t = FX_VSLIDE_DN_2;
+		event->f2p = b - 95;
+	} else if (b >= 105 && b <= 114) {	/* E */
+		event->f2t = FX_PORTA_DN;
+		event->f2p = (b - 105) << 2;
+	} else if (b >= 115 && b <= 124) {	/* F */
+		event->f2t = FX_PORTA_UP;
+		event->f2p = (b - 115) << 2;
+	} else if (b >= 128 && b <= 192) {	/* pan */
+		if (b == 192) {
+			event->f2p = 0xff;
+		} else {
+			event->f2p = (b - 128) << 2;
+		}
+		event->f2t = FX_SETPAN;
+	} else if (b >= 193 && b <= 202) {	/* G */
+		uint8 val[10] = {
+			0x00, 0x01, 0x04, 0x08, 0x10,
+			0x20, 0x40, 0x60, 0x80, 0xff
+		};
+		event->f2t = FX_TONEPORTA;
+		event->f2p = val[b - 193];
+	} else if (b >= 203 && b <= 212) {	/* H */
+		event->f2t = FX_VIBRATO;
+		event->f2p = b - 203;
+	}
 }
 
 
 static void fix_name(uint8 *s, int l)
 {
-    int i;
-
-    /* IT names can have 0 at start of data, replace with space */
-    for (l--, i = 0; i < l; i++) {
-	if (s[i] == 0)
-	    s[i] = ' ';
-    }
-    for (i--; i >= 0 && s[i] == ' '; i--) {
-	if (s[i] == ' ')
-	    s[i] = 0;
-    }
+	int i;
+
+	/* IT names can have 0 at start of data, replace with space */
+	for (l--, i = 0; i < l; i++) {
+		if (s[i] == 0)
+			s[i] = ' ';
+	}
+	for (i--; i >= 0 && s[i] == ' '; i--) {
+		if (s[i] == ' ')
+			s[i] = 0;
+	}
 }
 
 
-static void read_envelope(struct xmp_envelope *ei, struct it_envelope *env, HIO_HANDLE *f)
+static void read_envelope(struct xmp_envelope *ei, struct it_envelope *env,
+			  HIO_HANDLE *f)
 {
-    int j;
-
-    env->flg = hio_read8(f);
-    env->num = hio_read8(f);
-    env->lpb = hio_read8(f);
-    env->lpe = hio_read8(f);
-    env->slb = hio_read8(f);
-    env->sle = hio_read8(f);
-
-    for (j = 0; j < 25; j++) {
-    	env->node[j].y = hio_read8(f);
-    	env->node[j].x = hio_read16l(f);
-    }
-
-    env->unused = hio_read8(f);
-
-    ei->flg = env->flg & IT_ENV_ON ? XMP_ENVELOPE_ON : 0;
-    ei->flg |= env->flg & IT_ENV_LOOP ? XMP_ENVELOPE_LOOP : 0;
-    ei->flg |= env->flg & IT_ENV_SLOOP ? (XMP_ENVELOPE_SUS|XMP_ENVELOPE_SLOOP) : 0;
-    ei->flg |= env->flg & IT_ENV_CARRY ? XMP_ENVELOPE_CARRY : 0;
-    ei->npt = env->num;
-    ei->sus = env->slb;
-    ei->sue = env->sle;
-    ei->lps = env->lpb;
-    ei->lpe = env->lpe;
-
-    if (ei->npt > 0 && ei->npt < XMP_MAX_ENV_POINTS) {
-    	for (j = 0; j < ei->npt; j++) {
-    		ei->data[j * 2] = env->node[j].x;
-    		ei->data[j * 2 + 1] = env->node[j].y;
-    	}
-    } else {
-    	ei->flg &= ~XMP_ENVELOPE_ON;
-    }
-}
+	int j;
 
-static int it_load(struct module_data *m, HIO_HANDLE *f, const int start)
-{
-    struct xmp_module *mod = &m->mod;
-    int r, c, i, j, k, pat_len;
-    struct xmp_event *event, dummy, lastevent[L_CHANNELS];
-    struct it_file_header ifh;
-    struct it_instrument1_header i1h;
-    struct it_instrument2_header i2h;
-    struct it_sample_header ish;
-    struct it_envelope env;
-    uint8 b, mask[L_CHANNELS];
-    int max_ch;
-    int inst_map[120], inst_rmap[XMP_MAX_KEYS];
-#ifndef LIBXMP_CORE_PLAYER
-    char tracker_name[40];
-#endif
-    uint32 *pp_ins;		/* Pointers to instruments */
-    uint32 *pp_smp;		/* Pointers to samples */
-    uint32 *pp_pat;		/* Pointers to patterns */
-    uint8 last_fxp[64];
-    int dca2nna[] = { 0, 2, 3 };
-    int new_fx, sample_mode;
-
-    LOAD_INIT();
-
-    /* Load and convert header */
-    hio_read32b(f);		/* magic */
-
-    hio_read(&ifh.name, 26, 1, f);
-    ifh.hilite_min = hio_read8(f);
-    ifh.hilite_maj = hio_read8(f);
-
-    ifh.ordnum = hio_read16l(f);
-    ifh.insnum = hio_read16l(f);
-    ifh.smpnum = hio_read16l(f);
-    ifh.patnum = hio_read16l(f);
-
-    ifh.cwt = hio_read16l(f);
-    ifh.cmwt = hio_read16l(f);
-    ifh.flags = hio_read16l(f);
-    ifh.special = hio_read16l(f);
-
-    ifh.gv = hio_read8(f);
-    ifh.mv = hio_read8(f);
-    ifh.is = hio_read8(f);
-    ifh.it = hio_read8(f);
-    ifh.sep = hio_read8(f);
-    ifh.pwd = hio_read8(f);
-
-    ifh.msglen = hio_read16l(f);
-    ifh.msgofs = hio_read32l(f);
-    ifh.rsvd = hio_read32l(f);
-
-    hio_read(&ifh.chpan, 64, 1, f);
-    hio_read(&ifh.chvol, 64, 1, f);
-
-    strncpy(mod->name, (char *)ifh.name, XMP_NAME_SIZE);
-    mod->len = ifh.ordnum;
-    mod->ins = ifh.insnum;
-    mod->smp = ifh.smpnum;
-    mod->pat = ifh.patnum;
-
-    if (mod->ins) {
-        pp_ins = calloc(4, mod->ins);
-        if (pp_ins == NULL)
-	    goto err;
-    } else {
-	pp_ins = NULL;
-    }
-
-    pp_smp = calloc(4, mod->smp);
-    if (pp_smp == NULL)
-	goto err2;
-
-    pp_pat = calloc(4, mod->pat);
-    if (pp_pat == NULL)
-	goto err3;
-
-    mod->spd = ifh.is;
-    mod->bpm = ifh.it;
-
-    sample_mode = ~ifh.flags & IT_USE_INST;
-
-    if (ifh.flags & IT_LINEAR_FREQ) {
-       m->quirk |= QUIRK_LINEAR;
-    }
-
-    if (!sample_mode && ifh.cmwt >= 0x200) {
-       m->quirk |= QUIRK_INSVOL;
-    }
-
-    for (i = 0; i < 64; i++) {
-	struct xmp_channel *xxc = &mod->xxc[i];
-
-	if (ifh.chpan[i] == 100)	/* Surround -> center */
-	    ifh.chpan[i] = 32;
-
-	if (ifh.chpan[i] & 0x80) {	/* Channel mute */
-	    ifh.chvol[i] = 0;
-	    mod->xxc[i].flg |= XMP_CHANNEL_MUTE;
+	env->flg = hio_read8(f);
+	env->num = hio_read8(f);
+
+	/* Sanity check */
+	if (env->num >= XMP_MAX_ENV_POINTS) {
+		env->flg = 0;
+		env->num = 0;
+		return;
 	}
 
-	if (ifh.flags & IT_STEREO) {
-	    xxc->pan = (int)ifh.chpan[i] * 0x80 >> 5;
-	    if (xxc->pan > 0xff)
-		xxc->pan = 0xff;
-	} else {
-	    xxc->pan = 0x80;
+	env->lpb = hio_read8(f);
+	env->lpe = hio_read8(f);
+	env->slb = hio_read8(f);
+	env->sle = hio_read8(f);
+
+	for (j = 0; j < 25; j++) {
+		env->node[j].y = hio_read8(f);
+		env->node[j].x = hio_read16l(f);
 	}
 
-	xxc->vol = ifh.chvol[i];
-    }
-    if (mod->len <= XMP_MAX_MOD_LENGTH) {
-    	hio_read(mod->xxo, 1, mod->len, f);
-    } else {
-    	hio_read(mod->xxo, 1, XMP_MAX_MOD_LENGTH, f);
-    	hio_seek(f, mod->len - XMP_MAX_MOD_LENGTH, SEEK_CUR);
-    	mod->len = XMP_MAX_MOD_LENGTH;
-    }
-
-    new_fx = ifh.flags & IT_OLD_FX ? 0 : 1;
-
-    /* S3M skips pattern 0xfe */
-    for (i = 0; i < (mod->len - 1); i++) {
-	if (mod->xxo[i] == 0xfe) {
-	    memmove(&mod->xxo[i], &mod->xxo[i + 1], mod->len - i - 1);
-	    mod->len--;
+	env->unused = hio_read8(f);
+
+	ei->flg = env->flg & IT_ENV_ON ? XMP_ENVELOPE_ON : 0;
+
+	if (env->flg & IT_ENV_LOOP) {
+		ei->flg |= XMP_ENVELOPE_LOOP;
 	}
-    }
-    for (i = 0; i < mod->ins; i++)
-	pp_ins[i] = hio_read32l(f);
-    for (i = 0; i < mod->smp; i++)
-	pp_smp[i] = hio_read32l(f);
-    for (i = 0; i < mod->pat; i++)
-	pp_pat[i] = hio_read32l(f);
 
-    m->c4rate = C4_NTSC_RATE;
+	if (env->flg & IT_ENV_SLOOP) {
+		ei->flg |= XMP_ENVELOPE_SUS | XMP_ENVELOPE_SLOOP;
+	}
 
-#ifndef LIBXMP_CORE_PLAYER
-    /* Identify tracker */
-
-    switch (ifh.cwt >> 8) {
-    case 0x00:
-	strcpy(tracker_name, "unmo3");
-	break;
-    case 0x01:
-    case 0x02:		/* test from Schism Tracker sources */
-	if (ifh.cmwt == 0x0200 && ifh.cwt == 0x0214
-		&& ifh.flags == 9 && ifh.special == 0
-		&& ifh.hilite_maj == 0 && ifh.hilite_min == 0
-		&& ifh.insnum == 0 && ifh.patnum + 1 == ifh.ordnum
-		&& ifh.gv == 128 && ifh.mv == 100 && ifh.is == 1
-		&& ifh.sep == 128 && ifh.pwd == 0
-		&& ifh.msglen == 0 && ifh.msgofs == 0 && ifh.rsvd == 0)
-	{
-                strcpy(tracker_name, "OpenSPC conversion");
-	} else if (ifh.cmwt == 0x0200 && ifh.cwt == 0x0217) {
-	    strcpy(tracker_name, "ModPlug Tracker 1.16");
-	    /* ModPlug Tracker files aren't really IMPM 2.00 */
-	    ifh.cmwt = sample_mode ? 0x100 : 0x214;	
-	} else if (ifh.cwt == 0x0216) {
-	    strcpy(tracker_name, "Impulse Tracker 2.14v3");
-	} else if (ifh.cwt == 0x0217) {
-	    strcpy(tracker_name, "Impulse Tracker 2.14v5");
-	} else if (ifh.cwt == 0x0214 && !memcmp(&ifh.rsvd, "CHBI", 4)) {
-	    strcpy(tracker_name, "Chibi Tracker");
-	} else {
-	    snprintf(tracker_name, 40, "Impulse Tracker %d.%02x",
-			(ifh.cwt & 0x0f00) >> 8, ifh.cwt & 0xff);
+	if (env->flg & IT_ENV_CARRY) {
+		ei->flg |= XMP_ENVELOPE_CARRY;
 	}
-	break;
-    case 0x08:
-    case 0x7f:
-	if (ifh.cwt == 0x0888) {
-	    strcpy(tracker_name, "OpenMPT 1.17+");
-	} else if (ifh.cwt == 0x7fff) {
-	    strcpy(tracker_name, "munch.py");
+
+	ei->npt = env->num;
+	ei->sus = env->slb;
+	ei->sue = env->sle;
+	ei->lps = env->lpb;
+	ei->lpe = env->lpe;
+
+	if (ei->npt > 0 && ei->npt <= 25 /* XMP_MAX_ENV_POINTS */ ) {
+		for (j = 0; j < ei->npt; j++) {
+			ei->data[j * 2] = env->node[j].x;
+			ei->data[j * 2 + 1] = env->node[j].y;
+		}
 	} else {
-	    snprintf(tracker_name, 40, "unknown (%04x)", ifh.cwt);
+		ei->flg &= ~XMP_ENVELOPE_ON;
 	}
-	break;
-    default:
-	switch (ifh.cwt >> 12) {
-	case 0x1: {
-	    uint16 cwtv = ifh.cwt & 0x0fff;
-	    struct tm version;
-	    time_t version_sec;
-
-	    if (cwtv > 0x50) {
-		version_sec = ((cwtv - 0x050) * 86400) + 1254355200;
-		if (localtime_r(&version_sec, &version)) {
-		    snprintf(tracker_name, 40, "Schism Tracker %04d-%02d-%02d",
-				version.tm_year + 1900, version.tm_mon + 1,
-				version.tm_mday);
-                }
-	    } else {
-	    	snprintf(tracker_name, 40, "Schism Tracker 0.%x", cwtv);
-	    }
-	    break; }
-	case 0x5:
-	    snprintf(tracker_name, 40, "OpenMPT %d.%02x",
-			(ifh.cwt & 0x0f00) >> 8, ifh.cwt & 0xff);
-	    if (memcmp(&ifh.rsvd, "OMPT", 4))
-		strncat(tracker_name, " (compat.)", 40);
-	    break;
-	case 0x06:
-	    snprintf(tracker_name, 40, "BeRoTracker %d.%02x",
-			(ifh.cwt & 0x0f00) >> 8, ifh.cwt & 0xff);
-	    break;
+}
+
+static void identify_tracker(struct module_data *m, struct it_file_header *ifh)
+{
+#ifndef LIBXMP_CORE_PLAYER
+	char tracker_name[40];
+	int sample_mode = ~ifh->flags & IT_USE_INST;
+
+	switch (ifh->cwt >> 8) {
+	case 0x00:
+		strcpy(tracker_name, "unmo3");
+		break;
+	case 0x01:
+	case 0x02:		/* test from Schism Tracker sources */
+		if (ifh->cmwt == 0x0200 && ifh->cwt == 0x0214
+		    && ifh->flags == 9 && ifh->special == 0
+		    && ifh->hilite_maj == 0 && ifh->hilite_min == 0
+		    && ifh->insnum == 0 && ifh->patnum + 1 == ifh->ordnum
+		    && ifh->gv == 128 && ifh->mv == 100 && ifh->is == 1
+		    && ifh->sep == 128 && ifh->pwd == 0
+		    && ifh->msglen == 0 && ifh->msgofs == 0 && ifh->rsvd == 0) {
+			strcpy(tracker_name, "OpenSPC conversion");
+		} else if (ifh->cmwt == 0x0200 && ifh->cwt == 0x0217) {
+			strcpy(tracker_name, "ModPlug Tracker 1.16");
+			/* ModPlug Tracker files aren't really IMPM 2.00 */
+			ifh->cmwt = sample_mode ? 0x100 : 0x214;
+		} else if (ifh->cwt == 0x0216) {
+			strcpy(tracker_name, "Impulse Tracker 2.14v3");
+		} else if (ifh->cwt == 0x0217) {
+			strcpy(tracker_name, "Impulse Tracker 2.14v5");
+		} else if (ifh->cwt == 0x0214 && !memcmp(&ifh->rsvd, "CHBI", 4)) {
+			strcpy(tracker_name, "Chibi Tracker");
+		} else {
+			snprintf(tracker_name, 40, "Impulse Tracker %d.%02x",
+				 (ifh->cwt & 0x0f00) >> 8, ifh->cwt & 0xff);
+		}
+		break;
+	case 0x08:
+	case 0x7f:
+		if (ifh->cwt == 0x0888) {
+			strcpy(tracker_name, "OpenMPT 1.17");
+		} else if (ifh->cwt == 0x7fff) {
+			strcpy(tracker_name, "munch.py");
+		} else {
+			snprintf(tracker_name, 40, "unknown (%04x)", ifh->cwt);
+		}
+		break;
 	default:
-	    snprintf(tracker_name, 40, "unknown (%04x)", ifh.cwt);
+		switch (ifh->cwt >> 12) {
+		case 0x1:{
+			uint16 cwtv = ifh->cwt & 0x0fff;
+			struct tm version;
+			time_t version_sec;
+
+			if (cwtv > 0x50) {
+				version_sec = ((cwtv - 0x050) * 86400) + 1254355200;
+				if (localtime_r(&version_sec, &version)) {
+					snprintf(tracker_name, 40,
+						 "Schism Tracker %04d-%02d-%02d",
+						 version.tm_year + 1900,
+						 version.tm_mon + 1,
+						 version.tm_mday);
+				}
+			} else {
+				snprintf(tracker_name, 40,
+					 "Schism Tracker 0.%x", cwtv);
+			}
+			break; }
+		case 0x5:
+			snprintf(tracker_name, 40, "OpenMPT %d.%02x",
+				 (ifh->cwt & 0x0f00) >> 8, ifh->cwt & 0xff);
+			if (memcmp(&ifh->rsvd, "OMPT", 4))
+				strncat(tracker_name, " (compat.)", 39);
+			break;
+		case 0x06:
+			snprintf(tracker_name, 40, "BeRoTracker %d.%02x",
+				 (ifh->cwt & 0x0f00) >> 8, ifh->cwt & 0xff);
+			break;
+		default:
+			snprintf(tracker_name, 40, "unknown (%04x)", ifh->cwt);
+		}
 	}
-    }
 
-    set_type(m, "%s IT %d.%02x", tracker_name,
-			ifh.cmwt >> 8, ifh.cmwt & 0xff);
+	libxmp_set_type(m, "%s IT %d.%02x", tracker_name, ifh->cmwt >> 8,
+						ifh->cmwt & 0xff);
 #else
-    set_type(m, "Impulse Tracker");
+	libxmp_set_type(m, "Impulse Tracker");
 #endif
+}
+
+static int load_old_it_instrument(struct xmp_instrument *xxi, HIO_HANDLE *f)
+{
+	int inst_map[120], inst_rmap[XMP_MAX_KEYS];
+	struct it_instrument1_header i1h;
+	int c, k, j;
+
+	i1h.magic = hio_read32b(f);
+	hio_read(&i1h.dosname, 12, 1, f);
+
+	i1h.zero = hio_read8(f);
+	i1h.flags = hio_read8(f);
+	i1h.vls = hio_read8(f);
+	i1h.vle = hio_read8(f);
+	i1h.sls = hio_read8(f);
+	i1h.sle = hio_read8(f);
+	i1h.rsvd1 = hio_read16l(f);
+	i1h.fadeout = hio_read16l(f);
+
+	i1h.nna = hio_read8(f);
+	i1h.dnc = hio_read8(f);
+	i1h.trkvers = hio_read16l(f);
+	i1h.nos = hio_read8(f);
+	i1h.rsvd2 = hio_read8(f);
+
+	if (hio_error(f)) {
+		return -1;
+	}
 
-    MODULE_INFO();
+	if (hio_read(&i1h.name, 1, 26, f) != 26) {
+		return -1;
+	}
 
-    D_(D_INFO "Instrument/FX mode: %s/%s",
-			sample_mode ? "sample" : ifh.cmwt >= 0x200 ?
-			"new" : "old", ifh.flags & IT_OLD_FX ? "old" : "IT");
+	fix_name(i1h.name, 26);
 
-    if (sample_mode)
-	mod->ins = mod->smp;
+	if (hio_read(&i1h.rsvd3, 1, 6, f) != 6)
+		return -1;
+	if (hio_read(&i1h.keys, 1, 240, f) != 240)
+		return -1;
+	if (hio_read(&i1h.epoint, 1, 200, f) != 200)
+		return -1;
+	if (hio_read(&i1h.enode, 1, 50, f) != 50)
+		return -1;
 
-    if (instrument_init(mod) < 0)
-	goto err4;
+	libxmp_copy_adjust(xxi->name, i1h.name, 25);
 
-    D_(D_INFO "Instruments: %d", mod->ins);
+	xxi->rls = i1h.fadeout << 7;
 
-    for (i = 0; i < mod->ins; i++) {
-	/*
-	 * IT files can have three different instrument types: 'New'
-	 * instruments, 'old' instruments or just samples. We need a
-	 * different loader for each of them.
-	 */
+	xxi->aei.flg = 0;
+	if (i1h.flags & IT_ENV_ON) {
+		xxi->aei.flg |= XMP_ENVELOPE_ON;
+	}
+	if (i1h.flags & IT_ENV_LOOP) {
+		xxi->aei.flg |= XMP_ENVELOPE_LOOP;
+	}
+	if (i1h.flags & IT_ENV_SLOOP) {
+		xxi->aei.flg |= XMP_ENVELOPE_SUS | XMP_ENVELOPE_SLOOP;
+	}
+	if (i1h.flags & IT_ENV_CARRY) {
+		xxi->aei.flg |= XMP_ENVELOPE_SUS | XMP_ENVELOPE_CARRY;
+	}
+	xxi->aei.lps = i1h.vls;
+	xxi->aei.lpe = i1h.vle;
+	xxi->aei.sus = i1h.sls;
+	xxi->aei.sue = i1h.sle;
 
-	struct xmp_instrument *xxi = &mod->xxi[i];
+	for (k = 0; k < 25 && i1h.enode[k * 2] != 0xff; k++) ;
 
-	if (!sample_mode && ifh.cmwt >= 0x200) {
-	    /* New instrument format */
-	    if (hio_seek(f, start + pp_ins[i], SEEK_SET) != 0)
-	    	goto err4;
-
-	    i2h.magic = hio_read32b(f);
-	    hio_read(&i2h.dosname, 12, 1, f);
-	    i2h.zero = hio_read8(f);
-	    i2h.nna = hio_read8(f);
-	    i2h.dct = hio_read8(f);
-	    i2h.dca = hio_read8(f);
-	    i2h.fadeout = hio_read16l(f);
-
-	    i2h.pps = hio_read8(f);
-	    i2h.ppc = hio_read8(f);
-	    i2h.gbv = hio_read8(f);
-	    i2h.dfp = hio_read8(f);
-	    i2h.rv = hio_read8(f);
-	    i2h.rp = hio_read8(f);
-	    i2h.trkvers = hio_read16l(f);
-
-	    i2h.nos = hio_read8(f);
-	    i2h.rsvd1 = hio_read8(f);
-	    hio_read(&i2h.name, 26, 1, f);
-
-	    fix_name(i2h.name, 26);
-
-	    i2h.ifc = hio_read8(f);
-	    i2h.ifr = hio_read8(f);
-	    i2h.mch = hio_read8(f);
-	    i2h.mpr = hio_read8(f);
-	    i2h.mbnk = hio_read16l(f);
-	    hio_read(&i2h.keys, 240, 1, f);
-
-	    copy_adjust(xxi->name, i2h.name, 25);
-	    xxi->rls = i2h.fadeout << 6;
-
-	    /* Envelopes */
-
-	    read_envelope(&xxi->aei, &env, f);
-	    read_envelope(&xxi->pei, &env, f);
-	    read_envelope(&xxi->fei, &env, f);
-	    
-	    if (xxi->pei.flg & XMP_ENVELOPE_ON) {
+	/* Sanity check */
+	if (k >= 25 || i1h.enode[k * 2] != 0xff) {
+		return -1;
+	}
+
+	for (xxi->aei.npt = k; k--;) {
+		xxi->aei.data[k * 2] = i1h.enode[k * 2];
+		xxi->aei.data[k * 2 + 1] = i1h.enode[k * 2 + 1];
+	}
+
+	/* See how many different instruments we have */
+	for (j = 0; j < 120; j++)
+		inst_map[j] = -1;
+
+	for (k = j = 0; j < XMP_MAX_KEYS; j++) {
+		c = j < 120 ? i1h.keys[j * 2 + 1] - 1 : -1;
+		if (c < 0 || c >= 120) {
+			xxi->map[j].ins = 0;
+			xxi->map[j].xpo = 0;
+			continue;
+		}
+		if (inst_map[c] == -1) {
+			inst_map[c] = k;
+			inst_rmap[k] = c;
+			k++;
+		}
+		xxi->map[j].ins = inst_map[c];
+		xxi->map[j].xpo = i1h.keys[j * 2] - j;
+	}
+
+	xxi->nsm = k;
+	xxi->vol = 0x40;
+
+	if (k) {
+		xxi->sub = calloc(sizeof(struct xmp_subinstrument), k);
+		if (xxi->sub == NULL) {
+			return -1;
+		}
+
+		for (j = 0; j < k; j++) {
+			struct xmp_subinstrument *sub = &xxi->sub[j];
+
+			sub->sid = inst_rmap[j];
+			sub->nna = i1h.nna;
+			sub->dct =
+			    i1h.dnc ? XMP_INST_DCT_NOTE : XMP_INST_DCT_OFF;
+			sub->dca = XMP_INST_DCA_CUT;
+			sub->pan = -1;
+		}
+	}
+
+	D_(D_INFO "[  ] %-26.26s %d %-4.4s %4d %2d %c%c%c %3d",
+	   /*i,*/ i1h.name,
+	   i1h.nna,
+	   i1h.dnc ? "on" : "off",
+	   i1h.fadeout,
+	   xxi->aei.npt,
+	   xxi->aei.flg & XMP_ENVELOPE_ON ? 'V' : '-',
+	   xxi->aei.flg & XMP_ENVELOPE_LOOP ? 'L' : '-',
+	   xxi->aei.flg & XMP_ENVELOPE_SUS ? 'S' : '-', xxi->nsm);
+
+	return 0;
+}
+
+static int load_new_it_instrument(struct xmp_instrument *xxi, HIO_HANDLE *f)
+{
+	int inst_map[120], inst_rmap[XMP_MAX_KEYS];
+	struct it_instrument2_header i2h;
+	struct it_envelope env;
+	int dca2nna[] = { 0, 2, 3 };
+	int c, k, j;
+
+	i2h.magic = hio_read32b(f);
+	if (i2h.magic != MAGIC_IMPI) {
+		D_(D_CRIT "bad instrument magic");
+		return -1;
+	}
+	hio_read(&i2h.dosname, 12, 1, f);
+	i2h.zero = hio_read8(f);
+	i2h.nna = hio_read8(f);
+	i2h.dct = hio_read8(f);
+	i2h.dca = hio_read8(f);
+
+	/* Sanity check */
+	if (i2h.dca > 3) {
+		/* Northern Sky has an instrument with DCA 3 */
+		D_(D_WARN "bad instrument dca: %d", i2h.dca);
+		i2h.dca = 0;
+	}
+
+	i2h.fadeout = hio_read16l(f);
+
+	i2h.pps = hio_read8(f);
+	i2h.ppc = hio_read8(f);
+	i2h.gbv = hio_read8(f);
+	i2h.dfp = hio_read8(f);
+	i2h.rv = hio_read8(f);
+	i2h.rp = hio_read8(f);
+	i2h.trkvers = hio_read16l(f);
+
+	i2h.nos = hio_read8(f);
+	i2h.rsvd1 = hio_read8(f);
+
+	if (hio_error(f)) {
+		D_(D_CRIT "read error");
+		return -1;
+	}
+
+	if (hio_read(&i2h.name, 1, 26, f) != 26) {
+		D_(D_CRIT "name read error");
+		return -1;
+	}
+
+	fix_name(i2h.name, 26);
+
+	i2h.ifc = hio_read8(f);
+	i2h.ifr = hio_read8(f);
+	i2h.mch = hio_read8(f);
+	i2h.mpr = hio_read8(f);
+	i2h.mbnk = hio_read16l(f);
+
+	if (hio_read(&i2h.keys, 1, 240, f) != 240) {
+		D_(D_CRIT "key map read error");
+		return -1;
+	}
+
+	libxmp_copy_adjust(xxi->name, i2h.name, 25);
+	xxi->rls = i2h.fadeout << 6;
+
+	/* Envelopes */
+
+	read_envelope(&xxi->aei, &env, f);
+	read_envelope(&xxi->pei, &env, f);
+	read_envelope(&xxi->fei, &env, f);
+
+	if (xxi->pei.flg & XMP_ENVELOPE_ON) {
 		for (j = 0; j < xxi->pei.npt; j++)
-		    xxi->pei.data[j * 2 + 1] += 32;
-	    }
+			xxi->pei.data[j * 2 + 1] += 32;
+	}
 
-	    if (xxi->aei.flg & XMP_ENVELOPE_ON && xxi->aei.npt == 0)
+	if (xxi->aei.flg & XMP_ENVELOPE_ON && xxi->aei.npt == 0)
 		xxi->aei.npt = 1;
-	    if (xxi->pei.flg & XMP_ENVELOPE_ON && xxi->pei.npt == 0)
+	if (xxi->pei.flg & XMP_ENVELOPE_ON && xxi->pei.npt == 0)
 		xxi->pei.npt = 1;
-	    if (xxi->fei.flg & XMP_ENVELOPE_ON && xxi->fei.npt == 0)
+	if (xxi->fei.flg & XMP_ENVELOPE_ON && xxi->fei.npt == 0)
 		xxi->fei.npt = 1;
 
-	    if (env.flg & IT_ENV_FILTER) {
+	if (env.flg & IT_ENV_FILTER) {
 		xxi->fei.flg |= XMP_ENVELOPE_FLT;
 		for (j = 0; j < env.num; j++) {
-		    xxi->fei.data[j * 2 + 1] += 32;
-		    xxi->fei.data[j * 2 + 1] *= 4;
+			xxi->fei.data[j * 2 + 1] += 32;
+			xxi->fei.data[j * 2 + 1] *= 4;
 		}
-	    } else {
+	} else {
 		/* Pitch envelope is *50 to get fine interpolation */
 		for (j = 0; j < env.num; j++)
-		    xxi->fei.data[j * 2 + 1] *= 50;
-	    }
+			xxi->fei.data[j * 2 + 1] *= 50;
+	}
 
-	    /* See how many different instruments we have */
-	    for (j = 0; j < 120; j++)
+	/* See how many different instruments we have */
+	for (j = 0; j < 120; j++)
 		inst_map[j] = -1;
 
-	    for (k = j = 0; j < 120; j++) {
+	for (k = j = 0; j < 120; j++) {
 		c = i2h.keys[j * 2 + 1] - 1;
-		if (c < 0) {
-		    xxi->map[j].ins = 0xff;	/* No sample */
-		    xxi->map[j].xpo = 0;
-		    continue;
+		if (c < 0 || c >= 120) {
+			xxi->map[j].ins = 0xff;	/* No sample */
+			xxi->map[j].xpo = 0;
+			continue;
 		}
 		if (inst_map[c] == -1) {
-		    inst_map[c] = k;
-		    inst_rmap[k] = c;
-		    k++;
+			inst_map[c] = k;
+			inst_rmap[k] = c;
+			k++;
 		}
 		xxi->map[j].ins = inst_map[c];
 		xxi->map[j].xpo = i2h.keys[j * 2] - j;
-	    }
+	}
 
-	    xxi->nsm = k;
-	    xxi->vol = i2h.gbv >> 1;
+	xxi->nsm = k;
+	xxi->vol = i2h.gbv >> 1;
 
-	    if (k) {
-		xxi->sub = calloc(sizeof (struct xmp_subinstrument), k);
+	if (k) {
+		xxi->sub = calloc(sizeof(struct xmp_subinstrument), k);
 		if (xxi->sub == NULL)
-		    goto err4;
+			return -1;
 
 		for (j = 0; j < k; j++) {
-		    struct xmp_subinstrument *sub = &xxi->sub[j];
-
-		    sub->sid = inst_rmap[j];
-		    sub->nna = i2h.nna;
-		    sub->dct = i2h.dct;
-		    sub->dca = dca2nna[i2h.dca & 0x03];
-		    sub->pan = i2h.dfp & 0x80 ? -1 : i2h.dfp * 4;
-		    sub->ifc = i2h.ifc;
-		    sub->ifr = i2h.ifr;
-	        }
-	    }
-
-	    D_(D_INFO "[%2X] %-26.26s %d %d %d %4d %4d  %2x "
-			"%02x %c%c%c %3d %02x %02x",
-		i, i2h.name,
-		i2h.nna, i2h.dct, i2h.dca,
-		i2h.fadeout,
-		i2h.gbv,
-		i2h.dfp & 0x80 ? 0x80 : i2h.dfp * 4,
-		i2h.rv,
-		xxi->aei.flg & XMP_ENVELOPE_ON ? 'V' : '-',
-		xxi->pei.flg & XMP_ENVELOPE_ON ? 'P' : '-',
-		env.flg & 0x01 ? env.flg & 0x80 ? 'F' : 'P' : '-',
-		xxi->nsm,
-		i2h.ifc,
-		i2h.ifr
-	    );
-
-	} else if (!sample_mode) {
-	    /* Old instrument format */
-	    hio_seek(f, start + pp_ins[i], SEEK_SET);
-
-	    i1h.magic = hio_read32b(f);
-	    hio_read(&i1h.dosname, 12, 1, f);
-
-	    i1h.zero = hio_read8(f);
-	    i1h.flags = hio_read8(f);
-	    i1h.vls = hio_read8(f);
-	    i1h.vle = hio_read8(f);
-	    i1h.sls = hio_read8(f);
-	    i1h.sle = hio_read8(f);
-	    i1h.rsvd1 = hio_read16l(f);
-	    i1h.fadeout = hio_read16l(f);
-
-	    i1h.nna = hio_read8(f);
-	    i1h.dnc = hio_read8(f);
-	    i1h.trkvers = hio_read16l(f);
-	    i1h.nos = hio_read8(f);
-	    i1h.rsvd2 = hio_read8(f);
-
-	    hio_read(&i1h.name, 26, 1, f);
-
-	    fix_name(i1h.name, 26);
-
-	    hio_read(&i1h.rsvd3, 6, 1, f);
-	    hio_read(&i1h.keys, 240, 1, f);
-	    hio_read(&i1h.epoint, 200, 1, f);
-	    hio_read(&i1h.enode, 50, 1, f);
-
-	    copy_adjust(xxi->name, i1h.name, 25);
-
-	    xxi->rls = i1h.fadeout << 7;
-
-	    xxi->aei.flg = 0;
-	    if (i1h.flags & IT_ENV_ON) {
-		xxi->aei.flg |= XMP_ENVELOPE_ON;
-	    }
-	    if (i1h.flags & IT_ENV_LOOP) {
-		xxi->aei.flg |= XMP_ENVELOPE_LOOP;
-	    }
-	    if (i1h.flags & IT_ENV_SLOOP) {
-		xxi->aei.flg |= XMP_ENVELOPE_SUS | XMP_ENVELOPE_SLOOP;
-	    }
-	    if (i1h.flags & IT_ENV_CARRY) {
-		xxi->aei.flg |= XMP_ENVELOPE_SUS | XMP_ENVELOPE_CARRY;
-	    }
-	    xxi->aei.lps = i1h.vls;
-	    xxi->aei.lpe = i1h.vle;
-	    xxi->aei.sus = i1h.sls;
-	    xxi->aei.sue = i1h.sle;
-
-	    for (k = 0; i1h.enode[k * 2] != 0xff; k++);
-	    for (xxi->aei.npt = k; k--; ) {
-		xxi->aei.data[k * 2] = i1h.enode[k * 2];
-		xxi->aei.data[k * 2 + 1] = i1h.enode[k * 2 + 1];
-	    }
-	    
-	    /* See how many different instruments we have */
-	    for (j = 0; j < 120; j++)
-		inst_map[j] = -1;
-
-	    for (k = j = 0; j < XMP_MAX_KEYS; j++) {
-		c = j < 120 ? i1h.keys[j * 2 + 1] - 1 : -1;
-		if (c < 0) {
-		    xxi->map[j].ins = 0;
-		    xxi->map[j].xpo = 0;
-		    continue;
+			struct xmp_subinstrument *sub = &xxi->sub[j];
+
+			sub->sid = inst_rmap[j];
+			sub->nna = i2h.nna;
+			sub->dct = i2h.dct;
+			sub->dca = dca2nna[i2h.dca];
+			sub->pan = i2h.dfp & 0x80 ? -1 : i2h.dfp * 4;
+			sub->ifc = i2h.ifc;
+			sub->ifr = i2h.ifr;
+			sub->rvv = ((int)i2h.rp << 8) | i2h.rv;
 		}
-		if (inst_map[c] == -1) {
-		    inst_map[c] = k;
-		    inst_rmap[k] = c;
-		    k++;
-		}
-		xxi->map[j].ins = inst_map[c];
-		xxi->map[j].xpo = i1h.keys[j * 2] - j;
-	    }
-
-	    xxi->nsm = k;
-	    xxi->vol = i2h.gbv >> 1;
-
-	    if (k) {
-		xxi->sub = calloc(sizeof (struct xmp_subinstrument), k);
- 		if (xxi->sub == NULL)
-		    goto err4;
-
-		for (j = 0; j < k; j++) {
-		    struct xmp_subinstrument *sub = &xxi->sub[j];
-
-		    sub->sid = inst_rmap[j];
-		    sub->nna = i1h.nna;
-		    sub->dct = i1h.dnc ? XMP_INST_DCT_NOTE : XMP_INST_DCT_OFF;
-		    sub->dca = XMP_INST_DCA_CUT;
-		    sub->pan = 0x80;
-	        }
-	    }
-
-	    D_(D_INFO "[%2X] %-26.26s %d %-4.4s %4d %2d %c%c%c %3d",
-		i, i1h.name,
-		i1h.nna,
-		i1h.dnc ? "on" : "off",
-		i1h.fadeout,
-		xxi->aei.npt,
-		xxi->aei.flg & XMP_ENVELOPE_ON ? 'V' : '-',
-		xxi->aei.flg & XMP_ENVELOPE_LOOP ? 'L' : '-',
-		xxi->aei.flg & XMP_ENVELOPE_SUS ? 'S' : '-',
-		xxi->nsm
-	    );
 	}
-    }
 
-    D_(D_INFO "Stored Samples: %d", mod->smp);
+	D_(D_INFO "[  ] %-26.26s %d %d %d %4d %4d  %2x "
+	   "%02x %c%c%c %3d %02x %02x",
+	   /*i,*/ i2h.name,
+	   i2h.nna, i2h.dct, i2h.dca,
+	   i2h.fadeout,
+	   i2h.gbv,
+	   i2h.dfp & 0x80 ? 0x80 : i2h.dfp * 4,
+	   i2h.rv,
+	   xxi->aei.flg & XMP_ENVELOPE_ON ? 'V' : '-',
+	   xxi->pei.flg & XMP_ENVELOPE_ON ? 'P' : '-',
+	   env.flg & 0x01 ? env.flg & 0x80 ? 'F' : 'P' : '-',
+	   xxi->nsm, i2h.ifc, i2h.ifr);
+
+	return 0;
+}
 
-    for (i = 0; i < mod->smp; i++) {
-	struct xmp_sample *xxs = &mod->xxs[i];
+static int load_it_sample(struct module_data *m, int i, int start,
+			  int sample_mode, HIO_HANDLE *f)
+{
+	struct it_sample_header ish;
+	struct xmp_module *mod = &m->mod;
+	struct xmp_sample *xxs, *xsmp;
+	int j, k;
 
 	if (sample_mode) {
-	    mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1);
-	    if (mod->xxi[i].sub == NULL)
-		goto err4;
+		mod->xxi[i].sub = calloc(sizeof(struct xmp_subinstrument), 1);
+		if (mod->xxi[i].sub == NULL) {
+			return -1;
+		}
 	}
 
-	hio_seek(f, start + pp_smp[i], SEEK_SET);
-
 	ish.magic = hio_read32b(f);
+	if (ish.magic != MAGIC_IMPS) {
+		return -1;
+	}
+
+	xxs = &mod->xxs[i];
+	xsmp = &m->xsmp[i];
+
 	hio_read(&ish.dosname, 12, 1, f);
 	ish.zero = hio_read8(f);
 	ish.gvl = hio_read8(f);
 	ish.flags = hio_read8(f);
 	ish.vol = hio_read8(f);
-	hio_read(&ish.name, 26, 1, f);
+
+	if (hio_error(f)) {
+		return -1;
+	}
+
+	if (hio_read(&ish.name, 1, 26, f) != 26) {
+		return -1;
+	}
 
 	fix_name(ish.name, 26);
 
@@ -818,38 +750,55 @@ static int it_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	 * load correctly (both IT 2.04)
 	 */
 	if (ish.magic != MAGIC_IMPS)
-	    continue;
-	
+		return 0;
+
 	if (ish.flags & IT_SMP_16BIT) {
-	    xxs->flg = XMP_SAMPLE_16BIT;
+		xxs->flg = XMP_SAMPLE_16BIT;
 	}
 	xxs->len = ish.length;
+
+	/* Sanity check */
+	if (xxs->len > MAX_SAMPLE_SIZE) {
+		return -1;
+	}
+
 	xxs->lps = ish.loopbeg;
 	xxs->lpe = ish.loopend;
-
 	xxs->flg |= ish.flags & IT_SMP_LOOP ? XMP_SAMPLE_LOOP : 0;
 	xxs->flg |= ish.flags & IT_SMP_BLOOP ? XMP_SAMPLE_LOOP_BIDIR : 0;
+	xxs->flg |= ish.flags & IT_SMP_SLOOP ? XMP_SAMPLE_SLOOP : 0;
+	xxs->flg |= ish.flags & IT_SMP_BSLOOP ? XMP_SAMPLE_SLOOP_BIDIR : 0;
+
+	if (ish.flags & IT_SMP_SLOOP) {
+		memcpy(xsmp, xxs, sizeof (struct xmp_sample));
+		xsmp->lps = ish.sloopbeg;
+		xsmp->lpe = ish.sloopend;
+		xsmp->flg |= XMP_SAMPLE_LOOP;
+		xsmp->flg &= ~XMP_SAMPLE_LOOP_BIDIR;
+		if (ish.flags & IT_SMP_BSLOOP) {
+			xsmp->flg |= XMP_SAMPLE_LOOP_BIDIR;
+		}
+	}
 
 	if (sample_mode) {
-	    /* Create an instrument for each sample */
-	    mod->xxi[i].sub[0].vol = ish.vol;
-	    mod->xxi[i].sub[0].pan = 0x80;
-	    mod->xxi[i].sub[0].sid = i;
-	    mod->xxi[i].nsm = !!(xxs->len);
-	    instrument_name(mod, i, ish.name, 25);
+		/* Create an instrument for each sample */
+		mod->xxi[i].sub[0].vol = ish.vol;
+		mod->xxi[i].sub[0].pan = 0x80;
+		mod->xxi[i].sub[0].sid = i;
+		mod->xxi[i].nsm = !!(xxs->len);
+		libxmp_instrument_name(mod, i, ish.name, 25);
 	} else {
-	    copy_adjust(xxs->name, ish.name, 25);
+		libxmp_copy_adjust(xxs->name, ish.name, 25);
 	}
 
 	D_(D_INFO "\n[%2X] %-26.26s %05x%c%05x %05x %05x %05x "
-		    "%02x%02x %02x%02x %5d ",
-		    i, sample_mode ? xxs->name : mod->xxi[i].name,
-		    xxs->len,
-		    ish.flags & IT_SMP_16BIT ? '+' : ' ',
-		    MIN(xxs->lps, 0xfffff), MIN(xxs->lpe, 0xfffff),
-		    MIN(ish.sloopbeg, 0xfffff), MIN(ish.sloopend, 0xfffff),
-		    ish.flags, ish.convert,
-		    ish.vol, ish.gvl, ish.c5spd);
+	   "%02x%02x %02x%02x %5d ",
+	   i, sample_mode ? xxs->name : mod->xxi[i].name,
+	   xxs->len,
+	   ish.flags & IT_SMP_16BIT ? '+' : ' ',
+	   MIN(xxs->lps, 0xfffff), MIN(xxs->lpe, 0xfffff),
+	   MIN(ish.sloopbeg, 0xfffff), MIN(ish.sloopend, 0xfffff),
+	   ish.flags, ish.convert, ish.vol, ish.gvl, ish.c5spd);
 
 	/* Convert C5SPD to relnote/finetune
 	 *
@@ -857,305 +806,582 @@ static int it_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	 * instruments, but c5spd is a sample attribute -- so we must
 	 * scan all xmp instruments to set the correct transposition
 	 */
-	
+
 	for (j = 0; j < mod->ins; j++) {
-	    for (k = 0; k < mod->xxi[j].nsm; k++) {
-		struct xmp_subinstrument *sub = &mod->xxi[j].sub[k];
-		if (sub->sid == i) {
-		    sub->vol = ish.vol;
-		    sub->gvl = ish.gvl;
-		    sub->vra = ish.vis;	/* sample to sub-instrument vibrato */
-		    sub->vde = ish.vid >> 1;
-		    sub->vwf = ish.vit;
-		    sub->vsw = (0xff - ish.vir) >> 1;
-
-		    c2spd_to_note(ish.c5spd, &mod->xxi[j].sub[k].xpo, &mod->xxi[j].sub[k].fin);
+		for (k = 0; k < mod->xxi[j].nsm; k++) {
+			struct xmp_subinstrument *sub = &mod->xxi[j].sub[k];
+			if (sub->sid == i) {
+				sub->vol = ish.vol;
+				sub->gvl = ish.gvl;
+				sub->vra = ish.vis;	/* sample to sub-instrument vibrato */
+				sub->vde = ish.vid >> 1;
+				sub->vwf = ish.vit;
+				sub->vsw = (0xff - ish.vir) >> 1;
+
+				libxmp_c2spd_to_note(ish.c5spd,
+					      &mod->xxi[j].sub[k].xpo,
+					      &mod->xxi[j].sub[k].fin);
+
+				/* Set sample pan (overrides subinstrument) */
+				if (ish.dfp & 0x80) {
+					sub->pan = (ish.dfp & 0x7f) * 4;
+				} else if (sample_mode) {
+					sub->pan = -1;
+				}
+			}
 		}
-	    }
 	}
 
 	if (ish.flags & IT_SMP_SAMPLE && xxs->len > 1) {
-	    int cvt = 0;
+		int cvt = 0;
 
-	    if (0 != hio_seek(f, start + ish.sample_ptr, SEEK_SET))
-	    	goto err4;
+		if (0 != hio_seek(f, start + ish.sample_ptr, SEEK_SET))
+			return -1;
 
-	    if (xxs->lpe > xxs->len || xxs->lps >= xxs->lpe)
-	    	xxs->flg &= ~XMP_SAMPLE_LOOP;
+		if (xxs->lpe > xxs->len || xxs->lps >= xxs->lpe)
+			xxs->flg &= ~XMP_SAMPLE_LOOP;
 
-	    if (~ish.convert & IT_CVT_SIGNED)
-		cvt |= SAMPLE_FLAG_UNS;
+		if (~ish.convert & IT_CVT_SIGNED)
+			cvt |= SAMPLE_FLAG_UNS;
 
-	    /* compressed samples */
-	    if (ish.flags & IT_SMP_COMP) {
-		uint8 *buf;
-	    	int ret;
+		/* compressed samples */
+		if (ish.flags & IT_SMP_COMP) {
+			uint8 *buf;
+			int ret;
 
-		buf = calloc(1, xxs->len * 2);
-		if (buf == NULL)
-		    goto err4;
+			buf = calloc(1, xxs->len * 2);
+			if (buf == NULL)
+				return -1;
 
-		if (ish.flags & IT_SMP_16BIT) {
-		    itsex_decompress16(f, buf, xxs->len, 
-					ish.convert & IT_CVT_DIFF);
+			if (ish.flags & IT_SMP_16BIT) {
+				itsex_decompress16(f, buf, xxs->len,
+						   ish.convert & IT_CVT_DIFF);
 
 #ifdef WORDS_BIGENDIAN
-		    /* decompression generates native-endian samples, but
-		     * we want little-endian */
-		    cvt |= SAMPLE_FLAG_BIGEND;
+				/* decompression generates native-endian
+				 * samples, but we want little-endian
+				 */
+				cvt |= SAMPLE_FLAG_BIGEND;
 #endif
+			} else {
+				itsex_decompress8(f, buf, xxs->len,
+						  ish.convert & IT_CVT_DIFF);
+			}
+
+			if (ish.flags & IT_SMP_SLOOP) {
+				long pos = hio_tell(f);
+				if (pos < 0) {
+					free(buf);
+					return -1;
+				}
+				ret = libxmp_load_sample(m, NULL, SAMPLE_FLAG_NOLOAD |
+							cvt, &m->xsmp[i], buf);
+				if (ret < 0) {
+					free(buf);
+					return -1;
+				}
+				hio_seek(f, pos, SEEK_SET);
+			}
+
+			ret = libxmp_load_sample(m, NULL, SAMPLE_FLAG_NOLOAD | cvt,
+					  &mod->xxs[i], buf);
+			if (ret < 0) {
+				free(buf);
+				return -1;
+			}
+
+			free(buf);
 		} else {
-		    itsex_decompress8(f, buf, xxs->len, 
-					ish.convert & IT_CVT_DIFF);
+			if (ish.flags & IT_SMP_SLOOP) {
+				long pos = hio_tell(f);
+				if (pos < 0) {
+					return -1;
+				}
+				if (libxmp_load_sample(m, f, cvt, &m->xsmp[i], NULL) < 0)
+					return -1;
+				hio_seek(f, pos, SEEK_SET);
+			}
+
+			if (libxmp_load_sample(m, f, cvt, &mod->xxs[i], NULL) < 0)
+				return -1;
 		}
-
-		ret = load_sample(m, NULL, SAMPLE_FLAG_NOLOAD | cvt,
-							&mod->xxs[i], buf);
-		if (ret < 0) {
-		    free(buf);
-		    return -1;
-		}
-		free (buf);
-	    } else {
-		if (load_sample(m, f, cvt, &mod->xxs[i], NULL) < 0)
-		    return -1;
-	    }
 	}
-    }
 
-    D_(D_INFO "Stored Patterns: %d", mod->pat);
+	return 0;
+}
+
+static int load_it_pattern(struct module_data *m, int i, int new_fx,
+			   HIO_HANDLE *f)
+{
+	struct xmp_module *mod = &m->mod;
+	struct xmp_event *event, dummy, lastevent[L_CHANNELS];
+	uint8 mask[L_CHANNELS];
+	uint8 last_fxp[64];
 
-    /* Effects in muted channels are processed, so scan patterns first to
-     * see the real number of channels
-     */
-    max_ch = 0;
-    for (i = 0; i < mod->pat; i++) {
-	/* If the offset to a pattern is 0, the pattern is empty */
-	if (pp_pat[i] == 0)
-	    continue;
+	int r, c, pat_len;
+	uint8 b;
 
-	hio_seek(f, start + pp_pat[i], SEEK_SET);
-	pat_len = hio_read16l(f) /* - 4*/;
-	hio_read16l(f);
-	memset (mask, 0, L_CHANNELS);
+	r = 0;
+
+	memset(last_fxp, 0, 64);
+	memset(lastevent, 0, L_CHANNELS * sizeof(struct xmp_event));
+	memset(&dummy, 0, sizeof(struct xmp_event));
+
+	pat_len = hio_read16l(f) /* - 4 */ ;
+	mod->xxp[i]->rows = hio_read16l(f);
+
+	if (libxmp_alloc_tracks_in_pattern(mod, i) < 0)
+		return -1;
+
+	memset(mask, 0, L_CHANNELS);
 	hio_read16l(f);
 	hio_read16l(f);
 
 	while (--pat_len >= 0) {
-	    b = hio_read8(f);
-	    if (b == 0)
-		continue;
-
-	    c = (b - 1) & 63;
-
-	    if (c > max_ch)
-		max_ch = c;
-
-	    if (b & 0x80) {
-		mask[c] = hio_read8(f);
-		pat_len--;
-	    }
-
-	    if (mask[c] & 0x01) {
-		hio_read8(f);
-		pat_len--;
-	    }
-	    if (mask[c] & 0x02) {
-		hio_read8(f);
-		pat_len--;
-	    }
-	    if (mask[c] & 0x04) {
-		hio_read8(f);
-		pat_len--;
-	    }
-	    if (mask[c] & 0x08) {
-		hio_read8(f);
-		hio_read8(f);
-		pat_len -= 2;
-	    }
+		b = hio_read8(f);
+		if (!b) {
+			r++;
+			continue;
+		}
+		c = (b - 1) & 63;
+
+		if (b & 0x80) {
+			mask[c] = hio_read8(f);
+			pat_len--;
+		}
+		/*
+		 * WARNING: we IGNORE events in disabled channels. Disabled
+		 * channels should be muted only, but we don't know the
+		 * real number of channels before loading the patterns and
+		 * we don't want to set it to 64 channels.
+		 */
+		if (c >= mod->chn || r >= mod->xxp[i]->rows) {
+			event = &dummy;
+		} else {
+			event = &EVENT(i, c, r);
+		}
+
+		if (mask[c] & 0x01) {
+			b = hio_read8(f);
+
+			/* From ittech.txt:
+			 * Note ranges from 0->119 (C-0 -> B-9)
+			 * 255 = note off, 254 = notecut
+			 * Others = note fade (already programmed into IT's player
+			 *                     but not available in the editor)
+			 */
+			switch (b) {
+			case 0xff:	/* key off */
+				b = XMP_KEY_OFF;
+				break;
+			case 0xfe:	/* cut */
+				b = XMP_KEY_CUT;
+				break;
+			default:
+				if (b > 119) {	/* fade */
+					b = XMP_KEY_FADE;
+				} else {
+					b++;	/* note */
+				}
+			}
+			lastevent[c].note = event->note = b;
+			pat_len--;
+		}
+		if (mask[c] & 0x02) {
+			b = hio_read8(f);
+			lastevent[c].ins = event->ins = b;
+			pat_len--;
+		}
+		if (mask[c] & 0x04) {
+			b = hio_read8(f);
+			lastevent[c].vol = event->vol = b;
+			xlat_volfx(event);
+			pat_len--;
+		}
+		if (mask[c] & 0x08) {
+			b = hio_read8(f);
+			if (b > 26) {
+				return -1;
+			}
+			event->fxt = b;
+			event->fxp = hio_read8(f);
+			xlat_fx(c, event, last_fxp, new_fx);
+			lastevent[c].fxt = event->fxt;
+			lastevent[c].fxp = event->fxp;
+			pat_len -= 2;
+		}
+		if (mask[c] & 0x10) {
+			event->note = lastevent[c].note;
+		}
+		if (mask[c] & 0x20) {
+			event->ins = lastevent[c].ins;
+		}
+		if (mask[c] & 0x40) {
+			event->vol = lastevent[c].vol;
+			xlat_volfx(event);
+		}
+		if (mask[c] & 0x80) {
+			event->fxt = lastevent[c].fxt;
+			event->fxp = lastevent[c].fxp;
+		}
 	}
-    }
 
-    /* Set the number of channels actually used
-     */
-    mod->chn = max_ch + 1;
-    mod->trk = mod->pat * mod->chn;
+	return 0;
+}
 
-    memset(last_fxp, 0, 64);
+static int it_load(struct module_data *m, HIO_HANDLE *f, const int start)
+{
+	struct xmp_module *mod = &m->mod;
+	int c, i, j;
+	struct it_file_header ifh;
+	int max_ch;
+	uint32 *pp_ins;		/* Pointers to instruments */
+	uint32 *pp_smp;		/* Pointers to samples */
+	uint32 *pp_pat;		/* Pointers to patterns */
+	int new_fx, sample_mode;
+
+	LOAD_INIT();
+
+	/* Load and convert header */
+	ifh.magic = hio_read32b(f);
+	if (ifh.magic != MAGIC_IMPM) {
+		return -1;
+	}
 
-    if (pattern_init(mod) < 0)
-	goto err4;
+	hio_read(&ifh.name, 26, 1, f);
+	ifh.hilite_min = hio_read8(f);
+	ifh.hilite_maj = hio_read8(f);
+
+	ifh.ordnum = hio_read16l(f);
+	ifh.insnum = hio_read16l(f);
+	ifh.smpnum = hio_read16l(f);
+	ifh.patnum = hio_read16l(f);
+
+	ifh.cwt = hio_read16l(f);
+	ifh.cmwt = hio_read16l(f);
+	ifh.flags = hio_read16l(f);
+	ifh.special = hio_read16l(f);
+
+	ifh.gv = hio_read8(f);
+	ifh.mv = hio_read8(f);
+	ifh.is = hio_read8(f);
+	ifh.it = hio_read8(f);
+	ifh.sep = hio_read8(f);
+	ifh.pwd = hio_read8(f);
+
+	/* Sanity check */
+	if (ifh.gv > 0x80 || ifh.mv > 0x80) {
+		goto err;
+	}
 
-    /* Read patterns */
-    for (i = 0; i < mod->pat; i++) {
+	ifh.msglen = hio_read16l(f);
+	ifh.msgofs = hio_read32l(f);
+	ifh.rsvd = hio_read32l(f);
 
-	if (pattern_alloc(mod, i) < 0)
-	    goto err4;
+	hio_read(&ifh.chpan, 64, 1, f);
+	hio_read(&ifh.chvol, 64, 1, f);
 
-	r = 0;
+	strncpy(mod->name, (char *)ifh.name, XMP_NAME_SIZE);
+	mod->len = ifh.ordnum;
+	mod->ins = ifh.insnum;
+	mod->smp = ifh.smpnum;
+	mod->pat = ifh.patnum;
 
-	/* If the offset to a pattern is 0, the pattern is empty */
-	if (pp_pat[i] == 0) {
-	    mod->xxp[i]->rows = 64;
-	    for (j = 0; j < mod->chn; j++) {
-		int tnum = i * mod->chn + j;
-		if (track_alloc(mod, tnum, 64) < 0)
-		    goto err4;
-		mod->xxp[i]->index[j] = tnum;
-	    }
-	    continue;
+	/* Sanity check */
+	if (mod->ins > 255 || mod->smp > 255 || mod->pat > 255) {
+		goto err;
 	}
 
-	hio_seek(f, start + pp_pat[i], SEEK_SET);
-	pat_len = hio_read16l(f) /* - 4*/;
-	mod->xxp[i]->rows = hio_read16l(f);
+	if (mod->ins) {
+		pp_ins = calloc(4, mod->ins);
+		if (pp_ins == NULL)
+			goto err;
+	} else {
+		pp_ins = NULL;
+	}
 
-	if (tracks_in_pattern_alloc(mod, i) < 0)
-	    goto err4;
+	pp_smp = calloc(4, mod->smp);
+	if (pp_smp == NULL)
+		goto err2;
 
-	memset (mask, 0, L_CHANNELS);
-	hio_read16l(f);
-	hio_read16l(f);
+	pp_pat = calloc(4, mod->pat);
+	if (pp_pat == NULL)
+		goto err3;
 
-	while (--pat_len >= 0) {
-	    b = hio_read8(f);
-	    if (!b) {
-		r++;
-		continue;
-	    }
-	    c = (b - 1) & 63;
-
-	    if (b & 0x80) {
-		mask[c] = hio_read8(f);
-		pat_len--;
-	    }
-	    /*
-	     * WARNING: we IGNORE events in disabled channels. Disabled
-	     * channels should be muted only, but we don't know the
-	     * real number of channels before loading the patterns and
-	     * we don't want to set it to 64 channels.
-	     */
-	    event = c >= mod->chn || r >= mod->xxp[i]->rows ? &dummy : &EVENT (i, c, r);
-	    if (mask[c] & 0x01) {
-		b = hio_read8(f);
+	mod->spd = ifh.is;
+	mod->bpm = ifh.it;
+
+	sample_mode = ~ifh.flags & IT_USE_INST;
+
+	if (ifh.flags & IT_LINEAR_FREQ) {
+		m->period_type = PERIOD_LINEAR;
+	}
 
-		/* From ittech.txt:
-		 * Note ranges from 0->119 (C-0 -> B-9)
-		 * 255 = note off, 254 = notecut
-		 * Others = note fade (already programmed into IT's player
-		 *                     but not available in the editor)
+	if (!sample_mode && ifh.cmwt >= 0x200) {
+		m->quirk |= QUIRK_INSVOL;
+	}
+
+	for (i = 0; i < 64; i++) {
+		struct xmp_channel *xxc = &mod->xxc[i];
+
+		if (ifh.chpan[i] == 100) {	/* Surround -> center */
+			xxc->flg |= XMP_CHANNEL_SURROUND;
+		}
+
+		if (ifh.chpan[i] & 0x80) {	/* Channel mute */
+			ifh.chvol[i] = 0;
+			xxc->flg |= XMP_CHANNEL_MUTE;
+		}
+
+		if (ifh.flags & IT_STEREO) {
+			xxc->pan = (int)ifh.chpan[i] * 0x80 >> 5;
+			if (xxc->pan > 0xff)
+				xxc->pan = 0xff;
+		} else {
+			xxc->pan = 0x80;
+		}
+
+		xxc->vol = ifh.chvol[i];
+	}
+	if (mod->len <= XMP_MAX_MOD_LENGTH) {
+		hio_read(mod->xxo, 1, mod->len, f);
+	} else {
+		hio_read(mod->xxo, 1, XMP_MAX_MOD_LENGTH, f);
+		hio_seek(f, mod->len - XMP_MAX_MOD_LENGTH, SEEK_CUR);
+		mod->len = XMP_MAX_MOD_LENGTH;
+	}
+
+	new_fx = ifh.flags & IT_OLD_FX ? 0 : 1;
+
+	for (i = 0; i < mod->ins; i++)
+		pp_ins[i] = hio_read32l(f);
+	for (i = 0; i < mod->smp; i++)
+		pp_smp[i] = hio_read32l(f);
+	for (i = 0; i < mod->pat; i++)
+		pp_pat[i] = hio_read32l(f);
+
+	m->c4rate = C4_NTSC_RATE;
+
+	identify_tracker(m, &ifh);
+
+	MODULE_INFO();
+
+	D_(D_INFO "Instrument/FX mode: %s/%s",
+	   sample_mode ? "sample" : ifh.cmwt >= 0x200 ?
+	   "new" : "old", ifh.flags & IT_OLD_FX ? "old" : "IT");
+
+	if (sample_mode)
+		mod->ins = mod->smp;
+
+	if (libxmp_init_instrument(m) < 0)
+		goto err4;
+
+	/* Alloc extra samples for sustain loop */
+	if (mod->smp > 0) {
+		m->xsmp = calloc(sizeof (struct xmp_sample), mod->smp);
+		if (m->xsmp == NULL) {
+			goto err4;
+		}
+	}
+
+	D_(D_INFO "Instruments: %d", mod->ins);
+
+	for (i = 0; i < mod->ins; i++) {
+		/*
+		 * IT files can have three different instrument types: 'New'
+		 * instruments, 'old' instruments or just samples. We need a
+		 * different loader for each of them.
 		 */
-		switch (b) {
-		case 0xff:	/* key off */
-		    b = XMP_KEY_OFF;
-		    break;
-		case 0xfe:	/* cut */
-		    b = XMP_KEY_CUT;
-		    break;
-		default:
-		    if (b > 119)	/* fade */
-			b = XMP_KEY_FADE;
-		    else
-                        b++;	/* note */
+
+		struct xmp_instrument *xxi = &mod->xxi[i];
+
+		if (!sample_mode && ifh.cmwt >= 0x200) {
+			/* New instrument format */
+			if (hio_seek(f, start + pp_ins[i], SEEK_SET) < 0) {
+				goto err4;
+			}
+
+			if (load_new_it_instrument(xxi, f) < 0) {
+				goto err4;
+			}
+
+		} else if (!sample_mode) {
+			/* Old instrument format */
+			if (hio_seek(f, start + pp_ins[i], SEEK_SET) < 0) {
+				goto err4;
+			}
+
+			if (load_old_it_instrument(xxi, f) < 0) {
+				goto err4;
+			}
 		}
-		lastevent[c].note = event->note = b;
-		pat_len--;
-	    }
-	    if (mask[c] & 0x02) {
-		b = hio_read8(f);
-		lastevent[c].ins = event->ins = b;
-		pat_len--;
-	    }
-	    if (mask[c] & 0x04) {
-		b = hio_read8(f);
-		lastevent[c].vol = event->vol = b;
-		xlat_volfx(event);
-		pat_len--;
-	    }
-	    if (mask[c] & 0x08) {
-		b = hio_read8(f);
-		event->fxt = b;
-		event->fxp = hio_read8(f);
-		xlat_fx(c, event, last_fxp, new_fx);
-		lastevent[c].fxt = event->fxt;
-		lastevent[c].fxp = event->fxp;
-		pat_len -= 2;
-	    }
-	    if (mask[c] & 0x10) {
-		event->note = lastevent[c].note;
-	    }
-	    if (mask[c] & 0x20) {
-		event->ins = lastevent[c].ins;
-	    }
-	    if (mask[c] & 0x40) {
-		event->vol = lastevent[c].vol;
-		xlat_volfx(event);
-	    }
-	    if (mask[c] & 0x80) {
-		event->fxt = lastevent[c].fxt;
-		event->fxp = lastevent[c].fxp;
-	    }
 	}
-    }
 
-    free(pp_pat);
-    free(pp_smp);
-    free(pp_ins);
+	D_(D_INFO "Stored Samples: %d", mod->smp);
+
+	for (i = 0; i < mod->smp; i++) {
 
-    /* Song message */
+		if (hio_seek(f, start + pp_smp[i], SEEK_SET) < 0) {
+			goto err4;
+		}
 
-    if (ifh.special & IT_HAS_MSG) {
-	if ((m->comment = malloc(ifh.msglen + 1)) != NULL) {
-	    hio_seek(f, start + ifh.msgofs, SEEK_SET);
+		if (load_it_sample(m, i, start, sample_mode, f) < 0) {
+			goto err4;
+		}
+	}
 
-	    D_(D_INFO "Message length : %d", ifh.msglen);
+	D_(D_INFO "Stored Patterns: %d", mod->pat);
 
-	    for (j = 0; j < ifh.msglen; j++) {
-	        b = hio_read8(f);
-	        if (b == '\r') {
-		    b = '\n';
-	        } else if ((b < 32 || b > 127) && b != '\n' && b != '\t') {
-		    b = '.';
+	/* Effects in muted channels are processed, so scan patterns first to
+	 * see the real number of channels
+	 */
+	max_ch = 0;
+	for (i = 0; i < mod->pat; i++) {
+		uint8 mask[L_CHANNELS];
+		int pat_len;
+
+		/* If the offset to a pattern is 0, the pattern is empty */
+		if (pp_pat[i] == 0)
+			continue;
+
+		hio_seek(f, start + pp_pat[i], SEEK_SET);
+		pat_len = hio_read16l(f) /* - 4 */ ;
+		hio_read16l(f);
+		memset(mask, 0, L_CHANNELS);
+		hio_read16l(f);
+		hio_read16l(f);
+
+		while (--pat_len >= 0) {
+			int b = hio_read8(f);
+			if (b == 0)
+				continue;
+
+			c = (b - 1) & 63;
+
+			if (c > max_ch)
+				max_ch = c;
+
+			if (b & 0x80) {
+				mask[c] = hio_read8(f);
+				pat_len--;
+			}
+
+			if (mask[c] & 0x01) {
+				hio_read8(f);
+				pat_len--;
+			}
+			if (mask[c] & 0x02) {
+				hio_read8(f);
+				pat_len--;
+			}
+			if (mask[c] & 0x04) {
+				hio_read8(f);
+				pat_len--;
+			}
+			if (mask[c] & 0x08) {
+				hio_read8(f);
+				hio_read8(f);
+				pat_len -= 2;
+			}
 		}
-	        m->comment[j] = b;
-	    }
-	    m->comment[j] = 0;
 	}
-    }
 
-    /* Format quirks */
+	/* Set the number of channels actually used
+	 */
+	mod->chn = max_ch + 1;
+	mod->trk = mod->pat * mod->chn;
 
-    m->quirk |= QUIRKS_IT;
+	if (libxmp_init_pattern(mod) < 0)
+		goto err4;
 
-    if (ifh.flags & IT_LINK_GXX) {
-	m->quirk |= QUIRK_PRENV;
-    } else {
-	m->quirk |= QUIRK_UNISLD;
-    } 
+	/* Read patterns */
+	for (i = 0; i < mod->pat; i++) {
+
+		if (libxmp_alloc_pattern(mod, i) < 0)
+			goto err4;
+
+		/* If the offset to a pattern is 0, the pattern is empty */
+		if (pp_pat[i] == 0) {
+			mod->xxp[i]->rows = 64;
+			for (j = 0; j < mod->chn; j++) {
+				int tnum = i * mod->chn + j;
+				if (libxmp_alloc_track(mod, tnum, 64) < 0)
+					goto err4;
+				mod->xxp[i]->index[j] = tnum;
+			}
+			continue;
+		}
 
-    if (new_fx) {
-	m->quirk |= QUIRK_VIBHALF | QUIRK_VIBINV;
-    } else {
-	m->quirk &= ~QUIRK_VIBALL;
-    }
+		if (hio_seek(f, start + pp_pat[i], SEEK_SET) < 0) {
+			goto err4;
+		}
 
-    if (sample_mode) {
-	m->quirk &= ~QUIRK_VIRTUAL;
-    }
+		if (load_it_pattern(m, i, new_fx, f) < 0) {
+			goto err4;
+		}
+	}
 
-    m->gvolbase = 0x80;
-    m->read_event_type = READ_EVENT_IT;
+	free(pp_pat);
+	free(pp_smp);
+	free(pp_ins);
+
+	/* Song message */
+
+	if (ifh.special & IT_HAS_MSG) {
+		if ((m->comment = malloc(ifh.msglen + 1)) != NULL) {
+			hio_seek(f, start + ifh.msgofs, SEEK_SET);
+
+			D_(D_INFO "Message length : %d", ifh.msglen);
+
+			for (j = 0; j < ifh.msglen; j++) {
+				int b = hio_read8(f);
+				if (b == '\r') {
+					b = '\n';
+				} else if ((b < 32 || b > 127) && b != '\n'
+					   && b != '\t') {
+					b = '.';
+				}
+				m->comment[j] = b;
+			}
+			m->comment[j] = 0;
+		}
+	}
+
+	/* Format quirks */
+
+	m->quirk |= QUIRKS_IT | QUIRK_ARPMEM;
 
-    return 0;
+	if (ifh.flags & IT_LINK_GXX) {
+		m->quirk |= QUIRK_PRENV;
+	} else {
+		m->quirk |= QUIRK_UNISLD;
+	}
 
-  err4:
-    free(pp_pat);
-  err3:
-    free(pp_smp);
-  err2:
-    free(pp_ins);
-  err:
-    return -1;
+	if (new_fx) {
+		m->quirk |= QUIRK_VIBHALF | QUIRK_VIBINV;
+	} else {
+		m->quirk &= ~QUIRK_VIBALL;
+		m->quirk |= QUIRK_ITOLDFX;
+	}
+
+	if (sample_mode) {
+		m->quirk &= ~(QUIRK_VIRTUAL | QUIRK_RSTCHN);
+	}
+
+	m->gvolbase = 0x80;
+	m->gvol = ifh.gv;
+	m->read_event_type = READ_EVENT_IT;
+
+	return 0;
+
+err4:
+	free(pp_pat);
+err3:
+	free(pp_smp);
+err2:
+	free(pp_ins);
+err:
+	return -1;
 }
 
 #endif /* LIBXMP_CORE_DISABLE_IT */
diff --git a/src/loaders/liq_load.c b/src/loaders/liq_load.c
index 1818ab0..ae9a856 100644
--- a/src/loaders/liq_load.c
+++ b/src/loaders/liq_load.c
@@ -1,18 +1,31 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 /* Liquid Tracker module loader based on the format description written
  * by Nir Oren. Tested with Shell.liq sent by Adi Sapir.
  */
 
-#include 
-#include "period.h"
 #include "loader.h"
+#include "period.h"
 
 
 struct liq_header {
@@ -75,7 +88,7 @@ struct liq_pattern {
 static int liq_test (HIO_HANDLE *, char *, const int);
 static int liq_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader liq_loader = {
+const struct format_loader libxmp_loader_liq = {
     "Liquid Tracker",
     liq_test,
     liq_load
@@ -91,7 +104,7 @@ static int liq_test(HIO_HANDLE *f, char *t, const int start)
     if (memcmp(buf, "Liquid Module:", 14))
 	return -1;
 
-    read_title(f, t, 30);
+    libxmp_read_title(f, t, 30);
 
     return 0;
 }
@@ -125,7 +138,7 @@ static const uint8 fx[] = {
 	FX_VIBRATO,
 	NONE,
 	FX_TONE_VSLIDE,
-	FX_VIBRA_VSLIDE,
+	FX_VIBRA_VSLIDE
 };
 
 
@@ -177,7 +190,7 @@ static void xlat_fx(int c, struct xmp_event *e)
 }
 
 
-static void decode_event(uint8 x1, struct xmp_event *event, HIO_HANDLE *f)
+static int decode_event(uint8 x1, struct xmp_event *event, HIO_HANDLE *f)
 {
     uint8 x2;
 
@@ -206,10 +219,14 @@ static void decode_event(uint8 x1, struct xmp_event *event, HIO_HANDLE *f)
     D_(D_INFO "  event: %02x %02x %02x %02x %02x",
 	event->note, event->ins, event->vol, event->fxt, event->fxp);
 
-    assert (event->note <= 107 || event->note == XMP_KEY_OFF);
-    assert (event->ins <= 100);
-    assert (event->vol <= 64);
-    assert (event->fxt <= 26);
+    /* Sanity check */
+    if (event->note > 107 && event->note != XMP_KEY_OFF)
+	return -1;
+
+    if (event->ins > 100 || event->vol > 64 || event->fxt > 26)
+	return -1;
+
+    return 0;
 }
 
 static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
@@ -244,12 +261,21 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
     lh.len = hio_read16l(f);
     lh.hdrsz = hio_read16l(f);
 
+    /* Sanity check */
+    if (lh.chn > XMP_MAX_CHANNELS || lh.pat > 256 || lh.ins > 256) {
+	return -1;
+    }
+
     if ((lh.version >> 8) == 0) {
 	lh.hdrsz = lh.len;
 	lh.len = 0;
 	hio_seek(f, -2, SEEK_CUR);
     }
 
+    if (lh.len > 256) {
+	return -1;
+    }
+
     mod->spd = lh.speed;
     mod->bpm = lh.bpm;
     mod->chn = lh.chn;
@@ -274,8 +300,23 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		tracker_name, lh.version >> 8, lh.version & 0x00ff);
 
     if (lh.version > 0) {
-	for (i = 0; i < mod->chn; i++)
-	    mod->xxc[i].pan = hio_read8(f) << 2;
+	for (i = 0; i < mod->chn; i++) {
+	    uint8 pan = hio_read8(f);
+
+            if (pan >= 64) {
+	        if (pan == 64) {
+                    pan = 63;
+                } else if (pan == 66) {
+		    pan = 31;
+                    mod->xxc[i].flg |= XMP_CHANNEL_SURROUND;
+                } else {
+                    /* Sanity check */
+                    return -1;
+                }
+            }
+
+	    mod->xxc[i].pan = pan << 2;
+	}
 
 	for (i = 0; i < mod->chn; i++)
 	    mod->xxc[i].vol = hio_read8(f);
@@ -296,9 +337,11 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->len = i;
     }
 
+    m->c4rate = C4_NTSC_RATE;
+
     MODULE_INFO();
 
-    if (pattern_init(mod) < 0)
+    if (libxmp_init_pattern(mod) < 0)
 	return -1;
 
     /* Read and convert patterns */
@@ -309,7 +352,7 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
     for (i = 0; i < mod->pat; i++) {
 	int row, channel, count;
 
-	if (pattern_alloc(mod, i) < 0)
+	if (libxmp_alloc_pattern(mod, i) < 0)
 	    return -1;
 
 	pmag = hio_read32b(f);
@@ -323,14 +366,19 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	lp.size = hio_read32l(f);
 	lp.reserved = hio_read32l(f);
 
+	/* Sanity check */
+	if (lp.rows > 256) {
+	    return -1;
+	}
+
 	D_(D_INFO "rows: %d  size: %d\n", lp.rows, lp.size);
 
 	mod->xxp[i]->rows = lp.rows;
-	tracks_in_pattern_alloc(mod, i);
+	libxmp_alloc_tracks_in_pattern(mod, i);
 
 	row = 0;
 	channel = 0;
-	count = hio_tell (f);
+	count = hio_tell(f);
 
 /*
  * Packed pattern data is stored full Track after full Track from the left to
@@ -341,10 +389,15 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
  */
 
 read_event:
+	/* Sanity check */
+	if (i >= mod->pat || channel >= mod->chn || row >= mod->xxp[i]->rows)
+	    return -1;
+
 	event = &EVENT(i, channel, row);
 
 	if (x2) {
-	    decode_event (x1, event, f);
+	    if (decode_event(x1, event, f) < 0)
+		return -1;
 	    xlat_fx (channel, event); 
 	    x2--;
 	    goto next_row;	
@@ -353,6 +406,10 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	x1 = hio_read8(f);
 
 test_event:
+	/* Sanity check */
+	if (i >= mod->pat || channel >= mod->chn || row >= mod->xxp[i]->rows)
+		return -1;
+
 	event = &EVENT(i, channel, row);
 	D_(D_INFO "* count=%ld chan=%d row=%d event=%02x",
 				hio_tell(f) - count, channel, row, x1);
@@ -360,7 +417,8 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	switch (x1) {
 	case 0xc0:			/* end of pattern */
 	    D_(D_WARN "- end of pattern");
-	    assert (hio_tell (f) - count == lp.size);
+	    if (hio_tell(f) - count != lp.size)
+		return -1;
 	    goto next_pattern;
 	case 0xe1:			/* skip channels */
 	    x1 = hio_read8(f);
@@ -388,7 +446,8 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	if (x1 > 0xc0 && x1 < 0xe0) {	/* packed data */
 	    D_(D_INFO "  [packed data]");
-	    decode_event (x1, event, f);
+	    if (decode_event(x1, event, f) < 0)
+		return -1;
 	    xlat_fx (channel, event); 
 	    goto next_row;
 	}
@@ -396,7 +455,8 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	if (x1 > 0xa0 && x1 < 0xc0) {	/* packed data repeat */
 	    x2 = hio_read8(f);
 	    D_(D_INFO "  [packed data - repeat %d times]", x2);
-	    decode_event (x1, event, f);
+	    if (decode_event(x1, event, f) < 0)
+		return -1;
 	    xlat_fx (channel, event); 
 	    goto next_row;
 	}
@@ -404,10 +464,16 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	if (x1 > 0x80 && x1 < 0xa0) {	/* packed data repeat, keep note */
 	    x2 = hio_read8(f);
 	    D_(D_INFO "  [packed data - repeat %d times, keep note]", x2);
-	    decode_event (x1, event, f);
+	    if (decode_event(x1, event, f) < 0)
+		return -1;
 	    xlat_fx (channel, event); 
 	    while (x2) {
 	        row++;
+
+		/* Sanity check */
+		if (row >= lp.rows)
+		    return -1;
+
 		memcpy(&EVENT(i, channel, row), event, sizeof (struct xmp_event));
 		x2--;
 	    }
@@ -416,7 +482,7 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	/* unpacked data */
 	D_ (D_INFO "  [unpacked data]");
-	if (x1 != 0xff)
+	if (x1 < 0xfe)
 	    event->note = 1 + 36 + x1;
 	else if (x1 == 0xfe)
 	    event->note = XMP_KEY_OFF;
@@ -440,16 +506,22 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	x1 = hio_read8(f);
 	event->fxp = x1;
 
-	assert(event->fxt <= 26);
+	/* Sanity check */
+	if (event->fxt > 24) {
+		return -1;
+	}
 
 	xlat_fx(channel, event); 
 
 	D_(D_INFO "  event: %02x %02x %02x %02x %02x\n",
 	    event->note, event->ins, event->vol, event->fxt, event->fxp);
 
-	assert (event->note <= 119 || event->note == XMP_KEY_OFF);
-	assert (event->ins <= 100);
-	assert (event->vol <= 65);
+	/* Sanity check */
+	if (event->note > 119 && event->note != XMP_KEY_OFF)
+		return -1;
+
+	if (event->ins > 100 || event->vol > 65)
+		return -1;
 
 next_row:
 	row++;
@@ -457,11 +529,11 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	    row = 0;
 	    x2 = 0;
 	    channel++;
+	}
 
-	    /* FIXME */
-	    if (channel >= mod->chn) {
-		channel = 0;
-	    }
+	/* Sanity check */
+	if (channel >= mod->chn) {
+	    channel = 0;
 	}
 
 	goto read_event;
@@ -472,7 +544,7 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     /* Read and convert instruments */
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     D_(D_INFO "Instruments: %d", mod->ins);
@@ -483,7 +555,7 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	struct xmp_sample *xxs = &mod->xxs[i];
 	unsigned char b[4];
 
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 	    return -1;
 
 	sub = &xxi->sub[0];
@@ -492,8 +564,8 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	if (b[0] == '?' && b[1] == '?' && b[2] == '?' && b[3] == '?')
 	    continue;
-	assert (b[0] == 'L' && b[1] == 'D' && b[2] == 'S' && b[3] == 'S');
-	D_(D_WARN "INS %d: %c %c %c %c", i, b[0], b[1], b[2], b[3]);
+	if (b[0] != 'L' || b[1] != 'D' || b[2] != 'S' || b[3] != 'S')
+	    return -1;
 
 	li.version = hio_read16l(f);
 	hio_read(&li.name, 30, 1, f);
@@ -547,7 +619,7 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	sub->pan = li.pan;
 	sub->sid = i;
 
-	instrument_name(mod, i, li.name, 31);
+	libxmp_instrument_name(mod, i, li.name, 31);
 
 	D_(D_INFO "[%2X] %-30.30s %05x%c%05x %05x %c %02x %02x %2d.%02d %5d",
 		i, mod->xxi[i].name, mod->xxs[i].len,
@@ -555,13 +627,13 @@ static int liq_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', sub->vol, sub->gvl,
 		li.version >> 8, li.version & 0xff, li.c2spd);
 
-	c2spd_to_note(li.c2spd, &sub->xpo, &sub->fin);
+	libxmp_c2spd_to_note(li.c2spd, &sub->xpo, &sub->fin);
 	hio_seek(f, li.hdrsz - 0x90, SEEK_CUR);
 
 	if (xxs->len == 0)
 	    continue;
 
-	if (load_sample(m, f, 0, xxs, NULL) < 0)
+	if (libxmp_load_sample(m, f, 0, xxs, NULL) < 0)
 	    return -1;
     }
 
diff --git a/src/loaders/loader.h b/src/loaders/loader.h
index 07261f6..f0e3436 100644
--- a/src/loaders/loader.h
+++ b/src/loaders/loader.h
@@ -23,37 +23,38 @@
 #define SAMPLE_FLAG_HSC		0x2000	/* HSC Adlib synth instrument */
 #define SAMPLE_FLAG_ADPCM	0x4000	/* ADPCM4 encoded samples */
 
-int instrument_init(struct xmp_module *);
-int subinstrument_alloc(struct xmp_module *, int, int);
-int pattern_init(struct xmp_module *);
-int pattern_alloc(struct xmp_module *, int);
-int track_alloc(struct xmp_module *, int, int);
-int tracks_in_pattern_alloc(struct xmp_module *, int);
-int pattern_tracks_alloc(struct xmp_module *, int, int);
-char *instrument_name(struct xmp_module *, int, uint8 *, int);
-struct xmp_sample* realloc_samples(struct xmp_sample *, int *, int);
-
-char *copy_adjust(char *, uint8 *, int);
-int test_name(uint8 *, int);
-void read_title(HIO_HANDLE *, char *, int);
-void set_xxh_defaults(struct xmp_module *);
-void decode_protracker_event(struct xmp_event *, uint8 *);
-void decode_noisetracker_event(struct xmp_event *, uint8 *);
-void disable_continue_fx(struct xmp_event *);
-int check_filename_case(char *, char *, char *, int);
-void get_instrument_path(struct module_data *, char *, int);
-void set_type(struct module_data *, char *, ...);
-int load_sample(struct module_data *, HIO_HANDLE *, int, struct xmp_sample *, void *);
-
-extern uint8 ord_xlat[];
-extern const int arch_vol_table[];
+#define DEFPAN(x) (0x80 + ((x) - 0x80) * m->defpan / 100)
+
+int	libxmp_init_instrument		(struct module_data *);
+int	libxmp_alloc_subinstrument	(struct xmp_module *, int, int);
+int	libxmp_init_pattern		(struct xmp_module *);
+int	libxmp_alloc_pattern		(struct xmp_module *, int);
+int	libxmp_alloc_track		(struct xmp_module *, int, int);
+int	libxmp_alloc_tracks_in_pattern	(struct xmp_module *, int);
+int	libxmp_alloc_pattern_tracks	(struct xmp_module *, int, int);
+char	*libxmp_instrument_name		(struct xmp_module *, int, uint8 *, int);
+struct xmp_sample* libxmp_realloc_samples(struct xmp_sample *, int *, int);
+
+char	*libxmp_copy_adjust		(char *, uint8 *, int);
+int	libxmp_test_name		(uint8 *, int);
+void	libxmp_read_title		(HIO_HANDLE *, char *, int);
+void	libxmp_set_xxh_defaults		(struct xmp_module *);
+void	libxmp_decode_protracker_event	(struct xmp_event *, uint8 *);
+void	libxmp_decode_noisetracker_event(struct xmp_event *, uint8 *);
+void	libxmp_disable_continue_fx	(struct xmp_event *);
+int	libxmp_check_filename_case	(char *, char *, char *, int);
+void	libxmp_get_instrument_path	(struct module_data *, char *, int);
+void	libxmp_set_type			(struct module_data *, char *, ...);
+int	libxmp_load_sample		(struct module_data *, HIO_HANDLE *, int,
+					 struct xmp_sample *, void *);
+
+extern uint8		libxmp_ord_xlat[];
+extern const int	libxmp_arch_vol_table[];
 
 #define MAGIC4(a,b,c,d) \
     (((uint32)(a)<<24)|((uint32)(b)<<16)|((uint32)(c)<<8)|(d))
 
-#define LOAD_INIT() do { \
-    hio_seek(f, start, SEEK_SET); \
-} while (0)
+#define LOAD_INIT()
 
 #define MODULE_INFO() do { \
     D_(D_WARN "Module title: \"%s\"", m->mod.name); \
diff --git a/src/loaders/masi_load.c b/src/loaders/masi_load.c
index 26c0356..d968e27 100644
--- a/src/loaders/masi_load.c
+++ b/src/loaders/masi_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -57,14 +57,12 @@
 
 /*
  * Claudio's note: Sinaria seems to have a finetune byte just before
- * volume, slightly different sample size (subtract 2 bytes?) and some
- * kind of (stereo?) interleaved sample, with 16-byte frames (see Sinaria
- * songs 5 and 8). Sinaria song 10 sounds ugly, possibly caused by wrong
- * pitchbendings (see note above).
+ * volume and some kind of (stereo?) interleaved sample, with 16-byte
+ * frames (see Sinaria songs 5 and 8). Sinaria song 10 still sounds
+ * ugly, maybe caused by finetune issues?
  */
 
-/* FIXME: TODO: sinaria effects */
-
+#include 
 #include "loader.h"
 #include "iff.h"
 #include "period.h"
@@ -73,12 +71,13 @@
 #define MAGIC_FILE	MAGIC4('F','I','L','E')
 #define MAGIC_TITL	MAGIC4('T','I','T','L')
 #define MAGIC_OPLH	MAGIC4('O','P','L','H')
+#define MAGIC_PPAN	MAGIC4('P','P','A','N')
 
 
 static int masi_test (HIO_HANDLE *, char *, const int);
 static int masi_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader masi_loader = {
+const struct format_loader libxmp_loader_masi = {
 	"Epic MegaGames MASI",
 	masi_test,
 	masi_load
@@ -106,9 +105,9 @@ static int masi_test(HIO_HANDLE *f, char *t, const int start)
 
 	if (hio_read32b(f) == MAGIC_TITL) {
 		val = hio_read32l(f);
-		read_title(f, t, val);
+		libxmp_read_title(f, t, val);
 	} else {
-		read_title(f, t, 0);
+		libxmp_read_title(f, t, 0);
 	}
 
 	return 0;
@@ -170,15 +169,15 @@ static int get_dsmp(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	struct xmp_subinstrument *sub;
 	struct xmp_sample *xxs;
 	struct local_data *data = (struct local_data *)parm;
-	int i, srate;
+	int i, srate, flags;
 	int finetune;
 
-	hio_read8(f);					/* flags */
+	flags = hio_read8(f);				/* flags */
 	hio_seek(f, 8, SEEK_CUR);			/* songname */
 	hio_seek(f, data->sinaria ? 8 : 4, SEEK_CUR);	/* smpid */
 
 	i = data->cur_ins;
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 		return -1;
 
 	xxi = &mod->xxi[i];
@@ -186,14 +185,13 @@ static int get_dsmp(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	xxs = &mod->xxs[i];
 
 	hio_read(&xxi->name, 1, 31, f);
-	adjust_string((char *)xxi->name);
 	hio_seek(f, 8, SEEK_CUR);
 	hio_read8(f);		/* insno */
 	hio_read8(f);
 	xxs->len = hio_read32l(f);
 	xxs->lps = hio_read32l(f);
 	xxs->lpe = hio_read32l(f);
-	xxs->flg = xxs->lpe > 2 ? XMP_SAMPLE_LOOP : 0;
+	xxs->flg = flags & 0x80 ? XMP_SAMPLE_LOOP : 0;
 	hio_read16l(f);
 
 	if ((int32)xxs->lpe < 0)
@@ -204,11 +202,6 @@ static int get_dsmp(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 
 	finetune = 0;
 	if (data->sinaria) {
-		if (xxs->len > 2)
-			xxs->len -= 2;
-		if (xxs->lpe > 2)
-			xxs->lpe -= 2;
-
 		finetune = (int8)(hio_read8s(f) << 4);
 	}
 
@@ -216,19 +209,18 @@ static int get_dsmp(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	hio_read32l(f);
 	sub->pan = 0x80;
 	sub->sid = i;
-	srate = hio_read32l(f);
+	srate = hio_read16l(f);
 
 	D_(D_INFO "[%2X] %-32.32s %05x %05x %05x %c V%02x %+04d %5d", i,
 		xxi->name, xxs->len, xxs->lps, xxs->lpe,
 		xxs->flg & XMP_SAMPLE_LOOP ?  'L' : ' ',
 		sub->vol, finetune, srate);
 
-	srate = 8363 * srate / 8448;
-	c2spd_to_note(srate, &sub->xpo, &sub->fin);
+	libxmp_c2spd_to_note(srate, &sub->xpo, &sub->fin);
 	sub->fin += finetune;
 
 	hio_seek(f, 16, SEEK_CUR);
-	if (load_sample(m, f, SAMPLE_FLAG_8BDIFF, xxs, NULL) < 0)
+	if (libxmp_load_sample(m, f, SAMPLE_FLAG_8BDIFF, xxs, NULL) < 0)
 		return -1;
 
 	data->cur_ins++;
@@ -237,6 +229,19 @@ static int get_dsmp(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 }
 
 
+static uint8 convert_porta(uint8 param, int sinaria)
+{
+	if (sinaria) {
+		return param;
+	}
+
+	if (param < 4) {
+		return param | 0xf0;
+	} else {
+		return param >> 2;
+	}
+}
+
 static int get_pbod(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 {
 	struct xmp_module *mod = &m->mod;
@@ -253,14 +258,20 @@ static int get_pbod(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	hio_read(data->pnam + i * 8, 1, data->sinaria ? 8 : 4, f);
 
 	rows = hio_read16l(f);
+	if (hio_error(f)) {
+		return -1;
+	}
 
-	if (pattern_tracks_alloc(mod, i, rows) < 0)
+	if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
 		return -1;
 
 	r = 0;
 
 	do {
 		rowlen = hio_read16l(f) - 2;
+		if (hio_error(f)) {
+			return -1;
+		}
 		while (rowlen > 0) {
 			flag = hio_read8(f);
 	
@@ -276,9 +287,9 @@ static int get_pbod(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 				uint8 note = hio_read8(f);
 				rowlen--;
 				if (data->sinaria)
-					note += 37;
+					note += 36;
 				else
-					note = (note >> 4) * 12 + (note & 0x0f) + 2 + 12;
+					note = (note >> 4) * 12 + (note & 0x0f) + 1 + 12;
 				event->note = note;
 			}
 
@@ -288,7 +299,7 @@ static int get_pbod(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 			}
 	
 			if (flag & 0x20) {
-				event->vol = hio_read8(f) / 2;
+				event->vol = hio_read8(f) / 2 + 1;
 				rowlen--;
 			}
 	
@@ -296,23 +307,29 @@ static int get_pbod(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 				uint8 fxt = hio_read8(f);
 				uint8 fxp = hio_read8(f);
 				rowlen -= 2;
-	
+
+#if 0
 				/* compressed events */
 				if (fxt >= 0x40) {
 					switch (fxp >> 4) {
 					case 0x0: {
 						uint8 note;
 						note = (fxt>>4)*12 +
-							(fxt & 0x0f) + 2;
+							(fxt & 0x0f) + 1;
 						event->note = note;
 						fxt = FX_TONEPORTA;
 						fxp = (fxp + 1) * 2;
 						break; }
 					default:
 D_(D_CRIT "p%d r%d c%d: compressed event %02x %02x\n", i, r, chan, fxt, fxp);
+						return -1;
 					}
 				} else
+#endif
+
 				switch (fxt) {
+
+				/* Volume slide */
 				case 0x01:		/* fine volslide up */
 					fxt = FX_EXTENDED;
 					fxp = (EX_F_VSLIDE_UP << 4) |
@@ -331,43 +348,137 @@ D_(D_CRIT "p%d r%d c%d: compressed event %02x %02x\n", i, r, chan, fxt, fxp);
 					fxt = FX_VOLSLIDE;
 					fxp /= 2;
 					break;
-			    	case 0x0C:		/* portamento up */
+
+				/* Portamento */
+				case 0x0b:		/* fine portamento up */
 					fxt = FX_PORTA_UP;
-					fxp = (fxp - 1) / 2;
+					fxp = (EX_F_PORTA_UP << 4) |
+						convert_porta(fxp, data->sinaria);
 					break;
-				case 0x0E:		/* portamento down */
+			    	case 0x0c:		/* portamento up */
+					fxt = FX_PORTA_UP;
+					fxp = convert_porta(fxp, data->sinaria);
+					break;
+				case 0x0d:		/* fine portamento up */
+					fxt = FX_PORTA_DN;
+					fxp = (EX_F_PORTA_DN << 4) |
+						convert_porta(fxp, data->sinaria);
+					break;
+				case 0x0e:		/* portamento down */
 					fxt = FX_PORTA_DN;
-					fxp = (fxp - 1) / 2;
+					fxp = convert_porta(fxp, data->sinaria);
 					break;
 				case 0x0f:		/* tone portamento */
 					fxt = FX_TONEPORTA;
-					fxp /= 4;
+					fxp >>= 2;
+					break;
+				case 0x10:		/* toneporta + vslide up */
+					fxt = FX_TONE_VSLIDE;
+					fxp = fxt & 0xf0;
+					break;
+				case 0x11:		/* glissando */
+					fxt = FX_EXTENDED;
+					fxp = (EX_GLISS << 4) | (fxp & 0x0f);
+					break;
+				case 0x12:		/* toneporta + vslide down */
+					fxt = FX_TONE_VSLIDE;
+					fxp >>= 4;
 					break;
+
+				/* 0x13: S3M S: crashes MASI */
+
+				/* Vibrato */
 				case 0x15:		/* vibrato */
 					fxt = data->sinaria ?
 						FX_VIBRATO : FX_FINE_VIBRATO;
 					/* fxp remains the same */
 					break;
+				case 0x16:		/* vibrato waveform */
+					fxt = FX_EXTENDED;
+					fxp = (EX_VIBRATO_WF << 4) | (fxp & 0x0f); 
+					break;
+				case 0x17:		/* vibrato + vslide up */
+					fxt = FX_VIBRA_VSLIDE;
+					fxp >>= 4;
+					break;	
+				case 0x18:		/* vibrato + vslide down */
+					fxt = FX_VIBRA_VSLIDE;
+					fxp = fxp & 0x0f;
+					break;	
+
+				/* Tremolo */
+				case 0x1f:		/* tremolo */
+					fxt = FX_TREMOLO;
+					/* fxp remains the same */
+					break;
+				case 0x20:		/* tremolo waveform */
+					fxt = FX_EXTENDED;
+					fxp = (EX_TREMOLO_WF << 4) | (fxp & 0x0f); 
+					break;
+
+				/* Sample commands */
+				case 0x29:		/* 3-byte offset */
+					fxt = FX_OFFSET;
+					/* use only the middle byte */
+					fxp = hio_read8(f);
+					hio_read8(f);
+					rowlen -= 2;
+					break;
 				case 0x2a:		/* retrig note */
 					fxt = FX_EXTENDED;
 					fxp = (EX_RETRIG << 4) | (fxp & 0x0f); 
 					break;
-				case 0x29:		/* unknown */
-					hio_read16l(f);
-					rowlen -= 2;
+				case 0x2b:		/* note cut */
+					fxt = FX_EXTENDED;
+					fxp = (EX_CUT << 4) | (fxp & 0x0f); 
 					break;
-				case 0x33:		/* position Jump */
+				case 0x2c:		/* note delay */
+					fxt = FX_EXTENDED;
+					fxp = (EX_DELAY << 4) | (fxp & 0x0f); 
+					break;
+
+				/* Position change */
+				case 0x33:		/* position jump */
+					/* not used in MASI */
 					fxt = FX_JUMP;
+					fxp >>= 1;
+					hio_read8(f);
+					rowlen--;
 					break;
 			    	case 0x34:		/* pattern break */
+					/* not used in MASI */
 					fxt = FX_BREAK;
 					break;
-				case 0x3D:		/* speed */
+				case 0x35:		/* pattern loop */
+					fxt = FX_EXTENDED;
+					fxp = (EX_PATTERN_LOOP << 4) | (fxp & 0x0f); 
+					break;
+				case 0x36:		/* pattern delay */
+					fxt = FX_EXTENDED;
+					fxp = (EX_PATT_DELAY << 4) | (fxp & 0x0f); 
+					break;
+
+				/* Speed change */
+				case 0x3d:		/* speed */
 					fxt = FX_SPEED;
 					break;
-				case 0x3E:		/* tempo */
+				case 0x3e:		/* tempo */
 					fxt = FX_SPEED;
 					break;
+
+				/* Other */
+				case 0x47:		/* arpeggio */
+					fxt = FX_S3M_ARPEGGIO;
+					break;
+				case 0x48:		/* set finetune */
+					fxt = FX_EXTENDED;
+					fxp = (EX_FINETUNE << 4) | (fxp & 0x0f); 
+					break;
+				case 0x49:		/* set pan */
+					fxt = FX_SETPAN;
+					fxp <<= 4; 
+					break;
+
 				default:
 D_(D_CRIT "p%d r%d c%d: unknown effect %02x %02x\n", i, r, chan, fxt, fxp);
 					fxt = fxp = 0;
@@ -395,59 +506,202 @@ static int get_song(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	return 0;
 }
 
-static int get_song_2(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
+static int subchunk_oplh(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 {
 	struct xmp_module *mod = &m->mod;
 	struct local_data *data = (struct local_data *)parm;
-	uint32 magic;
-	char c, buf[20];
+	int first_order_chunk = INT_MAX;
+	int num_chunk, i;
+
+	/* First two bytes = Number of chunks that follow */
+	num_chunk = hio_read16l(f);
+
+	/* Sub sub chunks */
+	for (i = 0; i < num_chunk && size > 0; i++) {
+		int opcode = hio_read8(f);
+
+		size--;
+
+		if (opcode == 0) {	/* last sub sub chunk */
+			break;
+		}
+
+		/* Saga Musix's note in OpenMPT:
+		 *
+		 * "This is more like a playlist than a collection of global
+		 *  values. In theory, a tempo item inbetween two order items
+		 *  should modify the tempo when switching patterns. No module
+		 *  uses this feature in practice though, so we can keep our
+		 *  loader simple. Unimplemented opcodes do nothing or freeze
+		 *  MASI."
+		 */
+		switch (opcode) {
+		case 0x01:			/* Play order list item */
+			hio_read(data->pord + mod->len * 8, 1, data->sinaria ? 8 : 4, f);
+			size -= data->sinaria ? 8 : 4;
+			mod->len++;
+			if (first_order_chunk == INT_MAX) {
+				first_order_chunk = i;
+			}
+			break;
+
+		/* 0x02: Play range */
+		/* 0x03: Jump loop */
+
+		case 0x04: {			/* Jump line (restart position) */
+			int restart_chunk = hio_read16l(f);
+			size -= 2;
+
+			/* This jumps to the command line, but since we're converting
+			 * play order list items to our order list, only change the
+			 * restart position if it's after the first order chunk.
+			 */
+
+			if (restart_chunk >= first_order_chunk) {
+				mod->rst = restart_chunk - first_order_chunk;
+			}
+
+			break; }
+
+		/* 0x05: Channel flip */
+		/* 0x06: Transpose */
+
+		case 0x07:			/* Default speed */
+			mod->spd = hio_read8(f);
+			size--;
+			break;
+		case 0x08:			/* Default tempo */
+			mod->bpm = hio_read8(f);
+			size--;
+			break;
+		case 0x0c:			/* Sample map table */
+			hio_read16l(f);
+			hio_read16l(f);
+			hio_read16l(f);
+			size -= 6;
+			break;
+		case 0x0d: {			/* Channel panning table */
+			int chn = hio_read8(f);
+			int pan = hio_read8(f);
+			int type = hio_read8(f);
+			struct xmp_channel *xxc;
+
+			if (chn >= XMP_MAX_CHANNELS) {
+				break;
+			}
+
+			xxc = &mod->xxc[chn];
+
+			size -= 3;
+
+			switch (type) {
+			case 0:		/* use panning */
+				xxc->pan = pan ^ 0x80;
+				break;
+			case 2:		/* surround */
+				xxc->pan = 0x80;
+                        	xxc->flg |= XMP_CHANNEL_SURROUND;
+				break;
+			case 4:		/* center */
+				xxc->pan = 0x80;
+				break;
+			}
+			break; }
+		case 0x0e: {			/* Channel volume table */
+			int chn = hio_read8(f);
+			int vol = hio_read8(f);
+			struct xmp_channel *xxc;
+
+			if (chn >= XMP_MAX_CHANNELS) {
+				break;
+			}
+
+			xxc = &mod->xxc[chn];
+
+			size -= 2;
+
+			xxc->vol = (vol >> 2) + 1;
+			break; }
+		default:
+			/*printf("channel %d: %02x %02x\n", i, c, hio_read8(f));*/
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/* Sinaria channel panning table */
+static int subchunk_ppan(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
+{
+	struct xmp_module *mod = &m->mod;
 	int i;
 
+	for (i = 0; i < XMP_MAX_CHANNELS && size > 0; i++) {
+		struct xmp_channel *xxc = &mod->xxc[i];
+		int type = hio_read8(f);
+		int pan = hio_read8(f);
+
+		size -= 2;
+
+		switch (type) {
+		case 0:		/* use panning */
+			xxc->pan = pan ^ 0x80;
+			break;
+		case 2:		/* surround */
+			xxc->pan = 0x80;
+                       	xxc->flg |= XMP_CHANNEL_SURROUND;
+			break;
+		case 4:		/* center */
+			xxc->pan = 0x80;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/* Subchunk loader based on OpenMPT LoadPSM.cpp */
+static int get_song_2(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
+{
+	uint32 magic;
+	char buf[20];
+
 	hio_read(buf, 1, 9, f);
 	hio_read16l(f);
+	size -= 11;
 
 	D_(D_INFO "Subsong title: %-9.9s", buf);
 
-	magic = hio_read32b(f);
-	while (magic != MAGIC_OPLH) {
-		int skip;
-		skip = hio_read32l(f);;
-		hio_seek(f, skip, SEEK_CUR);
+	/* Iterate over subchunks. We want OPLH and PPAN */
+	while (size > 0) {
 		magic = hio_read32b(f);
-	}
+		int subchunk_size = hio_read32l(f);
 
-	hio_read32l(f);	/* chunk size */
+		if (subchunk_size == 0) {
+			return -1;
+		}
 
-	hio_seek(f, 9, SEEK_CUR);		/* unknown data */
-	
-	c = hio_read8(f);
-	for (i = 0; c != 0x01; c = hio_read8(f)) {
-		switch (c) {
-		case 0x07:
-			mod->spd = hio_read8(f);
-			hio_read8(f);		/* 08 */
-			mod->bpm = hio_read8(f);
-			break;
-		case 0x0d:
-			hio_read8(f);		/* channel number? */
-			mod->xxc[i].pan = hio_read8(f);
-			hio_read8(f);		/* flags? */
-			i++;
+		size -= subchunk_size;
+
+		switch (magic) {
+		case MAGIC_OPLH:
+			if (subchunk_oplh(m, size, f, parm) < 0) {
+				return -1;
+			}
 			break;
-		case 0x0e:
-			hio_read8(f);		/* channel number? */
-			hio_read8(f);		/* ? */
+
+		case MAGIC_PPAN:
+			if (subchunk_ppan(m, size, f, parm) < 0) {
+				return -1;
+			}
 			break;
+
 		default:
-			printf("channel %d: %02x %02x\n", i, c, hio_read8(f));
+			hio_seek(f, subchunk_size, SEEK_CUR);
 		}
 	}
 
-	for (; c == 0x01; c = hio_read8(f)) {
-		hio_read(data->pord + mod->len * 8, 1, data->sinaria ? 8 : 4, f);
-		mod->len++;
-	}
-
 	return 0;
 }
 
@@ -472,29 +726,29 @@ static int masi_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	data.cur_ins = 0;
 	offset = hio_tell(f);
 
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		goto err;
 
 	/* IFF chunk IDs */
-	ret = iff_register(handle, "TITL", get_titl);
-	ret |= iff_register(handle, "SDFT", get_sdft);
-	ret |= iff_register(handle, "SONG", get_song);
-	ret |= iff_register(handle, "DSMP", get_dsmp_cnt);
-	ret |= iff_register(handle, "PBOD", get_pbod_cnt);
+	ret = libxmp_iff_register(handle, "TITL", get_titl);
+	ret |= libxmp_iff_register(handle, "SDFT", get_sdft);
+	ret |= libxmp_iff_register(handle, "SONG", get_song);
+	ret |= libxmp_iff_register(handle, "DSMP", get_dsmp_cnt);
+	ret |= libxmp_iff_register(handle, "PBOD", get_pbod_cnt);
 
 	if (ret != 0)
 		goto err;
 
-	iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
+	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
 
 	/* Load IFF chunks */
-	if (iff_load(handle, m, f, &data) < 0) {
-		iff_release(handle);
+	if (libxmp_iff_load(handle, m, f, &data) < 0) {
+		libxmp_iff_release(handle);
 		goto err;
 	}
 
-	iff_release(handle);
+	libxmp_iff_release(handle);
 
 	mod->trk = mod->pat * mod->chn;
 	data.pnam = malloc(mod->pat * 8);	/* pattern names */
@@ -505,15 +759,17 @@ static int masi_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	if (data.pord == NULL)
 		goto err2;
 
-	set_type(m, data.sinaria ?
+	libxmp_set_type(m, data.sinaria ?
 		"Sinaria PSM" : "Epic MegaGames MASI PSM");
 
+	m->c4rate = C4_NTSC_RATE;
+
 	MODULE_INFO();
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		goto err3;
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		goto err3;
 
 	D_(D_INFO "Stored patterns: %d", mod->pat);
@@ -523,27 +779,27 @@ static int masi_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	mod->len = 0;
 
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		goto err3;
 
 	/* IFF chunk IDs */
-	ret = iff_register(handle, "SONG", get_song_2);
-	ret |= iff_register(handle, "DSMP", get_dsmp);
-	ret |= iff_register(handle, "PBOD", get_pbod);
+	ret = libxmp_iff_register(handle, "SONG", get_song_2);
+	ret |= libxmp_iff_register(handle, "DSMP", get_dsmp);
+	ret |= libxmp_iff_register(handle, "PBOD", get_pbod);
 
 	if (ret != 0)
 		goto err3;
 
-	iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
+	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
 
 	/* Load IFF chunks */
-	if (iff_load(handle, m, f, &data) < 0) {
-		iff_release(handle);
+	if (libxmp_iff_load(handle, m, f, &data) < 0) {
+		libxmp_iff_release(handle);
 		goto err3;
 	}
 
-	iff_release(handle);
+	libxmp_iff_release(handle);
 
 	for (i = 0; i < mod->len; i++) {
 		for (j = 0; j < mod->pat; j++) {
diff --git a/src/loaders/mdl_load.c b/src/loaders/mdl_load.c
index 88bfb83..0011145 100644
--- a/src/loaders/mdl_load.c
+++ b/src/loaders/mdl_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -34,7 +34,7 @@
 static int mdl_test (HIO_HANDLE *, char *, const int);
 static int mdl_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader mdl_loader = {
+const struct format_loader libxmp_loader_mdl = {
     "Digitrakker",
     mdl_test,
     mdl_load
@@ -52,9 +52,9 @@ static int mdl_test(HIO_HANDLE *f, char *t, const int start)
 
     if (id == 0x494e) {		/* IN */
 	hio_read32b(f);
-	read_title(f, t, 32);
+	libxmp_read_title(f, t, 32);
     } else {
-	read_title(f, t, 0);
+	libxmp_read_title(f, t, 0);
     }
 
     return 0;
@@ -82,7 +82,6 @@ struct local_data {
     int *v_index;	/* volume envelope */
     int *p_index;	/* pan envelope */
     int *f_index;	/* pitch envelope */
-    int *c2spd;
     int *packinfo;
     int v_envnum;
     int p_envnum;
@@ -100,7 +99,7 @@ static void fix_env(int i, struct xmp_envelope *ei, struct mdl_envelope *env,
 
     if (index[i] >= 0) {
 	ei->flg = XMP_ENVELOPE_ON;
-	ei->npt = 16;
+	ei->npt = 15;
 
 	for (j = 0; j < envnum; j++) {
     	    if (index[i] == env[j].num) {
@@ -233,16 +232,16 @@ static unsigned int get_bits(char i, uint8 **buf, int *len, struct bits *bits)
 	bits->b = readmem32l(*buf);
 	*buf += 4; *len -= 4;
 	bits->n = 32;
-	return 0;
     }
 
     x = bits->b & ((1 << i) - 1);	/* get i bits */
     bits->b >>= i;
     if ((bits->n -= i) <= 24) {
-	if (*len == 0)		/* FIXME: last few bits can't be consumed */
+	if (*len <= 0)		/* FIXME: last few bits can't be consumed */
 		return x;
 	bits->b |= readmem32l((*buf)++) << bits->n;
-	bits->n += 8; (*len)--;
+	bits->n += 8;
+	(*len)--;
     }
 
     return x;
@@ -271,31 +270,43 @@ static unsigned int get_bits(char i, uint8 **buf, int *len, struct bits *bits)
  *	xxx1s => byte = ; if s=1 then byte = byte xor 255
  */
 
-static void unpack_sample8(uint8 *t, uint8 *f, int len, int l)
+static int unpack_sample8(uint8 *t, uint8 *f, int len, int l)
 {
     int i, s;
     uint8 b, d;
     struct bits bits;
 
+    D_(D_INFO "unpack sample 8bit, len=%d", len);
     get_bits(0, &f, &len, &bits);
 
     for (i = b = d = 0; i < l; i++) {
+
+	/* Sanity check */
+        if (len < 0)
+            return -1;
+
 	s = get_bits(1, &f, &len, &bits);
 	if (get_bits(1, &f, &len, &bits)) {
 	    b = get_bits(3, &f, &len, &bits);
 	} else {
             b = 8;
-	    while (len >= 0 && !get_bits(1, &f, &len, &bits))
+	    while (len >= 0 && get_bits(1, &f, &len, &bits) == 0) {
+		/* Sanity check */
+                if (b >= 240) { return -1; }
 		b += 16;
+            }
 	    b += get_bits(4, &f, &len, &bits);
 	}
 
-	if (s)
+	if (s) {
 	    b ^= 0xff;
+	}
 
 	d += b;
 	*t++ = d;
     }
+
+    return 0;
 }
 
 /*
@@ -310,23 +321,31 @@ static void unpack_sample8(uint8 *t, uint8 *f, int len, int l)
  * Go on this way for the whole sample!
  */
 
-static void unpack_sample16(uint8 *t, uint8 *f, int len, int l)
+static int unpack_sample16(uint8 *t, uint8 *f, int len, int l)
 {
     int i, lo, s;
     uint8 b, d;
     struct bits bits;
 
+    D_(D_INFO "unpack sample 16bit, len=%d", len);
     get_bits(0, &f, &len, &bits);
 
     for (i = lo = b = d = 0; i < l; i++) {
+	/* Sanity check */
+        if (len < 0)
+            return -1;
+
 	lo = get_bits(8, &f, &len, &bits);
 	s = get_bits(1, &f, &len, &bits);
 	if (get_bits(1, &f, &len, &bits)) {
 	    b = get_bits(3, &f, &len, &bits);
 	} else {
             b = 8;
-	    while (len >= 0 && !get_bits (1, &f, &len, &bits))
+	    while (len >= 0 && get_bits(1, &f, &len, &bits) == 0) {
+		/* Sanity check */
+                if (b >= 240) { return -1; }
 		b += 16;
+            }
 	    b += get_bits(4, &f, &len, &bits);
 	}
 
@@ -337,6 +356,8 @@ static void unpack_sample16(uint8 *t, uint8 *f, int len, int l)
 	*t++ = lo;
 	*t++ = d;
     }
+
+    return 0;
 }
 
 
@@ -358,6 +379,11 @@ static int get_chunk_in(struct module_data *m, int size, HIO_HANDLE *f, void *pa
     mod->spd = hio_read8(f);
     mod->bpm = hio_read8(f);
 
+    /* Sanity check */
+    if (mod->len > 256 || mod->rst > 255) {
+	return -1;
+    }
+
     for (i = 0; i < 32; i++) {
 	uint8 chinfo = hio_read8(f);
 	if (chinfo & 0x80)
@@ -380,6 +406,10 @@ static int get_chunk_pa(struct module_data *m, int size, HIO_HANDLE *f, void *pa
     int i, j, chn;
     int x;
 
+    /* Sanity check */
+    if (mod->pat != 0)
+        return -1;
+
     mod->pat = hio_read8(f);
 
     if ((mod->xxp = calloc(sizeof (struct xmp_pattern *), mod->pat)) == NULL)
@@ -388,7 +418,7 @@ static int get_chunk_pa(struct module_data *m, int size, HIO_HANDLE *f, void *pa
     D_(D_INFO "Stored patterns: %d", mod->pat);
 
     for (i = 0; i < mod->pat; i++) {
-	if (pattern_alloc(mod, i) < 0)
+	if (libxmp_alloc_pattern(mod, i) < 0)
 	    return -1;
 
 	chn = hio_read8(f);
@@ -397,6 +427,7 @@ static int get_chunk_pa(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 	hio_seek(f, 16, SEEK_CUR);		/* Skip pattern name */
 	for (j = 0; j < chn; j++) {
 	    x = hio_read16l(f);
+
 	    if (j < mod->chn)
 		mod->xxp[i]->index[j] = x;
 	}
@@ -409,7 +440,11 @@ static int get_chunk_p0(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 {
     struct xmp_module *mod = &m->mod;
     int i, j;
-    uint16 x16;
+    uint16 x;
+
+    /* Sanity check */
+    if (mod->pat != 0)
+        return -1;
 
     mod->pat = hio_read8(f);
 
@@ -419,14 +454,15 @@ static int get_chunk_p0(struct module_data *m, int size, HIO_HANDLE *f, void *pa
     D_(D_INFO "Stored patterns: %d", mod->pat);
 
     for (i = 0; i < mod->pat; i++) {
-	if (pattern_alloc(mod, i) < 0)
+	if (libxmp_alloc_pattern(mod, i) < 0)
 	    return -1;
 	mod->xxp[i]->rows = 64;
 
 	for (j = 0; j < 32; j++) {
-	    x16 = hio_read16l(f);
+	    x = hio_read16l(f);
+
 	    if (j < mod->chn)
-		mod->xxp[i]->index[j] = x16;
+		mod->xxp[i]->index[j] = x;
 	}
     }
 
@@ -436,10 +472,23 @@ static int get_chunk_p0(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 static int get_chunk_tr(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 {
     struct xmp_module *mod = &m->mod;
-    int i, j, k, row, len;
+    int i, j, k, row, len, max_trk;
     struct xmp_track *track;
 
     mod->trk = hio_read16l(f) + 1;
+
+    /* Sanity check */
+    max_trk = 0;
+    for (i = 0; i < mod->pat; i++) {
+	for (j = 0; j < mod->chn; j++) {
+	    if (max_trk < mod->xxp[i]->index[j])
+		max_trk = mod->xxp[i]->index[j];
+	}
+    }
+    if (max_trk >= mod->trk) {
+	return -1;
+    }
+
     if ((mod->xxt = calloc(sizeof (struct xmp_track *), mod->trk)) == NULL)
 	return -1;
 
@@ -451,7 +500,7 @@ static int get_chunk_tr(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 	goto err;
 
     /* Empty track 0 is not stored in the file */
-    if (track_alloc(mod, 0, 256) < 0)
+    if (libxmp_alloc_track(mod, 0, 256) < 0)
 	goto err2;
 
     for (i = 1; i < mod->trk; i++) {
@@ -462,24 +511,37 @@ static int get_chunk_tr(struct module_data *m, int size, HIO_HANDLE *f, void *pa
             			sizeof (struct xmp_event) * 255);
 
 	for (row = 0; len;) {
-	    struct xmp_event *ev = &track->event[row];
+	    struct xmp_event *ev;
+
+	    /* Sanity check */
+	    if (row > 255) {
+		goto err2;
+	    }
+
+            ev = &track->event[row];
 
 	    j = hio_read8(f);
+
 	    len--;
 	    switch (j & 0x03) {
 	    case 0:
 		row += j >> 2;
-	        /* ev = &track->event[row]; */
 		break;
 	    case 1:
+		/* Sanity check */
+		if (row + (j >> 2) > 255)
+		    goto err2;
+
 		for (k = 0; k <= (j >> 2); k++)
-		    memcpy (&ev[k], &ev[-1], sizeof (struct xmp_event));
+		    memcpy(&ev[k], &ev[-1], sizeof (struct xmp_event));
 		row += k - 1;
-	        /* ev = &track->event[row]; */
 		break;
 	    case 2:
-		memcpy (ev, &track->event[j >> 2],
-		    sizeof (struct xmp_event));
+		/* Sanity check */
+		if ((j >> 2) == row) {
+		    goto err2;
+		}
+		memcpy(ev, &track->event[j >> 2], sizeof (struct xmp_event));
 		break;
 	    case 3:
 		if (j & MDL_NOTE_FOLLOWS) {
@@ -512,7 +574,7 @@ static int get_chunk_tr(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 	    row = 128;
 	else row = 256;
 
-	if (track_alloc(mod, i, row) < 0)
+	if (libxmp_alloc_track(mod, i, row) < 0)
 	    goto err2;
 
 	memcpy(mod->xxt[i], track, sizeof (struct xmp_track) +
@@ -549,7 +611,7 @@ static int get_chunk_ii(struct module_data *m, int size, HIO_HANDLE *f, void *pa
     mod->ins = hio_read8(f);
     D_(D_INFO "Instruments: %d", mod->ins);
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     for (i = 0; i < mod->ins; i++) {
@@ -559,12 +621,11 @@ static int get_chunk_ii(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 	xxi->nsm = hio_read8(f);
 	hio_read(buf, 1, 32, f);
 	buf[32] = 0;
-	adjust_string(buf);
-	strncpy((char *)xxi->name, buf, 32);
+	strncpy(xxi->name, buf, 31);
 
 	D_(D_INFO "[%2X] %-32.32s %2d", data->i_index[i], xxi->name, xxi->nsm);
 
-	if (subinstrument_alloc(mod, i, xxi->nsm) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, xxi->nsm) < 0)
 	    return -1;
 
 	for (j = 0; j < XMP_MAX_KEYS; j++)
@@ -602,7 +663,7 @@ static int get_chunk_ii(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 		xxi->rls = x;
 
 	    sub->vra = hio_read8(f);	/* vibrato rate */
-	    sub->vde = hio_read8(f) >> 1;	/* vibrato depth */
+	    sub->vde = hio_read8(f) << 1;	/* vibrato depth */
 	    sub->vsw = hio_read8(f);	/* vibrato sweep */
 	    sub->vwf = hio_read8(f);	/* vibrato waveform */
 	    hio_read8(f);		/* Reserved */
@@ -631,6 +692,8 @@ static int get_chunk_is(struct module_data *m, int size, HIO_HANDLE *f, void *pa
     mod->smp = hio_read8(f);
     if ((mod->xxs = calloc(sizeof (struct xmp_sample), mod->smp)) == NULL)
 	return -1;
+    if ((m->xtra = calloc(sizeof (struct extra_sample_data), mod->smp)) == NULL)
+        return -1;
 
     data->packinfo = calloc(sizeof (int), mod->smp);
     if (data->packinfo == NULL)
@@ -640,16 +703,16 @@ static int get_chunk_is(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 
     for (i = 0; i < mod->smp; i++) {
 	struct xmp_sample *xxs = &mod->xxs[i];
+	int c5spd;
 
 	data->s_index[i] = hio_read8(f);	/* Sample number */
 	hio_read(buf, 1, 32, f);
 	buf[32] = 0;
-	adjust_string(buf);
-	strncpy(xxs->name, buf, 32);
+	strncpy(xxs->name, buf, 31);
 
 	hio_seek(f, 8, SEEK_CUR);		/* Sample filename */
 
-	data->c2spd[i] = hio_read32l(f);
+	c5spd = hio_read32l(f);
 
 	xxs->len = hio_read32l(f);
 	xxs->lps = hio_read32l(f);
@@ -658,6 +721,8 @@ static int get_chunk_is(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 	xxs->flg = xxs->lpe > 0 ? XMP_SAMPLE_LOOP : 0;
 	xxs->lpe = xxs->lps + xxs->lpe;
 
+        m->xtra[i].c5spd = (double)c5spd;
+
 	hio_read8(f);				/* Volume in DMDL 0.0 */
 	x = hio_read8(f);
 	if (x & 0x01) {
@@ -674,7 +739,7 @@ static int get_chunk_is(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 			xxs->flg & XMP_SAMPLE_16BIT ? '+' : ' ',
 			xxs->lps, xxs->lpe,
 			xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
-			data->c2spd[i], data->packinfo[i]);
+			c5spd, data->packinfo[i]);
     }
 
     return 0;
@@ -692,7 +757,7 @@ static int get_chunk_i0(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 
     D_(D_INFO "Instruments: %d", mod->ins);
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     if ((data->packinfo = calloc(sizeof (int), mod->smp)) == NULL)
@@ -701,9 +766,10 @@ static int get_chunk_i0(struct module_data *m, int size, HIO_HANDLE *f, void *pa
     for (i = 0; i < mod->ins; i++) {
 	struct xmp_subinstrument *sub;
 	struct xmp_sample *xxs = &mod->xxs[i];
+	int c5spd;
 
 	mod->xxi[i].nsm = 1;
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 	    return -1;
 
 	sub = &mod->xxi[i].sub[0];
@@ -711,11 +777,10 @@ static int get_chunk_i0(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 
 	hio_read(buf, 1, 32, f);
 	buf[32] = 0;
-	adjust_string(buf);			/* Sample name */
 	hio_seek(f, 8, SEEK_CUR);	/* Sample filename */
-	strncpy(mod->xxi[i].name, buf, 32);
+	strncpy(mod->xxi[i].name, buf, 31);
 
-	data->c2spd[i] = hio_read16l(f);
+	c5spd = hio_read16l(f);
 
 	xxs->len = hio_read32l(f);
 	xxs->lps = hio_read32l(f);
@@ -726,6 +791,8 @@ static int get_chunk_i0(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 	sub->vol = hio_read8(f);	/* Volume */
 	sub->pan = 0x80;
 
+        m->xtra[i].c5spd = (double)c5spd;
+
 	x = hio_read8(f);
 	if (x & 0x01) {
 	    xxs->flg |= XMP_SAMPLE_16BIT;
@@ -737,7 +804,7 @@ static int get_chunk_i0(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 	data->packinfo[i] = (x & 0x0c) >> 2;
 
 	D_(D_INFO "[%2X] %-32.32s %5d V%02x %05x%c %05x %05x %d",
-		data->i_index[i], buf, data->c2spd[i], sub->vol,
+		data->i_index[i], buf, c5spd, sub->vol,
 		xxs->len, xxs->flg & XMP_SAMPLE_16BIT ? '+' : ' ',
 		xxs->lps, xxs->lpe, data->packinfo[i]);
     }
@@ -770,30 +837,48 @@ static int get_chunk_sa(struct module_data *m, int size, HIO_HANDLE *f, void *pa
 	    break;
 	case 1: 
 	    len = hio_read32l(f);
+            /* Sanity check */
+            if (xxs->flg & XMP_SAMPLE_16BIT)
+                goto err2;
+            if (len <= 0 || len > 0x80000)  /* Max compressed sample size */
+                goto err2;
 	    if ((buf = malloc(len + 4)) == NULL)
 		goto err2;
-	    hio_read(buf, 1, len, f);
-	    unpack_sample8(smpbuf, buf, len, xxs->len);
+	    if (hio_read(buf, 1, len, f) != len)
+                goto err3;
+            if (unpack_sample8(smpbuf, buf, len, xxs->len) < 0)
+                goto err3;
 	    free(buf);
 	    break;
 	case 2:
 	    len = hio_read32l(f);
+            /* Sanity check */
+            if (~xxs->flg & XMP_SAMPLE_16BIT)
+                goto err2;
+            if (len <= 0 || len > MAX_SAMPLE_SIZE)
+                goto err2;
 	    if ((buf = malloc(len + 4)) == NULL)
 		goto err2;
-	    hio_read(buf, 1, len, f);
-	    unpack_sample16(smpbuf, buf, len, xxs->len);
+	    if (hio_read(buf, 1, len, f) != len)
+                goto err3;
+            if (unpack_sample16(smpbuf, buf, len, xxs->len) < 0)
+                goto err3;
 	    free(buf);
 	    break;
+	default:
+	    /* Sanity check */
+            goto err2;
 	}
 	
-	if (load_sample(m, NULL, SAMPLE_FLAG_NOLOAD, xxs, (char *)smpbuf) < 0)
+	if (libxmp_load_sample(m, NULL, SAMPLE_FLAG_NOLOAD, xxs, (char *)smpbuf) < 0)
 	    goto err2;
 
 	free(smpbuf);
     }
 
     return 0;
-
+  err3:
+    free(buf);
   err2:
     free(smpbuf);
   err:
@@ -884,35 +969,35 @@ static int mdl_load(struct module_data *m, HIO_HANDLE *f, const int start)
     hio_read32b(f);
     hio_read(buf, 1, 1, f);
 
-    handle = iff_new();
+    handle = libxmp_iff_new();
     if (handle == NULL)
 	return -1;
 
     /* IFFoid chunk IDs */
-    iff_register(handle, "IN", get_chunk_in);	/* Module info */
-    iff_register(handle, "TR", get_chunk_tr);	/* Tracks */
-    iff_register(handle, "SA", get_chunk_sa);	/* Sampled data */
-    iff_register(handle, "VE", get_chunk_ve);	/* Volume envelopes */
-    iff_register(handle, "PE", get_chunk_pe);	/* Pan envelopes */
-    iff_register(handle, "FE", get_chunk_fe);	/* Pitch envelopes */
+    libxmp_iff_register(handle, "IN", get_chunk_in);	/* Module info */
+    libxmp_iff_register(handle, "TR", get_chunk_tr);	/* Tracks */
+    libxmp_iff_register(handle, "SA", get_chunk_sa);	/* Sampled data */
+    libxmp_iff_register(handle, "VE", get_chunk_ve);	/* Volume envelopes */
+    libxmp_iff_register(handle, "PE", get_chunk_pe);	/* Pan envelopes */
+    libxmp_iff_register(handle, "FE", get_chunk_fe);	/* Pitch envelopes */
 
     if (MSN(*buf)) {
-	iff_register(handle, "II", get_chunk_ii);	/* Instruments */
-	iff_register(handle, "PA", get_chunk_pa);	/* Patterns */
-	iff_register(handle, "IS", get_chunk_is);	/* Sample info */
+	libxmp_iff_register(handle, "II", get_chunk_ii);	/* Instruments */
+	libxmp_iff_register(handle, "PA", get_chunk_pa);	/* Patterns */
+	libxmp_iff_register(handle, "IS", get_chunk_is);	/* Sample info */
     } else {
-	iff_register(handle, "PA", get_chunk_p0);	/* Old 0.0 patterns */
-	iff_register(handle, "IS", get_chunk_i0);	/* Old 0.0 Sample info */
+	libxmp_iff_register(handle, "PA", get_chunk_p0);	/* Old 0.0 patterns */
+	libxmp_iff_register(handle, "IS", get_chunk_i0);	/* Old 0.0 Sample info */
     }
 
     /* MDL uses a IFF-style file format with 16 bit IDs and little endian
      * 32 bit chunk size. There's only one chunk per data type (i.e. one
      * big chunk for all samples).
      */
-    iff_id_size(handle, 2);
-    iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
+    libxmp_iff_id_size(handle, 2);
+    libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
 
-    set_type(m, "Digitrakker MDL %d.%d", MSN(*buf), LSN(*buf));
+    libxmp_set_type(m, "Digitrakker MDL %d.%d", MSN(*buf), LSN(*buf));
 
     m->volbase = 0xff;
     m->c4rate = C4_NTSC_RATE;
@@ -923,20 +1008,19 @@ static int mdl_load(struct module_data *m, HIO_HANDLE *f, const int start)
     data.v_index = malloc(256 * sizeof (int));
     data.p_index = malloc(256 * sizeof (int));
     data.f_index = malloc(256 * sizeof (int));
-    data.c2spd = calloc(256, sizeof (int));
 
     for (i = 0; i < 256; i++) {
 	data.v_index[i] = data.p_index[i] = data.f_index[i] = -1;
     }
 
     /* Load IFFoid chunks */
-    if (iff_load(handle, m, f, &data) < 0) {
-    	iff_release(handle);
+    if (libxmp_iff_load(handle, m, f, &data) < 0) {
+    	libxmp_iff_release(handle);
 	retval = -1;
 	goto err;
     }
 
-    iff_release(handle);
+    libxmp_iff_release(handle);
 
     /* Reindex instruments */
     for (i = 0; i < mod->trk; i++) {
@@ -962,8 +1046,8 @@ static int mdl_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	    for (k = 0; k < mod->smp; k++) {
 		if (mod->xxi[i].sub[j].sid == data.s_index[k]) {
 		    mod->xxi[i].sub[j].sid = k;
-		    c2spd_to_note(data.c2spd[k],
-			&mod->xxi[i].sub[j].xpo, &mod->xxi[i].sub[j].fin);
+		    /*libxmp_c2spd_to_note(data.c2spd[k],
+			&mod->xxi[i].sub[j].xpo, &mod->xxi[i].sub[j].fin);*/
 		    break;
 		}
 	    }
@@ -971,7 +1055,6 @@ static int mdl_load(struct module_data *m, HIO_HANDLE *f, const int start)
     }
 
   err:
-    free(data.c2spd);
     free(data.f_index);
     free(data.p_index);
     free(data.v_index);
diff --git a/src/loaders/med2_load.c b/src/loaders/med2_load.c
index f1c352b..d84a079 100644
--- a/src/loaders/med2_load.c
+++ b/src/loaders/med2_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -29,17 +29,15 @@
 #else
 #include 
 #endif
-#include 
-#include 
-#include "period.h"
 #include "loader.h"
+#include "period.h"
 
 #define MAGIC_MED2	MAGIC4('M','E','D',2)
 
 static int med2_test(HIO_HANDLE *, char *, const int);
 static int med2_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader med2_loader = {
+const struct format_loader libxmp_loader_med2 = {
 	"MED 1.12 MED2",
 	med2_test,
 	med2_load
@@ -51,7 +49,7 @@ static int med2_test(HIO_HANDLE *f, char *t, const int start)
 	if (hio_read32b(f) !=  MAGIC_MED2)
 		return -1;
 
-        read_title(f, t, 0);
+        libxmp_read_title(f, t, 0);
 
         return 0;
 }
@@ -70,19 +68,19 @@ int med2_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	if (hio_read32b(f) != MAGIC_MED2)
 		return -1;
 
-	set_type(m, "MED 1.12 MED2");
+	libxmp_set_type(m, "MED 1.12 MED2");
 
 	mod->ins = mod->smp = 32;
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	/* read instrument names */
 	hio_read(buf, 1, 40, f);	/* skip 0 */
 	for (i = 0; i < 31; i++) {
 		hio_read(buf, 1, 40, f);
-		instrument_name(mod, i, buf, 32);
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		libxmp_instrument_name(mod, i, buf, 32);
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 	}
 
@@ -113,15 +111,26 @@ int med2_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->pat = hio_read16b(f);
 	mod->trk = mod->chn * mod->pat;
 
-	hio_read(mod->xxo, 1, 100, f);
+	if (hio_read(mod->xxo, 1, 100, f) != 100)
+		return -1;
+
 	mod->len = hio_read16b(f);
 
-	mod->spd = 192 / hio_read16b(f);
+	/* Sanity check */
+	if (mod->pat > 256 || mod->len > 100)
+		return -1;
+
+	k = hio_read16b(f);
+	if (k < 1) {
+		return -1;
+	}
+
+	mod->spd = 192 / k;
 
 	hio_read16b(f);			/* flags */
-	sliding = hio_read16b(f);		/* sliding */
+	sliding = hio_read16b(f);	/* sliding */
 	hio_read32b(f);			/* jumping mask */
-	hio_seek(f, 16, SEEK_CUR);		/* rgb */
+	hio_seek(f, 16, SEEK_CUR);	/* rgb */
 
 	MODULE_INFO();
 
@@ -130,14 +139,14 @@ int med2_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	if (sliding == 6)
 		m->quirk |= QUIRK_VSALL | QUIRK_PBALL;
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	/* Load and convert patterns */
 	D_(D_INFO "Stored patterns: %d", mod->pat);
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 			return -1;
 
 		hio_read32b(f);
@@ -146,7 +155,7 @@ int med2_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			for (k = 0; k < 4; k++) {
 				uint8 x;
 				event = &EVENT(i, k, j);
-				event->note = period_to_note(hio_read16b(f));
+				event->note = libxmp_period_to_note(hio_read16b(f));
 				x = hio_read8(f);
 				event->ins = x >> 4;
 				event->fxt = x & 0x0f;
@@ -181,26 +190,29 @@ int med2_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		char ins_path[256];
 		char name[256];
 		HIO_HANDLE *s = NULL;
-		struct stat stat;
 		int found;
 
-		get_instrument_path(m, ins_path, 256);
-		found = check_filename_case(ins_path,
+		libxmp_get_instrument_path(m, ins_path, 256);
+		found = libxmp_check_filename_case(ins_path,
 				(char *)mod->xxi[i].name, name, 256);
 
 		if (found) {
 			snprintf(path, PATH_MAX, "%s/%s", ins_path, name);
 			if ((s = hio_open(path, "rb"))) {
-				hio_stat(s, &stat);
-				mod->xxs[i].len = stat.st_size;
+				mod->xxs[i].len = hio_size(s);
 			}
 		}
 
-		if (mod->xxs[i].len > 0)
+		if (mod->xxs[i].len > 0) {
 			mod->xxi[i].nsm = 1;
+		}
 
-		if (!strlen((char *)mod->xxi[i].name) && !mod->xxs[i].len)
+		if (!strlen((char *)mod->xxi[i].name) && !mod->xxs[i].len) {
+			if (s != NULL) {
+				hio_close(s);
+			}
 			continue;
+		}
 
 		D_(D_INFO "[%2X] %-32.32s %04x %04x %04x %c V%02x",
 			i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
@@ -208,11 +220,12 @@ int med2_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
 			mod->xxi[i].sub[0].vol);
 
-		if (found) {
-			int ret = load_sample(m, s, 0, &mod->xxs[i], NULL);
+		if (s != NULL) {
+			int ret = libxmp_load_sample(m, s, 0, &mod->xxs[i], NULL);
 			hio_close(s);
-			if (ret < 0)
+			if (ret < 0) {
 				return -1;
+			}
 		}
 	}
 
diff --git a/src/loaders/med3_load.c b/src/loaders/med3_load.c
index 6e25280..d96da1a 100644
--- a/src/loaders/med3_load.c
+++ b/src/loaders/med3_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -34,7 +34,7 @@
 static int med3_test(HIO_HANDLE *, char *, const int);
 static int med3_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader med3_loader = {
+const struct format_loader libxmp_loader_med3 = {
 	"MED 2.00 MED3",
 	med3_test,
 	med3_load
@@ -45,7 +45,7 @@ static int med3_test(HIO_HANDLE *f, char *t, const int start)
 	if (hio_read32b(f) !=  MAGIC_MED3)
 		return -1;
 
-	read_title(f, t, 0);
+	libxmp_read_title(f, t, 0);
 
 	return 0;
 }
@@ -70,7 +70,7 @@ static int med3_test(HIO_HANDLE *f, char *t, const int start)
 
 static uint8 get_nibble(uint8 *mem, uint16 *nbnum)
 {
-	uint8 *mloc = mem + (*nbnum / 2),res;
+	uint8 *mloc = mem + (*nbnum / 2), res;
 
 	if(*nbnum & 0x1)
 		res = *mloc & 0x0f;
@@ -81,19 +81,19 @@ static uint8 get_nibble(uint8 *mem, uint16 *nbnum)
 	return res;
 }
 
-static uint16 get_nibbles(uint8 *mem,uint16 *nbnum,uint8 nbs)
+static uint16 get_nibbles(uint8 *mem, uint16 *nbnum, uint8 nbs)
 {
 	uint16 res = 0;
 
 	while (nbs--) {
 		res <<= 4;
-		res |= get_nibble(mem,nbnum);
+		res |= get_nibble(mem, nbnum);
 	}
 
 	return res;
 }
 
-static int unpack_block(struct module_data *m, uint16 bnum, uint8 *from)
+static int unpack_block(struct module_data *m, uint16 bnum, uint8 *from, uint16 convsz)
 {
 	struct xmp_module *mod = &m->mod;
 	struct xmp_event *event;
@@ -107,8 +107,9 @@ static int unpack_block(struct module_data *m, uint16 bnum, uint8 *from)
 
 	/*from += 16;*/
 	patbuf = to = calloc(3, 4 * 64);
-	if (to == NULL)
-		return -1;
+	if (to == NULL) {
+		goto err;
+	}
 
 	for (i = 0; i < 64; i++) {
 		if (i == 32) {
@@ -117,6 +118,11 @@ static int unpack_block(struct module_data *m, uint16 bnum, uint8 *from)
 		}
 
 		if (*lmptr & MASK) {
+			if (trkn / 2 > convsz) {
+				goto err2;
+			}	
+			convsz -= trkn / 2;
+
 			lmsk = get_nibbles(fromst, &fromn, (uint8)(trkn / 4));
 			lmsk <<= (16 - trkn);
 			tmpto = to;
@@ -134,6 +140,11 @@ static int unpack_block(struct module_data *m, uint16 bnum, uint8 *from)
 		}
 
 		if (*fxptr & MASK) {
+			if (trkn / 2 > convsz) {
+				goto err2;
+			}	
+			convsz -= trkn / 2;
+
 			lmsk = get_nibbles(fromst,&fromn,(uint8)(trkn / 4));
 			lmsk <<= (16 - trkn);
 			tmpto = to;
@@ -212,6 +223,11 @@ static int unpack_block(struct module_data *m, uint16 bnum, uint8 *from)
 	free(patbuf);
 
 	return 0;
+
+     err2:
+	free(patbuf);
+     err:
+	return -1;
 }
 
 
@@ -226,11 +242,11 @@ static int med3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	hio_read32b(f);
 
-	set_type(m, "MED 2.00 MED3");
+	libxmp_set_type(m, "MED 2.00 MED3");
 
 	mod->ins = mod->smp = 32;
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	/* read instrument names */
@@ -242,8 +258,8 @@ static int med3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			if (c == 0)
 				break;
 		}
-		instrument_name(mod, i, buf, 32);
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		libxmp_instrument_name(mod, i, buf, 32);
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 	}
 
@@ -276,6 +292,11 @@ static int med3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->trk = mod->chn * mod->pat;
 
 	mod->len = hio_read16b(f);
+
+	/* Sanity check */
+	if (mod->len > 256 || mod->pat > 256)
+		return -1;
+
 	hio_read(mod->xxo, 1, mod->len, f);
 	mod->spd = hio_read16b(f);
 	if (mod->spd > 10) {
@@ -313,7 +334,7 @@ static int med3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	for (i = 0; i < 32; i++)
 		mod->xxi[i].sub[0].xpo = transp;
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	/* Load and convert patterns */
@@ -324,7 +345,7 @@ static int med3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		uint8 b, tracks;
 		uint16 convsz;
 
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 			return -1;
 
 		tracks = hio_read8(f);
@@ -363,9 +384,12 @@ static int med3_load(struct module_data *m, HIO_HANDLE *f, const int start)
                 else
 			*(conv + 3) = hio_read32b(f);
 
-		hio_read(conv + 4, 1, convsz, f);
+		if (hio_read(conv + 4, 1, convsz, f) != convsz) {
+			free(conv);
+			return -1;
+		}
 
-                if (unpack_block(m, i, (uint8 *)conv) < 0) {
+                if (unpack_block(m, i, (uint8 *)conv, convsz) < 0) {
 			free(conv);
 			return -1;
 		}
@@ -397,7 +421,7 @@ static int med3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
 			mod->xxi[i].sub[0].vol);
 
-		if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
 			return -1;
 	}
 
diff --git a/src/loaders/med4_load.c b/src/loaders/med4_load.c
index 8e41a04..29827a1 100644
--- a/src/loaders/med4_load.c
+++ b/src/loaders/med4_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -37,7 +37,7 @@
 static int med4_test(HIO_HANDLE *, char *, const int);
 static int med4_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader med4_loader = {
+const struct format_loader libxmp_loader_med4 = {
 	"MED 2.10 MED4",
 	med4_test,
 	med4_load
@@ -48,26 +48,11 @@ static int med4_test(HIO_HANDLE *f, char *t, const int start)
 	if (hio_read32b(f) != MAGIC_MED4)
 		return -1;
 
-	read_title(f, t, 0);
+	libxmp_read_title(f, t, 0);
 
 	return 0;
 }
 
-#ifdef DEBUG
-static const char *inst_type[] = {
-	"HYB",		/* -2 */
-	"SYN",		/* -1 */
-	"SMP",		/*  0 */
-	"I5O",		/*  1 */
-	"I3O",		/*  2 */
-	"I2O",		/*  3 */
-	"I4O",		/*  4 */
-	"I6O",		/*  5 */
-	"I7O",		/*  6 */
-	"EXT",		/*  7 */
-};
-#endif
-
 const unsigned MAX_CHANNELS = 16;
 
 static void fix_effect(struct xmp_event *event)
@@ -207,7 +192,10 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	/*
 	 * Check if we have a MEDV chunk at the end of the file
 	 */
-	pos = hio_tell(f);
+	if ((pos = hio_tell(f)) < 0) {
+		return -1;
+	}
+
 	hio_seek(f, 0, SEEK_END);
 	if (hio_tell(f) > 2000) {
 		hio_seek(f, -1024, SEEK_CUR);
@@ -234,7 +222,14 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			masksz++;
 		}
 	}
-	mask <<= 8 * (sizeof(mask) - masksz);
+
+	/* CID 128662 (#1 of 1): Bad bit shift operation (BAD_SHIFT)
+	 * large_shift: left shifting by more than 63 bits has undefined
+	 * behavior.
+	 */
+	if (masksz > 0) {
+		mask <<= 8 * (sizeof(mask) - masksz);
+	}
 	/*printf("m0=%x mask=%x\n", m0, mask);*/
 
 	/* read instrument names in temporary space */
@@ -279,15 +274,20 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		temp_inst[i].loop_end = temp_inst[i].loop_start + loop_len;
 
-		copy_adjust(temp_inst[i].name, buf, 32);
+		libxmp_copy_adjust(temp_inst[i].name, buf, 32);
 	}
 
 	mod->pat = hio_read16b(f);
 	mod->len = hio_read16b(f);
+
+	if (hio_error(f)) {
+		return -1;
+	}
+
 #ifdef MED4_DEBUG
 	printf("pat=%x len=%x\n", mod->pat, mod->len);
 #endif
-	if (mod->len > XMP_MAX_MOD_LENGTH)
+	if (mod->pat > 256 || mod->len > XMP_MAX_MOD_LENGTH)
 		return -1;
 	hio_read(mod->xxo, 1, mod->len, f);
 
@@ -334,7 +334,9 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	/* Scan patterns to determine number of channels */
 	mod->chn = 0;
-	pos = hio_tell(f);
+	if ((pos = hio_tell(f)) < 0) {
+		return -1;
+	}
 
 	for (i = 0; i < mod->pat; i++) {
 		int size, plen, chn;
@@ -349,9 +351,14 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		hio_seek(f, size + plen - 4, SEEK_CUR);
 	}
 
+	/* Sanity check */
+	if (mod->chn > 16) {
+		return -1;
+	}
+
 	mod->trk = mod->chn * mod->pat;
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	hio_seek(f, pos, SEEK_SET);
@@ -373,10 +380,13 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 #endif
 
 		size = hio_read8(f);	/* pattern control block */
-		pos = hio_tell(f);
+		if ((pos = hio_tell(f)) < 0) {
+			return -1;
+		}
 		chn = hio_read8(f);
-		if (chn > mod->chn)
+		if (chn > mod->chn) {
 			return -1;
+		}
 		rows = (int)hio_read8(f) + 1;
 		plen = hio_read16b(f);
 #ifdef MED4_DEBUG
@@ -397,7 +407,7 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 #endif
 		}
 
-		if (pattern_tracks_alloc(mod, i, rows) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
 			return -1;
 
 		/* initialize masks */
@@ -434,6 +444,9 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		for (j = 0; j < 32; j++) {
 			int line = y * 32 + j;
 
+			if (line >= rows)
+				break;
+
 			if (linemask[y] & 0x80000000) {
 				chmsk = stream_read_aligned16(&stream, chn);
 				for (k = 0; k < chn; k++, chmsk <<= 1) {
@@ -487,7 +500,7 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	mod->ins = num_ins;
 
-	if (med_new_module_extras(m) != 0)
+	if (libxmp_med_new_module_extras(m) != 0)
 		return -1;
 
 	/*
@@ -497,7 +510,7 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	if (mask == MAGIC4('M','E','D','V')) {
 		mod->smp = 0;
 
-		if (instrument_init(mod) < 0)
+		if (libxmp_init_instrument(m) < 0)
 			return -1;
 		hio_seek(f, -4, SEEK_CUR);
 		goto parse_iff;
@@ -508,7 +521,9 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mask <<= 1;	/* no instrument #0 */
 
 	/* obtain number of samples */
-	pos = hio_tell(f);
+	if ((pos = hio_tell(f)) < 0) {
+		return -1;
+	}
 	num_smp = 0;
 	{
 		int _len, _type;
@@ -521,7 +536,9 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 			_len = hio_read32b(f);
 			_type = (int16)hio_read16b(f);
-			_pos = hio_tell(f);
+			if ((_pos = hio_tell(f)) < 0) {
+				return -1;
+			}
 
 			if (_type == 0 || _type == -2) {
 				num_smp++;
@@ -537,7 +554,7 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	mod->smp = num_smp;
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	D_(D_INFO "Instruments: %d", mod->ins);
@@ -569,6 +586,9 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		if (type == -2) {			/* Hybrid */
 			int length, type;
 			int pos = hio_tell(f);
+			if (pos < 0) {
+				return -1;
+			}
 
 			hio_read32b(f);	/* ? - MSH 00 */
 			hio_read16b(f);	/* ? - ffff */
@@ -581,6 +601,14 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			synth.volspeed = hio_read8(f);
 			synth.wfspeed = hio_read8(f);
 			synth.wforms = hio_read16b(f);
+
+			/* Sanity check */
+			if (synth.voltbllen > 128 ||
+			    synth.wftbllen > 128 ||
+			    synth.wforms > 256) {
+				return -1;
+			}
+
 			hio_read(synth.voltbl, 1, synth.voltbllen, f);;
 			hio_read(synth.wftbl, 1, synth.wftbllen, f);;
 
@@ -588,11 +616,11 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			length = hio_read32b(f);
 			type = hio_read16b(f);
 
-			if (med_new_instrument_extras(xxi) != 0)
+			if (libxmp_med_new_instrument_extras(xxi) != 0)
 				return -1;
 
 			xxi->nsm = 1;
-			if (subinstrument_alloc(mod, i, 1) < 0)
+			if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 				return -1;
 
 			sub = &xxi->sub[0];
@@ -617,7 +645,7 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 					xxs->len, xxs->lps, xxs->lpe,
 					sub->vol, sub->xpo /*, sub->fin >> 4*/);
 
-			if (load_sample(m, f, 0, xxs, NULL) < 0)
+			if (libxmp_load_sample(m, f, 0, xxs, NULL) < 0)
 				return -1;
 
 			smp_idx++;
@@ -630,6 +658,9 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		if (type == -1) {		/* Synthetic */
 			int pos = hio_tell(f);
+			if (pos < 0) {
+				return -1;
+			}
 
 			hio_read32b(f);	/* ? - MSH 00 */
 			hio_read16b(f);	/* ? - ffff */
@@ -642,6 +673,14 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			synth.volspeed = hio_read8(f);
 			synth.wfspeed = hio_read8(f);
 			synth.wforms = hio_read16b(f);
+
+			/* Sanity check */
+			if (synth.voltbllen > 128 ||
+			    synth.wftbllen > 128 ||
+			    synth.wforms > 256) {
+				return -1;
+			}
+
 			hio_read(synth.voltbl, 1, synth.voltbllen, f);;
 			hio_read(synth.wftbl, 1, synth.wftbllen, f);;
 			if (synth.wforms == 0xffff)	
@@ -658,11 +697,11 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 					temp_inst[i].transpose /*,
 					exp_smp.finetune*/);
 
-			if (med_new_instrument_extras(&mod->xxi[i]) != 0)
+			if (libxmp_med_new_instrument_extras(&mod->xxi[i]) != 0)
 				return -1;
 
 			mod->xxi[i].nsm = synth.wforms;
-			if (subinstrument_alloc(mod, i, synth.wforms) < 0)
+			if (libxmp_alloc_subinstrument(mod, i, synth.wforms) < 0)
 				return -1;
 
 			MED_INSTRUMENT_EXTRAS(*xxi)->vts = synth.volspeed;
@@ -686,7 +725,7 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				xxs->lpe = xxs->len;
 				xxs->flg = XMP_SAMPLE_LOOP;
 
-				if (load_sample(m, f, 0, xxs, NULL) < 0) {
+				if (libxmp_load_sample(m, f, 0, xxs, NULL) < 0) {
 					return -1;
 				}
 
@@ -707,7 +746,7 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		/* instr type is sample */
 		xxi->nsm = 1;
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 		
 		sub = &xxi->sub[0];
@@ -717,6 +756,10 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		sub->xpo = temp_inst[i].transpose;
 		sub->sid = smp_idx;
 
+		/* Sanity check */
+		if (smp_idx >= mod->smp)
+			return -1;
+
 		xxs = &mod->xxs[smp_idx];
 
 		xxs->len = length;
@@ -729,7 +772,7 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
 				sub->vol, sub->xpo);
 
-		if (load_sample(m, f, 0, xxs, NULL) < 0)
+		if (libxmp_load_sample(m, f, 0, xxs, NULL) < 0)
 			return -1;
 
 		/* Limit range to 3 octave (see MED.El toro) */
@@ -756,13 +799,15 @@ static int med4_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	while (!hio_eof(f)) {
 		int32 id, size, s2, pos, ver;
 
-		if ((id = hio_read32b(f)) < 0)
+		if ((id = hio_read32b(f)) <= 0)
 			break;
 
-		if ((size = hio_read32b(f)) < 0)
+		if ((size = hio_read32b(f)) <= 0)
 			break;
 
-		pos = hio_tell(f);
+		if ((pos = hio_tell(f)) < 0) {
+			return -1;
+		}
 
 		switch (id) {
 		case MAGIC4('M','E','D','V'):
diff --git a/src/loaders/mfp_load.c b/src/loaders/mfp_load.c
index 2b1acff..6caacf5 100644
--- a/src/loaders/mfp_load.c
+++ b/src/loaders/mfp_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -39,7 +39,7 @@
 static int mfp_test(HIO_HANDLE *, char *, const int);
 static int mfp_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader mfp_loader = {
+const struct format_loader libxmp_loader_mfp = {
 	"Magnetic Fields Packer",
 	mfp_test,
 	mfp_load
@@ -94,7 +94,7 @@ static int mfp_test(HIO_HANDLE *f, char *t, const int start)
 	if (readmem16b(buf + 378) != readmem16b(buf + 380))
 		return -1;
 
-	read_title(f, t, 0);
+	libxmp_read_title(f, t, 0);
 
 	return 0;
 }
@@ -114,19 +114,19 @@ static int mfp_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	LOAD_INIT();
 
-	set_type(m, "Magnetic Fields Packer");
+	libxmp_set_type(m, "Magnetic Fields Packer");
 	MODULE_INFO();
 
 	mod->chn = 4;
 	mod->ins = mod->smp = 31;
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	for (i = 0; i < 31; i++) {
 		int loop_size;
 
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 		
 		mod->xxs[i].len = 2 * hio_read16b(f);
@@ -154,23 +154,19 @@ static int mfp_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->len = mod->pat = hio_read8(f);
 	hio_read8(f);		/* restart */
 
-	for (i = 0; i < 128; i++)
-		mod->xxo[i] = hio_read8(f);
-
-#if 0
 	for (i = 0; i < 128; i++) {
 		mod->xxo[i] = hio_read8(f);
-		if (mod->xxo[i] > mod->pat)
-			mod->pat = mod->xxo[i];
 	}
-	mod->pat++;
-#endif
+
+	if (hio_error(f)) {
+		return -1;
+	}
 
 	mod->trk = mod->pat * mod->chn;
 
 	/* Read and convert patterns */
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	size1 = hio_read16b(f);
@@ -187,7 +183,7 @@ static int mfp_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	pat_addr = hio_tell(f);
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 			return -1;
 
 		for (j = 0; j < 4; j++) {
@@ -200,7 +196,7 @@ static int mfp_load(struct module_data *m, HIO_HANDLE *f, const int start)
 					for (y = 0; y < 4; y++, row++) {
 						event = &EVENT(i, j, row);
 						memcpy(mod_event, &buf[buf[buf[buf[k] + x] + y] * 2], 4);
-						decode_protracker_event(event, mod_event);
+						libxmp_decode_protracker_event(event, mod_event);
 					}
 				}
 			}
@@ -240,14 +236,16 @@ static int mfp_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	}
 
 	for (i = 0; i < mod->ins; i++) {
-		if (load_sample(m, s, SAMPLE_FLAG_FULLREP,
-				  &mod->xxs[mod->xxi[i].sub[0].sid], NULL) < 0)
+		if (libxmp_load_sample(m, s, SAMPLE_FLAG_FULLREP,
+				&mod->xxs[mod->xxi[i].sub[0].sid], NULL) < 0) {
+			free(s);
 			return -1;
+		}
 	}
 
 	hio_close(s);
 
-	m->quirk |= QUIRK_MODRNG;
+	m->period_type = PERIOD_MODRNG;
 
 	return 0;
 
diff --git a/src/loaders/mgt_load.c b/src/loaders/mgt_load.c
index 4cf6c33..46cc645 100644
--- a/src/loaders/mgt_load.c
+++ b/src/loaders/mgt_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -16,7 +30,7 @@
 static int mgt_test (HIO_HANDLE *, char *, const int);
 static int mgt_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader mgt_loader = {
+const struct format_loader libxmp_loader_mgt = {
 	"Megatracker",
 	mgt_test,
 	mgt_load
@@ -36,7 +50,7 @@ static int mgt_test(HIO_HANDLE *f, char *t, const int start)
 	sng_ptr = hio_read32b(f);
 	hio_seek(f, start + sng_ptr, SEEK_SET);
 
-	read_title(f, t, 32);
+	libxmp_read_title(f, t, 32);
 	
 	return 0;
 }
@@ -56,7 +70,7 @@ static int mgt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	ver = hio_read8(f);
 	hio_read32b(f);		/* MCS */
 
-	set_type(m, "Megatracker MGT v%d.%d", MSN(ver), LSN(ver));
+	libxmp_set_type(m, "Megatracker MGT v%d.%d", MSN(ver), LSN(ver));
 
 	mod->chn = hio_read16b(f);
 	hio_read16b(f);			/* number of songs */
@@ -67,6 +81,11 @@ static int mgt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	hio_read16b(f);			/* reserved */
 	hio_read32b(f);			/* reserved */
 
+	/* Sanity check */
+	if (mod->chn > XMP_MAX_CHANNELS || mod->ins > 64) {
+		return -1;
+	}
+
 	sng_ptr = hio_read32b(f);
 	seq_ptr = hio_read32b(f);
 	ins_ptr = hio_read32b(f);
@@ -88,21 +107,34 @@ static int mgt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	hio_read8(f);			/* master L */
 	hio_read8(f);			/* master R */
 
+	/* Sanity check */
+	if (mod->len > 256 || mod->rst > 255) {
+		return -1;
+	}
+
 	for (i = 0; i < mod->chn; i++) {
 		hio_read16b(f);		/* pan */
 	}
+
+	m->c4rate = C4_NTSC_RATE;
 	
 	MODULE_INFO();
 
 	/* Sequence */
 
 	hio_seek(f, start + seq_ptr, SEEK_SET);
-	for (i = 0; i < mod->len; i++)
+	for (i = 0; i < mod->len; i++) {
 		mod->xxo[i] = hio_read16b(f);
 
+		/* Sanity check */
+		if (mod->xxo[i] >= mod->pat) {
+			return -1;
+		}
+	}
+
 	/* Instruments */
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	hio_seek(f, start + ins_ptr, SEEK_SET);
@@ -110,18 +142,24 @@ static int mgt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	for (i = 0; i < mod->ins; i++) {
 		int c2spd, flags;
 
-		if (subinstrument_alloc(mod, i , 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i , 1) < 0)
 			return -1;
 
 		hio_read(mod->xxi[i].name, 1, 32, f);
 		sdata[i] = hio_read32b(f);
 		mod->xxs[i].len = hio_read32b(f);
+
+		/* Sanity check */
+		if (mod->xxs[i].len > MAX_SAMPLE_SIZE) {
+			return -1;
+		}
+
 		mod->xxs[i].lps = hio_read32b(f);
 		mod->xxs[i].lpe = mod->xxs[i].lps + hio_read32b(f);
 		hio_read32b(f);
 		hio_read32b(f);
 		c2spd = hio_read32b(f);
-		c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
+		libxmp_c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
 		mod->xxi[i].sub[0].vol = hio_read16b(f) >> 4;
 		hio_read8(f);		/* vol L */
 		hio_read8(f);		/* vol R */
@@ -150,7 +188,7 @@ static int mgt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	}
 
 	/* PATTERN_INIT - alloc extra track*/
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	D_(D_INFO "Stored tracks: %d", mod->trk);
@@ -167,7 +205,11 @@ static int mgt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		rows = hio_read16b(f);
 
-		if (track_alloc(mod, i, rows) < 0)
+		/* Sanity check */
+		if (rows > 255)
+			return -1;
+
+		if (libxmp_alloc_track(mod, i, rows) < 0)
 			return -1;
 
 		//printf("\n=== Track %d ===\n\n", i);
@@ -177,6 +219,10 @@ static int mgt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			b = hio_read8(f);
 			j += b & 0x03;
 
+			/* Sanity check */
+			if (j >= rows)
+				return -1;
+
 			note = 0;
 			event = &mod->xxt[i]->event[j];
 			if (b & 0x04)
@@ -276,9 +322,11 @@ static int mgt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	}
 
 	/* Extra track */
-	mod->xxt[0] = calloc(sizeof(struct xmp_track) +
+	if (mod->trk > 0) {
+		mod->xxt[0] = calloc(sizeof(struct xmp_track) +
 			sizeof(struct xmp_event) * 64 - 1, 1);
-	mod->xxt[0]->rows = 64;
+		mod->xxt[0]->rows = 64;
+	}
 
 	/* Read and convert patterns */
 	D_(D_INFO "Stored patterns: %d", mod->pat);
@@ -286,12 +334,29 @@ static int mgt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	hio_seek(f, start + pat_ptr, SEEK_SET);
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_alloc(mod, i) < 0)
+		int rows;
+
+		if (libxmp_alloc_pattern(mod, i) < 0)
 			return -1;
 
-		mod->xxp[i]->rows = hio_read16b(f);
+		rows = hio_read16b(f);
+
+		/* Sanity check */
+		if (rows > 256) {
+			return -1;
+		}
+
+		mod->xxp[i]->rows = rows;
+
 		for (j = 0; j < mod->chn; j++) {
-			mod->xxp[i]->index[j] = hio_read16b(f) - 1;
+			int track = hio_read16b(f) - 1;
+
+			/* Sanity check */
+			if (track >= mod->trk) {
+				return -1;
+			}
+
+			mod->xxp[i]->index[j] = track;
 		}
 	}
 
@@ -304,7 +369,7 @@ static int mgt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			continue;
 
 		hio_seek(f, start + sdata[i], SEEK_SET);
-		if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
 			return -1;
 	}
 
diff --git a/src/loaders/mmd1_load.c b/src/loaders/mmd1_load.c
index b3bac12..f127ce7 100644
--- a/src/loaders/mmd1_load.c
+++ b/src/loaders/mmd1_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -31,7 +31,7 @@
 static int mmd1_test(HIO_HANDLE *, char *, const int);
 static int mmd1_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader mmd1_loader = {
+const struct format_loader libxmp_loader_mmd1 = {
 	"MED 2.10/OctaMED",
 	mmd1_test,
 	mmd1_load
@@ -56,9 +56,9 @@ static int mmd1_test(HIO_HANDLE *f, char *t, const int start)
 		offset = hio_read32b(f);
 		len = hio_read32b(f);
 		hio_seek(f, start + offset, SEEK_SET);
-		read_title(f, t, len);
+		libxmp_read_title(f, t, len);
 	} else {
-		read_title(f, t, 0);
+		libxmp_read_title(f, t, 0);
 	}
 
 	return 0;
@@ -138,8 +138,12 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	}
 	song.numblocks = hio_read16b(f);
 	song.songlen = hio_read16b(f);
-	if (song.songlen > 256)
-	  return -1;
+
+	/* Sanity check */
+	if (song.numblocks > 255 || song.songlen > 256) {
+		return -1;
+	}
+
 	D_(D_INFO "song.songlen = %d", song.songlen);
 	for (i = 0; i < 256; i++)
 		song.playseq[i] = hio_read8(f);
@@ -153,6 +157,11 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	song.mastervol = hio_read8(f);
 	song.numsamples = hio_read8(f);
 
+	/* Sanity check */
+	if (song.numsamples > 63) {
+		return -1;
+	}
+
 	/*
 	 * convert header
 	 */
@@ -192,8 +201,15 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		hio_read32b(f);				/* length */
 		type = hio_read16b(f);
 		if (type == -1) {			/* type is synth? */
+			int wforms;
 			hio_seek(f, 14, SEEK_CUR);
-			mod->smp += hio_read16b(f);		/* wforms */
+			wforms = hio_read16b(f);
+
+			/* Sanity check */
+			if (wforms > 256)
+				return -1;
+
+			mod->smp += wforms;
 		} else if (type >= 1 && type <= 6) {
 			mod->smp += num_oct[type - 1];
 		} else {
@@ -225,6 +241,15 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		D_(D_INFO "iinfo_offset = 0x%08x", iinfo_offset);
 		expdata.i_ext_entries = hio_read16b(f);
 		expdata.i_ext_entrsz = hio_read16b(f);
+
+		/* Sanity check */
+		if (expsmp_offset < 0 ||
+		    annotxt_offset < 0 ||
+                    expdata.annolen > 0x10000 ||
+		    iinfo_offset < 0) {
+			return -1;
+		}
+
 		hio_read32b(f);
 		hio_read32b(f);
 		hio_read32b(f);
@@ -269,19 +294,25 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		if (ver > 0) {
 			block.numtracks = hio_read16b(f);
-			block.lines = hio_read16b(f);
+			/* block.lines = */ hio_read16b(f);
 		} else {
 			block.numtracks = hio_read8(f);
-			block.lines = hio_read8(f);
+			/* block.lines = */ hio_read8(f);
 		}
 
-		if (block.numtracks > mod->chn)
+		if (block.numtracks > mod->chn) {
 			mod->chn = block.numtracks;
+		}
+	}
+
+	/* Sanity check */
+	if (mod->chn > XMP_MAX_CHANNELS) {
+		return -1;
 	}
 
 	mod->trk = mod->pat * mod->chn;
 
-	set_type(m, ver == 0 ? mod->chn > 4 ? "OctaMED 2.00 MMD0" :
+	libxmp_set_type(m, ver == 0 ? mod->chn > 4 ? "OctaMED 2.00 MMD0" :
 				"MED 2.10 MMD0" : "OctaMED 4.00 MMD1");
 	
 	MODULE_INFO();
@@ -294,7 +325,7 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	 * Read and convert patterns
 	 */
 	D_(D_WARN "read patterns");
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	for (i = 0; i < mod->pat; i++) {
@@ -317,7 +348,7 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			block.lines = hio_read8(f);
 		}
 
-		if (pattern_tracks_alloc(mod, i, block.lines + 1) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, block.lines + 1) < 0)
 			return -1;
 
 		if (ver > 0) {		/* MMD1 */
@@ -383,14 +414,14 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		}
 	}
 
-	if (med_new_module_extras(m))
+	if (libxmp_med_new_module_extras(m))
 		return -1;
 
 	/*
 	 * Read and convert instruments and samples
 	 */
 	D_(D_WARN "read instruments");
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	D_(D_INFO "Instruments: %d", mod->ins);
@@ -404,29 +435,38 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		D_(D_INFO "sample %d smpl_offset = 0x%08x", i, smpl_offset);
 
-		if (smpl_offset == 0)
+		if (smpl_offset == 0) {
 			continue;
-
-		if (hio_seek(f, start + smpl_offset, SEEK_SET) != 0)
+		}
+		if (hio_seek(f, start + smpl_offset, SEEK_SET) < 0) {
 			return -1;
+		}
 		instr.length = hio_read32b(f);
 		instr.type = hio_read16b(f);
 
-		pos = hio_tell(f);
+		if ((pos = hio_tell(f)) < 0) {
+			return -1;
+		}
 
 		if (expdata_offset && i < expdata.i_ext_entries) {
 			struct xmp_instrument *xxi = &mod->xxi[i];
-			if (hio_seek(f, iinfo_offset + i * expdata.i_ext_entrsz, SEEK_SET) != 0)
+			int offset = iinfo_offset + i * expdata.i_ext_entrsz;
+			
+			if (offset < 0 || hio_seek(f, offset, SEEK_SET) < 0) {
 				return -1;
+			}
 			hio_read(&xxi->name, 40, 1, f);
 		}
 
-		D_(D_INFO "\n[%2x] %-40.40s %d", i, name, instr.type);
+		D_(D_INFO "[%2x] %-40.40s %d", i, mod->xxi[i].name, instr.type);
 
 		exp_smp.finetune = 0;
 		if (expdata_offset && i < expdata.s_ext_entries) {
-			if (hio_seek(f, expsmp_offset + i * expdata.s_ext_entrsz, SEEK_SET) != 0)
-			  return -1;
+			int offset = expsmp_offset + i * expdata.s_ext_entrsz;
+
+			if (offset < 0 || hio_seek(f, offset, SEEK_SET) < 0) {
+				return -1;
+			}
 			exp_smp.hold = hio_read8(f);
 			exp_smp.decay = hio_read8(f);
 			exp_smp.suppress_midi_off = hio_read8(f);
@@ -448,9 +488,7 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				return -1;
 
 			continue;
-		}
-
-		if (instr.type == -1) {			/* Synthetic */
+		} else if (instr.type == -1) {			/* Synthetic */
 			int ret = mmd_load_synth_instrument(f, m, i, smp_idx,
 				&synth, &exp_smp, &song.sample[i]);
 
@@ -466,9 +504,7 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				return -1;
 
 			continue;
-		}
-
-		if (instr.type >= 1 && instr.type <= 6) {	/* IFFOCT */
+		} else if (instr.type >= 1 && instr.type <= 6) { /* IFFOCT */
 			int ret;
 			const int oct = num_oct[instr.type - 1];
 
@@ -483,9 +519,7 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			smp_idx += oct;
 
 			continue;
-		}
-
-		if (instr.type == 0) {			/* Sample */
+		} else if (instr.type == 0) {			/* Sample */
 			int ret;
 
 			hio_seek(f, start + smpl_offset + 6, SEEK_SET);
@@ -500,12 +534,15 @@ static int mmd1_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			smp_idx++;
 
 			continue;
+		} else {
+			/* Invalid instrument type */
+			return -1;
 		}
 	}
 
 	for (i = 0; i < mod->chn; i++) {
 		mod->xxc[i].vol = song.trkvol[i];
-		mod->xxc[i].pan = (((i + 1) / 2) % 2) * 0xff;
+		mod->xxc[i].pan = DEFPAN((((i + 1) / 2) % 2) * 0xff);
 	}
 
 	m->read_event_type = READ_EVENT_MED;
diff --git a/src/loaders/mmd3_load.c b/src/loaders/mmd3_load.c
index 52ec943..44af1b7 100644
--- a/src/loaders/mmd3_load.c
+++ b/src/loaders/mmd3_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -27,7 +27,7 @@
 static int mmd3_test (HIO_HANDLE *, char *, const int);
 static int mmd3_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader mmd3_loader = {
+const struct format_loader libxmp_loader_mmd3 = {
 	"OctaMED",
 	mmd3_test,
 	mmd3_load
@@ -52,9 +52,9 @@ static int mmd3_test(HIO_HANDLE *f, char *t, const int start)
 		offset = hio_read32b(f);
 		len = hio_read32b(f);
 		hio_seek(f, start + offset, SEEK_SET);
-		read_title(f, t, len);
+		libxmp_read_title(f, t, len);
 	} else {
-		read_title(f, t, 0);
+		libxmp_read_title(f, t, 0);
 	}
 
 	return 0;
@@ -164,6 +164,11 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	song.mastervol = hio_read8(f);
 	song.numsamples = hio_read8(f);
 
+	/* Sanity check */
+	if (song.numsamples > 63) {
+		return -1;
+	}
+
 	/*
 	 * read sequence
 	 */
@@ -174,8 +179,15 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	hio_read32b(f);
 	hio_read32b(f);
 	mod->len = hio_read16b(f);
-	for (i = 0; i < mod->len; i++)
+
+	/* Sanity check */
+	if (mod->len > 255) {
+		return -1;
+	}
+
+	for (i = 0; i < mod->len; i++) {
 		mod->xxo[i] = hio_read16b(f);
+	}
 
 	/*
 	 * convert header
@@ -229,7 +241,7 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	expdata.i_ext_entrsz = 0;
 	expsmp_offset = 0;
 	iinfo_offset = 0;
-	mmdinfo_offset = 0;
+
 	if (expdata_offset) {
 		hio_seek(f, start + expdata_offset, SEEK_SET);
 		hio_read32b(f);
@@ -243,6 +255,12 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		D_(D_INFO "iinfo_offset = 0x%08x", iinfo_offset);
 		expdata.i_ext_entries = hio_read16b(f);
 		expdata.i_ext_entrsz = hio_read16b(f);
+
+		/* Sanity check */
+		if (expsmp_offset < 0 || iinfo_offset < 0) {
+			return -1;
+		}
+
 		hio_read32b(f);
 		hio_read32b(f);
 		hio_read32b(f);
@@ -252,6 +270,10 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		hio_read32b(f);		/* dumps */
 		mmdinfo_offset = hio_read32b(f);
 
+		if (hio_error(f)) {
+			return -1;
+		}
+
 		hio_seek(f, start + songname_offset, SEEK_SET);
 		D_(D_INFO "expdata.songnamelen = %d", expdata.songnamelen);
 		for (i = 0; i < expdata.songnamelen; i++) {
@@ -282,18 +304,23 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		hio_seek(f, start + block_offset, SEEK_SET);
 
 		block.numtracks = hio_read16b(f);
-		block.lines = hio_read16b(f);
+		/* block.lines = */ hio_read16b(f);
 
-		if (block.numtracks > mod->chn)
+		if (block.numtracks > mod->chn) {
 			mod->chn = block.numtracks;
+		}
 	}
 
+	/* Sanity check */
+	if (mod->chn <= 0 || mod->chn > XMP_MAX_CHANNELS)
+		return -1;
+
 	mod->trk = mod->pat * mod->chn;
 
 	if (ver == 2)
-		set_type(m, "OctaMED v5 MMD2");
+		libxmp_set_type(m, "OctaMED v5 MMD2");
 	else
-		set_type(m, "OctaMED Soundstudio MMD%c", '0' + ver);
+		libxmp_set_type(m, "OctaMED Soundstudio MMD%c", '0' + ver);
 
 	MODULE_INFO();
 
@@ -306,7 +333,7 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	 */
 	D_(D_WARN "read patterns");
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	for (i = 0; i < mod->pat; i++) {
@@ -322,7 +349,7 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		block.lines = hio_read16b(f);
 		hio_read32b(f);
 
-		if (pattern_tracks_alloc(mod, i, block.lines + 1) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, block.lines + 1) < 0)
 			return -1;
 
 		for (j = 0; j < mod->xxp[i]->rows; j++) {
@@ -360,7 +387,7 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		}
 	}
 
-	if (med_new_module_extras(m) != 0)
+	if (libxmp_med_new_module_extras(m) != 0)
 		return -1;
 
 	/*
@@ -368,7 +395,7 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	 */
 	D_(D_WARN "read instruments");
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	D_(D_INFO "Instruments: %d", mod->ins);
@@ -381,27 +408,37 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		D_(D_INFO "sample %d smpl_offset = 0x%08x", i, smpl_offset);
 
-		if (smpl_offset == 0)
+		if (smpl_offset == 0) {
 			continue;
+		}
 
 		hio_seek(f, start + smpl_offset, SEEK_SET);
 		instr.length = hio_read32b(f);
 		instr.type = hio_read16b(f);
 
-		pos = hio_tell(f);
+		if ((pos = hio_tell(f)) < 0) {
+			return -1;
+		}
 
 		if (expdata_offset && i < expdata.i_ext_entries) {
 			struct xmp_instrument *xxi = &mod->xxi[i];
-			hio_seek(f, iinfo_offset + i * expdata.i_ext_entrsz,
-								SEEK_SET);
+			int offset = iinfo_offset + i * expdata.i_ext_entrsz;
+
+			if (offset < 0 || hio_seek(f, offset, SEEK_SET) < 0) {
+				return -1;
+			}
 			hio_read(&xxi->name, 40, 1, f);
-			D_(D_INFO "[%2x] %-40.40s %d", i, name, instr.type);
+			D_(D_INFO "[%2x] %-40.40s %d", i, mod->xxi[i].name, instr.type);
 		}
 
-		exp_smp.finetune = 0;
+		memset(&exp_smp, 0, sizeof(struct InstrExt));
+
 		if (expdata_offset && i < expdata.s_ext_entries) {
-			hio_seek(f, expsmp_offset + i * expdata.s_ext_entrsz,
-							SEEK_SET);
+			int offset = expsmp_offset + i * expdata.s_ext_entrsz;
+
+			if (offset < 0 || hio_seek(f, offset, SEEK_SET) < 0) {
+				return -1;
+			}
 			exp_smp.hold = hio_read8(f);
 			exp_smp.decay = hio_read8(f);
 			exp_smp.suppress_midi_off = hio_read8(f);
@@ -428,9 +465,7 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				return -1;
 
 			continue;
-		}
-
-		if (instr.type == -1) {			/* Synthetic */
+		} else if (instr.type == -1) {		/* Synthetic */
 			int ret = mmd_load_synth_instrument(f, m, i, smp_idx,
 				&synth, &exp_smp, &song.sample[i]);
 
@@ -446,9 +481,7 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				return -1;
 
 			continue;
-		}
-
-		if (instr.type >= 1 && instr.type <= 6) {	/* IFFOCT */
+		} else if (instr.type >= 1 && instr.type <= 6) { /* IFFOCT */
 			int ret;
 			const int oct = num_oct[instr.type - 1];
 
@@ -463,13 +496,11 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			smp_idx += oct;
 
 			continue;
-		}
-
-		/* Filter out stereo samples */
-		if ((instr.type & ~(S_16 | STEREO)) != 0)
+		} else if ((instr.type & ~(S_16 | STEREO)) != 0) {
+			D_(D_WARN "stereo sample unsupported");
+			mod->xxi[i].nsm = 0;
 			continue;
-
-		if (instr.type == 0) {			/* Sample */
+		} else if ((instr.type & ~S_16) == 0) {	/* Sample */
 			int ret;
 
 			hio_seek(f, start + smpl_offset + 6, SEEK_SET);
@@ -484,6 +515,10 @@ static int mmd3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			smp_idx++;
 
 			continue;
+		} else {
+			/* Invalid instrument type */
+			D_(D_CRIT "invalid instrument type");
+			return -1;
 		}
 	}
 
diff --git a/src/loaders/mmd_common.c b/src/loaders/mmd_common.c
index dd072d1..b66a343 100644
--- a/src/loaders/mmd_common.c
+++ b/src/loaders/mmd_common.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -133,7 +133,11 @@ void mmd_xlat_fx(struct xmp_event *event, int bpm_on, int bpmlen, int med_8ch,
 		 * This sets the secondary tempo (the number of timing
 		 * pulses per note). The argument must be from 01 to 20.
 		 */
-		event->fxt = FX_SPEED;
+		if (event->fxp >= 1 && event->fxp <= 20) {
+			event->fxt = FX_SPEED;
+		} else {
+			event->fxt = event->fxp = 0;
+		}
 		break;
 	case 0x0a:
 		/* 0A not mentioned but it's Protracker-compatible */
@@ -378,6 +382,11 @@ int mmd_load_hybrid_instrument(HIO_HANDLE *f, struct module_data *m, int i,
 	int length, type;
 	int pos = hio_tell(f);
 
+	/* Sanity check */
+	if (smp_idx >= mod->smp) {
+		return -1;
+	}
+
 	synth->defaultdecay = hio_read8(f);
 	hio_seek(f, 3, SEEK_CUR);
 	synth->rep = hio_read16b(f);
@@ -390,15 +399,20 @@ int mmd_load_hybrid_instrument(HIO_HANDLE *f, struct module_data *m, int i,
 	hio_read(synth->voltbl, 1, 128, f);;
 	hio_read(synth->wftbl, 1, 128, f);;
 
+	/* Sanity check */
+	if (synth->voltbllen > 128 || synth->wftbllen > 128) {
+		return -1;
+	}
+
 	hio_seek(f, pos - 6 + hio_read32b(f), SEEK_SET);
 	length = hio_read32b(f);
 	type = hio_read16b(f);
 
-	if (med_new_instrument_extras(xxi) != 0)
+	if (libxmp_med_new_instrument_extras(xxi) != 0)
 		return -1;
 
 	xxi->nsm = 1;
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 		return -1;
 
 	MED_INSTRUMENT_EXTRAS((*xxi))->vts = synth->volspeed;
@@ -419,7 +433,7 @@ int mmd_load_hybrid_instrument(HIO_HANDLE *f, struct module_data *m, int i,
 	xxs->lpe = xxs->lps + 2 * sample->replen;
 	xxs->flg = sample->replen > 1 ?  XMP_SAMPLE_LOOP : 0;
 
-	if (load_sample(m, f, 0, xxs, NULL) < 0)
+	if (libxmp_load_sample(m, f, 0, xxs, NULL) < 0)
 		return -1;
 
 	return 0;
@@ -448,6 +462,11 @@ int mmd_load_synth_instrument(HIO_HANDLE *f, struct module_data *m, int i,
 	for (j = 0; j < 64; j++)
 		synth->wf[j] = hio_read32b(f);
 
+	/* Sanity check */
+	if (synth->voltbllen > 128 || synth->wftbllen > 128 || synth->wforms > 256) {
+		return -1;
+	}
+
 	D_(D_INFO "  VS:%02x WS:%02x WF:%02x %02x %+3d %+1d",
 			synth->volspeed, synth->wfspeed,
 			synth->wforms & 0xff,
@@ -455,16 +474,19 @@ int mmd_load_synth_instrument(HIO_HANDLE *f, struct module_data *m, int i,
 			sample->strans,
 			exp_smp->finetune);
 
-	if (synth->wforms == 0xffff)	
+	if (synth->wforms == 0xffff) {
+		xxi->nsm = 0;
 		return 1;
+	}
+
 	if (synth->wforms > 64)
 		return -1;
 
-	if (med_new_instrument_extras(&mod->xxi[i]) != 0)
+	if (libxmp_med_new_instrument_extras(&mod->xxi[i]) != 0)
 		return -1;
 
 	mod->xxi[i].nsm = synth->wforms;
-	if (subinstrument_alloc(mod, i, synth->wforms) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, synth->wforms) < 0)
 		return -1;
 
 	MED_INSTRUMENT_EXTRAS((*xxi))->vts = synth->volspeed;
@@ -474,6 +496,10 @@ int mmd_load_synth_instrument(HIO_HANDLE *f, struct module_data *m, int i,
 		struct xmp_subinstrument *sub = &xxi->sub[j];
 		struct xmp_sample *xxs = &mod->xxs[smp_idx];
 
+		/* Sanity check */
+		if (j >= xxi->nsm || smp_idx >= mod->smp)
+			return -1;
+
 		sub->pan = 0x80;
 		sub->vol = 64;
 		sub->xpo = 12 + sample->strans;
@@ -487,7 +513,7 @@ int mmd_load_synth_instrument(HIO_HANDLE *f, struct module_data *m, int i,
 		xxs->lpe = mod->xxs[smp_idx].len;
 		xxs->flg = XMP_SAMPLE_LOOP;
 
-		if (load_sample(m, f, 0, xxs, NULL) < 0)
+		if (libxmp_load_sample(m, f, 0, xxs, NULL) < 0)
 			return -1;
 
 		smp_idx++;
@@ -507,14 +533,18 @@ int mmd_load_sampled_instrument(HIO_HANDLE *f, struct module_data *m, int i,
 	struct xmp_sample *xxs;
 	int j, k;
 
-	// hold & decay support
-        if (med_new_instrument_extras(xxi) != 0)
+	/* Sanity check */
+	if (smp_idx >= mod->smp)
+		return -1;
+
+	/* hold & decay support */
+        if (libxmp_med_new_instrument_extras(xxi) != 0)
                 return -1;
 	MED_INSTRUMENT_EXTRAS(*xxi)->hold = exp_smp->hold;
 	xxi->rls = 0xfff - (exp_smp->decay << 4);
 
 	xxi->nsm = 1;
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 		return -1;
 
 	sub = &xxi->sub[0];
@@ -576,7 +606,7 @@ int mmd_load_sampled_instrument(HIO_HANDLE *f, struct module_data *m, int i,
 	}
 
 
-	if (load_sample(m, f, SAMPLE_FLAG_BIGEND, xxs, NULL) < 0) {
+	if (libxmp_load_sample(m, f, SAMPLE_FLAG_BIGEND, xxs, NULL) < 0) {
 		return -1;
 	}
 
@@ -614,15 +644,19 @@ int mmd_load_iffoct_instrument(HIO_HANDLE *f, struct module_data *m, int i,
 	if (num_oct < 2 || num_oct > 7)
 		return -1;
 
-	// hold & decay support
-	if (med_new_instrument_extras(xxi) != 0)
+	/* Sanity check */
+	if (smp_idx + num_oct > mod->smp)
+		return -1;
+
+	/* hold & decay support */
+	if (libxmp_med_new_instrument_extras(xxi) != 0)
 		return -1;
 
 	MED_INSTRUMENT_EXTRAS(*xxi)->hold = exp_smp->hold;
 	xxi->rls = 0xfff - (exp_smp->decay << 4);
 
 	xxi->nsm = num_oct;
-	if (subinstrument_alloc(mod, i, num_oct) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, num_oct) < 0)
 		return -1;
 
 	/* base octave size */
@@ -650,7 +684,7 @@ int mmd_load_iffoct_instrument(HIO_HANDLE *f, struct module_data *m, int i,
 			xxs->flg |= XMP_SAMPLE_LOOP;
 		}
 	
-		if (load_sample(m, f, SAMPLE_FLAG_BIGEND, xxs, NULL) < 0) {
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_BIGEND, xxs, NULL) < 0) {
 			return -1;
 		}
 
@@ -708,7 +742,7 @@ void mmd_info_text(HIO_HANDLE *f, struct module_data *m, int offset)
 	type = hio_read16b(f);
 	if (type == 1) {	/* 1 = ASCII */
 		len = hio_read32b(f);
-		if (len != 0) {
+		if (len != 0 && len < 0x7fffffff) {
 			m->comment = malloc(len + 1);
 			if (m->comment == NULL)
 				return;
diff --git a/src/loaders/mod.h b/src/loaders/mod.h
index f5cde0f..707d47c 100644
--- a/src/loaders/mod.h
+++ b/src/loaders/mod.h
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
diff --git a/src/loaders/mod_load.c b/src/loaders/mod_load.c
index 294406d..378eecd 100644
--- a/src/loaders/mod_load.c
+++ b/src/loaders/mod_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -36,18 +36,15 @@
  */
 
 #include 
-#include 
-#include 
-#include 
 #include 
 #include "loader.h"
 #include "mod.h"
 
 struct mod_magic {
-    char *magic;
-    int flag;
-    int id;
-    int ch;
+	char *magic;
+	int flag;
+	int id;
+	int ch;
 };
 
 #define TRACKER_PROTRACKER	0
@@ -61,6 +58,7 @@ struct mod_magic {
 #define TRACKER_FLEXTRAX	8
 #define TRACKER_MODSGRAVE	9
 #define TRACKER_SCREAMTRACKER3	10
+#define TRACKER_OPENMPT		11
 #define TRACKER_UNKNOWN_CONV	95
 #define TRACKER_CONVERTEDST	96
 #define TRACKER_CONVERTED	97
@@ -70,150 +68,317 @@ struct mod_magic {
 #define TRACKER_PROBABLY_NOISETRACKER 20
 
 const struct mod_magic mod_magic[] = {
-    { "M.K.", 0, TRACKER_PROTRACKER, 4 },
-    { "M!K!", 1, TRACKER_PROTRACKER, 4 },
-    { "M&K!", 1, TRACKER_NOISETRACKER, 4 },
-    { "N.T.", 1, TRACKER_NOISETRACKER, 4 },
-    { "6CHN", 0, TRACKER_FASTTRACKER, 6 },
-    { "8CHN", 0, TRACKER_FASTTRACKER, 8 },
-    { "CD61", 1, TRACKER_OCTALYSER, 6 },	/* Atari STe/Falcon */
-    { "CD81", 1, TRACKER_OCTALYSER, 8 },	/* Atari STe/Falcon */
-    { "TDZ4", 1, TRACKER_TAKETRACKER, 4 },	/* see XModule SaveTracker.c */
-    { "FA04", 1, TRACKER_DIGITALTRACKER, 4 },	/* Atari Falcon */
-    { "FA06", 1, TRACKER_DIGITALTRACKER, 6 },	/* Atari Falcon */
-    { "FA08", 1, TRACKER_DIGITALTRACKER, 8 },	/* Atari Falcon */
-    { "NSMS", 1, TRACKER_UNKNOWN, 4 },		/* in Kingdom.mod */
-    { "", 0 }
+	{"M.K.", 0, TRACKER_PROTRACKER, 4},
+	{"M!K!", 1, TRACKER_PROTRACKER, 4},
+	{"M&K!", 1, TRACKER_NOISETRACKER, 4},
+	{"N.T.", 1, TRACKER_NOISETRACKER, 4},
+	{"6CHN", 0, TRACKER_FASTTRACKER, 6},
+	{"8CHN", 0, TRACKER_FASTTRACKER, 8},
+	{"CD61", 1, TRACKER_OCTALYSER, 6},	/* Atari STe/Falcon */
+	{"CD81", 1, TRACKER_OCTALYSER, 8},	/* Atari STe/Falcon */
+	{"TDZ4", 1, TRACKER_TAKETRACKER, 4},	/* see XModule SaveTracker.c */
+	{"FA04", 1, TRACKER_DIGITALTRACKER, 4},	/* Atari Falcon */
+	{"FA06", 1, TRACKER_DIGITALTRACKER, 6},	/* Atari Falcon */
+	{"FA08", 1, TRACKER_DIGITALTRACKER, 8},	/* Atari Falcon */
+	{"NSMS", 1, TRACKER_UNKNOWN, 4},	/* in Kingdom.mod */
+	{"", 0}
 };
 
+static int mod_test(HIO_HANDLE *, char *, const int);
+static int mod_load(struct module_data *, HIO_HANDLE *, const int);
 
-static int mod_test (HIO_HANDLE *, char *, const int);
-static int mod_load (struct module_data *, HIO_HANDLE *, const int);
-
-const struct format_loader mod_loader = {
-    "Amiga Protracker/Compatible",
-    mod_test,
-    mod_load
+const struct format_loader libxmp_loader_mod = {
+	"Amiga Protracker/Compatible",
+	mod_test,
+	mod_load
 };
 
-static int mod_test(HIO_HANDLE *f, char *t, const int start)
+static int validate_pattern(uint8 *buf)
 {
-    int i;
-    char buf[4];
-    struct stat st;
-    int smp_size, num_pat;
-
-    hio_seek(f, start + 1080, SEEK_SET);
-    if (hio_read(buf, 1, 4, f) < 4)
-	return -1;
+	int i, j;
 
-    if (!strncmp(buf + 2, "CH", 2) && isdigit((int)buf[0]) && isdigit((int)buf[1])) {
-	i = (buf[0] - '0') * 10 + buf[1] - '0';
-	if (i > 0 && i <= 32) {
-	    goto found;
+	for (i = 0; i < 64; i++) {
+		for (j = 0; j < 4; j++) {
+			uint8 *d = buf + (i * 4 + j) * 4;
+			if ((d[0] >> 4) > 1) {
+				return -1;
+			}
+		}
 	}
-    }
 
-    if (!strncmp(buf + 1, "CHN", 3) && isdigit((int)*buf)) {
-	if (*buf - '0') {
-	    goto found;
+	return 0;
+}
+
+static int mod_test(HIO_HANDLE * f, char *t, const int start)
+{
+	int i;
+	char buf[4];
+	uint8 pat_buf[1024];
+	int smp_size, num_pat;
+	long size;
+
+	hio_seek(f, start + 1080, SEEK_SET);
+	if (hio_read(buf, 1, 4, f) < 4) {
+		return -1;
 	}
-    }
 
-    for (i = 0; mod_magic[i].ch; i++) {
-	if (!memcmp(buf, mod_magic[i].magic, 4))
-	    break;
-    }
-    if (mod_magic[i].ch == 0)
-	return -1;
+	if (!strncmp(buf + 2, "CH", 2) && isdigit((int)buf[0])
+	    && isdigit((int)buf[1])) {
+		i = (buf[0] - '0') * 10 + buf[1] - '0';
+		if (i > 0 && i <= 32) {
+			goto found;
+		}
+	}
 
-    /*
-     * Sanity check to prevent loading NoiseRunner and other module
-     * formats with valid magic at offset 1080
-     */
+	if (!strncmp(buf + 1, "CHN", 3) && isdigit((int)*buf)) {
+		if (*buf - '0') {
+			goto found;
+		}
+	}
 
-    hio_seek(f, start + 20, SEEK_SET);
-    for (i = 0; i < 31; i++) {
-	hio_seek(f, 22, SEEK_CUR);		/* Instrument name */
-	if (hio_read16b(f) & 0x8000)		/* test length */
-		return -1;
-	if (hio_read8(f) & 0xf0)		/* test finetune */
-		return -1;
-	if (hio_read8(f) > 0x40)		/* test volume */
-		return -1;
-	if (hio_read16b(f) & 0x8000)		/* test loop start */
-		return -1;
-	if (hio_read16b(f) & 0x8000)		/* test loop size */
+	for (i = 0; mod_magic[i].ch; i++) {
+		if (!memcmp(buf, mod_magic[i].magic, 4))
+			break;
+	}
+	if (mod_magic[i].ch == 0) {
 		return -1;
-    }
+	}
 
-    if (HIO_HANDLE_TYPE(f) != HIO_HANDLE_TYPE_FILE)
-	goto found;
+	/*
+	 * Sanity check to prevent loading NoiseRunner and other module
+	 * formats with valid magic at offset 1080
+	 */
 
-    /* Test for UNIC tracker modules
-     *
-     * From Gryzor's Pro-Wizard PW_FORMATS-Engl.guide:
-     * ``The UNIC format is very similar to Protracker... At least in the
-     * heading... same length : 1084 bytes. Even the "M.K." is present,
-     * sometimes !! Maybe to disturb the rippers.. hehe but Pro-Wizard
-     * doesn't test this only!''
-     */
+	hio_seek(f, start + 20, SEEK_SET);
+	for (i = 0; i < 31; i++) {
+		uint8 x;
 
-    /* get file size */
-    hio_stat(f, &st);
-    smp_size = 0;
-    hio_seek(f, start + 20, SEEK_SET);
+		hio_seek(f, 22, SEEK_CUR);	/* Instrument name */
 
-    /* get samples size */
-    for (i = 0; i < 31; i++) {
-	hio_seek(f, 22, SEEK_CUR);
-	smp_size += 2 * hio_read16b(f);		/* Length in 16-bit words */
-	hio_seek(f, 6, SEEK_CUR);
-    } 
-
-    /* get number of patterns */
-    num_pat = 0;
-    hio_seek(f, start + 952, SEEK_SET);
-    for (i = 0; i < 128; i++) {
-	uint8 x = hio_read8(f);
-	if (x > 0x7f)
-		break;
-	if (x > num_pat)
-	    num_pat = x;
-    }
-    num_pat++;
+		/* OpenMPT can create mods with large samples */
+		hio_read16b(f);	/* sample size */
 
-    if (start + 1084 + num_pat * 0x300 + smp_size == st.st_size)
-	return -1;
+		/* Chris Spiegel tells me that sandman.mod has 0x20 in finetune */
+		x = hio_read8(f);
+		if (x & 0xf0 && x != 0x20)	/* test finetune */
+			return -1;
+		if (hio_read8(f) > 0x40)	/* test volume */
+			return -1;
+		hio_read16b(f);	/* loop start */
+		hio_read16b(f);	/* loop size */
+	}
 
-  found:
-    hio_seek(f, start + 0, SEEK_SET);
-    read_title(f, t, 20);
+	/* Test for UNIC tracker modules
+	 *
+	 * From Gryzor's Pro-Wizard PW_FORMATS-Engl.guide:
+	 * ``The UNIC format is very similar to Protracker... At least in the
+	 * heading... same length : 1084 bytes. Even the "M.K." is present,
+	 * sometimes !! Maybe to disturb the rippers.. hehe but Pro-Wizard
+	 * doesn't test this only!''
+	 */
+
+	/* get file size */
+	size = hio_size(f);
+	smp_size = 0;
+	hio_seek(f, start + 20, SEEK_SET);
+
+	/* get samples size */
+	for (i = 0; i < 31; i++) {
+		hio_seek(f, 22, SEEK_CUR);
+		smp_size += 2 * hio_read16b(f);	/* Length in 16-bit words */
+		hio_seek(f, 6, SEEK_CUR);
+	}
 
-    return 0;
-}
+	/* get number of patterns */
+	num_pat = 0;
+	hio_seek(f, start + 952, SEEK_SET);
+	for (i = 0; i < 128; i++) {
+		uint8 x = hio_read8(f);
+		if (x > 0x7f)
+			break;
+		if (x > num_pat)
+			num_pat = x;
+	}
+	num_pat++;
 
+	/* see if module size matches UNIC */
+	if (start + 1084 + num_pat * 0x300 + smp_size == size)
+		return -1;
+
+	/* validate pattern data in an attempt to catch UNICs with MOD size */
+	for (i = 0; i < num_pat; i++) {
+		hio_seek(f, start + 1084 + 1024 * i, SEEK_SET);
+		hio_read(pat_buf, 1024, 1, f);
+		if (validate_pattern(pat_buf) < 0)
+			return -1;
+	}
+
+found:
+	hio_seek(f, start + 0, SEEK_SET);
+	libxmp_read_title(f, t, 20);
 
-static int is_st_ins (char *s)
-{
-    if (s[0] != 's' && s[0] != 'S')
-	return 0;
-    if (s[1] != 't' && s[1] != 'T')
-	return 0;
-    if (s[2] != '-' || s[5] != ':')
-	return 0;
-    if (!isdigit((int)s[3]) || !isdigit((int)s[4]))
 	return 0;
+}
 
-    return 1;
+
+static int is_st_ins(char *s)
+{
+	if (s[0] != 's' && s[0] != 'S')
+		return 0;
+	if (s[1] != 't' && s[1] != 'T')
+		return 0;
+	if (s[2] != '-' || s[5] != ':')
+		return 0;
+	if (!isdigit((int)s[3]) || !isdigit((int)s[4]))
+		return 0;
+
+	return 1;
 }
 
+static int get_tracker_id(struct module_data *m, struct mod_header *mh, int id)
+{
+	struct xmp_module *mod = &m->mod;
+	int has_loop_0 = 0;
+	int has_vol_in_empty_ins = 0;
+	int i;
+
+	/* Check if has instruments with loop size 0 */
+	for (i = 0; i < 31; i++) {
+		if (mh->ins[i].loop_size == 0) {
+			has_loop_0 = 1;
+			break;
+		}
+	}
+
+	/* Check if has instruments with size 0 and volume > 0 */
+	for (i = 0; i < 31; i++) {
+		if (mh->ins[i].size == 0 && mh->ins[i].volume > 0) {
+			has_vol_in_empty_ins = 1;
+			break;
+		}
+	}
+
+	/*
+	 * Test Protracker-like files
+	 */
+	if (mh->restart == mod->pat) {
+		if (mod->chn == 4) {
+			id = TRACKER_SOUNDTRACKER;
+		} else {
+			id = TRACKER_UNKNOWN;
+		}
+	} else if (mh->restart == 0x78) {
+		if (mod->chn == 4) {
+			/* Can't trust this for Noisetracker, MOD.Data City Remix
+			 * has Protracker effects and Noisetracker restart byte
+			 */
+			id = TRACKER_PROBABLY_NOISETRACKER;
+		} else {
+			id = TRACKER_UNKNOWN;
+		}
+		return id;
+	} else if (mh->restart < 0x7f) {
+		if (mod->chn == 4 && !has_vol_in_empty_ins) {
+			id = TRACKER_NOISETRACKER;
+		} else {
+			id = TRACKER_UNKNOWN; /* ? */
+		}
+		mod->rst = mh->restart;
+	} else if (mh->restart == 0x7f) {
+		if (mod->chn == 4) {
+			if (has_loop_0) {
+				id = TRACKER_CLONE;
+			}
+		} else {
+			id = TRACKER_SCREAMTRACKER3;
+		}
+		return id;
+	} else if (mh->restart > 0x7f) {
+		id = TRACKER_UNKNOWN; /* ? */
+		return id;
+	}
+
+	if (!has_loop_0) { /* All loops are size 2 or greater */
+
+		for (i = 0; i < 31; i++) {
+			if (mh->ins[i].size == 1 && mh->ins[i].volume == 0) {
+				return TRACKER_CONVERTED;
+			}
+		}
+
+		for (i = 0; i < 31; i++) {
+			if (is_st_ins((char *)mh->ins[i].name))
+				break;
+		}
+		if (i == 31) {	/* No st- instruments */
+			for (i = 0; i < 31; i++) {
+				if (mh->ins[i].size != 0
+				    || mh->ins[i].loop_size != 1) {
+					continue;
+				}
+
+				switch (mod->chn) {
+				case 4:
+					if (has_vol_in_empty_ins) {
+						id = TRACKER_OPENMPT;
+					} else {
+						id = TRACKER_NOISETRACKER;
+						/* or Octalyser */
+					}
+					break;
+				case 6:
+				case 8:
+					id = TRACKER_OCTALYSER;
+					break;
+				default:
+					id = TRACKER_UNKNOWN;
+				}
+				return id;
+			}
+
+			if (mod->chn == 4) {
+				id = TRACKER_PROTRACKER;
+			} else if (mod->chn == 6 || mod->chn == 8) {
+				/* FastTracker 1.01? */
+				id = TRACKER_FASTTRACKER;
+			} else {
+				id = TRACKER_UNKNOWN;
+			}
+		}
+	} else { /* Has loops with size 0 */
+		for (i = 15; i < 31; i++) {
+			if (strlen((char *)mh->ins[i].name)
+			    || mh->ins[i].size > 0)
+				break;
+		}
+		if (i == 31 && is_st_ins((char *)mh->ins[14].name)) {
+			return TRACKER_CONVERTEDST;
+		}
+
+		/* Assume that Fast Tracker modules won't have ST- instruments */
+		for (i = 0; i < 31; i++) {
+			if (is_st_ins((char *)mh->ins[i].name))
+				break;
+		}
+		if (i < 31) {
+			return TRACKER_UNKNOWN_CONV;
+		}
+
+		if (mod->chn == 4 || mod->chn == 6 || mod->chn == 8) {
+			return TRACKER_FASTTRACKER;
+		}
+
+		id = TRACKER_UNKNOWN;	/* ??!? */
+	}
+
+	return id;
+}
 
 static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 {
     struct xmp_module *mod = &m->mod;
     int i, j;
-    int smp_size, /*pat_size,*/ wow, ptsong = 0;
+    int smp_size, ptsong = 0;
     struct xmp_event *event;
     struct mod_header mh;
     uint8 mod_event[4];
@@ -222,6 +387,7 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
     char magic[8], idbuffer[32];
     int ptkloop = 0;			/* Protracker loop */
     int tracker_id = TRACKER_PROTRACKER;
+    int out_of_range = 0;
 
     LOAD_INIT();
 
@@ -231,7 +397,7 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
     smp_size = 0;
     /*pat_size = 0;*/
 
-    m->quirk |= QUIRK_MODRNG;
+    m->period_type = PERIOD_MODRNG;
 
     hio_read(&mh.name, 20, 1, f);
     for (i = 0; i < 31; i++) {
@@ -248,7 +414,10 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
     mh.restart = hio_read8(f);
     hio_read(&mh.order, 128, 1, f);
     memset(magic, 0, 8);
-    hio_read(magic, 4, 1, f);
+    hio_read(magic, 1, 4, f);
+    if (hio_error(f)) {
+        return -1;
+    }
 
     for (i = 0; mod_magic[i].ch; i++) {
 	if (!(strncmp (magic, mod_magic[i].magic, 4))) {
@@ -259,7 +428,7 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	}
     }
 
-    if (!mod->chn) {
+    if (mod->chn == 0) {
 	if (!strncmp(magic + 2, "CH", 2) &&
 	    isdigit((int)magic[0]) && isdigit((int)magic[1])) {
 	    mod->chn = (*magic - '0') * 10 + magic[1] - '0';
@@ -270,7 +439,6 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	}
 	tracker_id = mod->chn & 1 ? TRACKER_TAKETRACKER : TRACKER_FASTTRACKER2;
 	detected = 1;
-	m->quirk &= ~QUIRK_MODRNG;
     }
 
     strncpy(mod->name, (char *) mh.name, 20);
@@ -293,28 +461,43 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     /*pat_size = 256 * mod->chn * mod->pat;*/
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     for (i = 0; i < mod->ins; i++) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	struct xmp_instrument *xxi;
+	struct xmp_subinstrument *sub;
+	struct xmp_sample *xxs;
+
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 	    return -1;
 
-	mod->xxs[i].len = 2 * mh.ins[i].size;
-	mod->xxs[i].lps = 2 * mh.ins[i].loop_start;
-	mod->xxs[i].lpe = mod->xxs[i].lps + 2 * mh.ins[i].loop_size;
-	if (mod->xxs[i].lpe > mod->xxs[i].len)
-		mod->xxs[i].lpe = mod->xxs[i].len;
-	mod->xxs[i].flg = (mh.ins[i].loop_size > 1 && mod->xxs[i].lpe >= 4) ?
+	if (mh.ins[i].size >= 0x8000) {
+	    tracker_id = TRACKER_OPENMPT;
+	    detected = 1;
+	}
+
+	xxi = &mod->xxi[i];
+	sub = &xxi->sub[0];
+	xxs = &mod->xxs[i];
+
+	xxs->len = 2 * mh.ins[i].size;
+	xxs->lps = 2 * mh.ins[i].loop_start;
+	xxs->lpe = xxs->lps + 2 * mh.ins[i].loop_size;
+	if (xxs->lpe > xxs->len) {
+		xxs->lpe = xxs->len;
+	}
+	xxs->flg = (mh.ins[i].loop_size > 1 && xxs->lpe >= 4) ?
 		XMP_SAMPLE_LOOP : 0;
-	mod->xxi[i].sub[0].fin = (int8)(mh.ins[i].finetune << 4);
-	mod->xxi[i].sub[0].vol = mh.ins[i].volume;
-	mod->xxi[i].sub[0].pan = 0x80;
-	mod->xxi[i].sub[0].sid = i;
-	instrument_name(mod, i, mh.ins[i].name, 22);
-
-	if (mod->xxs[i].len > 0)
-		mod->xxi[i].nsm = 1;
+	sub->fin = (int8)(mh.ins[i].finetune << 4);
+	sub->vol = mh.ins[i].volume;
+	sub->pan = 0x80;
+	sub->sid = i;
+	libxmp_instrument_name(mod, i, mh.ins[i].name, 22);
+
+	if (xxs->len > 0) {
+		xxi->nsm = 1;
+	}
     }
 
     /*
@@ -336,6 +519,9 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     if (0x43c + mod->pat * 4 * mod->chn * 0x40 + smp_size < m->size) {
 	int pos = hio_tell(f);
+        if (pos < 0) {
+           return -1;
+        }
 	hio_seek(f, start + 0x43c + mod->pat * 4 * mod->chn * 0x40 + smp_size, SEEK_SET);
 	hio_read(idbuffer, 1, 4, f);
 	hio_seek(f, start + pos, SEEK_SET);
@@ -355,134 +541,32 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
      * the module is an 8 channel WOW.
      */
 
-    if ((wow = (!strncmp(magic, "M.K.", 4) &&
-		(0x43c + mod->pat * 32 * 0x40 + smp_size == m->size)))) {
+    if ((!strncmp(magic, "M.K.", 4) &&
+		(0x43c + mod->pat * 32 * 0x40 + smp_size == m->size))) {
 	mod->chn = 8;
 	tracker_id = TRACKER_MODSGRAVE;
-	goto skip_test;
     }
-
-    /* Test for Protracker song files
-     */
+    /* Test for Protracker song files */
     else if ((ptsong = (!strncmp((char *)magic, "M.K.", 4) &&
 		(0x43c + mod->pat * 0x400 == m->size)))) {
 	tracker_id = TRACKER_PROTRACKER;
 	goto skip_test;
     }
-
-    /* Test Protracker-like files
-     */
-    if (mod->chn == 4 && mh.restart == mod->pat) {
-	tracker_id = TRACKER_SOUNDTRACKER;
-    } else if (mod->chn == 4 && mh.restart == 0x78) {
-	/* Can't trust this for Noisetracker, MOD.Data City Remix has
-	 * Protracker effects and Noisetracker restart byte */
-        tracker_id = TRACKER_PROBABLY_NOISETRACKER;
-    } else if (mh.restart < 0x7f) {
-	if (mod->chn == 4) {
-	    tracker_id = TRACKER_NOISETRACKER;
-	} else {
-	    tracker_id = TRACKER_UNKNOWN;
-	}
-	mod->rst = mh.restart;
+    /* something else */
+    else {
+        tracker_id = get_tracker_id(m, &mh, tracker_id);
     }
 
-    if (mod->chn != 4 && mh.restart == 0x7f) {
-	tracker_id = TRACKER_SCREAMTRACKER3;
-	m->quirk &= ~QUIRK_MODRNG;
-	m->read_event_type = READ_EVENT_ST3;
-    }
-
-    if (mod->chn == 4 && mh.restart == 0x7f) {
-	for (i = 0; i < 31; i++) {
-	    if (mh.ins[i].loop_size == 0)
-		break;
-	}
-	if (i < 31) {
-	    tracker_id = TRACKER_CLONE;
-	}
-    }
-
-    if (mh.restart != 0x78 && mh.restart < 0x7f) {
-	for (i = 0; i < 31; i++) {
-	    if (mh.ins[i].loop_size == 0)
-		break;
-	}
-	if (i == 31) {	/* All loops are size 2 or greater */
-	    for (i = 0; i < 31; i++) {
-		if (mh.ins[i].size == 1 && mh.ins[i].volume == 0) {
-		    tracker_id = TRACKER_CONVERTED;
-		    goto skip_test;
-		}
-	    }
-
-	    for (i = 0; i < 31; i++) {
-	        if (is_st_ins((char *)mh.ins[i].name))
-		    break;
-	    }
-	    if (i == 31) {	/* No st- instruments */
-	        for (i = 0; i < 31; i++) {
-		    if (mh.ins[i].size == 0 && mh.ins[i].loop_size == 1) {
-			switch (mod->chn) {
-			case 4:
-			    tracker_id = TRACKER_NOISETRACKER;	/* or Octalyser */
-			    break;
-			case 6:
-			case 8:
-		            tracker_id = TRACKER_OCTALYSER;
-			    break;
-			default:
-		            tracker_id = TRACKER_UNKNOWN;
-			}
-		        goto skip_test;
-		    }
-	        }
-
-		if (mod->chn == 4) {
-	    	    tracker_id = TRACKER_PROTRACKER;
-		} else if (mod->chn == 6 || mod->chn == 8) {
-	    	    tracker_id = TRACKER_FASTTRACKER;	/* FastTracker 1.01? */
-		    m->quirk &= ~QUIRK_MODRNG;
-		} else {
-	    	    tracker_id = TRACKER_UNKNOWN;
-		}
-	    }
-	} else {	/* Has loops with 0 size */
-	    for (i = 15; i < 31; i++) {
-	        if (strlen((char *)mh.ins[i].name) || mh.ins[i].size > 0)
-		    break;
-	    }
-	    if (i == 31 && is_st_ins((char *)mh.ins[14].name)) {
-		tracker_id = TRACKER_CONVERTEDST;
-		goto skip_test;
-	    }
-
-	    /* Assume that Fast Tracker modules won't have ST- instruments */
-	    for (i = 0; i < 31; i++) {
-	        if (is_st_ins((char *)mh.ins[i].name))
-		    break;
-	    }
-	    if (i < 31) {
-		tracker_id = TRACKER_UNKNOWN_CONV;
-		goto skip_test;
-	    }
-
-	    if (mod->chn == 4 || mod->chn == 6 || mod->chn == 8) {
-	    	tracker_id = TRACKER_FASTTRACKER;
-	        m->quirk &= ~QUIRK_MODRNG;
-		goto skip_test;
-	    }
+skip_test:
 
-	    tracker_id = TRACKER_UNKNOWN;	/* ??!? */
-	}
+    if (mod->chn >= XMP_MAX_CHANNELS) {
+        return -1;
     }
 
-skip_test:
-
     mod->trk = mod->chn * mod->pat;
 
     for (i = 0; i < mod->ins; i++) {
-	D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d %c\n",
+	D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d %c",
 		i, mod->xxi[i].name,
 		mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
 		(mh.ins[i].loop_size > 1 && mod->xxs[i].lpe > 8) ?
@@ -492,36 +576,72 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			mod->xxs[i].len > mod->xxs[i].lpe ? '!' : ' ');
     }
 
-    if (pattern_init(mod) < 0)
+    if (libxmp_init_pattern(mod) < 0)
 	return -1;
 
     /* Load and convert patterns */
     D_(D_INFO "Stored patterns: %d", mod->pat);
 
     for (i = 0; i < mod->pat; i++) {
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
+	long pos;
+
+	if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 	    return -1;
 
+	pos = hio_tell(f);
+	if (pos < 0) {
+		return -1;
+	}
+
 	for (j = 0; j < (64 * mod->chn); j++) {
-	    event = &EVENT (i, j % mod->chn, j / mod->chn);
-	    hio_read (mod_event, 1, 4, f);
+            int period;
+
+	    event = &EVENT(i, j % mod->chn, j / mod->chn);
+	    hio_read(mod_event, 1, 4, f);
+
+	    period = ((int)(LSN(mod_event[0])) << 8) | mod_event[1];
+	    if (period != 0 && (period < 108 || period > 907)) {
+		out_of_range = 1;
+	    }
 
 	    /* Filter noisetracker events */
 	    if (tracker_id == TRACKER_PROBABLY_NOISETRACKER) {
 		unsigned char fxt = LSN(mod_event[2]);
 		unsigned char fxp = LSN(mod_event[3]);
-        	if ((fxt > 0x06 && fxt < 0x0a) ||  (fxt == 0x0e && fxp > 1)) {
+
+        	if ((fxt > 0x06 && fxt < 0x0a) || (fxt == 0x0e && fxp > 1)) {
 		    tracker_id = TRACKER_UNKNOWN;
 		}
 	    }
+	}
+
+        if (out_of_range) {
+            if (tracker_id == TRACKER_UNKNOWN && mh.restart == 0x7f) {
+	        tracker_id = TRACKER_SCREAMTRACKER3;
+            }
+
+	    /* Check out-of-range notes in Amiga trackers */
+            if (tracker_id == TRACKER_PROTRACKER ||
+                    tracker_id == TRACKER_NOISETRACKER ||
+                    tracker_id == TRACKER_PROBABLY_NOISETRACKER ||
+                    tracker_id == TRACKER_SOUNDTRACKER) {   /* note > B-3 */
+                tracker_id = TRACKER_UNKNOWN;
+            }
+        }
+
+	hio_seek(f, pos, SEEK_SET);
+
+	for (j = 0; j < (64 * mod->chn); j++) {
+	    event = &EVENT(i, j % mod->chn, j / mod->chn);
+	    hio_read(mod_event, 1, 4, f);
 
 	    switch (tracker_id) {
 	    case TRACKER_PROBABLY_NOISETRACKER:
 	    case TRACKER_NOISETRACKER:
-	    	decode_noisetracker_event(event, mod_event);
+	    	libxmp_decode_noisetracker_event(event, mod_event);
 		break;
 	    default:	
-	        decode_protracker_event(event, mod_event);
+	        libxmp_decode_protracker_event(event, mod_event);
 	    }
 	}
     }
@@ -534,18 +654,20 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
     case TRACKER_PROBABLY_NOISETRACKER:
     case TRACKER_NOISETRACKER:
 	tracker = "Noisetracker";
-	ptkloop = 1;
+	m->quirk |= QUIRK_NOBPM;
 	break;
     case TRACKER_SOUNDTRACKER:
 	tracker = "Soundtracker";
-	ptkloop = 1;
+	m->quirk |= QUIRK_NOBPM;
 	break;
     case TRACKER_FASTTRACKER:
     case TRACKER_FASTTRACKER2:
 	tracker = "Fast Tracker";
+	m->period_type = PERIOD_AMIGA;
 	break;
     case TRACKER_TAKETRACKER:
 	tracker = "Take Tracker";
+	m->period_type = PERIOD_AMIGA;
 	break;
     case TRACKER_OCTALYSER:
 	tracker = "Octalyser";
@@ -561,7 +683,7 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	break;
     case TRACKER_SCREAMTRACKER3:
 	tracker = "Scream Tracker";
-	break;
+	m->period_type = PERIOD_AMIGA;
 	break;
     case TRACKER_CONVERTEDST:
     case TRACKER_CONVERTED:
@@ -569,14 +691,24 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	break;
     case TRACKER_CLONE:
 	tracker = "Protracker clone";
+	m->period_type = PERIOD_AMIGA;
+	break;
+    case TRACKER_OPENMPT:
+	tracker = "OpenMPT";
+	ptkloop = 1;
 	break;
     default:
     case TRACKER_UNKNOWN_CONV:
     case TRACKER_UNKNOWN:
 	tracker = "Unknown tracker";
+	m->period_type = PERIOD_AMIGA;
 	break;
     }
 
+    if (out_of_range) {
+	m->period_type = PERIOD_AMIGA;
+    }
+
     if (tracker_id == TRACKER_MODSGRAVE) {
 	snprintf(mod->type, XMP_NAME_SIZE, "%s", tracker);
     } else {
@@ -586,8 +718,6 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
     MODULE_INFO();
 
 
-
-
     /* Load samples */
 
     if (m->filename && (x = strrchr(m->filename, '/')))
@@ -601,7 +731,7 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	if (!mod->xxs[i].len)
 	    continue;
 
-	flags = ptkloop ? SAMPLE_FLAG_FULLREP : 0;
+	flags = (ptkloop && mod->xxs[i].lps == 0) ? SAMPLE_FLAG_FULLREP : 0;
 
 	if (ptsong) {
 	    HIO_HANDLE *s;
@@ -609,7 +739,7 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	    snprintf(sn, XMP_NAME_SIZE, "%s%s", pathname, mod->xxi[i].name);
 	
 	    if ((s = hio_open(sn, "rb"))) {
-	        if (load_sample(m, s, flags, &mod->xxs[i], NULL) < 0) {
+	        if (libxmp_load_sample(m, s, flags, &mod->xxs[i], NULL) < 0) {
 		    hio_close(s);
 		    return -1;
 		}
@@ -617,8 +747,13 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	    }
 	} else {
 	    uint8 buf[5];
-	    long pos = hio_tell(f);
-            int num = hio_read(buf, 1, 5, f);
+            long pos;
+            int num;
+
+	    if ((pos = hio_tell(f)) < 0) {
+                return -1;
+            }
+            num = hio_read(buf, 1, 5, f);
 
 	    if (num == 5 && !memcmp(buf, "ADPCM", 5)) {
 		flags |= SAMPLE_FLAG_ADPCM;
@@ -626,17 +761,22 @@ static int mod_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		hio_seek(f, pos, SEEK_SET);
 	    }
 
-	    if (load_sample(m, f, flags, &mod->xxs[i], NULL) < 0)
+	    if (libxmp_load_sample(m, f, flags, &mod->xxs[i], NULL) < 0)
 		return -1;
 	}
     }
 
-    if (mod->chn > 4) {
-	m->quirk &= ~QUIRK_MODRNG;
-	m->quirk |= QUIRKS_FT2;
+    if (tracker_id == TRACKER_PROTRACKER || tracker_id == TRACKER_OPENMPT) {
+	m->quirk |= QUIRK_PROTRACK;
+    } else if (tracker_id == TRACKER_SCREAMTRACKER3) {
+	m->c4rate = C4_NTSC_RATE;
+	m->quirk |= QUIRKS_ST3;
+	m->read_event_type = READ_EVENT_ST3;
+    } else if (tracker_id == TRACKER_FASTTRACKER || tracker_id == TRACKER_FASTTRACKER2 || tracker_id == TRACKER_TAKETRACKER || tracker_id == TRACKER_MODSGRAVE || mod->chn > 4) {
+	m->c4rate = C4_NTSC_RATE;
+	m->quirk |= QUIRKS_FT2 | QUIRK_FTMOD;
 	m->read_event_type = READ_EVENT_FT2;
-    } else if (strcmp(tracker, "Protracker") == 0) {
-	m->quirk |= QUIRK_INVLOOP;
+	m->period_type = PERIOD_AMIGA;
     }
 
     return 0;
diff --git a/src/loaders/mtm_load.c b/src/loaders/mtm_load.c
index a7367dc..1b482e7 100644
--- a/src/loaders/mtm_load.c
+++ b/src/loaders/mtm_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -22,7 +22,6 @@
 
 #include "loader.h"
 
-
 struct mtm_file_header {
 	uint8 magic[3];		/* "MTM" */
 	uint8 version;		/* MSN=major, LSN=minor */
@@ -48,180 +47,218 @@ struct mtm_instrument_header {
 	uint8 attr;		/* &0x01: 16bit sample */
 };
 
+static int mtm_test(HIO_HANDLE *, char *, const int);
+static int mtm_load(struct module_data *, HIO_HANDLE *, const int);
 
-static int mtm_test (HIO_HANDLE *, char *, const int);
-static int mtm_load (struct module_data *, HIO_HANDLE *, const int);
-
-const struct format_loader mtm_loader = {
-    "Multitracker",
-    mtm_test,
-    mtm_load
+const struct format_loader libxmp_loader_mtm = {
+	"Multitracker",
+	mtm_test,
+	mtm_load
 };
 
 static int mtm_test(HIO_HANDLE *f, char *t, const int start)
 {
-    uint8 buf[4];
+	uint8 buf[4];
 
-    if (hio_read(buf, 1, 4, f) < 4)
-	return -1;
-    if (memcmp(buf, "MTM", 3))
-	return -1;
-    if (buf[3] != 0x10)
-	return -1;
+	if (hio_read(buf, 1, 4, f) < 4)
+		return -1;
+	if (memcmp(buf, "MTM", 3))
+		return -1;
+	if (buf[3] != 0x10)
+		return -1;
 
-    read_title(f, t, 20);
+	libxmp_read_title(f, t, 20);
 
-    return 0;
+	return 0;
 }
 
 static int mtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 {
-    struct xmp_module *mod = &m->mod;
-    int i, j;
-    struct mtm_file_header mfh;
-    struct mtm_instrument_header mih;
-    uint8 mt[192];
-    uint16 mp[32];
-
-    LOAD_INIT();
-
-    hio_read(&mfh.magic, 3, 1, f);	/* "MTM" */
-    mfh.version = hio_read8(f);		/* MSN=major, LSN=minor */
-    hio_read(&mfh.name, 20, 1, f);	/* ASCIIZ Module name */
-    mfh.tracks = hio_read16l(f);	/* Number of tracks saved */
-    mfh.patterns = hio_read8(f);	/* Number of patterns saved */
-    mfh.modlen = hio_read8(f);		/* Module length */
-    mfh.extralen = hio_read16l(f);	/* Length of the comment field */
-    mfh.samples = hio_read8(f);		/* Number of samples */
-    mfh.attr = hio_read8(f);		/* Always zero */
-    mfh.rows = hio_read8(f);		/* Number rows per track */
-    mfh.channels = hio_read8(f);	/* Number of tracks per pattern */
-    hio_read(&mfh.pan, 32, 1, f);	/* Pan positions for each channel */
+	struct xmp_module *mod = &m->mod;
+	int i, j;
+	struct mtm_file_header mfh;
+	struct mtm_instrument_header mih;
+	uint8 mt[192];
+
+	LOAD_INIT();
+
+	hio_read(&mfh.magic, 3, 1, f);	/* "MTM" */
+	mfh.version = hio_read8(f);	/* MSN=major, LSN=minor */
+	hio_read(&mfh.name, 20, 1, f);	/* ASCIIZ Module name */
+	mfh.tracks = hio_read16l(f);	/* Number of tracks saved */
+	mfh.patterns = hio_read8(f);	/* Number of patterns saved */
+	mfh.modlen = hio_read8(f);	/* Module length */
+	mfh.extralen = hio_read16l(f);	/* Length of the comment field */
+
+	mfh.samples = hio_read8(f);	/* Number of samples */
+	if (mfh.samples > 63) {
+		return -1;
+	}
+
+	mfh.attr = hio_read8(f);	/* Always zero */
+
+	mfh.rows = hio_read8(f);	/* Number rows per track */
+	if (mfh.rows != 64)
+		return -1;
+
+	mfh.channels = hio_read8(f);	/* Number of tracks per pattern */
+	if (mfh.channels > XMP_MAX_CHANNELS) {
+		return -1;
+	}
+
+	hio_read(&mfh.pan, 32, 1, f);	/* Pan positions for each channel */
+
+	if (hio_error(f)) {
+		return -1;
+	}
 
 #if 0
-    if (strncmp ((char *)mfh.magic, "MTM", 3))
-	return -1;
+	if (strncmp((char *)mfh.magic, "MTM", 3))
+		return -1;
 #endif
 
-    mod->trk = mfh.tracks + 1;
-    mod->pat = mfh.patterns + 1;
-    mod->len = mfh.modlen + 1;
-    mod->ins = mfh.samples;
-    mod->smp = mod->ins;
-    mod->chn = mfh.channels;
-    mod->spd = 6;
-    mod->bpm = 125;
-
-    strncpy(mod->name, (char *)mfh.name, 20);
-    set_type(m, "MultiTracker %d.%02d MTM", MSN(mfh.version), LSN(mfh.version));
-
-    MODULE_INFO();
-
-    if (instrument_init(mod) < 0)
-	return -1;
-
-    /* Read and convert instruments */
-    for (i = 0; i < mod->ins; i++) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
-	    return -1;
-
-	hio_read(&mih.name, 22, 1, f);		/* Instrument name */
-	mih.length = hio_read32l(f);		/* Instrument length in bytes */
-	mih.loop_start = hio_read32l(f);	/* Sample loop start */
-	mih.loopend = hio_read32l(f);		/* Sample loop end */
-	mih.finetune = hio_read8(f);		/* Finetune */
-	mih.volume = hio_read8(f);		/* Playback volume */
-	mih.attr = hio_read8(f);		/* &0x01: 16bit sample */
-
-	mod->xxs[i].len = mih.length;
-	mod->xxs[i].lps = mih.loop_start;
-	mod->xxs[i].lpe = mih.loopend;
-	mod->xxs[i].flg = mod->xxs[i].lpe ? XMP_SAMPLE_LOOP : 0;	/* 1 == Forward loop */
-	if (mfh.attr & 1) {
-	    mod->xxs[i].flg |= XMP_SAMPLE_16BIT;
-	    mod->xxs[i].len >>= 1;
-	    mod->xxs[i].lps >>= 1;
-	    mod->xxs[i].lpe >>= 1;
-	}
+	mod->trk = mfh.tracks + 1;
+	mod->pat = mfh.patterns + 1;
+	mod->len = mfh.modlen + 1;
+	mod->ins = mfh.samples;
+	mod->smp = mod->ins;
+	mod->chn = mfh.channels;
+	mod->spd = 6;
+	mod->bpm = 125;
 
-	mod->xxi[i].sub[0].vol = mih.volume;
-	mod->xxi[i].sub[0].fin = mih.finetune;
-	mod->xxi[i].sub[0].pan = 0x80;
-	mod->xxi[i].sub[0].sid = i;
-
-	instrument_name(mod, i, mih.name, 22);
-
-	if (mod->xxs[i].len > 0)
-		mod->xxi[i].nsm = 1;
-
-	D_(D_INFO "[%2X] %-22.22s %04x%c%04x %04x %c V%02x F%+03d\n", i,
-		mod->xxi[i].name, mod->xxs[i].len,
-		mod->xxs[i].flg & XMP_SAMPLE_16BIT ? '+' : ' ',
-		mod->xxs[i].lps, mod->xxs[i].lpe,
-		mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
-		mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin - 0x80);
-    }
-
-    hio_read(mod->xxo, 1, 128, f);
-
-    if (pattern_init(mod) < 0)
-	return -1;
-
-    D_(D_INFO "Stored tracks: %d", mod->trk - 1);
-
-    for (i = 0; i < mod->trk; i++) {
-
-	if (track_alloc(mod, i, mfh.rows) < 0)
-	    return -1;
-
-	if (i == 0)
-	    continue;
-
-	hio_read (&mt, 3, 64, f);
-	for (j = 0; j < 64; j++) {
-	    if ((mod->xxt[i]->event[j].note = mt[j * 3] >> 2))
-		mod->xxt[i]->event[j].note += 37;
-	    mod->xxt[i]->event[j].ins = ((mt[j * 3] & 0x3) << 4) + MSN (mt[j * 3 + 1]);
-	    mod->xxt[i]->event[j].fxt = LSN (mt[j * 3 + 1]);
-	    mod->xxt[i]->event[j].fxp = mt[j * 3 + 2];
-	    if (mod->xxt[i]->event[j].fxt > FX_SPEED)
-		mod->xxt[i]->event[j].fxt = mod->xxt[i]->event[j].fxp = 0;
-	    /* Set pan effect translation */
-	    if ((mod->xxt[i]->event[j].fxt == FX_EXTENDED) &&
-		(MSN (mod->xxt[i]->event[j].fxp) == 0x8)) {
-		mod->xxt[i]->event[j].fxt = FX_SETPAN;
-		mod->xxt[i]->event[j].fxp <<= 4;
-	    }
+	strncpy(mod->name, (char *)mfh.name, 20);
+	libxmp_set_type(m, "MultiTracker %d.%02d MTM", MSN(mfh.version),
+		 LSN(mfh.version));
+
+	MODULE_INFO();
+
+	if (libxmp_init_instrument(m) < 0)
+		return -1;
+
+	/* Read and convert instruments */
+	for (i = 0; i < mod->ins; i++) {
+		struct xmp_instrument *xxi = &mod->xxi[i];
+		struct xmp_sample *xxs = &mod->xxs[i];
+		struct xmp_subinstrument *sub;
+
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+
+		sub = &xxi->sub[0];
+
+		hio_read(&mih.name, 22, 1, f);	/* Instrument name */
+		mih.length = hio_read32l(f);	/* Instrument length in bytes */
+
+		if (mih.length > MAX_SAMPLE_SIZE)
+			return -1;
+
+		mih.loop_start = hio_read32l(f); /* Sample loop start */
+		mih.loopend = hio_read32l(f);	/* Sample loop end */
+		mih.finetune = hio_read8(f);	/* Finetune */
+		mih.volume = hio_read8(f);	/* Playback volume */
+		mih.attr = hio_read8(f);	/* &0x01: 16bit sample */
+
+		xxs->len = mih.length;
+		xxs->lps = mih.loop_start;
+		xxs->lpe = mih.loopend;
+		xxs->flg = xxs->lpe ? XMP_SAMPLE_LOOP : 0;	/* 1 == Forward loop */
+		if (mfh.attr & 1) {
+			xxs->flg |= XMP_SAMPLE_16BIT;
+			xxs->len >>= 1;
+			xxs->lps >>= 1;
+			xxs->lpe >>= 1;
+		}
+
+		sub->vol = mih.volume;
+		sub->fin = mih.finetune;
+		sub->pan = 0x80;
+		sub->sid = i;
+
+		libxmp_instrument_name(mod, i, mih.name, 22);
+
+		if (xxs->len > 0)
+			mod->xxi[i].nsm = 1;
+
+		D_(D_INFO "[%2X] %-22.22s %04x%c%04x %04x %c V%02x F%+03d\n", i,
+		   xxi->name, xxs->len, xxs->flg & XMP_SAMPLE_16BIT ? '+' : ' ',
+		   xxs->lps, xxs->lpe, xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
+		   sub->vol, sub->fin - 0x80);
 	}
-    }
 
-    /* Read patterns */
-    D_(D_INFO "Stored patterns: %d", mod->pat - 1);
+	hio_read(mod->xxo, 1, 128, f);
 
-    for (i = 0; i < mod->pat; i++) {
-	if (pattern_alloc(mod, i) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
-	mod->xxp[i]->rows = 64;
-	for (j = 0; j < 32; j++)
-	    mp[j] = hio_read16l(f);
-	for (j = 0; j < mod->chn; j++)
-	    mod->xxp[i]->index[j] = mp[j];
-    }
+	D_(D_INFO "Stored tracks: %d", mod->trk - 1);
+
+	for (i = 0; i < mod->trk; i++) {
 
-    /* Comments */
-    hio_seek(f, mfh.extralen, SEEK_CUR);
+		if (libxmp_alloc_track(mod, i, mfh.rows) < 0)
+			return -1;
 
-    /* Read samples */
-    D_(D_INFO "Stored samples: %d", mod->smp);
+		if (i == 0)
+			continue;
+
+		if (hio_read(&mt, 3, 64, f) != 64)
+			return -1;
+
+		for (j = 0; j < 64; j++) {
+			struct xmp_event *e = &mod->xxt[i]->event[j];
+			uint8 *d = mt + j * 3;
+
+			if ((e->note = d[0] >> 2)) {
+				e->note += 37;
+			}
+			e->ins = ((d[0] & 0x3) << 4) + MSN(d[1]);
+			e->fxt = LSN(d[1]);
+			e->fxp = d[2];
+			if (e->fxt > FX_SPEED) {
+				e->fxt = e->fxp = 0;
+			}
+
+			/* Set pan effect translation */
+			if (e->fxt == FX_EXTENDED && MSN(e->fxp) == 0x8) {
+				e->fxt = FX_SETPAN;
+				e->fxp <<= 4;
+			}
+		}
+	}
 
-    for (i = 0; i < mod->ins; i++) {
-	if (load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
-	    return -1;
-    }
+	/* Read patterns */
+	D_(D_INFO "Stored patterns: %d", mod->pat - 1);
+
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern(mod, i) < 0)
+			return -1;
+
+		mod->xxp[i]->rows = 64;
+		for (j = 0; j < 32; j++) {
+			int track = hio_read16l(f);
+
+			if (track >= mod->trk) {
+				track = 0;
+			}
+
+			if (j < mod->chn) {
+				mod->xxp[i]->index[j] = track;
+			}
+		}
+	}
+
+	/* Comments */
+	hio_seek(f, mfh.extralen, SEEK_CUR);
+
+	/* Read samples */
+	D_(D_INFO "Stored samples: %d", mod->smp);
+
+	for (i = 0; i < mod->ins; i++) {
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
+			return -1;
+	}
 
-    for (i = 0; i < mod->chn; i++)
-	mod->xxc[i].pan = mfh.pan[i] << 4;
+	for (i = 0; i < mod->chn; i++)
+		mod->xxc[i].pan = mfh.pan[i] << 4;
 
-    return 0;
+	return 0;
 }
diff --git a/src/loaders/no_load.c b/src/loaders/no_load.c
index 7d5e271..500aea6 100644
--- a/src/loaders/no_load.c
+++ b/src/loaders/no_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -17,7 +31,7 @@
 static int no_test (HIO_HANDLE *, char *, const int);
 static int no_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader no_loader = {
+const struct format_loader libxmp_loader_no = {
 	"Liquid Tracker NO",
 	no_test,
 	no_load
@@ -25,10 +39,41 @@ const struct format_loader no_loader = {
 
 static int no_test(HIO_HANDLE *f, char *t, const int start)
 {
+	int nsize, pat, chn;
+	int i;
+
+	hio_seek(f, start, SEEK_CUR);
+
 	if (hio_read32b(f) != 0x4e4f0000)		/* NO 0x00 0x00 */
 		return -1;
 
-	read_title(f, t, hio_read8(f));
+	nsize = hio_read8(f);
+	if (nsize != 20)
+		return -1;
+
+	/* test title */
+	for (i = 0; i < nsize; i++) {
+		if (hio_read8(f) == 0)
+			return -1;
+	}
+
+	hio_seek(f, 9, SEEK_CUR);
+
+	/* test number of patterns */
+	pat = hio_read8(f);
+	if (pat == 0)
+		return -1;
+
+	hio_read8(f);
+
+	/* test number of channels */
+	chn = hio_read8(f);
+	if (chn <= 0 || chn > 16)
+		return -1;
+
+	hio_seek(f, start + 5, SEEK_SET);
+
+	libxmp_read_title(f, t, nsize);
 
 	return 0;
 }
@@ -64,7 +109,7 @@ static int no_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	hio_read32b(f);			/* NO 0x00 0x00 */
 
-	set_type(m, "Liquid Tracker");
+	libxmp_set_type(m, "Liquid Tracker");
 
 	nsize = hio_read8(f);
 	for (i = 0; i < nsize; i++) {
@@ -97,19 +142,25 @@ static int no_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	hio_seek(f, 255 - i, SEEK_CUR);
 	mod->len = i;
 
+	m->c4rate = C4_NTSC_RATE;
+
 	MODULE_INFO();
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	/* Read instrument names */
 	for (i = 0; i < mod->ins; i++) {
 		int hasname, c2spd;
 
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 
 		nsize = hio_read8(f);
+		if (hio_error(f)) {
+			return -1;
+		}
+
 		hasname = 0;
 		for (j = 0; j < nsize; j++) {
 			uint8 x = hio_read8(f);
@@ -149,18 +200,17 @@ static int no_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
 				mod->xxi[i].sub[0].vol, c2spd);
 
-		c2spd = 8363 * c2spd / 8448;
-		c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
+		libxmp_c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
 	}
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	/* Read and convert patterns */
 	D_(D_INFO "Stored patterns: %d ", mod->pat);
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 			return -1;
 
 		for (j = 0; j < mod->xxp[i]->rows; j++) {
@@ -196,7 +246,7 @@ static int no_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	for (i = 0; i < mod->ins; i++) {
 		if (mod->xxs[i].len == 0)
 			continue;
-		if (load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
 			return -1;
 	}
 
diff --git a/src/loaders/okt_load.c b/src/loaders/okt_load.c
index fbcaaf1..115f571 100644
--- a/src/loaders/okt_load.c
+++ b/src/loaders/okt_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -31,7 +31,7 @@
 static int okt_test(HIO_HANDLE *, char *, const int);
 static int okt_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader okt_loader = {
+const struct format_loader libxmp_loader_okt = {
 	"Oktalyzer",
 	okt_test,
 	okt_load
@@ -47,7 +47,7 @@ static int okt_test(HIO_HANDLE *f, char *t, const int start)
 	if (strncmp(magic, "OKTASONG", 8))
 		return -1;
 
-	read_title(f, t, 0);
+	libxmp_read_title(f, t, 0);
 
 	return 0;
 }
@@ -79,15 +79,15 @@ static const int fx[] = {
 	FX_OKT_ARP3,		/* 10 */
 	FX_OKT_ARP4,		/* 11 */
 	FX_OKT_ARP5,		/* 12 */
-	FX_NSLIDE_DN,		/* 13 */
+	FX_NSLIDE2_DN,		/* 13 */
 	NONE,
 	NONE,			/* 15 - filter */
 	NONE,
-	FX_NSLIDE_UP,		/* 17 */
+	FX_NSLIDE2_UP,		/* 17 */
 	NONE,
 	NONE,
 	NONE,
-	FX_F_NSLIDE_DN,		/* 21 */
+	FX_NSLIDE_DN,		/* 21 */
 	NONE,
 	NONE,
 	NONE,
@@ -96,22 +96,29 @@ static const int fx[] = {
 	NONE,			/* 27 - release */
 	FX_SPEED,		/* 28 */
 	NONE,
-	FX_F_NSLIDE_UP,		/* 30 */
+	FX_NSLIDE_UP,		/* 30 */
 	FX_VOLSET		/* 31 */
 };
 
 static int get_cmod(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 {
 	struct xmp_module *mod = &m->mod;
-	int i, j, k;
+	int i;
 
 	mod->chn = 0;
 	for (i = 0; i < 4; i++) {
-		j = hio_read16b(f);
-		for (k = ! !j; k >= 0; k--) {
-			mod->xxc[mod->chn].pan = (((i + 1) / 2) % 2) * 0xff;
-			mod->chn++;
+		int pan = (((i + 1) / 2) % 2) * 0xff;
+		int p = 0x80 + (pan - 0x80) * m->defpan / 100;
+
+		if (hio_read16b(f) == 0) {
+			mod->xxc[mod->chn++].pan = p;
+		} else {
+			mod->xxc[mod->chn].flg |= XMP_CHANNEL_SPLIT | (i << 4);
+			mod->xxc[mod->chn++].pan = p;
+			mod->xxc[mod->chn].flg |= XMP_CHANNEL_SPLIT | (i << 4);
+			mod->xxc[mod->chn++].pan = p;
 		}
+
 	}
 
 	return 0;
@@ -124,11 +131,15 @@ static int get_samp(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	int i, j;
 	int looplen;
 
+	/* Sanity check */
+	if (size != 36 * 32)
+		return -1;
+
 	/* Should be always 36 */
 	mod->ins = size / 32;	/* sizeof(struct okt_instrument_header); */
 	mod->smp = mod->ins;
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	for (j = i = 0; i < mod->ins; i++) {
@@ -136,18 +147,17 @@ static int get_samp(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 		struct xmp_sample *xxs = &mod->xxs[j];
 		struct xmp_subinstrument *sub;
 
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 
 		sub = &xxi->sub[0];
 
 		hio_read(xxi->name, 1, 20, f);
-		adjust_string((char *)xxi->name);
 
 		/* Sample size is always rounded down */
 		xxs->len = hio_read32b(f) & ~1;
-		xxs->lps = hio_read16b(f);
-		looplen = hio_read16b(f);
+		xxs->lps = hio_read16b(f) << 1;
+		looplen = hio_read16b(f) << 1;
 		xxs->lpe = xxs->lps + looplen;
 		xxs->flg = looplen > 2 ? XMP_SAMPLE_LOOP : 0;
 
@@ -193,6 +203,11 @@ static int get_plen(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	struct xmp_module *mod = &m->mod;
 
 	mod->len = hio_read16b(f);
+
+	/* Sanity check */
+	if (mod->len > 256)
+		return -1;
+
 	D_(D_INFO "Module length: %d", mod->len);
 
 	return 0;
@@ -202,7 +217,8 @@ static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 {
 	struct xmp_module *mod = &m->mod;
 
-	hio_read(mod->xxo, 1, mod->len, f);
+	if (hio_read(mod->xxo, 1, mod->len, f) != mod->len)
+		return -1;
 
 	return 0;
 }
@@ -219,18 +235,18 @@ static int get_pbod(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 		return 0;
 
 	if (!data->pattern) {
-		if (pattern_init(mod) < 0)
+		if (libxmp_init_pattern(mod) < 0)
 			return -1;
 		D_(D_INFO "Stored patterns: %d", mod->pat);
 	}
 
 	rows = hio_read16b(f);
 
-	if (pattern_tracks_alloc(mod, data->pattern, rows) < 0)
+	if (libxmp_alloc_pattern_tracks(mod, data->pattern, rows) < 0)
 		return -1;
 
 	for (j = 0; j < rows * mod->chn; j++) {
-		uint8 note, ins;
+		uint8 note, ins, fxt;
 
 		e = &EVENT(data->pattern, j % mod->chn, j / mod->chn);
 		memset(e, 0, sizeof(struct xmp_event));
@@ -243,7 +259,11 @@ static int get_pbod(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 			e->ins = 1 + ins;
 		}
 
-		e->fxt = fx[hio_read8(f)];
+		fxt = hio_read8(f);
+		if (fxt >= 32) {
+			return -1;
+		}
+		e->fxt = fx[fxt];
 		e->fxp = hio_read8(f);
 
 		if ((e->fxt == FX_VOLSET) && (e->fxp > 0x40)) {
@@ -288,7 +308,7 @@ static int get_sbod(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 		flags = SAMPLE_FLAG_7BIT;
 
 	sid = mod->xxi[i].sub[0].sid;
-	if (load_sample(m, f, flags, &mod->xxs[sid], NULL) < 0)
+	if (libxmp_load_sample(m, f, flags, &mod->xxs[sid], NULL) < 0)
 		return -1;
 
 	data->sample++;
@@ -306,36 +326,38 @@ static int okt_load(struct module_data *m, HIO_HANDLE * f, const int start)
 
 	hio_seek(f, 8, SEEK_CUR);	/* OKTASONG */
 
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		return -1;
 
 	memset(&data, 0, sizeof(struct local_data));
 
 	/* IFF chunk IDs */
-	ret = iff_register(handle, "CMOD", get_cmod);
-	ret |= iff_register(handle, "SAMP", get_samp);
-	ret |= iff_register(handle, "SPEE", get_spee);
-	ret |= iff_register(handle, "SLEN", get_slen);
-	ret |= iff_register(handle, "PLEN", get_plen);
-	ret |= iff_register(handle, "PATT", get_patt);
-	ret |= iff_register(handle, "PBOD", get_pbod);
-	ret |= iff_register(handle, "SBOD", get_sbod);
+	ret = libxmp_iff_register(handle, "CMOD", get_cmod);
+	ret |= libxmp_iff_register(handle, "SAMP", get_samp);
+	ret |= libxmp_iff_register(handle, "SPEE", get_spee);
+	ret |= libxmp_iff_register(handle, "SLEN", get_slen);
+	ret |= libxmp_iff_register(handle, "PLEN", get_plen);
+	ret |= libxmp_iff_register(handle, "PATT", get_patt);
+	ret |= libxmp_iff_register(handle, "PBOD", get_pbod);
+	ret |= libxmp_iff_register(handle, "SBOD", get_sbod);
 
 	if (ret != 0)
 		return -1;
 
-	set_type(m, "Oktalyzer");
+	libxmp_set_type(m, "Oktalyzer");
 
 	MODULE_INFO();
 
 	/* Load IFF chunks */
-	if (iff_load(handle, m, f, &data) < 0) {
-		iff_release(handle);
+	if (libxmp_iff_load(handle, m, f, &data) < 0) {
+		libxmp_iff_release(handle);
 		return -1;
 	}
 
-	iff_release(handle);
+	libxmp_iff_release(handle);
+
+	m->period_type = PERIOD_MODRNG;
 
 	return 0;
 }
diff --git a/src/loaders/polly_load.c b/src/loaders/polly_load.c
new file mode 100644
index 0000000..38cdaeb
--- /dev/null
+++ b/src/loaders/polly_load.c
@@ -0,0 +1,232 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * This file is part of the Extended Module Player and is distributed
+ * under the terms of the GNU Lesser General Public License. See COPYING.LIB
+ * for more information.
+ */
+
+/*
+ * Polly Tracker is a tracker for the Commodore 64 written by Aleksi Eeben.
+ * See http://aleksieeben.blogspot.com/2007/05/polly-tracker.html for more
+ * information.
+ */
+
+#include "loader.h"
+
+static int polly_test(HIO_HANDLE *, char *, const int);
+static int polly_load(struct module_data *, HIO_HANDLE *, const int);
+
+const struct format_loader libxmp_loader_polly = {
+	"Polly Tracker",
+	polly_test,
+	polly_load
+};
+
+#define NUM_PAT 0x1f
+#define PAT_SIZE (64 * 4)
+#define ORD_OFS (NUM_PAT * PAT_SIZE)
+#define SMP_OFS (NUM_PAT * PAT_SIZE + 256)
+
+
+static void decode_rle(uint8 *out, HIO_HANDLE *f, int size)
+{
+	int i;
+
+	for (i = 0; i < size; ) {
+		int x = hio_read8(f);
+
+		if (hio_eof(f))
+			return;
+
+		if (x == 0xae) {
+			int n,v;
+			switch (n = hio_read8(f)) {
+			case 0x01:
+				out[i++] = 0xae;
+				break;
+			default:
+				v = hio_read8(f);
+				while (n-- && i < size)
+					out[i++] = v;
+			}
+		} else {
+			out[i++] = x;
+		}
+	}
+}
+
+static int polly_test(HIO_HANDLE *f, char *t, const int start)
+{
+	int i;
+	uint8 *buf;
+
+	if (hio_read8(f) != 0xae)
+		return -1;
+
+	if ((buf = malloc(0x10000)) == NULL)
+		return -1;
+
+	decode_rle(buf, f, 0x10000);
+
+	for (i = 0; i < 128; i++) {
+		if (buf[ORD_OFS + i] != 0 && buf[ORD_OFS] < 0xe0) {
+			free(buf);
+			return -1;
+		}
+	}
+
+	if (t) {
+		memcpy(t, buf + ORD_OFS + 160, 16);
+		t[16] = 0;
+		for (i = 15; i >=0; i--) {
+			if (t[i] == ' ') {
+				t[i] = 0;
+			} else {
+				break;
+			}
+		}
+	}
+
+	free(buf);
+
+	return 0;
+}
+
+static int polly_load(struct module_data *m, HIO_HANDLE *f, const int start)
+{
+	struct xmp_module *mod = &m->mod;
+	struct xmp_event *event;
+	uint8 *buf;
+	int i, j, k;
+
+	LOAD_INIT();
+
+	hio_read8(f);			/* skip 0xae */
+	/*
+	 * File is RLE-encoded, escape is 0xAE (Aleksi Eeben's initials).
+	 * Actual 0xAE is encoded as 0xAE 0x01
+	 */
+	if ((buf = calloc(1, 0x10000)) == NULL)
+		return -1;
+
+	decode_rle(buf, f, 0x10000);
+
+	for (i = 0; buf[ORD_OFS + i] != 0 && i < 128; i++)
+		mod->xxo[i] = buf[ORD_OFS + i] - 0xe0;
+	mod->len = i;
+
+	memcpy(mod->name, buf + ORD_OFS + 160, 16);
+	/* memcpy(m->author, buf + ORD_OFS + 176, 16); */
+	libxmp_set_type(m, "Polly Tracker");
+	MODULE_INFO();
+
+	mod->spd = 0x03;
+	mod->bpm = 0x7d * buf[ORD_OFS + 193] / 0x88;
+#if 0
+	for (i = 0; i < 1024; i++) {
+		if ((i % 16) == 0) printf("\n");
+		printf("%02x ", buf[ORD_OFS + i]);
+	}
+#endif
+
+	mod->pat = 0;
+	for (i = 0; i < mod->len; i++) {
+		if (mod->xxo[i] > mod->pat)
+			mod->pat = mod->xxo[i];
+	}
+	mod->pat++;
+	
+	mod->chn = 4;
+	mod->trk = mod->pat * mod->chn;
+
+	if (libxmp_init_pattern(mod) < 0) {
+		free(buf);
+		return -1;
+	}
+
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0) {
+			free(buf);
+			return -1;
+		}
+
+		for (j = 0; j < 64; j++) {
+			for (k = 0; k < 4; k++) {
+				uint8 x = buf[i * PAT_SIZE + j * 4 + k];
+				event = &EVENT(i, k, j);
+				if (x == 0xf0) {
+					event->fxt = FX_BREAK;
+					event->fxp = 0;
+					continue;
+				}
+				event->note = LSN(x);
+				if (event->note)
+					event->note += 48;
+				event->ins = MSN(x);
+			}
+		}
+	}
+
+	mod->ins = mod->smp = 15;
+	if (libxmp_init_instrument(m) < 0) {
+		free(buf);
+		return -1;
+	}
+
+	for (i = 0; i < 15; i++) {
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0) {
+			free(buf);
+			return -1;
+		}
+		mod->xxs[i].len = buf[ORD_OFS + 129 + i] < 0x10 ? 0 :
+					256 * buf[ORD_OFS + 145 + i];
+		mod->xxi[i].sub[0].fin = 0;
+		mod->xxi[i].sub[0].vol = 0x40;
+		mod->xxs[i].lps = 0;
+		mod->xxs[i].lpe = 0;
+		mod->xxs[i].flg = 0;
+		mod->xxi[i].sub[0].pan = 0x80;
+		mod->xxi[i].sub[0].sid = i;
+		mod->xxi[i].nsm = !!(mod->xxs[i].len);
+		mod->xxi[i].rls = 0xfff;
+
+                D_(D_INFO "[%2X] %04x %04x %04x %c V%02x",
+                       		i, mod->xxs[i].len, mod->xxs[i].lps,
+                        	mod->xxs[i].lpe, ' ', mod->xxi[i].sub[0].vol);
+	}
+
+	/* Convert samples from 6 to 8 bits */
+	for (i = SMP_OFS; i < 0x10000; i++)
+		buf[i] = buf[i] << 2;
+
+	/* Read samples */
+	D_(D_INFO "Loading samples: %d", mod->ins);
+
+	for (i = 0; i < mod->ins; i++) {
+		int ret;
+
+		if (mod->xxs[i].len == 0)
+			continue;
+		ret = libxmp_load_sample(m, NULL, SAMPLE_FLAG_NOLOAD | SAMPLE_FLAG_UNS,
+				&mod->xxs[i], (char*)buf + ORD_OFS + 256 +
+					256 * (buf[ORD_OFS + 129 + i] - 0x10));
+
+		if (ret < 0) {
+			free(buf);
+			return -1;
+		}
+	}
+
+	free(buf);
+
+	/* make it mono */
+	for (i = 0; i < mod->chn; i++)
+		mod->xxc[i].pan = 0x80;
+
+	m->quirk |= QUIRK_MODRNG;
+
+	return 0;
+}
diff --git a/src/loaders/prowizard/Makefile b/src/loaders/prowizard/Makefile
deleted file mode 100644
index 26b1168..0000000
--- a/src/loaders/prowizard/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-
-PROWIZ_OBJS	= prowiz.o ptktable.o tuning.o ac1d.o di.o eureka.o \
-		  fc-m.o fuchs.o fuzzac.o gmc.o heatseek.o ksm.o \
-		  mp.o np1.o np2.o np3.o p61a.o pm10c.o pm18a.o \
-		  pha.o prun1.o prun2.o tdd.o unic.o unic2.o wn.o zen.o \
-		  tp3.o p40.o xann.o theplayer.o pp21.o starpack.o titanics.o \
-		  skyt.o novotrade.o hrt.o noiserun.o
-PROWIZ_OBJS2	= pm.o pm01.o \
-		  pm20.o pm40.o pp10.o pp30.o tp1.o tp2.o
-PROWIZ_DFILES	= Makefile $(PROWIZ_OBJS:.o=.c) $(PROWIZ_OBJS2:.o=.c) prowiz.h
-PROWIZ_PATH	= src/loaders/prowizard
-
-OBJS += $(addprefix $(PROWIZ_PATH)/, $(PROWIZ_OBJS))
-
-dist-prowiz::
-	mkdir -p $(DIST)/$(PROWIZ_PATH)
-	cp -RPp $(addprefix $(PROWIZ_PATH)/,$(PROWIZ_DFILES)) $(DIST)/$(PROWIZ_PATH)
-
-
diff --git a/src/loaders/prowizard/ac1d.c b/src/loaders/prowizard/ac1d.c
index 0d2663d..a2513d0 100644
--- a/src/loaders/prowizard/ac1d.c
+++ b/src/loaders/prowizard/ac1d.c
@@ -1,10 +1,11 @@
 /*
  * ac1d.c   Copyright (C) 1996-1997 Asle / ReDoX
- *	    Copyright (C) 2006-2007 Claudio Matsuoka
  *
- * Converts AC1D packed MODs back to PTK MODs
+ * Converts ac1d packed MODs back to PTK MODs
  * thanks to Gryzor and his ProWizard tool ! ... without it, this prog
  * would not exist !!!
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -13,7 +14,7 @@
 
 #define NO_NOTE 0xff
 
-static int depack_AC1D(FILE *in, FILE *out)
+static int depack_ac1d(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1, c2, c3, c4;
 	uint8 npos;
@@ -26,35 +27,39 @@ static int depack_AC1D(FILE *in, FILE *out)
 	int ssize = 0;
 	int paddr[128];
 	int psize[128];
-	int tsize1, tsize2, tsize3;
+	/*int tsize1, tsize2, tsize3;*/
 	int i, j, k;
 
 	memset(paddr, 0, 128 * 4);
 	memset(psize, 0, 128 * 4);
 
-	npos = read8(in);
-	ntk_byte = read8(in);
-	read16b(in);			/* bypass ID */
-	saddr = read32b(in);		/* sample data address */
+	npos = hio_read8(in);
+	ntk_byte = hio_read8(in);
+	hio_read16b(in);			/* bypass ID */
+	saddr = hio_read32b(in);		/* sample data address */
 
 	pw_write_zero(out, 20);		/* write title */
 
 	for (i = 0; i < 31; i++) {
 		pw_write_zero(out, 22);		/* name */
-		write16b(out, size = read16b(in));	/* size */
+		write16b(out, size = hio_read16b(in));	/* size */
 		ssize += size * 2;
-		write8(out, read8(in));		/* finetune */
-		write8(out, read8(in));		/* volume */
-		write16b(out, read16b(in));	/* loop start */
-		write16b(out, read16b(in));	/* loop size */
+		write8(out, hio_read8(in));		/* finetune */
+		write8(out, hio_read8(in));		/* volume */
+		write16b(out, hio_read16b(in));	/* loop start */
+		write16b(out, hio_read16b(in));	/* loop size */
 	}
 
 	/* pattern addresses */
 	for (npat = 0; npat < 128; npat++) {
-		paddr[npat] = read32b(in);
+		paddr[npat] = hio_read32b(in);
 		if (paddr[npat] == 0)
 			break;
 	}
+	if (npat == 0) {
+		return -1;
+	}
+
 	npat--;
 
 	for (i = 0; i < (npat - 1); i++)
@@ -63,32 +68,31 @@ static int depack_AC1D(FILE *in, FILE *out)
 	write8(out, npos);		/* write number of pattern pos */
 	write8(out, ntk_byte);		/* write "noisetracker" byte */
 
-	fseek(in, 0x300, SEEK_SET);	/* go to pattern table .. */
+	hio_seek(in, 0x300, SEEK_SET);	/* go to pattern table .. */
 	pw_move_data(out, in, 128);	/* pattern table */
 	
 	write32b(out, PW_MOD_MAGIC);	/* M.K. */
 
 	/* pattern data */
 	for (i = 0; i < npat; i++) {
-		fseek(in, paddr[i], SEEK_SET);
-		tsize1 = read32b(in);
-		tsize2 = read32b(in);
-		tsize3 = read32b(in);
+		hio_seek(in, paddr[i], SEEK_SET);
+		/*tsize1 =*/ hio_read32b(in);
+		/*tsize2 =*/ hio_read32b(in);
+		/*tsize3 =*/ hio_read32b(in);
 
 		memset(tmp, 0, 1024);
 		for (k = 0; k < 4; k++) {
 			for (j = 0; j < 64; j++) {
 				int x = j * 16 + k * 4;
 
-				note = ins = fxt = fxp = 0x00;
-				c1 = read8(in);
+				c1 = hio_read8(in);
 				if (c1 & 0x80) {
 					c4 = c1 & 0x7f;
 					j += (c4 - 1);
 					continue;
 				}
 
-				c2 = read8(in);
+				c2 = hio_read8(in);
 				ins = ((c1 & 0xc0) >> 2) | ((c2 >> 4) & 0x0f);
 				note = c1 & 0x3f;
 
@@ -108,13 +112,11 @@ static int depack_AC1D(FILE *in, FILE *out)
 				}
 
 				if ((c2 & 0x0f) == 0x07) {
-					fxt = 0x00;
-					fxp = 0x00;
 					tmp[x + 2] = (ins << 4) & 0xf0;
 					continue;
 				}
 
-				c3 = read8(in);
+				c3 = hio_read8(in);
 				fxt = c2 & 0x0f;
 				fxp = c3;
 				tmp[x + 2] = ((ins << 4) & 0xf0) | fxt;
@@ -125,16 +127,15 @@ static int depack_AC1D(FILE *in, FILE *out)
 	}
 
 	/* sample data */
-	fseek(in, saddr, 0);
+	hio_seek(in, saddr, 0);
 	pw_move_data(out, in, ssize);
 
 	return 0;
 }
 
-static int test_AC1D(uint8 *data, char *t, int s)
+static int test_ac1d(uint8 *data, char *t, int s)
 {
-	int j, k;
-	int start = 0;
+	int i;
 
 	PW_REQUEST_DATA(s, 896);
 
@@ -143,18 +144,18 @@ static int test_AC1D(uint8 *data, char *t, int s)
 		return -1;
 
 	/* test #2 */
-	if (data[start] > 0x7f)
+	if (data[0] > 0x7f)
 		return -1;
 
 	/* test #4 */
-	for (k = 0; k < 31; k++) {
-		if (data[start + 10 + 8 * k] > 0x0f)
+	for (i = 0; i < 31; i++) {
+		if (data[10 + 8 * i] > 0x0f)
 			return -1;
 	}
 
 	/* test #5 */
-	for (j = 0; j < 128; j++) {
-		if (data[start + 768 + j] > 0x7f)
+	for (i = 0; i < 128; i++) {
+		if (data[768 + i] > 0x7f)
 			return -1;
 	}
 
@@ -165,7 +166,7 @@ static int test_AC1D(uint8 *data, char *t, int s)
 
 const struct pw_format pw_ac1d = {
 	"AC1D Packer",
-	test_AC1D,
-	depack_AC1D
+	test_ac1d,
+	depack_ac1d
 };
 
diff --git a/src/loaders/prowizard/di.c b/src/loaders/prowizard/di.c
index a73bbe8..73b88bc 100644
--- a/src/loaders/prowizard/di.c
+++ b/src/loaders/prowizard/di.c
@@ -1,8 +1,9 @@
 /*
  * Digital_Illusion.c   Copyright (C) 1997 Asle / ReDoX
- *			Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Converts DI packed MODs back to PTK MODs
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -10,51 +11,82 @@
 #include "prowiz.h"
 
 
-static int depack_di(FILE * in, FILE * out)
+static int write_event(uint8 c1, uint8 c2, uint8 fxp, FILE *out)
+{
+	uint8 note, ins, fxt;
+	uint8 p[4];
+
+	note = ((c1 << 4) & 0x30) | ((c2 >> 4) & 0x0f);
+	if (note >= 37) {
+		/* di.nightmare has note 49! */
+		uint32 x = 0;
+		fwrite(&x, 4, 1, out);
+		return 0;
+	}
+	p[0] = ptk_table[note][0];
+	p[1] = ptk_table[note][1];
+	ins = (c1 >> 2) & 0x1f;
+	p[0] |= (ins & 0xf0);
+	p[2] = (ins << 4) & 0xf0;
+	fxt = c2 & 0x0f;
+	p[2] |= fxt;
+	p[3] = fxp;
+	fwrite(p, 4, 1, out);
+
+	return 0;
+}
+
+static int depack_di(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1, c2, c3;
-	uint8 note, ins, fxt, fxp;
-	uint8 ptk_tab[5];
 	uint8 nins, npat, max;
 	uint8 ptable[128];
 	uint16 paddr[128];
 	uint8 tmp[50];
 	int i, k;
-	int seq_offs, pat_offs, smp_offs;
+	int seq_offs, /*pat_offs,*/ smp_offs;
+	int size, ssize;
 	int pos;
-	int size, ssize = 0;
 
 	memset(ptable, 0, 128);
-	memset(ptk_tab, 0, 5);
-	memset(paddr, 0, 128);
+	memset(paddr, 0, 256);
 
 	pw_write_zero(out, 20);			/* title */
 
-	nins = read16b(in);
-	seq_offs = read32b(in);
-	pat_offs = read32b(in);
-	smp_offs = read32b(in);
+	nins = hio_read16b(in);
+	/* Sanity check */
+	if (nins > 31) {
+		return -1;
+	}
+
+	seq_offs = hio_read32b(in);
+	/*pat_offs =*/ hio_read32b(in);
+	smp_offs = hio_read32b(in);
 
+	ssize = 0;
 	for (i = 0; i < nins; i++) {
 		pw_write_zero(out, 22);			/* name */
-		write16b(out, size = read16b(in));	/* size */
+		write16b(out, size = hio_read16b(in));	/* size */
 		ssize += size * 2;
-		write8(out, read8(in));			/* finetune */
-		write8(out, read8(in));			/* volume */
-		write16b(out, read16b(in));		/* loop start */
-		write16b(out, read16b(in));		/* loop size */
+		write8(out, hio_read8(in));			/* finetune */
+		write8(out, hio_read8(in));			/* volume */
+		write16b(out, hio_read16b(in));		/* loop start */
+		write16b(out, hio_read16b(in));		/* loop size */
 	}
 
 	memset(tmp, 0, 50);
-	for (i = nins; i < 31; i++)
+	for (i = nins; i < 31; i++) {
 		fwrite(tmp, 30, 1, out);
+	}
 
-	pos = ftell(in);
-	fseek (in, seq_offs, 0);
+	if ((pos = hio_tell(in)) < 0) {
+		return -1;
+	}
+	hio_seek(in, seq_offs, SEEK_SET);
 
 	i = 0;
 	do {
-		c1 = read8(in);
+		c1 = hio_read8(in);
 		ptable[i++] = c1;
 	} while (c1 != 0xff);
 
@@ -71,62 +103,45 @@ static int depack_di(FILE * in, FILE * out)
 
 	write32b(out, PW_MOD_MAGIC);
 
-	fseek(in, pos, 0);
+	hio_seek(in, pos, SEEK_SET);
+
 	for (i = 0; i <= max; i++)
-		paddr[i] = read16b(in);
+		paddr[i] = hio_read16b(in);
 
 	for (i = 0; i <= max; i++) {
-		fseek(in, paddr[i], 0);
+		hio_seek(in, paddr[i], 0);
 		for (k = 0; k < 256; k++) {	/* 256 = 4 voices * 64 rows */
-			memset(ptk_tab, 0, 5);
-			c1 = read8(in);
+			c1 = hio_read8(in);
 			if ((c1 & 0x80) == 0) {
-				c2 = read8(in);
-				note = ((c1 << 4) & 0x30) | ((c2 >> 4) & 0x0f);
-				ptk_tab[0] = ptk_table[note][0];
-				ptk_tab[1] = ptk_table[note][1];
-				ins = (c1 >> 2) & 0x1f;
-				ptk_tab[0] |= (ins & 0xf0);
-				ptk_tab[2] = (ins << 4) & 0xf0;
-				fxt = c2 & 0x0f;
-				ptk_tab[2] |= fxt;
-				fxp = 0x00;
-				ptk_tab[3] = fxp;
-				fwrite (ptk_tab, 4, 1, out);
-				continue;
+				c2 = hio_read8(in);
+				if (write_event(c1, c2, 0, out) < 0) {
+					return -1;
+				}
+			} else if (c1 == 0xff) {
+				uint32 x = 0;
+				fwrite(&x, 1, 4, out);
+			} else {
+				c2 = hio_read8(in);
+				c3 = hio_read8(in);
+				if (write_event(c1, c2, c3, out) < 0) {
+					return -1;
+				}
 			}
-			if (c1 == 0xff) {
-				memset(ptk_tab, 0, 5);
-				fwrite (ptk_tab, 4, 1, out);
-				continue;
-			}
-			c2 = read8(in);
-			c3 = read8(in);
-			note = (((c1 << 4) & 0x30) | ((c2 >> 4) & 0x0f));
-			ptk_tab[0] = ptk_table[note][0];
-			ptk_tab[1] = ptk_table[note][1];
-			ins = (c1 >> 2) & 0x1f;
-			ptk_tab[0] |= (ins & 0xf0);
-			ptk_tab[2] = (ins << 4) & 0xf0;
-			fxt = c2 & 0x0f;
-			ptk_tab[2] |= fxt;
-			fxp = c3;
-			ptk_tab[3] = fxp;
-			fwrite(ptk_tab, 4, 1, out);
 		}
 	}
 
-	fseek(in, smp_offs, 0);
+	hio_seek(in, smp_offs, SEEK_SET);
 	pw_move_data(out, in, ssize);
 
 	return 0;
 }
 
 
-static int test_di (uint8 *data, char *t, int s)
+static int test_di(uint8 *data, char *t, int s)
 {
-	int ssize, start = 0;
-	int j, k, l, m, n, o;
+	int i;
+	int numsmp, ssize, psize;
+	int ptab_offs, pat_offs, smp_offs;
 
 	PW_REQUEST_DATA (s, 21);
 
@@ -139,49 +154,49 @@ static int test_di (uint8 *data, char *t, int s)
 #endif
 
 	/* test #2  (number of sample) */
-	k = readmem16b(data + start);
-	if (k > 31)
+	numsmp = readmem16b(data);
+	if (numsmp > 31)
 		return -1;
 
 	/* test #3 (finetunes and whole sample size) */
-	/* k = number of samples */
-	l = 0;
-	for (j = 0; j < k; j++) {
-		o = readmem16b(data + start + 14) * 2;
-		m = readmem16b(data + start + 18) * 2;
-		n = readmem16b(data + start + 20) * 2;
-
-		if (o > 0xffff || m > 0xffff || n > 0xffff)
+	ssize = 0;
+	for (i = 0; i < numsmp; i++) {
+		int len = readmem16b(data + 14) << 1;
+		int start = readmem16b(data + 18) << 1;
+		int lsize = readmem16b(data + 20) << 1;
+		uint8 *d = data + i * 8;
+
+		if (len > 0xffff || start > 0xffff || lsize > 0xffff)
 			return -1;
 
-		if (m + n > o)
+		if (start + lsize > len)
 			return -1;
 
-		if (data[start + 16 + j * 8] > 0x0f)
+		if (d[16] > 0x0f)
 			return -1;
 
-		if (data[start + 17 + j * 8] > 0x40)
+		if (d[17] > 0x40)
 			return -1;
 
 		/* get total size of samples */
-		l += o;
+		ssize += len;
 	}
-	if (l <= 2)
+	if (ssize <= 2) {
 		return -1;
+	}
 
 	/* test #4 (addresses of pattern in file ... ptk_tableible ?) */
-	/* k is still the number of sample */
 
-	ssize = k * 8 + 2;
+	psize = numsmp * 8 + 2;
 
-	j = readmem32b(data + start + 2);	/* address of pattern table */
-	k = readmem32b(data + start + 6);	/* address of pattern data */
-	l = readmem32b(data + start + 10);	/* address of sample data */
+	ptab_offs = readmem32b(data + 2);	/* address of pattern table */
+	pat_offs = readmem32b(data + 6);	/* address of pattern data */
+	smp_offs = readmem32b(data + 10);	/* address of sample data */
 
-	if (k <= j || l <= j || l <= k)
+	if (pat_offs <= ptab_offs || smp_offs <= ptab_offs || smp_offs <= pat_offs)
 		return -1;
 
-	if (k - j > 128)
+	if (pat_offs - ptab_offs > 128)
 		return -1;
 
 #if 0
@@ -190,32 +205,32 @@ static int test_di (uint8 *data, char *t, int s)
 #endif
 
 	/* test #4,1 :) */
-	if (j < ssize)
+	if (ptab_offs < psize)
 		return -1;
 
 #if 0
 	/* test #5 */
-	if ((k + start) > in_size) {
+	if ((pat_offs + start) > in_size) {
 		Test = BAD;
 		return;
 	}
 #endif
 
-	PW_REQUEST_DATA (s, start + k - 1);
+	PW_REQUEST_DATA(s, pat_offs - 1);
 
 	/* test pattern table reliability */
-	for (m = j; m < (k - 1); m++) {
-		if (data[start + m] > 0x80)
+	for (i = ptab_offs; i < pat_offs - 1; i++) {
+		if (data[i] > 0x80)
 			return -1;
 	}
 
 	/* test #6  ($FF at the end of pattern list ?) */
-	if (data[start + k - 1] != 0xFF)
+	if (data[pat_offs - 1] != 0xff)
 		return -1;
 
-	/* test #7 (addres of sample data > $FFFF ? ) */
+	/* test #7 (address of sample data > $FFFF ? ) */
 	/* l is still the address of the sample data */
-	if (l > 65535)
+	if (smp_offs > 65535)
 		return -1;
 
 	pw_read_title(NULL, t, 0);
diff --git a/src/loaders/prowizard/eureka.c b/src/loaders/prowizard/eureka.c
index bb1de14..ca9c607 100644
--- a/src/loaders/prowizard/eureka.c
+++ b/src/loaders/prowizard/eureka.c
@@ -1,8 +1,9 @@
 /*
  * EurekaPacker.c   Copyright (C) 1997 Asle / ReDoX
- *		    Modified by Claudio Matsuoka
  *
  * Converts MODs packed with Eureka packer back to ptk
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -10,7 +11,7 @@
 #include "prowiz.h"
 
 
-static int depack_eu(FILE *in, FILE *out)
+static int depack_eu(HIO_HANDLE *in, FILE *out)
 {
 	uint8 tmp[1080];
 	uint8 c1;
@@ -20,7 +21,7 @@ static int depack_eu(FILE *in, FILE *out)
 	int i, j, k;
 
 	/* read header ... same as ptk */
-	fread(tmp, 1080, 1, in);
+	hio_read(tmp, 1080, 1, in);
 	fwrite(tmp, 1080, 1, out);
 
 	/* now, let's sort out that a bit :) */
@@ -36,27 +37,27 @@ static int depack_eu(FILE *in, FILE *out)
 	npat++;
 
 	write32b(out, PW_MOD_MAGIC);		/* write ptk ID */
-	smp_addr = read32b(in);			/* read sample data address */
+	smp_addr = hio_read32b(in);			/* read sample data address */
 
 	/* read tracks addresses */
 	for (i = 0; i < npat; i++) {
 		for (j = 0; j < 4; j++)
-			trk_addr[i][j] = read16b(in);
+			trk_addr[i][j] = hio_read16b(in);
 	}
 
 	/* the track data now ... */
 	for (i = 0; i < npat; i++) {
 		memset(tmp, 0, 1024);
 		for (j = 0; j < 4; j++) {
-			fseek(in, trk_addr[i][j], SEEK_SET);
+			hio_seek(in, trk_addr[i][j], SEEK_SET);
 			for (k = 0; k < 64; k++) {
 				uint8 *x = &tmp[k * 16 + j * 4];
-				c1 = read8(in);
+				c1 = hio_read8(in);
 				if ((c1 & 0xc0) == 0x00) {
 					*x++ = c1;
-					*x++ = read8(in);
-					*x++ = read8(in);
-					*x++ = read8(in);
+					*x++ = hio_read8(in);
+					*x++ = hio_read8(in);
+					*x++ = hio_read8(in);
 					continue;
 				}
 				if ((c1 & 0xc0) == 0xc0) {
@@ -66,12 +67,12 @@ static int depack_eu(FILE *in, FILE *out)
 				if ((c1 & 0xc0) == 0x40) {
 					x += 2;
 					*x++ = c1 & 0x0f;
-					*x++ = read8(in);
+					*x++ = hio_read8(in);
 					continue;
 				}
 				if ((c1 & 0xc0) == 0x80) {
-					*x++ = read8(in);
-					*x++ = read8(in);
+					*x++ = hio_read8(in);
+					*x++ = hio_read8(in);
 					*x++ = (c1 << 4) & 0xf0;
 					continue;
 				}
@@ -80,121 +81,110 @@ static int depack_eu(FILE *in, FILE *out)
 		fwrite(tmp, 1024, 1, out);
 	}
 
-	fseek(in, smp_addr, SEEK_SET);
+	hio_seek(in, smp_addr, SEEK_SET);
 	pw_move_data(out, in, ssize);
 
 	return 0;
 }
 
-static int test_eu (uint8 *data, char *t, int s)
+static int test_eu(uint8 *data, char *t, int s)
 {
-	int j, k, l, m, n, o;
-	int start = 0;
+	int i;
+	int len, max_pat, smp_offs;
+	int max_trk, min_trk;
 
-	PW_REQUEST_DATA (s, 1084);
+	PW_REQUEST_DATA(s, 1084);
 
 	/* test 2 */
-	j = data[start + 950];
-	if (j == 0 || j > 127)
+	len = data[950];
+	if (len == 0 || len > 127)
 		return -1;
 
 	/* test #3  finetunes & volumes */
-	for (k = 0; k < 31; k++) {
-		o = (data[start + 42 + k * 30] << 8) +
-			data[start + 43 + k * 30];
-		m = (data[start + 46 + k * 30] << 8) +
-			data[start + 47 + k * 30];
-		n = (data[start + 48 + k * 30] << 8) +
-			data[start + 49 + k * 30];
-		o *= 2;
-		m *= 2;
-		n *= 2;
-		if (o > 0xffff || m > 0xffff || n > 0xffff)
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 30;
+		int size = readmem16b(d + 42) << 1;
+		int start = readmem16b(d + 46) << 1;
+		int lsize = readmem16b(d + 48) << 1;
+
+		if (size > 0xffff || start > 0xffff || lsize > 0xffff)
 			return -1;
 
-		if ((m + n) > (o + 2))
+		if (start + lsize > size + 2)
 			return -1;
 
-		if (data[start + 44 + k * 30] > 0x0f ||
-			data[start + 45 + k * 30] > 0x40)
+		if (d[44] > 0x0f || d[45] > 0x40)
 			return -1;
 	}
 
 
 	/* test 4 */
-	l = (data[start + 1080] << 24) + (data[start + 1081] << 16)
-		+ (data[start + 1082] << 8) + data[start + 1083];
+	smp_offs = readmem32b(data + 1080);
 
 #if 0
-	if ((l + start) > in_size)
+	if (smp_offs > in_size)
 		return -1;
 #endif
 
-	if (l < 1084)
+	if (smp_offs < 1084)
 		return -1;
 
-	m = 0;
 	/* pattern list */
-	for (k = 0; k < j; k++) {
-		n = data[start + 952 + k];
-		if (n > m)
-			m = n;
-		if (n > 127)
+	max_pat = 0;
+	for (i = 0; i < len; i++) {
+		int pat = data[952 + i];
+		if (pat > 127)
 			return -1;
+		if (pat > max_pat)
+			max_pat = pat;
 	}
-	k += 2;		/* to be sure .. */
-
-	while (k != 128) {
-		if (data[start + 952 + k] != 0)
+	for (/*i += 2*/; i < 128; i++) {
+		if (data[952 + i] != 0)
 			return -1;
-		k += 1;
 	}
-	m += 1;
-	/* m is the highest pattern number */
 
+	max_pat++;
 
 	/* test #5 */
-	/* j is still the size if the pattern table */
-	/* l is still the address of the sample data */
-	/* m is the highest pattern number */
-	n = 0;
-	j = 999999L;
-
-	PW_REQUEST_DATA (s, start + (m * 4) * 2 + 1085);
-
-	for (k = 0; k < (m * 4); k++) {
-		o = (data[start + k * 2 + 1084] << 8) +
-			data[start + k * 2 + 1085];
-		if (o > l || o < 1084)
+	/* max_trkptr is the highest track address */
+	/* min_trkptr is the lowest track address */
+	max_trk = 0;
+	min_trk = 999999;
+
+	PW_REQUEST_DATA(s, max_pat * 4 * 2 + 1085);
+
+	for (i = 0; i < (max_pat * 4); i++) {
+		int trk = readmem16b(data + i * 2 + 1084);
+		if (trk > smp_offs || trk < 1084)
 			return -1;
-		if (o > n)
-			n = o;
-		if (o < j)
-			j = o;
+		if (trk > max_trk)
+			max_trk = trk;
+		if (trk < min_trk)
+			min_trk = trk;
 	}
-	/* o is the highest track address */
-	/* j is the lowest track address */
 
 	/* test track datas */
 	/* last track wont be tested ... */
-	for (k = j; k < o; k++) {
-		if ((data[start + k] & 0xC0) == 0xC0)
+	for (i = min_trk; i < max_trk; i++) {
+		if ((data[i] & 0xc0) == 0xc0)
 			continue;
-		if ((data[start + k] & 0xC0) == 0x80) {
-			k += 2;
+
+		if ((data[i] & 0xc0) == 0x80) {
+			i += 2;
 			continue;
 		}
-		if ((data[start + k] & 0xC0) == 0x40) {
-			if ((data[start + k] & 0x3F) == 0x00 &&
-				data[start + k + 1] == 0x00)
+
+		if ((data[i] & 0xc0) == 0x40) {
+			if ((data[i] & 0x3f) == 0 && data[i + 1] == 0)
 				return -1;
-			k += 1;
+			i++;
 			continue;
 		}
-		if ((data[start + k] & 0xC0) == 0x00) {
-			if (data[start + k] > 0x13)
+
+		if ((data[i] & 0xc0) == 0) {
+			if (data[i] > 0x13)
 				return -1;
-			k += 3;
+			i += 3;
 			continue;
 		}
 	}
diff --git a/src/loaders/prowizard/fc-m.c b/src/loaders/prowizard/fc-m.c
index 6b7606f..43143b0 100644
--- a/src/loaders/prowizard/fc-m.c
+++ b/src/loaders/prowizard/fc-m.c
@@ -1,8 +1,9 @@
 /*
  * FC-M_Packer.c   Copyright (C) 1997 Asle / ReDoX
- *                 Copyright (c) 2006-2007 Claudio Matsuoka
  *
  * Converts back to ptk FC-M packed MODs
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -10,7 +11,7 @@
 #include "prowiz.h"
 
 
-static int depack_fcm(FILE *in, FILE *out)
+static int depack_fcm(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1;
 	uint8 ptable[128];
@@ -21,34 +22,34 @@ static int depack_fcm(FILE *in, FILE *out)
 
 	memset(ptable, 0, 128);
 
-	read32b(in);				/* bypass "FC-M" ID */
-	read16b(in);				/* version number? */
-	read32b(in);				/* bypass "NAME" chunk */
+	hio_read32b(in);				/* bypass "FC-M" ID */
+	hio_read16b(in);				/* version number? */
+	hio_read32b(in);				/* bypass "NAME" chunk */
 	pw_move_data(out, in, 20);		/* read and write title */
-	read32b(in);				/* bypass "INST" chunk */
+	hio_read32b(in);				/* bypass "INST" chunk */
 
 	/* read and write sample descriptions */
 	for (i = 0; i < 31; i++) {
 		pw_write_zero(out, 22);		/*sample name */
-		write16b(out, size = read16b(in));	/* size */
+		write16b(out, size = hio_read16b(in));	/* size */
 		ssize += size * 2;
-		write8(out, read8(in));		/* finetune */
-		write8(out, read8(in));		/* volume */
-		write16b(out, read16b(in));	/* loop start */
-		size = read16b(in);		/* loop size */
+		write8(out, hio_read8(in));		/* finetune */
+		write8(out, hio_read8(in));		/* volume */
+		write16b(out, hio_read16b(in));	/* loop start */
+		size = hio_read16b(in);		/* loop size */
 		if (size == 0)
 			size = 1;
 		write16b(out, size);
 	}
 
-	read32b(in);				/* bypass "LONG" chunk */
-	write8(out, pat_pos = read8(in));	/* pattern table lenght */
-	write8(out, read8(in));			/* NoiseTracker byte */
-	read32b(in);				/* bypass "PATT" chunk */
+	hio_read32b(in);				/* bypass "LONG" chunk */
+	write8(out, pat_pos = hio_read8(in));	/* pattern table lenght */
+	write8(out, hio_read8(in));			/* NoiseTracker byte */
+	hio_read32b(in);				/* bypass "PATT" chunk */
 
 	/* read and write pattern list and get highest patt number */
 	for (pat_max = i = 0; i < pat_pos; i++) {
-		write8(out, c1 = read8(in));
+		write8(out, c1 = hio_read8(in));
 		if (c1 > pat_max)
 			pat_max = c1;
 	}
@@ -56,12 +57,12 @@ static int depack_fcm(FILE *in, FILE *out)
 		write8(out, 0);
 
 	write32b(out, PW_MOD_MAGIC);		/* write ptk ID */
-	read32b(in);				/* bypass "SONG" chunk */
+	hio_read32b(in);				/* bypass "SONG" chunk */
 
 	for (i = 0; i <= pat_max; i++)		/* pattern data */
 		pw_move_data(out, in, 1024);
 
-	read32b(in);				/* bypass "SAMP" chunk */
+	hio_read32b(in);				/* bypass "SAMP" chunk */
 	pw_move_data(out, in, ssize);		/* sample data */
 
 	return 0;
@@ -69,7 +70,6 @@ static int depack_fcm(FILE *in, FILE *out)
 
 static int test_fcm(uint8 *data, char *t, int s)
 {
-	int start = 0;
 	int j;
 
 	PW_REQUEST_DATA(s, 37 + 8 * 31);
@@ -80,16 +80,16 @@ static int test_fcm(uint8 *data, char *t, int s)
 		return -1;
 
 	/* test 1 */
-	if (data[start + 4] != 0x01)
+	if (data[4] != 0x01)
 		return -1;
 
 	/* test 2 */
-	if (data[start + 5] != 0x00)
+	if (data[5] != 0x00)
 		return -1;
 
 	/* test 3 */
 	for (j = 0; j < 31; j++) {
-		if (data[start + 37 + 8 * j] > 0x40)
+		if (data[37 + 8 * j] > 0x40)
 			return -1;
 	}
 
diff --git a/src/loaders/prowizard/fuchs.c b/src/loaders/prowizard/fuchs.c
index 8fdc806..1979eb3 100644
--- a/src/loaders/prowizard/fuchs.c
+++ b/src/loaders/prowizard/fuchs.c
@@ -1,8 +1,9 @@
 /*
  * FuchsTracker.c   Copyright (C) 1999 Sylvain "Asle" Chipaux
- *                  Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Depacks Fuchs Tracker modules
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -10,140 +11,119 @@
 #include "prowiz.h"
 
 
-static int depack_fuchs(FILE *in, FILE *out)
+static int depack_fuchs(HIO_HANDLE *in, FILE *out)
 {
 	uint8 *tmp;
-	uint8 c1;
-	uint8 pmax;
-	int ssize = 0;
-	int SampleSizes[16];
-	int LoopStart[16];
-	int i, j;
+	uint8 max_pat;
+	/*int ssize;*/
+	uint8 data[1080];
+	unsigned smp_len[16];
+	unsigned loop_start[16];
+	unsigned pat_size;
+	unsigned i;
 
-	memset(SampleSizes, 0, 16 * 4);
-	memset(LoopStart, 0, 16 * 4);
+	memset(smp_len, 0, 16 * 4);
+	memset(loop_start, 0, 16 * 4);
+	memset(data, 0, 1080);
 
-	pw_write_zero(out, 1080);		/* write ptk header */
-	fseek(out, 0, SEEK_SET);
-	pw_move_data(out, in, 10);		/* read/write title */
-	ssize = read32b(in);			/* read all sample data size */
+	hio_read(data, 1, 10, in);		/* read/write title */
+	/*ssize =*/ hio_read32b(in);		/* read all sample data size */
 
 	/* read/write sample sizes */
 	for (i = 0; i < 16; i++) {
-		fseek(out, 42 + i * 30, SEEK_SET);
-		write16b(out, (SampleSizes[i] = read16b(in)) / 2);
+		smp_len[i] = hio_read16b(in);
+		data[42 + i * 30] = smp_len[i] >> 9;
+		data[43 + i * 30] = smp_len[i] >> 1;
 	}
 
 	/* read/write volumes */
 	for (i = 0; i < 16; i++) {
-		fseek(out, 45 + i * 30, SEEK_SET);
-		fseek(in, 1, SEEK_CUR);
-		write8(out, read8(in));
+		data[45 + i * 30] = hio_read16b(in);
 	}
 
 	/* read/write loop start */
 	for (i = 0; i < 16; i++) {
-		fseek(out, 46 + i * 30, SEEK_SET);
-		write8(out, (LoopStart[i] = read16b(in)) / 2);
+		loop_start[i] = hio_read16b(in);
+		data[46 + i * 30] = loop_start[i] >> 1;
 	}
 
 	/* write replen */
 	for (i = 0; i < 16; i++) {
-		fseek(out, 48 + i * 30, SEEK_SET);
-		j = SampleSizes[i] - LoopStart[i];
-		if ((j == 0) || (LoopStart[i] == 0))
-			write16b(out, 0x0001);
-		else
-			write16b(out, j / 2);
+		int loop_size;
+
+		loop_size = smp_len[i] - loop_start[i];
+		if (loop_size == 0 || loop_start[i] == 0) {
+			data[49 + i * 30] = 1;
+		} else {
+			data[48 + i * 30] = loop_size >> 9;
+			data[49 + i * 30] = loop_size >> 1;
+		}
 	}
 
 	/* fill replens up to 31st sample wiz $0001 */
 	for (i = 16; i < 31; i++) {
-		fseek(out, 48 + i * 30, SEEK_SET);
-		write16b(out, 0x0001);
+		data[49 + i * 30] = 1;
 	}
 
 	/* that's it for the samples ! */
 	/* now, the pattern list */
 
 	/* read number of pattern to play */
-	fseek(out, 950, SEEK_SET);
-	/* bypass empty byte (saved wiz a WORD ..) */
-	fseek(in, 1, SEEK_CUR);
-	write8(out, read8(in));
-
-	/* write ntk byte */
-	write8(out, 0x7f);
+	data[950] = hio_read16b(in);
+	data[951] = 0x7f;
 
 	/* read/write pattern list */
-	for (pmax = i = 0; i < 40; i++) {
-		fseek(in, 1, SEEK_CUR);
-		write8(out, c1 = read8(in));
-		if (c1 > pmax)
-			pmax = c1;
+	for (max_pat = i = 0; i < 40; i++) {
+		uint8 pat = hio_read16b(in);
+		data[952 + i] = pat;
+		if (pat > max_pat) {
+			max_pat = pat;
+		}
 	}
 
 	/* write ptk's ID */
-	fseek(out, 0, SEEK_END);
+	if (fwrite(data, 1, 1080, out) != 1080) {
+		return -1;
+	}
 	write32b(out, PW_MOD_MAGIC);
 
 	/* now, the pattern data */
 
 	/* bypass the "SONG" ID */
-	fseek(in, 4, 1);
+	hio_read32b(in);
 
 	/* read pattern data size */
-	j = read32b(in);
+	pat_size = hio_read32b(in);
+
+	/* Sanity check */
+	if (pat_size <= 0 || pat_size > 0x20000)
+		return -1;
 
 	/* read pattern data */
-	tmp = (uint8 *)malloc(j);
-	fread(tmp, j, 1, in);
+	tmp = (uint8 *)malloc(pat_size);
+	if (hio_read(tmp, 1, pat_size, in) != pat_size) {
+		free(tmp);
+		return -1;
+	}
 
 	/* convert shits */
-	for (i = 0; i < j; i += 4) {
+	for (i = 0; i < pat_size; i += 4) {
 		/* convert fx C arg back to hex value */
 		if ((tmp[i + 2] & 0x0f) == 0x0c) {
-			c1 = tmp[i + 3];
-			if (c1 <= 9) {
-				tmp[i + 3] = c1;
-				continue;
-			}
-			if ((c1 >= 16) && (c1 <= 25)) {
-				tmp[i + 3] = (c1 - 6);
-				continue;
-			}
-			if ((c1 >= 32) && (c1 <= 41)) {
-				tmp[i + 3] = (c1 - 12);
-				continue;
-			}
-			if ((c1 >= 48) && (c1 <= 57)) {
-				tmp[i + 3] = (c1 - 18);
-				continue;
-			}
-			if ((c1 >= 64) && (c1 <= 73)) {
-				tmp[i + 3] = (c1 - 24);
-				continue;
-			}
-			if ((c1 >= 80) && (c1 <= 89)) {
-				tmp[i + 3] = (c1 - 30);
-				continue;
-			}
-			if ((c1 >= 96) && (c1 <= 100)) {
-				tmp[i + 3] = (c1 - 36);
-				continue;
-			}
+			int x = tmp[i + 3];
+			tmp[i + 3] = 10 * (x >> 4) + (x & 0xf);
 		}
 	}
 
 	/* write pattern data */
-	fwrite(tmp, j, 1, out);
+	fwrite(tmp, pat_size, 1, out);
 	free(tmp);
 
 	/* read/write sample data */
-	fseek (in, 4, SEEK_CUR);	/* bypass "INST" Id */
+	hio_read32b(in);			/* bypass "INST" Id */
 	for (i = 0; i < 16; i++) {
-		if (SampleSizes[i] != 0)
-			pw_move_data(out, in, SampleSizes[i]);
+		if (smp_len[i] != 0)
+			pw_move_data(out, in, smp_len[i]);
 	}
 
 	return 0;
@@ -151,8 +131,8 @@ static int depack_fuchs(FILE *in, FILE *out)
 
 static int test_fuchs (uint8 *data, char *t, int s)
 {
-	int start = 0;
-	int j, k, m, n, o;
+	int i;
+	int ssize, hdr_ssize;
 
 #if 0
 	/* test #1 */
@@ -167,60 +147,48 @@ static int test_fuchs (uint8 *data, char *t, int s)
 		return -1;
 
 	/* all sample size */
-	j = ((data[start + 10] << 24) + (data[start + 11] << 16) +
-		(data[start + 12] << 8) + data[start + 13]);
+	hdr_ssize = readmem32b(data + 10);
 
-	if (j <= 2 || j >= (65535 * 16))
+	if (hdr_ssize <= 2 || hdr_ssize >= 65535 * 16)
 		return -1;
 
 	/* samples descriptions */
-	m = 0;
-	for (k = 0; k < 16; k++) {
-		/* size */
-		o = (data[start + k * 2 + 14] << 8) + data[start + k * 2 + 15];
-		/* loop start */
-		n = (data[start + k * 2 + 78] << 8) + data[start + k * 2 + 79];
+	ssize = 0;
+	for (i = 0; i < 16; i++) {
+		uint8 *d = data + i * 2;
+		int len = readmem16b(d + 14);
+		int start = readmem16b(d + 78);
 
 		/* volumes */
-		if (data[start + 46 + k * 2] > 0x40)
+		if (d[46] > 0x40)
 			return -1;
 
-		/* size < loop start ? */
-		if (o < n)
+		if (len < start)
 			return -1;
 
-		m += o;
+		ssize += len;
 	}
 
-	/* m is the size of all samples (in descriptions) */
-	/* j is the sample data sizes (header) */
-	/* size<2  or  size > header sample size ? */
-	if (m <= 2 || m > j)
+	if (ssize <= 2 || ssize > hdr_ssize)
 		return -1;
 
 	/* get highest pattern number in pattern list */
-	k = 0;
-	for (j = 0; j < 40; j++) {
-		n = data[start + j * 2 + 113];
-		if (n > 40)
+	/*max_pat = 0;*/
+	for (i = 0; i < 40; i++) {
+		int pat = data[i * 2 + 113];
+		if (pat > 40)
 			return -1;
-		if (n > k)
-			k = n;
+		/*if (pat > max_pat)
+			max_pat = pat;*/
 	}
 
-	/* m is the size of all samples (in descriptions) */
-	/* k is the highest pattern data -1 */
-
 #if 0
 	/* input file not long enough ? */
-	k += 1;
-	k *= 1024;
+	max_pat++;
+	max_pat *= 1024;
 	PW_REQUEST_DATA (s, k + 200);
 #endif
 
-	/* m is the size of all samples (in descriptions) */
-	/* k is the pattern data size */
-
 	pw_read_title(NULL, t, 0);
 
 	return 0;
diff --git a/src/loaders/prowizard/fuzzac.c b/src/loaders/prowizard/fuzzac.c
index 1f90a31..f0370e9 100644
--- a/src/loaders/prowizard/fuzzac.c
+++ b/src/loaders/prowizard/fuzzac.c
@@ -1,6 +1,5 @@
 /*
  * fuzzac.c   Copyright (C) 1997 Asle / ReDoX
- *            Modified by Claudio Matsuoka
  *
  * Converts Fuzzac packed MODs back to PTK MODs
  * thanks to Gryzor and his ProWizard tool ! ... without it, this prog
@@ -11,6 +10,8 @@
  *      pattern order (most of the time the list is generated badly ..).
  *      Dont know why I did it for this depacker because I've but one
  *      exemple file ! :)
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -18,7 +19,7 @@
 #include "prowiz.h"
 
 
-static int depack_fuzz(FILE *in, FILE *out)
+static int depack_fuzz(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1;
 	uint8 data[1024];
@@ -36,34 +37,40 @@ static int depack_fuzz(FILE *in, FILE *out)
 	memset(tidx_real, 0, 128 * 4);
 	memset(ord, 0, 128);
 
-	read32b(in);			/* bypass ID */
-	read16b(in);			/* bypass 2 unknown bytes */
+	hio_read32b(in);			/* bypass ID */
+	hio_read16b(in);			/* bypass 2 unknown bytes */
 	pw_write_zero(out, 20);		/* write title */
 
 	for (i = 0; i < 31; i++) {
 		pw_move_data(out, in, 22);	/*sample name */
-		fseek(in, 38, SEEK_CUR);
-		write16b(out, size = read16b(in));
+		hio_seek(in, 38, SEEK_CUR);
+		write16b(out, size = hio_read16b(in));
 		ssize += size * 2;
-		lps = read16b(in);		/* loop start */
-		lsz = read16b(in);		/* loop size */
-		write8(out, read8(in));		/* finetune */
-		write8(out, read8(in));		/* volume */
+		lps = hio_read16b(in);		/* loop start */
+		lsz = hio_read16b(in);		/* loop size */
+		write8(out, hio_read8(in));		/* finetune */
+		write8(out, hio_read8(in));		/* volume */
 		write16b(out, lps);
 		write16b(out, lsz > 0 ? lsz : 1);
 	}
 
-	write8(out, len = read8(in));	/* size of pattern list */
-	ntrk = read8(in);		/* read the number of tracks */
+	len = hio_read8(in);		/* size of pattern list */
+
+	/* Sanity check */
+	if (len > 128)
+		return -1;
+
+	write8(out, len);
+	ntrk = hio_read8(in);		/* read the number of tracks */
 	write8(out, 0x7f);		/* write noisetracker byte */
 
 	/* place file pointer at track number list address */
-	fseek(in, 2118, SEEK_SET);
+	hio_seek(in, 2118, SEEK_SET);
 
 	/* read tracks numbers */
 	for (i = 0; i < 4; i++) {
 		for (j = 0; j < len; j++)
-			fread(&tidx[j][i * 4], 1, 4, in);
+			hio_read(&tidx[j][i * 4], 1, 4, in);
 	}
 
 	/* sort tracks numbers */
@@ -136,17 +143,17 @@ static int depack_fuzz(FILE *in, FILE *out)
 		memset(data, 0, 1024);
 		memset(track, 0, 4 << 8);
 
-		fseek(in, l + (tidx_real[i][0] << 8), SEEK_SET);
-		fread(track[0], 256, 1, in);
+		hio_seek(in, l + (tidx_real[i][0] << 8), SEEK_SET);
+		hio_read(track[0], 256, 1, in);
 
-		fseek(in, l + (tidx_real[i][1] << 8), SEEK_SET);
-		fread(track[1], 256, 1, in);
+		hio_seek(in, l + (tidx_real[i][1] << 8), SEEK_SET);
+		hio_read(track[1], 256, 1, in);
 
-		fseek(in, l + (tidx_real[i][2] << 8), SEEK_SET);
-		fread(track[2], 256, 1, in);
+		hio_seek(in, l + (tidx_real[i][2] << 8), SEEK_SET);
+		hio_read(track[2], 256, 1, in);
 
-		fseek(in, l + (tidx_real[i][3] << 8), SEEK_SET);
-		fread(track[3], 256, 1, in);
+		hio_seek(in, l + (tidx_real[i][3] << 8), SEEK_SET);
+		hio_read(track[3], 256, 1, in);
 
 		for (j = 0; j < 64; j++) {
 			memcpy(&data[j * 16     ], &track[0][j * 4], 4);
@@ -160,42 +167,40 @@ static int depack_fuzz(FILE *in, FILE *out)
 
 	/* sample data */
 	/* bypass the "SEnd" unidentified ID */
-	fseek(in, l + (ntrk << 8) + 4, SEEK_SET);
+	hio_seek(in, l + (ntrk << 8) + 4, SEEK_SET);
 	pw_move_data(out, in, ssize);
 
 	return 0;
 }
 
-static int test_fuzz (uint8 *data, char *t, int s)
+static int test_fuzz(uint8 *data, char *t, int s)
 {
-	int j, k;
-	int start = 0, ssize = 0;
+	int i;
 
 	if (readmem32b(data) != MAGIC4('M','1','.','0'))
 		return -1;
 
 	/* test finetune */
-	for (k = 0; k < 31; k++) {
-		if (data[start + 72 + k * 68] > 0x0f)
+	for (i = 0; i < 31; i++) {
+		if (data[72 + i * 68] > 0x0f)
 			return -1;
 	}
 
 	/* test volumes */
-	for (k = 0; k < 31; k++) {
-		if (data[start + 73 + k * 68] > 0x40)
+	for (i = 0; i < 31; i++) {
+		if (data[73 + i * 68] > 0x40)
 			return -1;
 	}
 
 	/* test sample sizes */
-	for (k = 0; k < 31; k++) {
-		j = readmem16b(data + start + k * 68 + 66);
-		if (j > 0x8000)
+	for (i = 0; i < 31; i++) {
+		int len = readmem16b(data + i * 68 + 66);
+		if (len > 0x8000)
 			return -1;
-		ssize += j * 2;
 	}
 
 	/* test size of pattern list */
-	if (data[start + 2114] == 0x00)
+	if (data[2114] == 0x00)
 		return -1;
 
 	pw_read_title(NULL, t, 0);
diff --git a/src/loaders/prowizard/gmc.c b/src/loaders/prowizard/gmc.c
index 829c405..8b8d9f1 100644
--- a/src/loaders/prowizard/gmc.c
+++ b/src/loaders/prowizard/gmc.c
@@ -1,8 +1,9 @@
 /*
  * gmc.c    Copyright (C) 1997 Sylvain "Asle" Chipaux
- *          Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Depacks musics in the Game Music Creator format and saves in ptk.
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -10,12 +11,12 @@
 #include "prowiz.h"
 
 
-static int depack_GMC(FILE *in, FILE *out)
+static int depack_GMC(HIO_HANDLE *in, FILE *out)
 {
 	uint8 tmp[1024];
 	uint8 ptable[128];
 	uint8 max;
-	uint8 PatPos;
+	uint8 pat_pos;
 	uint16 len, looplen;
 	long ssize = 0;
 	long i = 0, j = 0;
@@ -26,18 +27,19 @@ static int depack_GMC(FILE *in, FILE *out)
 
 	for (i = 0; i < 15; i++) {
 		pw_write_zero(out, 22);		/* name */
-		read32b(in);			/* bypass 4 address bytes */
-		write16b(out, len = read16b(in));	/* size */
+		hio_read32b(in);		/* bypass 4 address bytes */
+		len = hio_read16b(in);
+		write16b(out, len);		/* size */
 		ssize += len * 2;
-		read8(in);
+		hio_read8(in);
 		write8(out, 0);			/* finetune */
-		write8(out, read8(in));		/* volume */
-		read32b(in);			/* bypass 4 address bytes */
+		write8(out, hio_read8(in));	/* volume */
+		hio_read32b(in);		/* bypass 4 address bytes */
 
-		looplen = read16b(in);		/* loop size */
+		looplen = hio_read16b(in);	/* loop size */
 		write16b(out, looplen > 2 ? len - looplen : 0);
 		write16b(out, looplen <= 2 ? 1 : looplen);
-		read16b(in);	/* always zero? */
+		hio_read16b(in);		/* always zero? */
 	}
 
 	memset(tmp, 0, 30);
@@ -45,14 +47,14 @@ static int depack_GMC(FILE *in, FILE *out)
 	for (i = 0; i < 16; i++)
 		fwrite(tmp, 30, 1, out);
 
-	fseek(in, 0xf3, 0);
-	write8(out, PatPos = read8(in));	/* pattern list size */
+	hio_seek(in, 0xf3, 0);
+	write8(out, pat_pos = hio_read8(in));	/* pattern list size */
 	write8(out, 0x7f);			/* ntk byte */
 
 	/* read and write size of pattern list */
 	/*printf ( "Creating the pattern table ... " ); */
 	for (i = 0; i < 100; i++)
-		ptable[i] = read16b(in) / 1024;
+		ptable[i] = hio_read16b(in) / 1024;
 	fwrite(ptable, 128, 1, out);
 
 	/* get number of pattern */
@@ -65,10 +67,10 @@ static int depack_GMC(FILE *in, FILE *out)
 	write32b(out, PW_MOD_MAGIC);
 
 	/* pattern data */
-	fseek(in, 444, SEEK_SET);
+	hio_seek(in, 444, SEEK_SET);
 	for (i = 0; i <= max; i++) {
 		memset(tmp, 0, 1024);
-		fread(tmp, 1024, 1, in);
+		hio_read(tmp, 1024, 1, in);
 		for (j = 0; j < 256; j++) {
 			switch (tmp[(j * 4) + 2] & 0x0f) {
 			case 3:	/* replace by C */
@@ -104,84 +106,88 @@ static int depack_GMC(FILE *in, FILE *out)
 
 static int test_GMC(uint8 *data, char *t, int s)
 {
-	int j, k, l, m, n, o;
-	int start = 0;
+	int i, j, k;
+	int ssize, numpat;
 
 	PW_REQUEST_DATA(s, 1024);
 
 #if 0
 	/* test #1 */
 	if (i < 7) {
-/*printf ( "#1\n" );*/
 		return -1;
 	}
 	start = i - 7;
 #endif
 
 	/* samples descriptions */
-	m = 0;
-	j = 0;
-	for (k = 0; k < 15; k++) {
-		o = (data[start + 16 * k + 4] << 8) + data[start + 16 * k + 5];
-		n = (data[start + 16 * k + 12] << 8) +
-		    data[start + 16 * k + 13];
-		o *= 2;
+	ssize = 0;
+	for (i = 0; i < 15; i++) {
+		int len, lsize;
+		uint8 *d = data + 16 * i;
 
 		/* volumes */
-		if (data[start + 7 + (16 * k)] > 0x40)
+		if (d[7] > 0x40)
 			return -1;
 
+		len = readmem16b(d + 4) << 1;
+		lsize = readmem16b(d + 12);
+
 		/* size */
-		if (o > 0xFFFF)
+		if (len > 0xffff)
 			return -1;
 
-		if (n > o)
+		if (lsize > len)
 			return -1;
 
-		m += o;
-		if (o != 0)
-			j = k + 1;
+		ssize += len;
 	}
-	if (m <= 4)
+	if (ssize <= 4)
 		return -1;
-	/* j is the highest not null sample */
 
 	/* pattern table size */
-	if (data[start + 243] > 0x64 || data[start + 243] == 0x00)
+	if (data[243] > 0x64 || data[243] == 0)
 		return -1;
 
 	/* pattern order table */
-	l = 0;
-	for (n = 0; n < 100; n++) {
-		k = readmem16b(data + start + 244 + n * 2);
+	numpat = 0;
+	for (i = 0; i < 100; i++) {
+		k = readmem16b(data + 244 + i * 2);
 		if (k & 0x03ff)
 			return -1;
-		l = ((k >> 10) > l) ? k >> 10 : l;
+		if ((k >> 10) > numpat)
+			numpat = k >> 10;
 	}
-	l++;
+	numpat++;
 
-	/* l is the number of pattern */
-	if (l == 1 || l > 0x64)
+	if (numpat == 1 || numpat > 100)
 		return -1;
 
-	PW_REQUEST_DATA(s, 444 + k * 1024 + n * 4 + 3);
+	PW_REQUEST_DATA(s, 444 + k * 1024 + i * 4 + 3);
 
 	/* test pattern data */
-	o = data[start + 243];
-	for (k = 0; k < l; k++) {
-		for (n = 0; n < 256; n++) {
-			int offset = start + 444 + k * 1024 + n * 4;
-			uint8 *d = &data[offset];
+	for (i = 0; i < numpat; i++) {
+		for (j = 0; j < 256; j++) {
+			int offset = 444 + i * 1024 + j * 4;
+			uint8 *d;
+
+			PW_REQUEST_DATA(s, offset + 4);
+
+			d = &data[offset];
 
 			if (offset > (PW_TEST_CHUNK - 4))
 				return -1;
 				
+#if 0
 			/* First test fails with Jumping Jackson */
+			/* Second test never succeeds! */
 			if (/*d[0] > 0x03 ||*/ (d[2] & 0x0f) >= 0x90)
 				return -1;
+#endif
+
 #if 0
 			/* Test fails with Jumping Jackson */
-			if (((d[2] & 0xf0) >> 4) > j)
+			/* x is the highest jot jull sample */
+			if (((d[2] & 0xf0) >> 4) > x)
 				return -1;
 #endif
 			if ((d[2] & 0x0f) == 3 && d[3] > 0x40)
@@ -190,7 +196,7 @@ static int test_GMC(uint8 *data, char *t, int s)
 			if ((d[2] & 0x0f) == 4 && d[3] > 0x63)
 				return -1;
 
-			if ((d[2] & 0x0f) == 5 && d[3] > (o + 1))
+			if ((d[2] & 0x0f) == 5 && d[3] > (data[243] + 1))
 				return -1;
 
 			if ((d[2] & 0x0f) == 6 && d[3] >= 0x02)
diff --git a/src/loaders/prowizard/heatseek.c b/src/loaders/prowizard/heatseek.c
index 6c8d746..ae6a7a7 100644
--- a/src/loaders/prowizard/heatseek.c
+++ b/src/loaders/prowizard/heatseek.c
@@ -1,10 +1,11 @@
 /*
  * Heatseeker_mc1.0.c   Copyright (C) 1997 Asle / ReDoX
- *			Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Converts back to ptk Heatseeker packed MODs
  *
  * Asle's note: There's a good job ! .. gosh !.
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -12,9 +13,9 @@
 #include "prowiz.h"
 
 
-static int depack_crb(FILE *in, FILE *out)
+static int depack_crb(HIO_HANDLE *in, FILE *out)
 {
-	uint8 c1, c2, c3, c4;
+	uint8 c1;
 	uint8 ptable[128];
 	uint8 pat_pos, pat_max;
 	uint8 pat[1024];
@@ -30,21 +31,21 @@ static int depack_crb(FILE *in, FILE *out)
 	/* read and write sample descriptions */
 	for (i = 0; i < 31; i++) {
 		pw_write_zero(out, 22);			/*sample name */
-		write16b(out, size = read16b(in));	/* size */
+		write16b(out, size = hio_read16b(in));	/* size */
 		ssize += size * 2;
-		write8(out, read8(in));			/* finetune */
-		write8(out, read8(in));			/* volume */
-		write16b(out, read16b(in));		/* loop start */
-		size = read16b(in);			/* loop size */
+		write8(out, hio_read8(in));			/* finetune */
+		write8(out, hio_read8(in));			/* volume */
+		write16b(out, hio_read16b(in));		/* loop start */
+		size = hio_read16b(in);			/* loop size */
 		write16b(out, size ? size : 1);
 	}
 
-	write8(out, pat_pos = read8(in));		/* pat table length */
-	write8(out, read8(in)); 			/* NoiseTracker byte */
+	write8(out, pat_pos = hio_read8(in));		/* pat table length */
+	write8(out, hio_read8(in)); 			/* NoiseTracker byte */
 
 	/* read and write pattern list and get highest patt number */
 	for (pat_max = i = 0; i < 128; i++) {
-		write8(out, c1 = read8(in));
+		write8(out, c1 = hio_read8(in));
 		if (c1 > pat_max)
 			pat_max = c1;
 	}
@@ -57,49 +58,49 @@ static int depack_crb(FILE *in, FILE *out)
 	for (i = 0; i < pat_max; i++) {
 		memset(pat, 0, 1024);
 		for (j = 0; j < 4; j++) {
-			taddr[i * 4 + j] = ftell(in);
+			int x = hio_tell(in);
+			if (x < 0) {
+				return -1;
+			}
+			taddr[i * 4 + j] = x;
 			for (k = 0; k < 64; k++) {
 				int y = k * 16 + j * 4;
 
-				c1 = read8(in);
+				c1 = hio_read8(in);
 				if (c1 == 0x80) {
-					c2 = read8(in);
-					c3 = read8(in);
-					c4 = read8(in);
-					k += c4;
+					k += hio_read24b(in);
 					continue;
 				}
 				if (c1 == 0xc0) {
-					c2 = read8(in);
-					c3 = read8(in);
-					c4 = read8(in);
-					l = ftell(in);
-					fseek(in, taddr[((c3 << 8) + c4) / 4],
-								SEEK_SET);
+					m = hio_read24b(in);
+					l = hio_tell(in);
+
+					/* Sanity check */
+					if (l < 0 || m >= 2048)
+						return -1;
+
+					hio_seek(in, taddr[m >> 2], SEEK_SET);
 					for (m = 0; m < 64; m++) {
 						int x = m * 16 + j * 4;
 
-						c1 = read8(in);
+						c1 = hio_read8(in);
 						if (c1 == 0x80) {
-							c2 = read8(in);
-							c3 = read8(in);
-							c4 = read8(in);
-							m += c4;
+							m += hio_read24b(in);
 							continue;
 						}
 						pat[x] = c1;
-						pat[x + 1] = read8(in);
-						pat[x + 2] = read8(in);
-						pat[x + 3] = read8(in);
+						pat[x + 1] = hio_read8(in);
+						pat[x + 2] = hio_read8(in);
+						pat[x + 3] = hio_read8(in);
 					}
-					fseek (in, l, 0);	/* SEEK_SET */
+					hio_seek(in, l, SEEK_SET);
 					k += 100;
 					continue;
 				}
 				pat[y] = c1;
-				pat[y + 1] = read8(in);
-				pat[y + 2] = read8(in);
-				pat[y + 3] = read8(in);
+				pat[y + 1] = hio_read8(in);
+				pat[y + 2] = hio_read8(in);
+				pat[y + 3] = hio_read8(in);
 			}
 		}
 		fwrite (pat, 1024, 1, out);
@@ -113,88 +114,90 @@ static int depack_crb(FILE *in, FILE *out)
 
 static int test_crb(uint8 *data, char *t, int s)
 {
-	int j, k, l, m, n, o;
-	int start = 0, ssize;
+	int i, j, k;
+	int ssize, max, idx;
 
 	PW_REQUEST_DATA (s, 378);
 
 	/* size of the pattern table */
-	if (data[start + 248] > 0x7f || data[start + 248] == 0x00)
+	if (data[248] > 0x7f || data[248] == 0x00)
 		return -1;
 
 	/* test noisetracker byte */
-	if (data[start + 249] != 0x7f)
+	if (data[249] != 0x7f)
 		return -1;
 
 	/* test samples */
 	ssize = 0;
-	for (k = 0; k < 31; k++) {
-		if (data[start + 2 + k * 8] > 0x0f)
+	for (i = 0; i < 31; i++) {
+		int len, start, lsize;
+		uint8 *d = data + i * 8;
+
+		if (d[2] > 0x0f)
 			return -1;
 
 		/* test volumes */
-		if (data[start + 3 + k * 8] > 0x40)
+		if (d[3] > 0x40)
 			return -1;
 
-		j = readmem16b(data + start + k * 8) * 2;	/* size */
-		m = readmem16b(data + start + k * 8 + 4) * 2;	/* loop start */
-		n = readmem16b(data + start + k * 8 + 6) * 2;	/* loop size */
+		len = readmem16b(d) << 1;		/* size */
+		start = readmem16b(d + 4) << 1;		/* loop start */
+		lsize = readmem16b(d + 6) << 1;		/* loop size */
 
-		if (j > 0xffff || m > 0xffff || n > 0xffff)
+		if (len > 0xffff || start > 0xffff || lsize > 0xffff)
 			return -1;
 
-		/* n != 2 test added by claudio -- asle, please check! */
-		if (n != 0 && n != 2 && (m + n) > j)
+		if (lsize != 0 && lsize != 2 && (start + lsize) > len)
 			return -1;
 
-		if (m != 0 && n <= 2)
+		if (start != 0 && lsize <= 2)
 			return -1;
 
-		ssize += j;
+		ssize += len;
 	}
 
-/* printf ("3\n"); */
+	/* printf ("3\n"); */
 	if (ssize <= 4)
 		return -1;
 
 	/* test pattern table */
-	l = 0;
-	for (j = 0; j < 128; j++) {
-		if (data[start + 250 + j] > 0x7f)
-			return -1;
-		if (data[start + 250 + j] > l)
-			l = data[start + 250 + j];
-	}
+	{
+		uint8 *d = data + 250;
+		max = 0;
+		for (i = 0; i < 128; i++) {
+			if (d[i] > 0x7f)
+				return -1;
+			if (d[i] > max)
+				max = data[250 + i];
+		}
 
-	/* FIXME */
-	PW_REQUEST_DATA (s, 379 + 4 * l * 4 * 64);
+		/* FIXME */
+		PW_REQUEST_DATA(s, 379 + 4 * max * 4 * 64);
+	}
 
 	/* test notes */
-	k = 0;
-	j = 0;
-	for (m = 0; m <= l; m++) {
-		for (n = 0; n < 4; n++) {
-			for (o = 0; o < 64; o++) {
-				switch (data[start + 378 + j] & 0xC0) {
+	idx = 0;
+	for (i = 0; i <= max; i++) {
+		for (j = 0; j < 4; j++) {
+			for (k = 0; k < 64; k++) {
+				uint8 *d = data + 378 + idx;
+				switch (d[0] & 0xC0) {
 				case 0x00:
-					if ((data[start + 378 + j] & 0x0F) > 0x03)
+					if ((d[0] & 0x0F) > 0x03)
 						return -1;
-					k += 4;
-					j += 4;
+					idx += 4;
 					break;
 				case 0x80:
-					if (data[start + 379 + j] != 0x00)
+					if (d[1] != 0)
 						return -1;
-					o += data[start + 381 + j];
-					j += 4;
-					k += 4;
+					k += d[3];
+					idx += 4;
 					break;
 				case 0xC0:
-					if (data[start + 379 + j] != 0x00)
+					if (d[1] != 0)
 						return -1;
-					o = 100;
-					j += 4;
-					k += 4;
+					k = 100;
+					idx += 4;
 					break;
 				default:
 					break;
diff --git a/src/loaders/prowizard/hrt.c b/src/loaders/prowizard/hrt.c
index 218283d..641fdf7 100644
--- a/src/loaders/prowizard/hrt.c
+++ b/src/loaders/prowizard/hrt.c
@@ -1,6 +1,7 @@
 /*
  * Hornet_Packer.c Copyright (C) 1997 Asle / ReDoX
- * xmp version Copyright (C) 2009 Claudio Matsuoka
+ *
+ * Modified in 2009,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -8,7 +9,7 @@
 #include "prowiz.h"
 
 
-static int depack_hrt(FILE *in, FILE *out)
+static int depack_hrt(HIO_HANDLE *in, FILE *out)
 {
 	uint8 buf[1024];
 	uint8 c1, c2, c3, c4;
@@ -18,7 +19,7 @@ static int depack_hrt(FILE *in, FILE *out)
 
 	memset(buf, 0, 950);
 
-	fread(buf, 950, 1, in);			/* read header */
+	hio_read(buf, 950, 1, in);			/* read header */
 	for (i = 0; i < 31; i++)		/* erase addresses */
 		*(uint32 *)(buf + 38 + 30 * i) = 0;
 	fwrite(buf, 950, 1, out);		/* write header */
@@ -26,10 +27,10 @@ static int depack_hrt(FILE *in, FILE *out)
 	for (i = 0; i < 31; i++)		/* samples size */
 		ssize += readmem16b(buf + 42 + 30 * i) * 2;
 
-	write8(out, len = read8(in));		/* song length */
-	write8(out, read8(in));			/* nst byte */
+	write8(out, len = hio_read8(in));		/* song length */
+	write8(out, hio_read8(in));			/* nst byte */
 
-	fread(buf, 1, 128, in);			/* pattern list */
+	hio_read(buf, 1, 128, in);			/* pattern list */
 
 	npat = 0;				/* number of patterns */
 	for (i = 0; i < 128; i++) {
@@ -41,13 +42,13 @@ static int depack_hrt(FILE *in, FILE *out)
 	write32b(out, PW_MOD_MAGIC);		/* write ptk ID */
 
 	/* pattern data */
-	fseek(in, 1084, SEEK_SET);
+	hio_seek(in, 1084, SEEK_SET);
 	for (i = 0; i < npat; i++) {
 		for (j = 0; j < 256; j++) {
-			buf[0] = read8(in);
-			buf[1] = read8(in);
-			buf[2] = read8(in);
-			buf[3] = read8(in);
+			buf[0] = hio_read8(in);
+			buf[1] = hio_read8(in);
+			buf[2] = hio_read8(in);
+			buf[3] = hio_read8(in);
 
 			buf[0] /= 2;
 			c1 = buf[0] & 0xf0;
@@ -78,7 +79,6 @@ static int depack_hrt(FILE *in, FILE *out)
 static int test_hrt(uint8 *data, char *t, int s)
 {
 	int i;
-	int start = 0;
 
 	PW_REQUEST_DATA(s, 1084);
 
@@ -86,14 +86,15 @@ static int test_hrt(uint8 *data, char *t, int s)
 		return -1;
 
 	for (i = 0; i < 31; i++) {
+		uint8 *d = data + 20 + i * 30;
+
 		/* test finetune */
-		if (data[start + 20 + i * 30 + 24] > 0x0f)
+		if (d[24] > 0x0f)
 			return -1;
 
 		/* test volume */
-		if (data[start + 20 + i * 30 + 25] > 0x40)
+		if (d[25] > 0x40)
 			return -1;
-		
 	}
 
 	pw_read_title(data, t, 20);
diff --git a/src/loaders/prowizard/kris.c b/src/loaders/prowizard/kris.c
new file mode 100644
index 0000000..b19c344
--- /dev/null
+++ b/src/loaders/prowizard/kris.c
@@ -0,0 +1,157 @@
+/*
+ * Kris_tracker.c   Copyright (C) 1997 Asle / ReDoX
+ *                  Copyright (C) 2006-2007 Claudio Matsuoka
+ *
+ * Kris Tracker to Protracker.
+ */
+
+#include 
+#include 
+#include "prowiz.h"
+
+
+static int depack_kris(HIO_HANDLE *in, FILE *out)
+{
+	uint8 tmp[1024];
+	uint8 c3;
+	uint8 npat, max;
+	uint8 ptable[128];
+	uint8 note, ins, fxt, fxp;
+	uint8 tdata[512][256];
+	short taddr[128][4];
+	short maxtaddr = 0;
+	int i, j, k;
+	int size, ssize = 0;
+
+	memset(tmp, 0, 1024);
+	memset(ptable, 0, 128);
+	memset(taddr, 0, 128 * 4 * 2);
+	memset(tdata, 0, 512 << 8);
+
+	pw_move_data(out, in, 20);			/* title */
+	hio_seek(in, 2, SEEK_CUR);
+
+	/* 31 samples */
+	for (i = 0; i < 31; i++) {
+		/* sample name */
+		hio_read(tmp, 22, 1, in);
+		if (tmp[0] == 0x01)
+			tmp[0] = 0x00;
+		fwrite(tmp, 22, 1, out);
+
+		write16b(out, size = hio_read16b(in));	/* size */
+		ssize += size * 2;
+		write8(out, hio_read8(in));			/* fine */
+		write8(out, hio_read8(in));			/* volume */
+		write16b(out, hio_read16b(in) / 2);		/* loop start */
+		write16b(out, hio_read16b(in));		/* loop size */
+	}
+
+	hio_read32b(in);			/* bypass ID "KRIS" */
+	write8(out, npat = hio_read8(in));	/* number of pattern in pattern list */
+	write8(out, hio_read8(in));		/* Noisetracker restart byte */
+
+	/* pattern table (read,count and write) */
+	c3 = 0;
+	k = 0;
+	for (i = 0; i < 128; i++, k++) {
+		for (j = 0; j < 4; j++) {
+			taddr[k][j] = hio_read16b(in);
+			if (taddr[k][j] > maxtaddr)
+				maxtaddr = taddr[k][j];
+		}
+
+		for (j = 0; j < k; j++) {
+			if (!memcmp(taddr[j], taddr[k], 4)) {
+				ptable[i] = ptable[j];
+				k--;
+				break;
+			}
+		}
+
+		if (k == j)
+			ptable[i] = c3++;
+
+		write8(out, ptable[i]);
+	}
+
+	max = c3 - 1;
+	write32b(out, PW_MOD_MAGIC);	/* ptk ID */
+	hio_read16b(in);			/* bypass two unknown bytes */
+
+	/* Track data ... */
+	for (i = 0; i <= (maxtaddr / 256); i += 1) {
+		memset(tmp, 0, 1024);
+		hio_read(tmp, 256, 1, in);
+
+		for (j = 0; j < 64 * 4; j += 4) {
+			note = tmp[j];
+			ins = tmp[j + 1];
+			fxt = tmp[j + 2] & 0x0f;
+			fxp = tmp[j + 3];
+
+			tdata[i][j] = ins & 0xf0;
+
+			if (note != 0xa8) {
+				tdata[i][j] |= ptk_table[(note / 2) - 35][0];
+				tdata[i][j + 1] = ptk_table[(note / 2) - 35][1];
+			}
+			tdata[i][j + 2] = ((ins << 4) & 0xf0) | (fxt & 0x0f);
+			tdata[i][j + 3] = fxp;
+		}
+	}
+
+	for (i = 0; i <= max; i++) {
+		memset(tmp, 0, 1024);
+		for (j = 0; j < 64 * 4; j += 4) {
+			uint8 *p = &tmp[j * 4];
+
+			memcpy(p, &tdata[taddr[i][0] / 256][j], 4);
+			memcpy(p + 4, &tdata[taddr[i][1] / 256][j], 4);
+			memcpy(p + 8, &tdata[taddr[i][2] / 256][j], 4);
+			memcpy(p + 12, &tdata[taddr[i][3] / 256][j], 4);
+		}
+		fwrite(tmp, 1024, 1, out);
+	}
+
+	/* sample data */
+	pw_move_data(out, in, ssize);
+
+	return 0;
+}
+
+static int test_kris (uint8 *data, char *t, int s)
+{
+	int j;
+	int start = 0;
+
+	/* test 1 */
+	PW_REQUEST_DATA (s, 1024);
+
+	if (readmem32b(data + 952) != MAGIC4('K','R','I','S'))
+		return -1;
+
+	/* test 2 */
+	for (j = 0; j < 31; j++) {
+		if (data[47 + j * 30] > 0x40)
+			return -1;
+		if (data[46 + j * 30] > 0x0f)
+			return -1;
+	}
+
+	/* test volumes */
+	for (j = 0; j < 31; j++) {
+		if (data[start + j * 30 + 47] > 0x40)
+			return -1;
+	}
+
+	pw_read_title(data, t, 20);
+
+	return 0;
+}
+
+const struct pw_format pw_kris = {
+	"ChipTracker",
+	test_kris,
+	depack_kris
+};
diff --git a/src/loaders/prowizard/ksm.c b/src/loaders/prowizard/ksm.c
index 1892c44..ce94e62 100644
--- a/src/loaders/prowizard/ksm.c
+++ b/src/loaders/prowizard/ksm.c
@@ -1,18 +1,17 @@
 /*
  * Kefrens_Sound_Machine.c   Copyright (C) 1997 Sylvain "Asle" Chipaux
- *                           Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Depacks musics in the Kefrens Sound Machine format and saves in ptk.
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
 #include 
 #include "prowiz.h"
 
-#define ON  1
-#define OFF 2
 
-static int depack_ksm (FILE *in, FILE *out)
+static int depack_ksm(HIO_HANDLE *in, FILE *out)
 {
 	uint8 tmp[1024];
 	uint8 c1, c5;
@@ -20,9 +19,9 @@ static int depack_ksm (FILE *in, FILE *out)
 	uint8 trknum[128][4];
 	uint8 real_tnum[128][4];
 	uint8 tdata[4][192];
-	uint8 Max;
-	uint8 PatPos;
-	uint8 Status = ON;
+	uint8 max_trknum;
+	uint8 len;
+	uint8 status = 1;
 	int ssize = 0;
 	int i, j, k;
 
@@ -31,110 +30,110 @@ static int depack_ksm (FILE *in, FILE *out)
 	memset(real_tnum, 0, 128 * 4);
 
 	/* title */
-	fseek(in, 2, SEEK_SET);
+	hio_seek(in, 2, SEEK_SET);
 	pw_move_data(out, in, 13);
 	pw_write_zero(out, 7);
 
 	/* read and write whole header */
 	/*printf ( "Converting sample headers ... " ); */
-	fseek(in, 32, SEEK_SET);
+	hio_seek(in, 32, SEEK_SET);
 	for (i = 0; i < 15; i++) {
 		pw_write_zero(out, 22);		/* write name */
-		fseek(in, 20, SEEK_CUR);	/* 16 unknown/4 addr bytes */
-		write16b(out, (k = read16b(in)) / 2); /* size */
+		hio_seek(in, 20, SEEK_CUR);	/* 16 unknown/4 addr bytes */
+		write16b(out, (k = hio_read16b(in)) / 2); /* size */
 		ssize += k;
 		write8(out, 0);			/* finetune */
-		write8(out, read8(in));		/* volume */
-		read8(in);			/* bypass 1 unknown byte */
-		write16b(out, (j = read16b(in)) / 2);	/* loop start */
+		write8(out, hio_read8(in));		/* volume */
+		hio_read8(in);			/* bypass 1 unknown byte */
+		write16b(out, (j = hio_read16b(in)) / 2);	/* loop start */
 		j = k - j;
 		write16b(out, j != k ? j / 2 : 1);	/* loop size */
-		fseek(in, 6, SEEK_CUR);		/* bypass 6 unknown bytes */
+		hio_seek(in, 6, SEEK_CUR);		/* bypass 6 unknown bytes */
 	}
 
 	memset(tmp, 0, 30);
-	tmp[29] = 0x01;
+	tmp[29] = 1;
 	for (i = 0; i < 16; i++)
 		fwrite(tmp, 30, 1, out);
 
 	/* pattern list */
-	fseek (in, 512, 0);
-	for (Max = PatPos = 0; PatPos < 128; PatPos++) {
-		fread(&trknum[PatPos][0], 1, 1, in);
-		fread(&trknum[PatPos][1], 1, 1, in);
-		fread(&trknum[PatPos][2], 1, 1, in);
-		fread(&trknum[PatPos][3], 1, 1, in);
-		if (trknum[PatPos][0] == 0xFF)
+	hio_seek(in, 512, SEEK_SET);
+	for (max_trknum = len = 0; len < 128; len++) {
+		hio_read(&trknum[len][0], 1, 1, in);
+		hio_read(&trknum[len][1], 1, 1, in);
+		hio_read(&trknum[len][2], 1, 1, in);
+		hio_read(&trknum[len][3], 1, 1, in);
+		if (trknum[len][0] == 0xFF)
 			break;
-		if (trknum[PatPos][0] > Max)
-			Max = trknum[PatPos][0];
-		if (trknum[PatPos][1] > Max)
-			Max = trknum[PatPos][1];
-		if (trknum[PatPos][2] > Max)
-			Max = trknum[PatPos][2];
-		if (trknum[PatPos][3] > Max)
-			Max = trknum[PatPos][3];
+		if (trknum[len][0] > max_trknum)
+			max_trknum = trknum[len][0];
+		if (trknum[len][1] > max_trknum)
+			max_trknum = trknum[len][1];
+		if (trknum[len][2] > max_trknum)
+			max_trknum = trknum[len][2];
+		if (trknum[len][3] > max_trknum)
+			max_trknum = trknum[len][3];
 	}
 
-	write8(out, PatPos);		/* write patpos */
+	write8(out, len);		/* write patpos */
 	write8(out, 0x7f);		/* ntk byte */
 
 	/* sort tracks numbers */
 	c5 = 0x00;
-	for (i = 0; i < PatPos; i++) {
+	for (i = 0; i < len; i++) {
 		if (i == 0) {
 			plist[0] = c5;
-			c5 += 0x01;
+			c5++;
 			continue;
 		}
 		for (j = 0; j < i; j++) {
-			Status = ON;
+			status = 1;
 			for (k = 0; k < 4; k++) {
 				if (trknum[j][k] !=
 					trknum[i][k]) {
-					Status = OFF;
+					status = 0;
 					break;
 				}
 			}
-			if (Status == ON) {
+			if (status == 1) {
 				plist[i] = plist[j];
 				break;
 			}
 		}
-		if (Status == OFF) {
+		if (status == 0) {
 			plist[i] = c5;
-			c5 += 0x01;
+			c5++;
 		}
-		Status = ON;
+		status = 1;
 	}
-	/* c5 is the Max pattern number */
+	/* c5 is the max pattern number */
 
 	/* create real list of tracks numbers for really existing patterns */
-	c1 = 0x00;
-	for (i = 0; i < PatPos; i++) {
+	c1 = 0;
+	for (i = 0; i < len; i++) {
 		if (i == 0) {
 			real_tnum[c1][0] = trknum[i][0];
 			real_tnum[c1][1] = trknum[i][1];
 			real_tnum[c1][2] = trknum[i][2];
 			real_tnum[c1][3] = trknum[i][3];
-			c1 += 0x01;
+			c1++;
 			continue;
 		}
 		for (j = 0; j < i; j++) {
-			Status = ON;
+			status = 1;
 			if (plist[i] == plist[j]) {
-				Status = OFF;
+				status = 0;
 				break;
 			}
 		}
-		if (Status == OFF)
+		if (status == 0)
 			continue;
 		real_tnum[c1][0] = trknum[i][0];
 		real_tnum[c1][1] = trknum[i][1];
 		real_tnum[c1][2] = trknum[i][2];
 		real_tnum[c1][3] = trknum[i][3];
-		c1 += 0x01;
-		Status = ON;
+		c1++;
+		status = 1;
 	}
 
 	fwrite(plist, 128, 1, out);	/* write pattern list */
@@ -144,52 +143,35 @@ static int depack_ksm (FILE *in, FILE *out)
 	for (i = 0; i < c5; i++) {
 		memset(tmp, 0, 1024);
 		memset(tdata, 0, 192 * 4);
-		fseek(in, 1536 + 192 * real_tnum[i][0], SEEK_SET);
-		fread(tdata[0], 192, 1, in);
-		fseek(in, 1536 + 192 * real_tnum[i][1], SEEK_SET);
-		fread(tdata[1], 192, 1, in);
-		fseek(in, 1536 + 192 * real_tnum[i][2], SEEK_SET);
-		fread(tdata[2], 192, 1, in);
-		fseek(in, 1536 + 192 * real_tnum[i][3], SEEK_SET);
-		fread(tdata[3], 192, 1, in);
+
+		for (k = 0; k < 4; k++) {
+			hio_seek(in, 1536 + 192 * real_tnum[i][k], SEEK_SET);
+			hio_read(tdata[k], 192, 1, in);
+		}
 
 		for (j = 0; j < 64; j++) {
 			int x = j * 16;
 
-			tmp[x] = ptk_table[tdata[0][j * 3]][0];
-			tmp[x + 1] = ptk_table[tdata[0][j * 3]][1];
-			if ((tdata[0][j * 3 + 1] & 0x0f) == 0x0d)
-				tdata[0][j * 3 + 1] -= 0x03;
-			tmp[x + 2] = tdata[0][j * 3 + 1];
-			tmp[x + 3] = tdata[0][j * 3 + 2];
-
-			tmp[x + 4] = ptk_table[tdata[1][j * 3]][0];
-			tmp[x + 5] = ptk_table[tdata[1][j * 3]][1];
-			if ((tdata[1][j * 3 + 1] & 0x0f) == 0x0d)
-				tdata[1][j * 3 + 1] -= 0x03;
-			tmp[x + 6] = tdata[1][j * 3 + 1];
-			tmp[x + 7] = tdata[1][j * 3 + 2];
-
-			tmp[x + 8] = ptk_table[tdata[2][j * 3]][0];
-			tmp[x + 9] = ptk_table[tdata[2][j * 3]][1];
-			if ((tdata[2][j * 3 + 1] & 0x0f) == 0x0d)
-				tdata[2][j * 3 + 1] -= 0x03;
-			tmp[x + 10] = tdata[2][j * 3 + 1];
-			tmp[x + 11] = tdata[2][j * 3 + 2];
-
-			tmp[x + 12] = ptk_table[tdata[3][j * 3]][0];
-			tmp[x + 13] = ptk_table[tdata[3][j * 3]][1];
-			if ((tdata[3][j * 3 + 1] & 0x0f) == 0x0d)
-				tdata[3][j * 3 + 1] -= 0x03;
-			tmp[x + 14] = tdata[3][j * 3 + 1];
-			tmp[x + 15] = tdata[3][j * 3 + 2];
+			for (k = 0; k < 4; k++) {
+				uint8 *t = &tdata[k][j * 3];
+
+				/* Sanity check */
+				if (t[0] >= 37) {
+					return -1;
+				}
+
+				memcpy(tmp + x + k * 4, ptk_table[t[0]], 2);
+				if ((t[1] & 0x0f) == 0x0d)
+					t[1] -= 0x03;
+				memcpy(tmp + x + k * 4 + 2, &t[1], 2);
+			}
 		}
 
 		fwrite(tmp, 1024, 1, out);
 	}
 
 	/* sample data */
-	fseek(in, 1536 + (192 * (Max + 1)), SEEK_SET);
+	hio_seek(in, 1536 + (192 * (max_trknum + 1)), SEEK_SET);
 	pw_move_data(out, in, ssize);
 
 	return 0;
@@ -197,54 +179,53 @@ static int depack_ksm (FILE *in, FILE *out)
 
 static int test_ksm (uint8 *data, char *t, int s)
 {
-	int j, k, l;
-	int start = 0;
+	int i, j;
+	int max_trk;
 
 	PW_REQUEST_DATA(s, 1536);
 
-	if (data[start] != 'M' || data[start + 1] != '.')
+	if (data[0] != 'M' || data[1] != '.')
 		return -1;
 
 	/* test "a" */
-	if (data[start + 15] != 'a')
+	if (data[15] != 'a')
 		return -1;
 
 	/* test volumes */
-	for (k = 0; k < 15; k++) {
-		if (data[start + 54 + k * 32] > 0x40)
+	for (i = 0; i < 15; i++) {
+		if (data[54 + i * 32] > 0x40)
 			return -1;
 	}
 
 
 	/* test tracks data */
 	/* first, get the highest track number .. */
-	j = 0;
-	for (k = 0; k < 1024; k++) {
-		if (data[start + k + 512] == 0xFF)
+	max_trk = 0;
+	for (i = 0; i < 1024; i++) {
+		int x = data[i + 512];
+		if (x == 0xff)
 			break;
-		if (data[start + k + 512] > j)
-			j = data[start + k + 512];
+		if (x > max_trk)
+			max_trk = x;
 	}
 
-	if (k == 1024)
+	if (i == 1024)
 		return -1;
 
-	if (j == 0)
+	if (max_trk == 0)
 		return -1;
 
-	PW_REQUEST_DATA(s, start + 1536 + j * 192 + 63 * 3);
+	PW_REQUEST_DATA(s, 1536 + max_trk * 192 + 63 * 3);
 
-	/* so, now, j is the highest track number (first is 00h !!) */
 	/* real test on tracks data starts now */
-	for (k = 0; k <= j; k++) {
-		for (l = 0; l < 64; l++) {
-			if (data[start + 1536 + k * 192 + l * 3] > 0x24)
+	for (i = 0; i <= max_trk; i++) {
+		uint8 *d = data + 1536 + i * 192;
+		for (j = 0; j < 64; j++) {
+			if (d[j * 3] > 0x24)
 				return -1;
 		}
 	}
 
-	/* j is still the highest track number */
-
 	pw_read_title(data + 2, t, 13);
 
 	return 0;
diff --git a/src/loaders/prowizard/mp.c b/src/loaders/prowizard/mp.c
index 0ef0676..16ff10b 100644
--- a/src/loaders/prowizard/mp.c
+++ b/src/loaders/prowizard/mp.c
@@ -1,8 +1,9 @@
 /*
  * Module_Protector.c   Copyright (C) 1997 Asle / ReDoX
- *                      Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Converts MP packed MODs back to PTK MODs
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -12,7 +13,7 @@
 #define MAGIC_TRK1	MAGIC4('T','R','K','1')
 
 
-static int depack_mp(FILE *in, FILE *out)
+static int depack_mp(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1;
 	uint8 ptable[128];
@@ -24,24 +25,24 @@ static int depack_mp(FILE *in, FILE *out)
 
 	pw_write_zero(out, 20);				/* title */
 
-	if (read32b(in) != MAGIC_TRK1)			/* TRK1 */
-		fseek(in, -4, SEEK_CUR);
+	if (hio_read32b(in) != MAGIC_TRK1)			/* TRK1 */
+		hio_seek(in, -4, SEEK_CUR);
 
 	for (i = 0; i < 31; i++) {
 		pw_write_zero(out, 22);			/* sample name */
-		write16b(out, size = read16b(in));	/* size */
+		write16b(out, size = hio_read16b(in));	/* size */
 		ssize += size * 2;
-		write8(out, read8(in));			/* finetune */
-		write8(out, read8(in));			/* volume */
-		write16b(out, read16b(in));		/* loop start */
-		write16b(out, read16b(in));		/* loop size */
+		write8(out, hio_read8(in));			/* finetune */
+		write8(out, hio_read8(in));			/* volume */
+		write16b(out, hio_read16b(in));		/* loop start */
+		write16b(out, hio_read16b(in));		/* loop size */
 	}
 
-	write8(out, read8(in));		/* pattern table length */
-	write8(out, read8(in));		/* NoiseTracker restart byte */
+	write8(out, hio_read8(in));		/* pattern table length */
+	write8(out, hio_read8(in));		/* NoiseTracker restart byte */
 
 	for (max = i = 0; i < 128; i++) {
-		write8(out, c1 = read8(in));
+		write8(out, c1 = hio_read8(in));
 		if (c1 > max)
 			max = c1;
 	}
@@ -49,8 +50,8 @@ static int depack_mp(FILE *in, FILE *out)
 
 	write32b(out, PW_MOD_MAGIC);		/* M.K. */
 
-	if (read32b(in) != 0)			/* bypass unknown empty bytes */
-		fseek (in, -4, SEEK_CUR);
+	if (hio_read32b(in) != 0)			/* bypass unknown empty bytes */
+		hio_seek(in, -4, SEEK_CUR);
 
 	pw_move_data(out, in, 1024 * max);	/* pattern data */
 	pw_move_data(out, in, ssize);		/* sample data */
@@ -60,97 +61,95 @@ static int depack_mp(FILE *in, FILE *out)
 
 static int test_mp_noid(uint8 *data, char *t, int s)
 {
-	int start, ssize;
-	int j, k, l, m, n;
-
-	start = 0;
+	int i;
+	int len, psize, hdr_ssize;
 
 #if 0
-	if (i < 3) {
-		Test = BAD;
-		return;
+	if (s < 378) {
+		return - 1;
 	}
 #endif
 
 	/* test #2 */
-	l = 0;
-	for (j = 0; j < 31; j++) {
-		int x = start + 8 * j;
+	hdr_ssize = 0;
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 8;
+		int size = readmem16b(d) << 1;		/* size */
+		int start = readmem16b(d + 4) << 1;	/* loop start */
+		int lsize = readmem16b(d + 6) << 1;	/* loop size */
 
-		k = readmem16b(data + x) * 2;		/* size */
-		m = readmem16b(data + x + 4) * 2;	/* loop start */
-		n = readmem16b(data + x + 6) * 2;	/* loop size */
-		l += k;
+		hdr_ssize += size;
 
 		/* finetune > 0x0f ? */
-		if (data[x + 2] > 0x0f)
+		if (d[2] > 0x0f)
 			return -1;
 
-		/* loop start+replen > size ? */
-		if (n != 2 && (m + n) > k)
+		/* loop start+repsize > size ? */
+		if (lsize != 2 && (start + lsize) > size)
 			return -1;
 
 		/* loop size > size ? */
-		if (n > (k + 2))
+		if (lsize > (size + 2))
 			return -1;
 
 		/* loop start != 0 and loop size = 0 */
-		if (m != 0 && n <= 2)
+		if (start != 0 && lsize <= 2)
 			return -1;
 
 		/* when size!=0  loopsize==0 ? */
-		if (k != 0 && n == 0)
+		if (size != 0 && lsize == 0)
 			return -1;
 	}
 
-	if (l <= 2)
+	if (hdr_ssize <= 2)
 		return -1;
 
 	/* test #3 */
-	l = data[start + 248];
-	if (l > 0x7f || l == 0x00)
+	len = data[248];
+	if (len == 0 || len > 0x7f)
 		return -1;
 
 	/* test #4 */
-	/* l contains the size of the pattern list */
-	k = 0;
-	for (j = 0; j < 128; j++) {
-		if (data[start + 250 + j] > k)
-			k = data[start + 250 + j];
-		if (data[start + 250 + j] > 0x7f)
+	psize = 0;
+	for (i = 0; i < 128; i++) {
+		int pat = data[250 + i];
+		if (pat > 0x7f)
 			return -1;
-		if (j > l + 3) {
-			if (data[start + 250 + j] != 0x00)
+		if (pat > psize)
+			psize = pat;
+		if (i > len + 3) {
+			if (pat != 0)
 				return -1;
 		}
 	}
-	k++;
+	psize++;
+	psize <<= 8;
+
+	PW_REQUEST_DATA(s, 378 + psize * 4);
 
 	/* test #5  ptk notes .. gosh ! (testing all patterns !) */
-	/* k contains the number of pattern saved */
-	for (j = 0; j < (256 * k); j++) {
-		int x = start + j * 4;
+	for (i = 0; i < psize; i++) {
+		uint8 *d = data + 378 + i * 4;
+		uint16 data;
 
-		l = data[x + 378];
-		if (l > 19 && l != 74)		/* MadeInCroatia has l == 74 */
+		/* MadeInCroatia has l == 74 */
+		if (*d > 19 && *d != 74)
 			return -1;
 
-		ssize = data[x + 378] & 0x0f;
-		ssize *= 256;
-		ssize += data[x + 379];
+		data = readmem16b(d) & 0x0fff;
 
-		if (ssize > 0 && ssize < 0x71)
+		if (data > 0 && data < 0x71)
 			return -1;
 	}
 
 	/* test #6  (loopStart+LoopSize > Sample ? ) */
-	for (j = 0; j < 31; j++) {
-		int x = start + j * 8;
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 8;
 
-		k = readmem16b(data + x) * 2;
-		l = (readmem16b(data + x + 4) + readmem16b(data + x + 6)) * 2;
+		int size = readmem16b(d) << 1;
+		int lend = (readmem16b(d + 4) + readmem16b(d + 6)) << 1;
 
-		if (l > (k + 2))
+		if (lend > size + 2)
 			return -1;
 	}
 
@@ -161,39 +160,41 @@ static int test_mp_noid(uint8 *data, char *t, int s)
 
 static int test_mp_id(uint8 *data, char *t, int s)
 {
-	int j, l, k;
-	int start = 0;
+	int i;
+	int len, psize;
 
 	/* "TRK1" Module Protector */
 	if (readmem32b(data) != MAGIC_TRK1)
 		return -1;
 
 	/* test #1 */
-	for (j = 0; j < 31; j++) {
-		if (data[start + 6 + 8 * j] > 0x0f)
+	for (i = 0; i < 31; i++) {
+		if (data[6 + 8 * i] > 0x0f)
 			return -1;
 	}
 
 	/* test #2 */
-	l = data[start + 252];
-	if (l > 0x7f || l == 0x00)
+	len = data[252];
+	if (len == 0 || len > 0x7f)
 		return -1;
 
 	/* test #4 */
-	k = 0;
-	for (j = 0; j < 128; j++) {
-		if (data[start + 254 + j] > k)
-			k = data[start + 254 + j];
-		if (data[start + 254 + j] > 0x7f)
+	psize = 0;
+	for (i = 0; i < 128; i++) {
+		int pat = data[254 + i];
+		if (pat > 0x7f)
 			return -1;
+		if (pat > psize)
+			psize = pat;
 	}
-	k++;
+	psize++;
+	psize <<= 8;
 
 	/* test #5  ptk notes .. gosh ! (testing all patterns !) */
 	/* k contains the number of pattern saved */
-	for (j = 0; j < (256 * k); j++) {
-		l = data[start + 382 + j * 4];
-		if (l > 19)
+	for (i = 0; i < psize; i++) {
+		int x = data[382 + i * 4];
+		if (x > 19)
 			return -1;
 	}
 
diff --git a/src/loaders/prowizard/noiserun.c b/src/loaders/prowizard/noiserun.c
index bb528f6..1c6ea2c 100644
--- a/src/loaders/prowizard/noiserun.c
+++ b/src/loaders/prowizard/noiserun.c
@@ -1,8 +1,9 @@
 /*
  *  NoiseRunner.c	Copyright (C) 1997 Asle / ReDoX
- *			Copyright (C) 2010 Claudio Matsuoka
  *
  *  Converts NoiseRunner packed MODs back to Protracker
+ *
+ *  Modified in 2010,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -16,7 +17,7 @@ static int fine_table[] = {
 };
 
 
-static int depack_nru(FILE *in, FILE *out)
+static int depack_nru(HIO_HANDLE *in, FILE *out)
 {
 	uint8 tmp[1025];
 	uint8 ptable[128];
@@ -33,15 +34,15 @@ static int depack_nru(FILE *in, FILE *out)
 		int vol, size, addr, start, lsize;
 
 		pw_write_zero(out, 22);		/* sample name */
-		read8(in);			/* bypass 0x00 */
-		vol = read8(in);		/* read volume */
-		addr = read32b(in);		/* read sample address */
-		write16b(out, size = read16b(in)); /* read/write sample size */
+		hio_read8(in);			/* bypass 0x00 */
+		vol = hio_read8(in);		/* read volume */
+		addr = hio_read32b(in);		/* read sample address */
+		write16b(out, size = hio_read16b(in)); /* read/write sample size */
 		ssize += size * 2;
-		start = read32b(in);		/* read loop start address */
+		start = hio_read32b(in);		/* read loop start address */
 
-		lsize = read16b(in);		/* read loop size */
-		fine = read16b(in);		/* read finetune ?!? */
+		lsize = hio_read16b(in);		/* read loop size */
+		fine = hio_read16b(in);		/* read finetune ?!? */
 
 		for (j = 0; j < 16; j++) {
 			if (fine == fine_table[j]) {
@@ -58,13 +59,13 @@ static int depack_nru(FILE *in, FILE *out)
 		write16b(out, lsize);		/* write loop size */
 	}
 
-	fseek(in, 950, SEEK_SET);
-	write8(out, read8(in));			/* size of pattern list */
-	write8(out, read8(in));			/* ntk byte */
+	hio_seek(in, 950, SEEK_SET);
+	write8(out, hio_read8(in));			/* size of pattern list */
+	write8(out, hio_read8(in));			/* ntk byte */
 
 	/* pattern table */
 	max_pat = 0;
-	fread(ptable, 128, 1, in);
+	hio_read(ptable, 128, 1, in);
 	fwrite(ptable, 128, 1, out);
 	for (i = 0; i < 128; i++) {
 		if (ptable[i] > max_pat)
@@ -75,10 +76,10 @@ static int depack_nru(FILE *in, FILE *out)
 	write32b(out, PW_MOD_MAGIC);
 
 	/* pattern data */
-	fseek (in, 0x043c, SEEK_SET);
+	hio_seek(in, 0x043c, SEEK_SET);
 	for (i = 0; i < max_pat; i++) {
 		memset(pat_data, 0, 1025);
-		fread(tmp, 1024, 1, in);
+		hio_read(tmp, 1024, 1, in);
 		for (j = 0; j < 256; j++) {
 			ins = (tmp[j * 4 + 3] >> 3) & 0x1f;
 			note = tmp[j * 4 + 2];
@@ -112,9 +113,8 @@ static int depack_nru(FILE *in, FILE *out)
 
 static int test_nru(uint8 *data, char *t, int s)
 {
-	int i, j, k, l;
-	int start = 0;
-	int ssize;
+	int i;
+	int len, psize, ssize;
 
 	PW_REQUEST_DATA(s, 1500);
 
@@ -125,63 +125,59 @@ static int test_nru(uint8 *data, char *t, int s)
 	}
 #endif
 
-	if (readmem32b(data + start + 1080) != PW_MOD_MAGIC)
+	if (readmem32b(data + 1080) != PW_MOD_MAGIC)
 		return -1;
 
 	/* test 2 */
 	ssize = 0;
 	for (i = 0; i < 31; i++)
-		ssize += 2 * readmem16b(data + start + 6 + i * 16);
+		ssize += 2 * readmem16b(data + 6 + i * 16);
 	if (ssize == 0)
 		return -1;
 
 	/* test #3 volumes */
 	for (i = 0; i < 31; i++) {
-		if (data[start + 1 + i * 16] > 0x40)
+		if (data[1 + i * 16] > 0x40)
 			return -1;
 	}
 
 	/* test #4  pattern list size */
-	l = data[start + 950];
-	if (l > 127 || l == 0) {
+	len = data[950];
+	if (len == 0 || len > 127) {
 		return -1;
 	}
 
 	/* l holds the size of the pattern list */
-	k = 0;
-	for (j = 0; j < l; j++) {
-		if (data[start + 952 + j] > k)
-			k = data[start + 952 + j];
-		if (data[start + 952 + j] > 127) {
+	psize = 0;
+	for (i = 0; i < len; i++) {
+		int x = data[952 + i];
+		if (x > psize)
+			psize = x;
+		if (x > 127) {
 			return -1;
 		}
 	}
-	/* k holds the highest pattern number */
 	/* test last patterns of the pattern list = 0 ? */
-	while (j != 128) {
-		if (data[start + 952 + j] != 0) {
+	while (i != 128) {
+		if (data[952 + i] != 0) {
 			return -1;
 		}
-		j++;
+		i++;
 	}
-	/* k is the number of pattern in the file (-1) */
-	k += 1;
 
+	psize++;
+	psize <<= 8;
 
 	/* test #5 pattern data ... */
-	for (j = 0; j < (k << 8); j++) {
+	for (i = 0; i < psize; i++) {
+		uint8 *d = data + 1084 + i * 4;
 		/* note > 48h ? */
-		if (data[start + 1086 + j * 4] > 0x48) {
+		if (d[2] > 0x48)
 			return -1;
-		}
-		l = data[start + 1087 + j * 4];
-		if (l & 0x07) {
+		if (d[3] & 0x07)
 			return -1;
-		}
-		l = data[start + 1084 + j * 4];
-		if (l & 0x03) {
+		if (d[0] & 0x03)
 			return -1;
-		}
 	}
 
 	pw_read_title(NULL, t, 0);
diff --git a/src/loaders/prowizard/novotrade.c b/src/loaders/prowizard/novotrade.c
index 041ce91..a51aace 100644
--- a/src/loaders/prowizard/novotrade.c
+++ b/src/loaders/prowizard/novotrade.c
@@ -1,6 +1,7 @@
 /*
  * NovoTrade.c   Copyright (C) 2007 Asle / ReDoX
- * xmp version Copyright (C) 2009 Claudio Matsuoka
+ *
+ * Modified in 2009,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -8,7 +9,7 @@
 #include "prowiz.h"
 
 
-static int depack_ntp(FILE *in, FILE *out)
+static int depack_ntp(HIO_HANDLE *in, FILE *out)
 {
 	uint8 buf[1024];
 	int i, j;
@@ -16,42 +17,42 @@ static int depack_ntp(FILE *in, FILE *out)
 	short body_addr, smp_addr, nins, len, npat;
 	int size, ssize = 0;
 
-	read32b(in);				/* skip MODU */
+	hio_read32b(in);				/* skip MODU */
 
 	pw_move_data(out, in, 16);		/* title */
 	write32b(out, 0);
 	
-	body_addr = read16b(in) + 4;		/* get 'BODY' address */
-	nins = read16b(in);			/* number of samples */
-	len = read16b(in);			/* size of pattern list */
-	npat = read16b(in);			/* number of patterns stored */
-	smp_addr = read16b(in) + body_addr + 4;	/* get 'SAMP' address */
+	body_addr = hio_read16b(in) + 4;		/* get 'BODY' address */
+	nins = hio_read16b(in);			/* number of samples */
+	len = hio_read16b(in);			/* size of pattern list */
+	npat = hio_read16b(in);			/* number of patterns stored */
+	smp_addr = hio_read16b(in) + body_addr + 4;	/* get 'SAMP' address */
 
 	memset(buf, 0, 930);
 
 	/* instruments */
 	for (i = 0; i < nins; i++) {
-		int x = read8(in);		/* instrument number */
+		int x = hio_read8(in);		/* instrument number */
 
 		if (x > 30) {
-			fseek(in, 7, SEEK_CUR);
+			hio_seek(in, 7, SEEK_CUR);
 			continue;
 		}
 
 		x *= 30;
 
-		buf[x + 25] = read8(in);	/* volume */
+		buf[x + 25] = hio_read8(in);	/* volume */
 
-		size = read16b(in);		/* size */
+		size = hio_read16b(in);		/* size */
 		buf[x + 22] = size >> 8;
 		buf[x + 23] = size & 0xff;
 		ssize += size * 2;
 
-		buf[x + 26] = read8(in);	/* loop start */
-		buf[x + 27] = read8(in);
+		buf[x + 26] = hio_read8(in);	/* loop start */
+		buf[x + 27] = hio_read8(in);
 
-		buf[x + 28] = read8(in);	/* loop size */
-		buf[x + 29] = read8(in);
+		buf[x + 28] = hio_read8(in);	/* loop size */
+		buf[x + 29] = hio_read8(in);
 	}
 	fwrite(buf, 930, 1, out);
 
@@ -61,39 +62,39 @@ static int depack_ntp(FILE *in, FILE *out)
 	/* pattern list */
 	memset(buf, 0, 128);
 	for (i = 0; i < len; i++)
-		buf[i] = read16b(in);
+		buf[i] = hio_read16b(in);
 	fwrite(buf, 128, 1, out);
 
 	/* pattern addresses now */
 	/* Where is on it */
 	memset(pat_addr, 0, 256);
 	for (i = 0; i < npat; i++)
-		pat_addr[i] = read16b(in);
+		pat_addr[i] = hio_read16b(in);
 
 	write32b(out, PW_MOD_MAGIC);
 
 	/* pattern data now ... *gee* */
 	for (i = 0; i < npat; i++) {
-		fseek(in, body_addr + 4 + pat_addr[i], SEEK_SET);
+		hio_seek(in, body_addr + 4 + pat_addr[i], SEEK_SET);
 		memset(buf, 0, 1024);
 
 		for (j = 0; j < 64; j++) {
-			int x = read16b(in);
+			int x = hio_read16b(in);
 
 			if (x & 0x0001)
-				fread(buf + j * 16, 1, 4, in);
+				hio_read(buf + j * 16, 1, 4, in);
 			if (x & 0x0002)
-				fread(buf + j * 16 + 4, 1, 4, in);
+				hio_read(buf + j * 16 + 4, 1, 4, in);
 			if (x & 0x0004)
-				fread(buf + j * 16 + 8, 1, 4, in);
+				hio_read(buf + j * 16 + 8, 1, 4, in);
 			if (x & 0x0008)
-				fread(buf + j * 16 + 12, 1, 4, in);
+				hio_read(buf + j * 16 + 12, 1, 4, in);
 		}
 		fwrite(buf, 1024, 1, out);
 	}
 
 	/* samples */
-	fseek(in, smp_addr, SEEK_SET);
+	hio_seek(in, smp_addr, SEEK_SET);
 	pw_move_data(out, in, ssize);
 	
 	return 0;
@@ -102,21 +103,20 @@ static int depack_ntp(FILE *in, FILE *out)
 static int test_ntp(uint8 *data, char *t, int s)
 {
 	int j, k;
-	int start = 0;
 
 	PW_REQUEST_DATA(s, 64);
-	if (readmem32b(data + start) != MAGIC4('M','O','D','U'))
+	if (readmem32b(data) != MAGIC4('M','O','D','U'))
 		return -1;
 
-	j = readmem16b(data + start + 20) + 4;		/* "BODY" tag */
-	k = readmem16b(data + start + 28) + j + 4;	/* "SAMP" tag */
+	j = readmem16b(data + 20) + 4;		/* "BODY" tag */
+	k = readmem16b(data + 28) + j + 4;	/* "SAMP" tag */
 
 	PW_REQUEST_DATA(s, j + 4);
-	if (readmem32b(data + start + j) != MAGIC4('B','O','D','Y'))
+	if (readmem32b(data + j) != MAGIC4('B','O','D','Y'))
 		return -1;
 
 	PW_REQUEST_DATA(s, k + 4);
-	if (readmem32b(data + start + k) != MAGIC4('S','A','M','P'))
+	if (readmem32b(data + k) != MAGIC4('S','A','M','P'))
 		return -1;
 
 	pw_read_title(data + 4, t, 16);
diff --git a/src/loaders/prowizard/np1.c b/src/loaders/prowizard/np1.c
index 20d7ecc..ee0cd36 100644
--- a/src/loaders/prowizard/np1.c
+++ b/src/loaders/prowizard/np1.c
@@ -1,8 +1,9 @@
 /*
  * NoisePacker_v1.c   Copyright (C) 1997 Asle / ReDoX
- *                    Modified by Claudio Matsuoka
  *
  * Converts NoisePacked MODs back to ptk
+ *
+ * Modified in 2006,2007,2014,2015 by Claudio Matsuoka
  */
 
 #include 
@@ -10,101 +11,108 @@
 #include "prowiz.h"
 
 
-static int depack_np1(FILE *in, FILE *out)
+static int depack_np1(HIO_HANDLE *in, FILE *out)
 {
 	uint8 tmp[1024];
 	uint8 c1, c2, c3, c4;
-	uint8 len;
-	uint8 nins;
 	uint8 ptable[128];
-	uint8 npat = 0x00;
+	int len, nins, npat;
 	int max_addr;
 	int size, ssize = 0;
-	int tsize;
-	int taddr[128][4];
-	int i = 0, j = 0, k;
-	int tdata;
+	/*int tsize;*/
+	int trk_addr[128][4];
+	int i, j, k;
+	int trk_start;
 
 	memset(ptable, 0, 128);
-	memset(taddr, 0, 128 * 4 * 4);
+	memset(trk_addr, 0, 128 * 4 * 4);
 
-	/* read number of sample */
-	c1 = read8(in);
-	c2 = read8(in);
+	c1 = hio_read8(in);			/* read number of samples */
+	c2 = hio_read8(in);
 	nins = ((c1 << 4) & 0xf0) | ((c2 >> 4) & 0x0f);
 
-	/* write title */
-	pw_write_zero(out, 20);
+	pw_write_zero(out, 20);			/* write title */
+
+	len = hio_read16b(in) >> 1;		/* size of pattern list */
+
+	/* Sanity check */
+	if (len > 128) {
+		return -1;
+	}
 
-	len = read16b(in) / 2;		/* size of pattern list */
-	read16b(in);			/* 2 unknown bytes */
-	tsize = read16b(in);		/* read track data size */
+	hio_read16b(in);			/* 2 unknown bytes */
+	/*tsize =*/ hio_read16b(in);		/* read track data size */
 
 	/* read sample descriptions */
 	for (i = 0; i < nins; i++) {
-		read32b(in);			/* bypass 4 unknown bytes */
+		hio_read32b(in);		/* bypass 4 unknown bytes */
 		pw_write_zero(out, 22);		/* sample name */
-		write16b(out, size = read16b(in));	/* sample size */
+		write16b(out, size = hio_read16b(in));	/* size */
 		ssize += size * 2;
-		write8(out, read8(in));		/* finetune */
-		write8(out, read8(in));		/* volume */
-		read32b(in);			/* bypass 4 unknown bytes */
-		size = read16b(in);		/* read loop size */
-		write16b(out, read16b(in) / 2);	/* loop start */
+		write8(out, hio_read8(in));	/* finetune */
+		write8(out, hio_read8(in));	/* volume */
+		hio_read32b(in);		/* bypass 4 unknown bytes */
+		size = hio_read16b(in);		/* read loop size */
+		write16b(out, hio_read16b(in) / 2);	/* loop start */
 		write16b(out, size);		/* write loop size */
 	}
 
 	/* fill up to 31 samples */
 	memset(tmp, 0, 30);
 	tmp[29] = 0x01;
-	for (; i < 31; i++)
+	for (; i < 31; i++) {
 		fwrite(tmp, 30, 1, out);
+	}
 
 	write8(out, len);		/* write size of pattern list */
 	write8(out, 0x7f);		/* write noisetracker byte */
 
-	read16b(in);	/* bypass 2 bytes ... seems always the same as in $02 */
-	read16b(in);	/* bypass 2 other bytes which meaning is beside me */
+	hio_seek(in, 2, SEEK_CUR);	/* always $02? */
+	hio_seek(in, 2, SEEK_CUR);	/* unknown */
 
 	/* read pattern table */
 	npat = 0;
 	for (i = 0; i < len; i++) {
-		ptable[i] = read16b(in);
+		ptable[i] = hio_read16b(in) >> 3;
 		if (ptable[i] > npat)
 			npat = ptable[i];
 	}
 	npat++;
 
-	fwrite(ptable, 128, 1, out);		/* write pattern table */
-	write32b(out, PW_MOD_MAGIC);		/* write ptk ID */
+	fwrite(ptable, 128, 1, out);	/* write pattern table */
+	write32b(out, PW_MOD_MAGIC);	/* write ptk ID */
 
 	/* read tracks addresses per pattern */
 	max_addr = 0;
 	for (i = 0; i < npat; i++) {
-		if ((taddr[i][0] = read16b(in)) > max_addr)
-			max_addr = taddr[i][0];
-		if ((taddr[i][1] = read16b(in)) > max_addr)
-			max_addr = taddr[i][1];
-		if ((taddr[i][2] = read16b(in)) > max_addr)
-			max_addr = taddr[i][2];
-		if ((taddr[i][3] = read16b(in)) > max_addr)
-			max_addr = taddr[i][3];
+		if ((trk_addr[i][0] = hio_read16b(in)) > max_addr)
+			max_addr = trk_addr[i][0];
+		if ((trk_addr[i][1] = hio_read16b(in)) > max_addr)
+			max_addr = trk_addr[i][1];
+		if ((trk_addr[i][2] = hio_read16b(in)) > max_addr)
+			max_addr = trk_addr[i][2];
+		if ((trk_addr[i][3] = hio_read16b(in)) > max_addr)
+			max_addr = trk_addr[i][3];
 	}
-	tdata = ftell(in);
+	trk_start = hio_tell(in);
 
 	/* the track data now ... */
 	for (i = 0; i < npat; i++) {
 		memset(tmp, 0, 1024);
 		for (j = 0; j < 4; j++) {
-			fseek(in, tdata + taddr[i][3 - j], 0);
+			hio_seek(in, trk_start + trk_addr[i][3 - j], SEEK_SET);
 			for (k = 0; k < 64; k++) {
 				int x = k * 16 + j * 4;
 
-				c1 = read8(in);
-				c2 = read8(in);
-				c3 = read8(in);
+				c1 = hio_read8(in);
+				c2 = hio_read8(in);
+				c3 = hio_read8(in);
 				c4 = (c1 & 0xfe) / 2;
 
+				if (hio_error(in) || c4 >= 37) {
+					return -1;
+				}
+
 				tmp[x] = ((c1 << 4) & 0x10) | ptk_table[c4][0];
 				tmp[x + 1] = ptk_table[c4][1];
 
@@ -120,7 +128,7 @@ static int depack_np1(FILE *in, FILE *out)
 					c3 = c3 > 0x80 ? 0x100 - c3 :
 							(c3 << 4) & 0xf0;
 					break;
-				case 0x0B:
+				case 0x0b:
 					c3 = (c3 + 4) / 2;
 					break;
 				}
@@ -133,7 +141,7 @@ static int depack_np1(FILE *in, FILE *out)
 	}
 
 	/* sample data */
-	fseek(in, max_addr + 192 + tdata, 0);
+	hio_seek(in, max_addr + 192 + trk_start, SEEK_SET);
 	pw_move_data(out, in, ssize);
 
 	return 0;
@@ -141,79 +149,86 @@ static int depack_np1(FILE *in, FILE *out)
 
 static int test_np1(uint8 *data, char *t, int s)
 {
-	int j, k, l, m, n, o;
-	int start = 0, ssize;
+	int num_ins, ssize, hdr_size, ptab_size, trk_size, max_pptr;
+	int i;
+
+	PW_REQUEST_DATA(s, 10);
 
 	/* size of the pattern table */
-	j = readmem16b(data + start + 2);
-	if (j % 2 || j == 0)
+	ptab_size = readmem16b(data + 2);
+	if (ptab_size == 0 || ptab_size & 1 || ptab_size > 0xff)
 		return -1;
 
-	/* test nbr of samples */
-	if ((data[start + 1] & 0x0f) != 0x0C)
+	/* test number of samples */
+	if ((data[1] & 0x0f) != 0x0c)
 		return -1;
 
-	l = ((data[start] << 4) & 0xf0) | ((data[start + 1] >> 4) & 0x0f);
-	if (l > 0x1F || l == 0)
+	/* number of samples */
+	num_ins = ((data[0] << 4) & 0xf0) | ((data[1] >> 4) & 0x0f);
+	if (num_ins == 0 || num_ins > 0x1f)
 		return -1;
-	/* l is the number of samples */
 
-	PW_REQUEST_DATA(s, start + 15 + l * 16);
+	PW_REQUEST_DATA(s, 15 + num_ins * 16);
 
 	/* test volumes */
-	for (k = 0; k < l; k++) {
-		if (data[start + 15 + k * 16] > 0x40)
+	for (i = 0; i < num_ins; i++) {
+		if (data[15 + i * 16] > 0x40)
 			return -1;
 	}
 
 	/* test sample sizes */
 	ssize = 0;
-	for (k = 0; k < l; k++) {
-		o = readmem16b(data + start + k * 16 + 12) * 2;
-		m = readmem16b(data + start + k * 16 + 20) * 2;
-		n = readmem16b(data + start + k * 16 + 22);
+	for (i = 0; i < num_ins; i++) {
+		uint8 *d = data + i * 16;
 
-		if (o > 0xFFFF || m > 0xFFFF || n > 0xFFFF)
+		int len = readmem16b(d + 12) << 1;
+		int start = readmem16b(d + 20) << 1;
+		int lsize = readmem16b(d + 22);
+
+		if (len > 0xffff || start > 0xffff || lsize > 0xffff)
 			return -1;
 
-		if (m + n > o + 2)
+		if (start + lsize > len + 2)
 			return -1;
 
-		if (n != 0 && m == 0)
+		if (start == 0 && lsize != 0)
 			return -1;
 
-		ssize += o;
+		ssize += len;
 	}
 
 	if (ssize <= 4)
 		return -1;
 
-	l = l * 16 + 8 + 4;
-	/* l is the size of the header til the end of sample descriptions */
+	/* size of the header til the end of sample descriptions */
+	hdr_size = num_ins * 16 + 8 + 4;
+
+	PW_REQUEST_DATA(s, hdr_size + ptab_size + 2);
 
 	/* test pattern table */
-	n = 0;
-	for (k = 0; k < j; k += 2) {
-		m = readmem16b(data + start + l + k);
-		if (m % 8)
+	max_pptr = 0;
+	for (i = 0; i < ptab_size; i += 2) {
+		int pptr = readmem16b(data + hdr_size + i);
+		if (pptr & 0x07 || pptr >= 0x400)
 			return -1;
-		if (m > n)
-			n = m;
+		if (pptr > max_pptr)
+			max_pptr = pptr;
 	}
 
-	l += j + n + 8;	/* paske on a que l'address du dernier pattern .. */
-	/* l is now the size of the header 'til the end of the track list */
+	/* paske on a que l'address du dernier pattern .. */
+	/* size of the header 'til the end of the track list */
+	hdr_size += ptab_size + max_pptr + 8;
 
 	/* test track data size */
-	k = readmem16b(data + start + 6);
-	if (k < 192 || k % 192)
+	trk_size = readmem16b(data + 6);
+	if (trk_size < 192 || (trk_size & 0x3f))
 		return -1;
 
-	PW_REQUEST_DATA(s, start + l + k);
+	PW_REQUEST_DATA(s, hdr_size + trk_size);
 
 	/* test notes */
-	for (m = 0; m < k; m += 3) {
-		if (data[start + l + m] > 0x49)
+	for (i = 0; i < trk_size; i += 3) {
+		if (data[hdr_size + i] > 0x49)
 			return -1;
 	}
 
diff --git a/src/loaders/prowizard/np2.c b/src/loaders/prowizard/np2.c
index 97f11b0..dc14918 100644
--- a/src/loaders/prowizard/np2.c
+++ b/src/loaders/prowizard/np2.c
@@ -1,8 +1,9 @@
 /*
  * NoisePacker_v2.c   Copyright (C) 1997 Asle / ReDoX
- *                    Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Converts NoisePacked MODs back to ptk
+ *
+ * Modified in 2006,2007,2014,2015 by Claudio Matsuoka
  */
 
 #include 
@@ -10,7 +11,7 @@
 #include "prowiz.h"
 
 
-static int depack_np2(FILE *in, FILE *out)
+static int depack_np2(HIO_HANDLE *in, FILE *out)
 {
 	uint8 tmp[1024];
 	uint8 c1, c2, c3, c4;
@@ -18,7 +19,7 @@ static int depack_np2(FILE *in, FILE *out)
 	int len, nins, npat;
 	int max_addr;
 	int size, ssize = 0;
-	int tsize;
+	/*int tsize;*/
 	int trk_addr[128][4];
 	int i, j, k;
 	int trk_start;
@@ -26,48 +27,59 @@ static int depack_np2(FILE *in, FILE *out)
 	memset(ptable, 0, 128);
 	memset(trk_addr, 0, 128 * 4 * 4);
 
-	c1 = read8(in);			/* read number of samples */
-	c2 = read8(in);
+	c1 = hio_read8(in);			/* read number of samples */
+	c2 = hio_read8(in);
 	nins = ((c1 << 4) & 0xf0) | ((c2 >> 4) & 0x0f);
 
-	pw_write_zero(out, 20);		/* write title */
+	pw_write_zero(out, 20);			/* write title */
+
+	len = hio_read16b(in) >> 1;		/* size of pattern list */
+
+	/* Sanity check */
+	if (len > 128) {
+		return -1;
+	}
 
-	read8(in);
-	len = read8(in) / 2;		/* read size of pattern list */
-	read16b(in);			/* 2 unknown bytes */
-	tsize = read16b(in);		/* read track data size */
+	hio_read16b(in);			/* 2 unknown bytes */
+	/*tsize =*/ hio_read16b(in);		/* read track data size */
 
 	/* read sample descriptions */
 	for (i = 0; i < nins; i++) {
-		read32b(in);			/* bypass 4 unknown bytes */
+		hio_read32b(in);		/* bypass 4 unknown bytes */
 		pw_write_zero(out, 22);		/* sample name */
-		write16b(out, size = read16b(in));	/* size */
+		write16b(out, size = hio_read16b(in));	/* size */
 		ssize += size * 2;
-		write8(out, read8(in));		/* finetune */
-		write8(out, read8(in));		/* volume */
-		read32b(in);			/* bypass 4 unknown bytes */
-		size = read16b(in);		/* read loop size */
-		write16b(out, read16b(in));	/* loop start */
+		write8(out, hio_read8(in));	/* finetune */
+		write8(out, hio_read8(in));	/* volume */
+		hio_read32b(in);		/* bypass 4 unknown bytes */
+		size = hio_read16b(in);		/* read loop size */
+		write16b(out, hio_read16b(in));	/* loop start */
 		write16b(out, size);		/* write loop size */
 	}
 
 	/* fill up to 31 samples */
 	memset(tmp, 0, 30);
 	tmp[29] = 0x01;
-	for (; i < 31; i++)
+	for (; i < 31; i++) {
 		fwrite(tmp, 30, 1, out);
+	}
 
 	write8(out, len);		/* write size of pattern list */
 	write8(out, 0x7f);		/* write noisetracker byte */
 
-	fseek(in, 2, SEEK_CUR);		/* always $02? */
-	fseek(in, 2, SEEK_CUR);		/* unknown */
+	hio_seek(in, 2, SEEK_CUR);	/* always $02? */
+	hio_seek(in, 2, SEEK_CUR);	/* unknown */
 
 	/* read pattern table */
-	for (npat = i = 0; i < len; i++) {
-		ptable[i] = read16b(in) / 8;
-		if (ptable[i] > npat)
+	npat = 0;
+	for (i = 0; i < len; i++) {
+		ptable[i] = hio_read16b(in) >> 3;
+		if (ptable[i] > 255) {
+			return -1;
+		}
+		if (ptable[i] > npat) {
 			npat = ptable[i];
+		}
 	}
 	npat++;
 
@@ -75,31 +87,36 @@ static int depack_np2(FILE *in, FILE *out)
 	write32b(out, PW_MOD_MAGIC);	/* write ptk ID */
 
 	/* read tracks addresses per pattern */
-	for (max_addr = i = 0; i < npat; i++) {
-		if ((trk_addr[i][0] = read16b(in)) > max_addr)
+	max_addr = 0;
+	for (i = 0; i < npat; i++) {
+		if ((trk_addr[i][0] = hio_read16b(in)) > max_addr)
 			max_addr = trk_addr[i][0];
-		if ((trk_addr[i][1] = read16b(in)) > max_addr)
+		if ((trk_addr[i][1] = hio_read16b(in)) > max_addr)
 			max_addr = trk_addr[i][1];
-		if ((trk_addr[i][2] = read16b(in)) > max_addr)
+		if ((trk_addr[i][2] = hio_read16b(in)) > max_addr)
 			max_addr = trk_addr[i][2];
-		if ((trk_addr[i][3] = read16b(in)) > max_addr)
+		if ((trk_addr[i][3] = hio_read16b(in)) > max_addr)
 			max_addr = trk_addr[i][3];
 	}
-	trk_start = ftell(in);
+	trk_start = hio_tell(in);
 
 	/* the track data now ... */
 	for (i = 0; i < npat; i++) {
 		memset(tmp, 0, 1024);
 		for (j = 0; j < 4; j++) {
-			fseek(in, trk_start + trk_addr[i][3 - j], SEEK_SET);
+			hio_seek(in, trk_start + trk_addr[i][3 - j], SEEK_SET);
 			for (k = 0; k < 64; k++) {
 				int x = k * 16 + j * 4;
 
-				c1 = read8(in);
-				c2 = read8(in);
-				c3 = read8(in);
+				c1 = hio_read8(in);
+				c2 = hio_read8(in);
+				c3 = hio_read8(in);
 				c4 = (c1 & 0xfe) / 2;
 
+				if (hio_error(in) || c4 >= 37) {
+					return -1;
+				}
+
 				tmp[x] = ((c1 << 4) & 0x10) | ptk_table[c4][0];
 				tmp[x + 1] = ptk_table[c4][1];
 
@@ -122,6 +139,7 @@ static int depack_np2(FILE *in, FILE *out)
 					c3 = (c3 + 4) / 2;
 					break;
 				}
+
 				tmp[x + 2] = c2;
 				tmp[x + 3] = c3;
 			}
@@ -130,7 +148,7 @@ static int depack_np2(FILE *in, FILE *out)
 	}
 
 	/* sample data */
-	fseek(in, max_addr + 192 + trk_start, SEEK_SET);
+	hio_seek(in, max_addr + 192 + trk_start, SEEK_SET);
 	pw_move_data(out, in, ssize);
 
 	return 0;
@@ -138,123 +156,109 @@ static int depack_np2(FILE *in, FILE *out)
 
 static int test_np2(uint8 *data, char *t, int s)
 {
-	int j, k, l, o, m, n;
-	int start, ssize;
-
-	PW_REQUEST_DATA (s, 1024);
-
-#if 0
-	if (i < 15) {
-		Test = BAD;
-		return;
-	}
-#endif
+	int num_ins, ssize, hdr_size, ptab_size, trk_size, max_pptr;
+	int i;
 
-	start = 0;
+	PW_REQUEST_DATA(s, 10);
 
-	/* j is the size of the pattern list (*2) */
-	j = (data[start + 2] << 8) + data[start + 3];
-	if (j & 1 || j == 0)
-		return - 1;
+	/* size of the pattern table */
+	ptab_size = readmem16b(data + 2);
+	if (ptab_size == 0 || ptab_size & 1 || ptab_size > 0xff)
+		return -1;
 
-	/* test nbr of samples */
-	if ((data[start + 1] & 0x0f) != 0x0C)
+	/* test number of samples */
+	if ((data[1] & 0x0f) != 0x0c)
 		return -1;
 
-	/* l is the number of samples */
-	l = ((data[start] << 4) & 0xf0) | ((data[start + 1] >> 4) & 0x0f);
-	if (l > 0x1f || l == 0)
+	/* number of samples */
+	num_ins = ((data[0] << 4) & 0xf0) | ((data[1] >> 4) & 0x0f);
+	if (num_ins == 0 || num_ins > 0x1f)
 		return -1;
 
+	PW_REQUEST_DATA(s, 15 + num_ins * 16);
+
 	/* test volumes */
-	for (k = 0; k < l; k++) {
-		if (data[start + 15 + k * 16] > 0x40)
+	for (i = 0; i < num_ins; i++) {
+		if (data[15 + i * 16] > 0x40)
 			return -1;
 	}
 
 	/* test sample sizes */
 	ssize = 0;
-	for (k = 0; k < l; k++) {
-		int x = start + k * 16;
+	for (i = 0; i < num_ins; i++) {
+		uint8 *d = data + i * 16;
 
-		o = 2 * ((data[x + 12] << 8) + data[x + 13]);
-		m = 2 * ((data[x + 20] << 8) + data[x + 21]);
-		n = 2 * ((data[x + 22] << 8) + data[x + 23]);
+		int len = readmem16b(d + 12) << 1;
+		int start = readmem16b(d + 20) << 1;
+		int lsize = readmem16b(d + 22) << 1;
 
-		if (o > 0xffff || m > 0xffff || n > 0xffff)
+		if (len > 0xffff || start > 0xffff || lsize > 0xffff)
 			return -1;
 
-		if ((m + n) > (o + 2))
+		if (start + lsize > len + 2)
 			return -1;
 
-		if (n != 0 && m == 0)
+		if (start == 0 && lsize != 0)
 			return -1;
 
-		ssize += o;
+		ssize += len;
 	}
 
 	if (ssize <= 4)
 		return -1;
 
-	l *= 16;
-	l += 8 + 4;
-	/* l is now the size of the header 'til the end of sample descriptions */
+	/* size of the header til the end of sample descriptions */
+	hdr_size = num_ins * 16 + 8 + 4;
+
+	PW_REQUEST_DATA(s, hdr_size + ptab_size + 2);
 
 	/* test pattern table */
-	n = 0;
-	for (k = 0; k < j; k += 2) {
-		m = ((data[start + l + k] << 8) + data[start + l + k + 1]);
-		if (((m / 8) * 8) != m)
+	max_pptr = 0;
+	for (i = 0; i < ptab_size; i += 2) {
+		int pptr = readmem16b(data + hdr_size + i);
+		if (pptr & 0x07 || pptr > 0x400)
 			return -1;
-		if (m > n)
-			n = m;
+		if (pptr > max_pptr)
+			max_pptr = pptr;
 	}
 
-	l += j + n + 8;
+	/* max_pptr is the highest pattern number (*8) */
 
 	/* paske on a que l'address du dernier pattern... */
-	/* l is now the size of the header 'til the end of the track list */
-	/* n is the highest pattern number (*8) */
+	/* size of the header 'til the end of the track list */
+	hdr_size += ptab_size + max_pptr + 8;
 
 	/* test track data size */
-	k = (data[start + 6] << 8) + data[start + 7];
-	if (k < 192 || ((k / 192) * 192) != k)
+	trk_size = readmem16b(data + 6);
+	if (trk_size < 192 || (trk_size & 0x3f))
 		return -1;
 
-	PW_REQUEST_DATA (s, k + l + 16);
+	PW_REQUEST_DATA(s, hdr_size + trk_size + 16);
 
 	/* test notes */
-	j = ((data[start] << 4) & 0xf0) | ((data[start + 1] >> 4) & 0x0f);
-	for (m = 0; m < k; m += 3) {
-		if (data[start + l + m] > 0x49) {
-			printf ("Fail 1 on m = %d\n", m);
+	for (i = 0; i < trk_size; i += 3) {
+		uint8 *d = data + hdr_size + i;
+
+		if (d[0] > 0x49) {
 			return -1;
 		}
 
-		if ((((data[start + l + m] << 4) & 0x10) |
-			((data[start + l + m + 1] >> 4) & 0x0f)) > j) {
-			printf ("Fail 2 on m = %d", m);
+		if ((((d[0] << 4) & 0x10) | ((d[1] >> 4) & 0x0f)) > num_ins) {
 			return -1;
 		}
 
-		n = (data[start + l + m + 1] & 0x0F);
-		if (n == 0 && data[start + l + m + 2] != 0x00) {
-			printf ("Fail 3 on m = %d", m);
+		if ((d[1] & 0x0f) == 0 && d[2] != 0) {
 			return -1;
 		}
 	}
 
-	/* ssize is the size of the sample data */
-	/* l is the size of the header 'til the track datas */
-	/* k is the size of the track datas */
-
 	pw_read_title(NULL, t, 0);
 
 	return 0;
 }
 
 const struct pw_format pw_np2 = {
-	"Noisepacker v2",
+	"NoisePacker v2",
 	test_np2,
 	depack_np2
 };
diff --git a/src/loaders/prowizard/np3.c b/src/loaders/prowizard/np3.c
index 2dcc7e2..a25a3b6 100644
--- a/src/loaders/prowizard/np3.c
+++ b/src/loaders/prowizard/np3.c
@@ -1,11 +1,12 @@
 /*
  * NoisePacker_v3.c   Copyright (C) 1998 Asle / ReDoX
- *                    Modified by Claudio Matsuoka
  *
  * Converts NoisePacked MODs back to ptk
  * Last revision : 26/11/1999 by Sylvain "Asle" Chipaux
  *                 reduced to only one FREAD.
  *                 Speed-up and Binary smaller.
+ *
+ * Modified in 2006,2007,2014,2015 by Claudio Matsuoka
  */
 
 #include 
@@ -13,15 +14,15 @@
 #include "prowiz.h"
 
 
-static int depack_np3(FILE *in, FILE *out)
+static int depack_np3(HIO_HANDLE *in, FILE *out)
 {
 	uint8 tmp[1024];
 	uint8 c1, c2, c3, c4;
 	uint8 ptable[128];
 	int len, nins, npat;
-	int max_addr, smp_addr = 0;
+	int max_addr, smp_addr;
 	int size, ssize = 0;
-	int tsize;
+	/*int tsize;*/
 	int trk_addr[128][4];
 	int i, j, k;
 	int trk_start;
@@ -29,20 +30,22 @@ static int depack_np3(FILE *in, FILE *out)
 	memset(ptable, 0, 128);
 	memset(trk_addr, 0, 128 * 4 * 4);
 
-	c1 = read8(in);			/* read number of samples */
-	c2 = read8(in);
+	c1 = hio_read8(in);			/* read number of samples */
+	c2 = hio_read8(in);
 	nins = ((c1 << 4) & 0xf0) | ((c2 >> 4) & 0x0f);
 
-	pw_write_zero(out, 20);		/* write title */
+	pw_write_zero(out, 20);			/* write title */
 
-	read8(in);
-	len = read8(in) / 2;		/* read size of pattern list */
-	read16b(in);			/* 2 unknown bytes */
-	tsize = read16b(in);		/* read track data size */
+	len = hio_read16b(in) >> 1;		/* size of pattern list */
+	if (len > 128) {
+		return -1;
+	}
+	hio_read16b(in);			/* 2 unknown bytes */
+	/*tsize =*/ hio_read16b(in);		/* read track data size */
 
 	/* read sample descriptions */
 	for (i = 0; i < nins; i++) {
-		fread(tmp, 1, 16, in);
+		hio_read(tmp, 1, 16, in);
 		pw_write_zero(out, 22);		/* sample name */
 		write16b(out, size = readmem16b(tmp + 6));
 		ssize += size * 2;
@@ -61,12 +64,13 @@ static int depack_np3(FILE *in, FILE *out)
 	write8(out, len);		/* write size of pattern list */
 	write8(out, 0x7f);		/* write noisetracker byte */
 
-	read16b(in);	/* bypass 2 bytes ... seems always the same as in $02 */
-	read16b(in);	/* bypass 2 other bytes which meaning is beside me */
+	hio_seek(in, 2, SEEK_CUR);	/* always $02? */
+	hio_seek(in, 2, SEEK_CUR);	/* unknown */
 
 	/* read pattern table */
-	for (npat = i = 0; i < len; i++) {
-		ptable[i] = read16b(in) / 8;
+	npat = 0;
+	for (i = 0; i < len; i++) {
+		ptable[i] = hio_read16b(in) / 8;
 		if (ptable[i] > npat)
 			npat = ptable[i];
 	}
@@ -77,31 +81,34 @@ static int depack_np3(FILE *in, FILE *out)
 
 	/* read tracks addresses per pattern */
 	for (max_addr = i = 0; i < npat; i++) {
-		if ((trk_addr[i][0] = read16b(in)) > max_addr)
+		if ((trk_addr[i][0] = hio_read16b(in)) > max_addr)
 			max_addr = trk_addr[i][0];
-		if ((trk_addr[i][1] = read16b(in)) > max_addr)
+		if ((trk_addr[i][1] = hio_read16b(in)) > max_addr)
 			max_addr = trk_addr[i][1];
-		if ((trk_addr[i][2] = read16b(in)) > max_addr)
+		if ((trk_addr[i][2] = hio_read16b(in)) > max_addr)
 			max_addr = trk_addr[i][2];
-		if ((trk_addr[i][3] = read16b(in)) > max_addr)
+		if ((trk_addr[i][3] = hio_read16b(in)) > max_addr)
 			max_addr = trk_addr[i][3];
 	}
-	trk_start = ftell(in);
+	trk_start = hio_tell(in);
 
 	/* the track data now ... */
+	smp_addr = 0;
 	for (i = 0; i < npat; i++) {
 		memset(tmp, 0, 1024);
 		for (j = 0; j < 4; j++) {
-			fseek(in, trk_start + trk_addr[i][3 - j], SEEK_SET);
+			int x;
+
+			hio_seek(in, trk_start + trk_addr[i][3 - j], SEEK_SET);
 			for (k = 0; k < 64; k++) {
 				int x = k * 16 + j * 4;
 
-				if ((c1 = read8(in)) >= 0x80) {
+				if ((c1 = hio_read8(in)) >= 0x80) {
 					k += (0x100 - c1) - 1;
 					continue;
 				}
-				c2 = read8(in);
-				c3 = read8(in);
+				c2 = hio_read8(in);
+				c3 = hio_read8(in);
 				c4 = (c1 & 0xfe) / 2;
 
 				tmp[x] = ((c1 << 4) & 0x10) | ptk_table[c4][0];
@@ -134,15 +141,21 @@ static int depack_np3(FILE *in, FILE *out)
 					break;
 			}
 
-			if (ftell(in) > smp_addr)
-				smp_addr = ftell(in);
+			x = hio_tell(in);
+			if (x < 0) {
+				return -1;
+			}
+			if (x > smp_addr) {
+				smp_addr = x;
+			}
 		}
 		fwrite(tmp, 1024, 1, out);
 	}
 
+	/* sample data */
 	if (smp_addr & 1)
 		smp_addr++;
-	fseek(in, smp_addr, SEEK_SET);
+	hio_seek(in, smp_addr, SEEK_SET);
 	pw_move_data(out, in, ssize);
 
 	return 0;
@@ -150,106 +163,108 @@ static int depack_np3(FILE *in, FILE *out)
 
 static int test_np3(uint8 *data, char *t, int s)
 {
-	int j, k, l, m, n, o;
-	int start = 0, ssize;
+	int num_ins, ssize, hdr_size, ptab_size, trk_size, max_pptr;
+	int i;
 
 	PW_REQUEST_DATA(s, 10);
 
 	/* size of the pattern table */
-	j = readmem16b(data + start + 2);
-	if (j & 0x01 || j == 0)
+	ptab_size = readmem16b(data + 2);
+	if (ptab_size == 0 || ptab_size & 0x01 || ptab_size > 0xff)
 		return -1;
 
-	/* test nbr of samples */
-	if ((data[start + 1] & 0x0f) != 0x0C)
+	/* test number of samples */
+	if ((data[1] & 0x0f) != 0x0c)
 		return -1;
 
-	l = ((data[start] << 4) & 0xf0) | ((data[start + 1] >> 4) & 0x0f);
-	if (l > 0x1F || l == 0)
+	num_ins = ((data[0] << 4) & 0xf0) | ((data[1] >> 4) & 0x0f);
+	if (num_ins == 0 || num_ins > 0x1f)
 		return -1;
-	/* l is the number of samples */
+
+	PW_REQUEST_DATA(s, 15 + num_ins * 16);
 
 	/* test volumes */
-	for (k = 0; k < l; k++) {
-		if (data[start + 9 + k * 16] > 0x40)
+	for (i = 0; i < num_ins; i++) {
+		if (data[9 + i * 16] > 0x40)
 			return -1;
 	}
 
 	/* test sample sizes */
 	ssize = 0;
-	for (k = 0; k < l; k++) {
-		o = readmem16b(data + start + k * 16 + 14) * 2;
-		m = readmem16b(data + start + k * 16 + 20) * 2;
-		n = readmem16b(data + start + k * 16 + 22) * 2;
+	for (i = 0; i < num_ins; i++) {
+		uint8 *d = data + i * 16;
+		int len = readmem16b(d + 14) << 1;
+		int start = readmem16b(d + 20) << 1;
+		int lsize = readmem16b(d + 22) << 1;
 
-		if (o > 0xFFFF || m > 0xFFFF || n > 0xFFFF)
+		if (len > 0xffff || start > 0xffff || lsize > 0xffff)
 			return -1;
 
-		if ((m + n) > (o + 2))
+		if (start + lsize > len + 2)
 			return -1;
 
-		if (n != 0 && m == 0)
+		if (start == 0 && lsize != 0)
 			return -1;
 
-		ssize += o;
+		ssize += len;
 	}
 
 	if (ssize <= 4)
 		return -1;
 
-	l = l * 16 + 8 + 4;
-	/* l is the size of the header 'til the end of sample descriptions */
+	/* size of the header 'til the end of sample descriptions */
+	hdr_size = num_ins * 16 + 8 + 4;
+
+	PW_REQUEST_DATA(s, hdr_size + ptab_size + 2);
 
 	/* test pattern table */
-	n = 0;
-	for (k = 0; k < j; k += 2) {
-		m = readmem16b(data + start + l + k);
-		if (m & 0x07)
+	max_pptr = 0;
+	for (i = 0; i < ptab_size; i += 2) {
+		int pptr = readmem16b(data + hdr_size + i);
+		if (pptr & 0x07 || pptr > 0x400)
 			return -1;
-		if (m > n)
-			n = m;
+		if (pptr > max_pptr)
+			max_pptr = pptr;
 	}
-	l += j + n + 8;	/* paske on a que l'address du dernier pattern .. */
-	/* l is now the size of the header 'til the end of the track list */
-	/* j is now available for use :) */
-	/* n is the highest pattern number (*8) */
+
+	/* max_pptr is the highest pattern number (*8) */
+
+	/* paske on a que l'address du dernier pattern .. */
+	/* size of the header 'til the end of the track list */
+	hdr_size += ptab_size + max_pptr + 8;
 
 	/* test track data size */
-	k = readmem16b(data + start + 6);
-	if (k <= 63)
+	trk_size = readmem16b(data + 6);
+	if (trk_size <= 63)
 		return -1;
 
-	PW_REQUEST_DATA(s, start + l + k);
+	PW_REQUEST_DATA(s, hdr_size + trk_size + 2);
 
 	/* test notes */
 	/* re-calculate the number of sample */
-	/* k is the track data size */
-	j = ((data[start] << 4) & 0xf0) | ((data[start + 1] >> 4) & 0x0f);
-	for (m = 0; m < k; m++) {
-		if (data[start + l + m] & 0x80)
+	for (i = 0; i < trk_size ; i++) {
+		uint8 *d = data + hdr_size + i;
+
+		if (d[0] & 0x80)
 			continue;
 
 		/* si note trop grande et si effet = A */
-		if ((data[start + l + m] > 0x49) ||
-		    ((data[start + l + m + 1] & 0x0f) == 0x0A))
+		if (d[0] > 0x49 || (d[1] & 0x0f) == 0x0a)
 			return -1;
 
 		/* si effet D et arg > 0x40 */
-		if (((data[start + l + m + 1] & 0x0f) == 0x0D)
-		    && (data[start + l + m + 2] > 0x40))
+		if ((d[1] & 0x0f) == 0x0d && d[2] > 0x40)
 			return -1;
 
 		/* sample nbr > ce qui est defini au debut ? */
-		if ((((data[start + l + m] << 4) & 0x10) |
-		     ((data[start + l + m + 1] >> 4) & 0x0f)) > j)
+		if ((((d[0] << 4) & 0x10) | ((d[1] >> 4) & 0x0f)) > num_ins)
 			return -1;
 
 		/* all is empty ?!? ... cannot be ! */
-		if (data[start + l + m] == 0 && data[start + l + m + 1] == 0 &&
-		    data[start + l + m + 2] == 0 && m < (k - 3))
+		if (d[0] == 0 && d[1] == 0 && d[2] == 0 && i < (trk_size - 3))
 			return -1;
 
-		m += 2;
+		i += 2;
 	}
 
 	pw_read_title(NULL, t, 0);
@@ -258,7 +273,7 @@ static int test_np3(uint8 *data, char *t, int s)
 }
 
 const struct pw_format pw_np3 = {
-	"Noisepacker v3",
+	"NoisePacker v3",
 	test_np3,
 	depack_np3
 };
diff --git a/src/loaders/prowizard/p40.c b/src/loaders/prowizard/p40.c
index cb2fcd3..c090751 100644
--- a/src/loaders/prowizard/p40.c
+++ b/src/loaders/prowizard/p40.c
@@ -24,14 +24,14 @@ struct smp {
 	uint8 vol;
 };
 
-static int depack_p4x (FILE *in, FILE *out)
+static int depack_p4x(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1, c2, c3, c4, c5;
 	uint8 tmp[1024];
 	uint8 len, npat, nsmp;
 	uint8 sample, mynote, note[2];
 	uint8 tr[512][256];
-	short track_addr[128][4];
+	uint16 track_addr[128][4];
 	int trkdat_ofs, trktab_ofs, smp_ofs;
 	int ssize = 0;
 	int SampleAddress[31];
@@ -45,7 +45,7 @@ static int depack_p4x (FILE *in, FILE *out)
 	memset(SampleAddress, 0, 31 * 4);
 	memset(SampleSize, 0, 31 * 4);
 
-	id = read32b(in);
+	id = hio_read32b(in);
 #if 0
 	if (id == MAGIC_P40A) {
 		pw_p4x.id = "P40A";
@@ -59,35 +59,51 @@ static int depack_p4x (FILE *in, FILE *out)
 	}
 #endif
 
-	npat = read8(in);		/* read Real number of pattern */
-	len = read8(in);		/* read number of pattern in list */
-	nsmp = read8(in);		/* read number of samples */
-	read8(in);			/* bypass empty byte */
-	trkdat_ofs = read32b(in);	/* read track data address */
-	trktab_ofs = read32b(in);	/* read track table address */
-	smp_ofs = read32b(in);		/* read sample data address */
+	npat = hio_read8(in);		/* read Real number of pattern */
+	len = hio_read8(in);		/* read number of patterns in list */
+
+	/* Sanity check */
+	if (len >= 128) {
+		return -1;
+	}
+
+	nsmp = hio_read8(in);		/* read number of samples */
+
+	/* Sanity check */
+	if (nsmp > 31) {
+		return -1;
+	}
+
+	hio_read8(in);			/* bypass empty byte */
+	trkdat_ofs = hio_read32b(in);	/* read track data address */
+	trktab_ofs = hio_read32b(in);	/* read track table address */
+	smp_ofs = hio_read32b(in);	/* read sample data address */
+
+	if (hio_error(in)) {
+		return -1;
+	}
 
 	pw_write_zero(out, 20);		/* write title */
 
 	/* sample headers stuff */
 	for (i = 0; i < nsmp; i++) {
-		ins.addr = read32b(in);		/* read sample address */
+		ins.addr = hio_read32b(in);		/* sample address */
 		SampleAddress[i] = ins.addr;
-		ins.size = read16b(in);		/* read sample size */
+		ins.size = hio_read16b(in);		/* sample size */
 		SampleSize[i] = ins.size * 2;
 		ssize += SampleSize[i];
-		ins.loop_addr = read32b(in);	/* loop start */
-		ins.loop_size = read16b(in);	/* loop size */
+		ins.loop_addr = hio_read32b(in);	/* loop start */
+		ins.loop_size = hio_read16b(in);	/* loop size */
 		ins.fine = 0;
 		if (id == MAGIC_P40A || id == MAGIC_P40B)
-			ins.fine = read16b(in);	/* finetune */
-		read8(in);			/* bypass 00h */
-		ins.vol = read8(in);		/* read vol */
+			ins.fine = hio_read16b(in);	/* finetune */
+		hio_read8(in);				/* bypass 00h */
+		ins.vol = hio_read8(in);		/* read vol */
 		if (id == MAGIC_P41A)
-			ins.fine = read16b(in);	/* finetune */
+			ins.fine = hio_read16b(in);	/* finetune */
 
 		/* writing now */
-		pw_write_zero(out, 22);		/* sample name */
+		pw_write_zero(out, 22);			/* sample name */
 		write16b(out, ins.size);
 		write8(out, ins.fine / 74);
 		write8(out, ins.vol);
@@ -104,7 +120,7 @@ static int depack_p4x (FILE *in, FILE *out)
 	write8(out, len);		/* write size of pattern list */
 	write8(out, 0x7f);		/* write noisetracker byte */
 
-	fseek(in, trktab_ofs + 4, SEEK_SET);
+	hio_seek(in, trktab_ofs + 4, SEEK_SET);
 
 	for (c1 = 0; c1 < len; c1++)	/* write pattern list */
 		write8(out, c1);
@@ -115,22 +131,22 @@ static int depack_p4x (FILE *in, FILE *out)
 
 	for (i = 0; i < len; i++) {	/* read all track addresses */
 		for (j = 0; j < 4; j++)
-			track_addr[i][j] = read16b(in) + trkdat_ofs + 4;
+			track_addr[i][j] = hio_read16b(in) + trkdat_ofs + 4;
 	}
 
-	fseek(in, trkdat_ofs + 4, SEEK_SET);
+	hio_seek(in, trkdat_ofs + 4, SEEK_SET);
 
 	for (i = 0; i < len; i++) {	/* rewrite the track data */
 		for (j = 0; j < 4; j++) {
 			int y, x = i * 4 + j;
 
-			fseek(in, track_addr[i][j], SEEK_SET);
+			hio_seek(in, track_addr[i][j], SEEK_SET);
 
 			for (k = 0; k < 64; k++) {
-				c1 = read8(in);
-				c2 = read8(in);
-				c3 = read8(in);
-				c4 = read8(in);
+				c1 = hio_read8(in);
+				c2 = hio_read8(in);
+				c3 = hio_read8(in);
+				c4 = hio_read8(in);
 
 				if (c1 != 0x80) {
 					sample = ((c1 << 4) & 0x10) |
@@ -178,18 +194,20 @@ static int depack_p4x (FILE *in, FILE *out)
 					continue;
 				}
 
-				a = ftell (in);
+				if ((a = hio_tell(in)) < 0) {
+					return -1;
+				}
 
 				c5 = c2;
 				b = (c3 << 8) + c4 + trkdat_ofs + 4;
 
-				fseek(in, b, SEEK_SET);
+				hio_seek(in, b, SEEK_SET);
 
 				for (c = 0; c <= c5; c++) {
-					c1 = read8(in);
-					c2 = read8(in);
-					c3 = read8(in);
-					c4 = read8(in);
+					c1 = hio_read8(in);
+					c2 = hio_read8(in);
+					c3 = hio_read8(in);
+					c4 = hio_read8(in);
 
 					sample = ((c1 << 4) & 0x10) |
 						((c2 >> 4) & 0x0f);
@@ -235,7 +253,7 @@ static int depack_p4x (FILE *in, FILE *out)
 					k++;
 				}
 				k--;
-				fseek(in, a, SEEK_SET);
+				hio_seek(in, a, SEEK_SET);
 			}
 		}
 	}
@@ -259,7 +277,7 @@ static int depack_p4x (FILE *in, FILE *out)
 
 	/* read and write sample data */
 	for (i = 0; i < nsmp; i++) {
-		fseek(in, SampleAddress[i] + smp_ofs, SEEK_SET);
+		hio_seek(in, SampleAddress[i] + smp_ofs, SEEK_SET);
 		pw_move_data(out, in, SampleSize[i]);
 	}
 
diff --git a/src/loaders/prowizard/p61a.c b/src/loaders/prowizard/p61a.c
index c4466b2..8f3ab63 100644
--- a/src/loaders/prowizard/p61a.c
+++ b/src/loaders/prowizard/p61a.c
@@ -17,15 +17,15 @@
 #include "prowiz.h"
 
 
-static int depack_p61a(FILE *in, FILE *out)
+static int depack_p61a(HIO_HANDLE *in, FILE *out)
 {
     uint8 c1, c2, c3, c4, c5, c6;
     long max_row;
     uint8 tmp[1024];
     signed char *smp_buffer;
-    int len = 0;
-    int npat = 0;
-    int nins = 0;
+    int len;
+    int npat;
+    int nins;
     uint8 tdata[512][256];
     uint8 ptable[128];
     int isize[31];
@@ -49,13 +49,19 @@ static int depack_p61a(FILE *in, FILE *out)
     memset(isize, 0, 31 * 2);
     for (i = 0; i < 31; i++) {
 	PACK[i] = 0;
-/*    DELTA[i] = 0;*/
+	/* DELTA[i] = 0;*/
     }
 
     saddr[0] = 0;
-    sdata_addr = read16b(in);		/* read sample data address */
-    npat = read8(in);			/* read Real number of pattern */
-    nins = read8(in);			/* read number of samples */
+    sdata_addr = hio_read16b(in);	/* read sample data address */
+    npat = hio_read8(in);		/* read real number of pattern */
+
+    /* Sanity check */
+    if (npat >= 128) {
+        return -1;
+    }
+
+    nins = hio_read8(in);		/* read number of samples */
 
     if (nins & 0x80) {
 	/* Samples are saved as delta values */
@@ -70,7 +76,7 @@ static int depack_p61a(FILE *in, FILE *out)
 
     /* read unpacked sample data size */
     if (use_packed == 1)
-	Unpacked_Sample_Data_Size = read32b(in);
+	Unpacked_Sample_Data_Size = hio_read32b(in);
 
     pw_write_zero(out, 20);		/* write title */
 
@@ -78,7 +84,7 @@ static int depack_p61a(FILE *in, FILE *out)
     for (i = 0; i < nins; i++) {
 	pw_write_zero(out, 22);		/* write sample name */
 
-	j = isize[i] = read16b(in);	/* sample size */
+	j = isize[i] = hio_read16b(in);	/* sample size */
 
 	if (j > 0xff00) {
 	    smp_size[i] = smp_size[0xffff - j];
@@ -94,16 +100,16 @@ static int depack_p61a(FILE *in, FILE *out)
 	j = smp_size[i] / 2;
 	write16b(out, isize[i]);
 
-	c1 = read8(in);			/* finetune */
+	c1 = hio_read8(in);			/* finetune */
 	if (c1 & 0x40)
 	    PACK[i] = 1;
 	c1 &= 0x3f;
 	write8(out, c1);
 
-	write8(out, read8(in));		/* volume */
+	write8(out, hio_read8(in));		/* volume */
 
 	/* loop start */
-	x = read16b(in);
+	x = hio_read16b(in);
 	if (x == 0xffff) {
 	    write16b(out, 0x0000);
 	    write16b(out, 0x0001);
@@ -122,12 +128,12 @@ static int depack_p61a(FILE *in, FILE *out)
     /* read tracks addresses per pattern */
     for (i = 0; i < npat; i++) {
 	for (j = 0; j < 4; j++)
-	    taddr[i][j] = read16b(in);
+	    taddr[i][j] = hio_read16b(in);
     }
 
     /* pattern table */
     for (len = 0; len < 128; len++) {
-	c1 = read8(in);
+	c1 = hio_read8(in);
 	if (c1 == 0xff)
 	    break;
 	ptable[len] = c1;		/* <--- /2 in p50a */
@@ -138,27 +144,29 @@ static int depack_p61a(FILE *in, FILE *out)
     fwrite(ptable, 128, 1, out);	/* write pattern table */
     write32b(out, PW_MOD_MAGIC);	/* write ptk ID */
 
-    tdata_addr = ftell(in);
+    if ((tdata_addr = hio_tell(in)) < 0) {
+        return -1;
+    }
 
     /* rewrite the track data */
     for (i = 0; i < npat; i++) {
 	max_row = 63;
 	for (j = 0; j < 4; j++) {
-	    fseek(in, taddr[i][j] + tdata_addr, SEEK_SET);
+	    hio_seek(in, taddr[i][j] + tdata_addr, SEEK_SET);
 	    for (k = 0; k <= max_row; k++) {
 		uint8 *x = &tdata[i * 4 + j][k * 4];
-		c1 = read8(in);
+		c1 = hio_read8(in);
 
 	        /* case no fxt nor fxtArg  (3 bytes) */
 	        if ((c1 & 0x70) == 0x70 && c1 != 0xff && c1 != 0x7F) {
-		    c2 = read8(in);
+		    c2 = hio_read8(in);
 	            c6 = ((c1 << 4) & 0xf0) | ((c2 >> 4) & 0x0e);
 	            *x++ = (c2 & 0x10) | (ptk_table[c6 / 2][0]);
 	            *x++ = ptk_table[c6 / 2][1];
 	            *x++ = (c2 << 4) & 0xf0;
 
 	            if (c1 & 0x80) {
-			c3 = read8(in);
+			c3 = hio_read8(in);
 	                if (c3 < 0x80) {
 	                    k += c3;
 	                    continue;
@@ -179,7 +187,7 @@ static int depack_p61a(FILE *in, FILE *out)
 
 	        /* case no sample number nor relative note number */
 	        if ((c1 & 0x70) == 0x60 && c1 != 0xff) {
-		    c2 = read8(in);
+		    c2 = hio_read8(in);
 	            c6 = c1 & 0x0f;
 	            if (c6 == 0x08)
 	                c1 -= 0x08;
@@ -198,7 +206,7 @@ static int depack_p61a(FILE *in, FILE *out)
 			break;
 	            }
 	            if (c1 & 0x80) {
-			c3 = read8(in);
+			c3 = hio_read8(in);
 	                if (c3 < 0x80) {	/* bypass c3 rows */
 	                    k += c3;
 	                    continue;
@@ -216,9 +224,9 @@ static int depack_p61a(FILE *in, FILE *out)
 	        /* end of case no Sample number nor Relative not number */
 
 	        if ((c1 & 0x80) == 0x80 && c1 != 0xff) {
-		    c2 = read8(in);
-		    c3 = read8(in);
-		    c4 = read8(in);
+		    c2 = hio_read8(in);
+		    c3 = hio_read8(in);
+		    c4 = hio_read8(in);
 	            c1 &= 0x7f;
 
 		    *x++ = ((c1 << 4) & 0x10) | ptk_table[c1 / 2][0];
@@ -271,38 +279,40 @@ static int depack_p61a(FILE *in, FILE *out)
 	                /*k += 1; */
 	                continue;
 	            }
-		    c2 = read8(in);
+		    c2 = hio_read8(in);
 	            if (c2 < 0x40) {	/* bypass c2 rows */
 	                k += c2;
 	                continue;
 	            }
 	            c2 -= 0x40;
-		    c3 = read8(in);
+		    c3 = hio_read8(in);
 	            z = c3;
 	            if (c2 >= 0x80) {
 	                c2 -= 0x80;
-			c4 = read8(in);
+			c4 = hio_read8(in);
 	                z = (c3 << 8) + c4;
 	            }
-	            a = ftell(in);
+	            if ((a = hio_tell(in)) < 0) {
+                        return -1;
+                    }
 	            c5 = c2;
 
-	            fseek(in, -z, SEEK_CUR);
+	            hio_seek(in, -z, SEEK_CUR);
 
 	            for (l = 0; l <= c5 && k <= max_row; l++, k++) {
-			c1 = read8(in);
+			c1 = hio_read8(in);
 			x = &tdata[i * 4 + j][k * 4];
 
 	                /* case no fxt nor fxtArg  (3 bytes) */
 	                if ((c1 & 0x70) == 0x70 && c1 != 0xff && c1 != 0x7f) {
-			    c2 = read8(in);
+			    c2 = hio_read8(in);
 	                    c6 = ((c1 << 4) & 0xf0) | ((c2 >> 4) & 0x0e);
 	                    *x++ = (c2 & 0x10) | ptk_table[c6 / 2][0];
 	                    *x++ = ptk_table[c6 / 2][1];
 	                    *x++ = (c2 << 4) & 0xf0;
 
 	                    if (c1 & 0x80) {
-				c3 = read8(in);
+				c3 = hio_read8(in);
 	                        if (c3 < 0x80) {	/* bypass c3 rows */
 	                            k += c3;
 	                            continue;
@@ -322,7 +332,7 @@ static int depack_p61a(FILE *in, FILE *out)
 
 	                /* case no sample number nor relative note number */
 	                if ((c1 & 0x60) == 0x60 && c1 != 0xff && c1 != 0x7f) {
-			    c2 = read8(in);
+			    c2 = hio_read8(in);
 	                    c6 = c1 & 0x0f;
 	                    if (c6 == 0x08)
 	                        c1 -= 0x08;
@@ -344,7 +354,7 @@ static int depack_p61a(FILE *in, FILE *out)
 	                    }
 
 	                    if (c1 & 0x80) {
-				c3 = read8(in);
+				c3 = hio_read8(in);
 	                        if (c3 < 0x80) {	/* bypass c3 rows */
 	                            k += c3;
 	                            continue;
@@ -362,9 +372,9 @@ static int depack_p61a(FILE *in, FILE *out)
 	                /* end of case no sample nor relative note number */
 
 	                if ((c1 & 0x80) && c1 != 0xff && c1 != 0x7f) {
-			    c2 = read8(in);
-			    c3 = read8(in);
-			    c4 = read8(in);
+			    c2 = hio_read8(in);
+			    c3 = hio_read8(in);
+			    c4 = hio_read8(in);
 	                    c1 &= 0x7f;
 
 	                    *x++ = ((c1 << 4) & 0x10) | ptk_table[c1 / 2][0];
@@ -415,7 +425,7 @@ static int depack_p61a(FILE *in, FILE *out)
 	                        /*k += 1; */
 	                        continue;
 	                    }
-			    c2 = read8(in);
+			    c2 = hio_read8(in);
 	                    if (c2 < 0x40) {	/* bypass c2 rows */
 	                        k += c2;
 	                        continue;
@@ -423,8 +433,8 @@ static int depack_p61a(FILE *in, FILE *out)
 	                    continue;
 	                }
 
-			c2 = read8(in);
-			c3 = read8(in);
+			c2 = hio_read8(in);
+			c3 = hio_read8(in);
 
 	                *x++ = ((c1 << 4) & 0x10) | ptk_table[c1 / 2][0];
 	                *x++ = ptk_table[c1 / 2][1];
@@ -438,13 +448,13 @@ static int depack_p61a(FILE *in, FILE *out)
 	                    c3 = c3 > 0x7f ? (0x100 - c3) << 4 : c3;
 	                *x++ = c3;
 	            }
-	            fseek(in, a, SEEK_SET);
+	            hio_seek(in, a, SEEK_SET);
 	            k -= 1;
 	            continue;
 	        }
 
-		c2 = read8(in);
-		c3 = read8(in);
+		c2 = hio_read8(in);
+		c3 = hio_read8(in);
 
 	        *x++ = ((c1 << 4) & 0x10) | ptk_table[c1 / 2][0];
 	        *x++ = ptk_table[c1 / 2][1];
@@ -483,16 +493,16 @@ static int depack_p61a(FILE *in, FILE *out)
     }
 
     /* go to sample data address */
-    fseek (in, sdata_addr, 0);
+    hio_seek(in, sdata_addr, SEEK_SET);
 
     /* read and write sample data */
 
     /*printf ( "writing sample data ... " ); */
     for (i = 0; i < nins; i++) {
-	fseek(in, sdata_addr + saddr[i], 0);
+	hio_seek(in, sdata_addr + saddr[i], 0);
 	smp_buffer = malloc(smp_size[i]);
 	memset(smp_buffer, 0, smp_size[i]);
-	fread(smp_buffer, smp_size[i], 1, in);
+	hio_read(smp_buffer, smp_size[i], 1, in);
 	if (use_delta == 1) {
 	    c1 = 0;
 	    for (j = 1; j < smp_size[i]; j++) {
diff --git a/src/loaders/prowizard/pha.c b/src/loaders/prowizard/pha.c
index ae66c11..7eb28ac 100644
--- a/src/loaders/prowizard/pha.c
+++ b/src/loaders/prowizard/pha.c
@@ -1,9 +1,10 @@
 /*
  * PhaPacker.c   Copyright (C) 1996-1999 Asle / ReDoX
- *               Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Converts PHA packed MODs back to PTK MODs
  * nth revision :(.
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -11,7 +12,7 @@
 #include "prowiz.h"
 
 
-static int depack_pha(FILE *in, FILE *out)
+static int depack_pha(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1, c2;
 	uint8 pnum[128];
@@ -26,7 +27,7 @@ static int depack_pha(FILE *in, FILE *out)
 	int i, j, k;
 	int paddr1[128];
 	int paddr2[128];
-	int tmp_ptr, tmp1, tmp2;
+	int tmp_ptr, tmp;
 	int pat_addr;
 	int psize;
 	int size, ssize = 0;
@@ -41,33 +42,37 @@ static int depack_pha(FILE *in, FILE *out)
 	memset(onote, 0, 4 * 4);
 	memset(ocpt, 0, 4 * 2);
 
-	pw_write_zero(out, 20);			/* title */
+	pw_write_zero(out, 20);				/* title */
 
 	for (i = 0; i < 31; i++) {
-		pw_write_zero(out, 22);			/*sample name */
-		write16b(out, size = read16b(in));	/* size */
+		int vol, fin, lps, lsz;
+
+		pw_write_zero(out, 22);			/* sample name */
+		write16b(out, size = hio_read16b(in));	/* size */
 		ssize += size * 2;
-		read8(in);
-		write8(out, 0);				/* finetune byte */
-		write8(out, read8(in));			/* volume */
-		write16b(out, read16b(in));		/* loop start */
-		write16b(out, read16b(in));		/* loop size */
-
-		read32b(in);
-
-		c1 = read8(in);
-		if(c1 != 0x00)
-			c1 += 0x0b;
-		fseek(out, -6, SEEK_END);
-		write8(out, c1);
-		fseek(out, 0, SEEK_END);
-		fseek(in, 1, SEEK_CUR);
+		hio_read8(in);				/* ??? */
+		
+		vol = hio_read8(in);			/* volume */
+		lps = hio_read16b(in);			/* loop start */
+		lsz = hio_read16b(in);			/* loop size */
+		hio_read32b(in);			/* sample address */
+		hio_read8(in);				/* ??? */
+
+		fin = hio_read8(in);			/* finetune - 11 */
+		if (fin != 0) {
+			fin += 11;
+		}
+		write8(out, fin);
+		write8(out, vol);
+		write16b(out, lps);
+		write16b(out, lsz);
+
 	}
 
-	fseek(in, 14, SEEK_CUR);		/* bypass unknown 14 bytes */
+	hio_seek(in, 14, SEEK_CUR);		/* bypass unknown 14 bytes */
 
 	for (i = 0; i < 128; i++)
-		paddr[i] = read32b(in);
+		paddr[i] = hio_read32b(in);
 
 	/* ordering of patterns addresses */
 
@@ -97,12 +102,13 @@ static int depack_pha(FILE *in, FILE *out)
 	for (i = 0; i < 128; i++) {
 		for (j = 0; j < i; j++) {
 			if (paddr1[i] < paddr1[j]) {
-				tmp2 = pnum[j];
+				tmp = pnum[j];
 				pnum[j] = pnum[i];
-				pnum[i] = tmp2;
-				tmp1 = paddr1[j];
+				pnum[i] = tmp;
+
+				tmp = paddr1[j];
 				paddr1[j] = paddr1[i];
-				paddr1[i] = tmp1;
+				paddr1[i] = tmp;
 				goto restart;
 			}
 		}
@@ -135,10 +141,11 @@ static int depack_pha(FILE *in, FILE *out)
 	}
 
 	for (c1 = 0; c1 < 128; c1++) {
-		for (c2 = 0; c2 < 128; c2++)
+		for (c2 = 0; c2 < 128; c2++) {
 			if (paddr[c1] == paddr1[c2]) {
 				pnum1[c1] = c2;
 			}
+		}
 	}
 
 	memset(pnum, 0, 128);
@@ -170,8 +177,8 @@ static int depack_pha(FILE *in, FILE *out)
 
 	write32b(out, PW_MOD_MAGIC);		/* ID string */
 
-	smp_addr = ftell(in);
-	fseek(in, pat_addr, SEEK_SET);
+	smp_addr = hio_tell(in);
+	hio_seek(in, pat_addr, SEEK_SET);
 
 	/* pattern datas */
 	/* read ALL pattern data */
@@ -185,7 +192,7 @@ static int depack_pha(FILE *in, FILE *out)
 #endif
 	psize = npat * 1024;
 	pdata = (uint8 *) malloc (psize);
-	psize = fread(pdata, 1, psize, in);
+	psize = hio_read(pdata, 1, psize, in);
 	npat += 1;		/* coz first value is $00 */
 	pat = (uint8 *)malloc(npat * 1024);
 	memset(pat, 0, npat * 1024);
@@ -238,16 +245,16 @@ static int depack_pha(FILE *in, FILE *out)
 	free(pat);
 
 	/* Sample data */
-	fseek(in, smp_addr, SEEK_SET);
+	hio_seek(in, smp_addr, SEEK_SET);
 	pw_move_data(out, in, ssize);
 
 	return 0;
 }
 
-static int test_pha (uint8 *data, char *t, int s)
+static int test_pha(uint8 *data, char *t, int s)
 {
-	int j, k, l, m, n;
-	int start = 0, ssize;
+	int i;
+	int ptr, ssize;
 
 	PW_REQUEST_DATA(s, 451 + 128 * 4);
 
@@ -255,47 +262,38 @@ static int test_pha (uint8 *data, char *t, int s)
 		return -1;
 
 	/* test #2 (volumes,sample addresses and whole sample size) */
-	l = 0;
-	for (j = 0; j < 31; j++) {
+	ssize = 0;
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 14;
+
 		/* sample size */
-		n = readmem16b(data + start + j * 14) * 2;
-		l += n;
+		ssize += readmem16b(d) << 1;
 
-		if (data[start + j * 14 + 3] > 0x40)
+		if (d[3] > 0x40)
 			return -1;
 
 		/* loop start */
-		m = readmem16b(data + start + j * 14 + 4) * 2;
-
-		if (m > l)
+		if ((readmem16b(d + 4) << 1) > ssize)
 			return -1;
 
 		/* address of sample data */
-		k = readmem32b(data + start + j * 14 + 8);
-
-		if (k < 0x3C0)
+		if (readmem32b(d + 8) < 0x3c0)
 			return -1;
 	}
 
-	if (l <= 2 || l > (31 * 65535))
+	if (ssize <= 2 || ssize > 31 * 65535)
 		return -1;
 
 	/* test #3 (addresses of pattern in file ... ptk_tableible ?) */
 	/* l is the whole sample size */
 	/* ssize is used here as a variable ... set to 0 afterward */
-	l += 960;
-	k = 0;
-	for (j = 0; j < 128; j++) {
-		ssize = readmem32b(data + start + 448 + j * 4);
 
-		if (ssize > k)
-			k = ssize;
+	for (i = 0; i < 128; i++) {
+		ptr = readmem32b(data + 448 + i * 4);
 
-		if ((ssize + 2) < l)
+		if (ptr + 2 - 960 < ssize)
 			return -1;
 	}
-	ssize = 0;
-	/* k is the highest pattern data address */
 
 	pw_read_title(NULL, t, 0);
 
diff --git a/src/loaders/prowizard/pm.c b/src/loaders/prowizard/pm.c
index 8a18090..323f927 100644
--- a/src/loaders/prowizard/pm.c
+++ b/src/loaders/prowizard/pm.c
@@ -19,7 +19,7 @@ void Depack_PM (FILE * in, FILE * out)
 	uint8 Max = 0x00;
 	long ssize = 0;
 	long i = 0;
-	// FILE *in,*out;
+	// HIO_HANDLE *in,*out;
 
 	if (Save_Status == BAD)
 		return;
diff --git a/src/loaders/prowizard/pm01.c b/src/loaders/prowizard/pm01.c
index 5674f14..c7f6a2f 100644
--- a/src/loaders/prowizard/pm01.c
+++ b/src/loaders/prowizard/pm01.c
@@ -1,317 +1,225 @@
 /*
- *   Promizer_0.1_Packer.c   1997 (c) Asle / ReDoX
+ * Promizer_0.1_Packer.c Copyright (C) 1997 Asle / ReDoX
  *
  * Converts back to ptk Promizer 0.1 packed MODs
  *
-*/
+ * Modified in 2016 by Claudio Matsuoka
+ */
 
 #include 
 #include 
+#include 
+#include "prowiz.h"
 
-void Depack_PM01 (FILE * in, FILE * out)
+static int depack_pm01(HIO_HANDLE *in, FILE *out)
 {
-	uint8 c1 = 0x00, c2 = 0x00, c3 = 0x00, c4 = 0x00;
 	uint8 ptable[128];
-	uint8 pat_pos;
-	uint8 pat_max;
-	uint8 ptk_table[37][2];
-	uint8 *tmp;
-	uint8 *PatternData;
+	uint8 len;
+	uint8 npat;
+	uint8 tmp[1024];
+	uint8 pdata[1024];
 	uint8 fin[31];
-	uint8 Old_ins_Nbr[4];
-	long i = 0, j = 0, k = 0, l = 0;
-	long ssize = 0;
-	long Pattern_Address[128];
-	// FILE *in,*out;
-
-#include "tuning.h"
-#include "ptktable.h"
-
-	if (Save_Status == BAD)
-		return;
+	uint8 oldins[4];
+	int i, j;
+	int psize, size, ssize = 0;
+	int pat_ofs[128];
 
 	memset(ptable, 0, 128);
-	memset(Pattern_Address, 0, 128 * 4);
+	memset(pat_ofs, 0, 128 * 4);
 	memset(fin, 0, 31);
-	memset(Old_ins_Nbr, 0, 4);
-
-	// in = fdopen (fd_in, "rb");
-	// sprintf ( Depacked_OutName , "%ld.mod" , Cpt_Filename-1 );
-	// out = fdopen (fd_out, "w+b");
+	memset(oldins, 0, 4);
 
-	/* write title */
-	for (i = 0; i < 20; i++)	/* title */
-		fwrite (&c1, 1, 1, out);
+	pw_write_zero(out, 20);			/* title */
 
 	/* read and write sample descriptions */
 	for (i = 0; i < 31; i++) {
-		c1 = 0x00;
-		for (j = 0; j < 22; j++)	/*sample name */
-			fwrite (&c1, 1, 1, out);
-
-		fread (&c1, 1, 1, in);	/* size */
-		fread (&c2, 1, 1, in);
-		ssize += (((c1 << 8) + c2) * 2);
-		fwrite (&c1, 1, 1, out);
-		fwrite (&c2, 1, 1, out);
-		fread (&c1, 1, 1, in);	/* finetune */
-		fin[i] = c1;
-		fwrite (&c1, 1, 1, out);
-		fread (&c1, 1, 1, in);	/* volume */
-		fwrite (&c1, 1, 1, out);
-		fread (&c1, 1, 1, in);	/* loop start */
-		fread (&c2, 1, 1, in);
-		fwrite (&c1, 1, 1, out);
-		fwrite (&c2, 1, 1, out);
-		fread (&c1, 1, 1, in);	/* loop size */
-		fread (&c2, 1, 1, in);
-		if ((c1 == 0x00) && (c2 == 0x00))
-			c2 = 0x01;
-		fwrite (&c1, 1, 1, out);
-		fwrite (&c2, 1, 1, out);
-	}
-	/*printf ( "Whole sample size : %ld\n" , ssize ); */
 
-	/* pattern table lenght */
-	fread (&c1, 1, 1, in);
-	fread (&c2, 1, 1, in);
-	pat_pos = ((c1 << 8) + c2) / 4;
-	fwrite (&pat_pos, 1, 1, out);
-	/*printf ( "Size of pattern list : %d\n" , pat_pos ); */
+		if (hio_read(tmp, 1, 8, in) != 8) {
+			return -1;
+		}
+
+		pw_write_zero(out, 22);			/* sample name */
+
+		size = readmem16b(tmp);			/* size */
+		ssize += size * 2;
 
-	/* write NoiseTracker byte */
-	c1 = 0x7f;
-	fwrite (&c1, 1, 1, out);
+		fin[i] = tmp[2];
+
+		if (tmp[4] == 0 && tmp[5] == 0) {	/* loop size */
+			tmp[5] = 1;
+		}
+
+		if (fwrite(tmp, 1, 8, out) != 8) {
+			return -1;
+		}
+	}
+
+	len = hio_read16b(in) >> 2;		/* pattern table lenght */
+	write8(out, len);
+	write8(out, 0x7f);			/* write NoiseTracker byte */
 
 	/* read pattern address list */
 	for (i = 0; i < 128; i++) {
-		fread (&c1, 1, 1, in);
-		fread (&c2, 1, 1, in);
-		fread (&c3, 1, 1, in);
-		fread (&c4, 1, 1, in);
-		Pattern_Address[i] =
-			(c1 << 24) + (c2 << 16) +
-			(c3 << 8) + c4;
+		pat_ofs[i] = hio_read32b(in);
 	}
 
 	/* deduce pattern list and write it */
-	pat_max = 0x00;
-	for (i = 0; i < 128; i++) {
-		ptable[i] = Pattern_Address[i] / 1024;
-		fwrite (&ptable[i], 1, 1, out);
-		if (ptable[i] > pat_max)
-			pat_max = ptable[i];
+	for (npat = i = 0; i < 128; i++) {
+		ptable[i] = pat_ofs[i] / 1024;
+		write8(out, ptable[i]);
+		if (ptable[i] > npat) {
+			npat = ptable[i];
+		}
+	}
+	npat++;
+
+	write32b(out, PW_MOD_MAGIC);		/* ID string */
+
+	psize = hio_read32b(in);		/* get pattern data size */
+
+	if (npat * 1024 != psize) {
+		return -1;
 	}
-	pat_max += 1;
-	/*printf ( "Number of pattern : %d\n" , pat_max ); */
-
-	/* write ptk's ID */
-	c1 = 'M';
-	c2 = '.';
-	c3 = 'K';
-	fwrite (&c1, 1, 1, out);
-	fwrite (&c2, 1, 1, out);
-	fwrite (&c3, 1, 1, out);
-	fwrite (&c2, 1, 1, out);
-
-	/* get pattern data size */
-	fread (&c1, 1, 1, in);
-	fread (&c2, 1, 1, in);
-	fread (&c3, 1, 1, in);
-	fread (&c4, 1, 1, in);
-	j = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
-	/*printf ( "Size of the pattern data : %ld\n" , j ); */
 
 	/* read and XOR pattern data */
-	tmp = (uint8 *) malloc (j);
-	PatternData = (uint8 *) malloc (j);
-	memset(tmp, 0, j);
-	fread (tmp, j, 1, in);
-	for (k = 0; k < j; k++) {
-		if (k % 4 == 3) {
-			PatternData[k] =
-				((240 - (tmp[k] & 0xf0)) +
-				(tmp[k] & 0x0f));
-			continue;
+	for (i = 0; i < npat; i++) {
+		memset(pdata, 0, 1024);
+		if (hio_read(pdata, 1, 1024, in) != 1024) {
+			return -1;
 		}
-		PatternData[k] = 255 - tmp[k];
-	}
 
-	/* all right, now, let's take care of these 'finetuned' value ... pfff */
-	Old_ins_Nbr[0] = Old_ins_Nbr[1] = Old_ins_Nbr[2] = Old_ins_Nbr[3] =
-		0x1f;
-	memset(tmp, 0, j);
-	for (i = 0; i < j / 4; i++) {
-		c1 = PatternData[i * 4] & 0x0f;
-		c2 = PatternData[i * 4 + 1];
-		k = (c1 << 8) + c2;
-		c3 =
-			(PatternData[i * 4] & 0xf0) | ((PatternData[i * 4 +
-					   2] >> 4) & 0x0f);
-		if (c3 == 0)
-			c3 = Old_ins_Nbr[i % 4];
-		else
-			Old_ins_Nbr[i % 4] = c3;
-		if ((k != 0) && (fin[c3 - 1] != 0x00)) {
-/*fprintf ( info , "! (at %ld)(smp:%x)(pitch:%ld)\n" , (i*4)+382 , c3 , k );*/
-			for (l = 0; l < 36; l++) {
-				if (k == tun_table[fin[c3 - 1]][l]) {
-					tmp[i * 4] = ptk_table[l + 1][0];
-					tmp[i * 4 + 1] = ptk_table[l + 1][1];
-				}
+		for (j = 0; j < 1024; j++) {
+			if (j % 4 == 3) {
+				pdata[j] = (240 - (pdata[j] & 0xf0)) +
+						(pdata[j] & 0x0f);
+				continue;
 			}
-		} else {
-			tmp[i * 4] = PatternData[i * 4] & 0x0f;
-			tmp[i * 4 + 1] = PatternData[i * 4 + 1];
+			pdata[j] = pdata[j] ^ 0xff;
 		}
-		tmp[i * 4] |= (PatternData[i * 4] & 0xf0);
-		tmp[i * 4 + 2] = PatternData[i * 4 + 2];
-		tmp[i * 4 + 3] = PatternData[i * 4 + 3];
-	}
-	fwrite (tmp, j, 1, out);
-	free (tmp);
-	free (PatternData);
 
-	/* sample data */
-	tmp = (uint8 *) malloc (ssize);
-	fread (tmp, ssize, 1, in);
-	fwrite (tmp, ssize, 1, out);
-	free (tmp);
+		/* now take care of these 'finetuned' values ... pfff */
+		oldins[0] = oldins[1] = oldins[2] = oldins[3] = 0x1f;
+		for (j = 0; j < 64 * 4; j++) {
+			uint8 *p = pdata + j * 4;
+			int note = readmem16b(p) & 0x0fff;
+			int ins = (p[0] & 0xf0) | ((p[2] >> 4) & 0x0f);
+
+			if (note == 0) {
+				continue;
+			}
+
+			if (ins == 0) {
+				ins = oldins[i % 4];
+			} else {
+				oldins[i % 4] = ins;
+			}
+
+			note = (int)((double)note *
+					pow(2, -1.0 * fin[j % 4] / 12 / 8));
+			if (note > 0) {
+				note = period_to_note(note) - 48;
+			}
+
+			p[0] = ptk_table[note][0];
+			p[1] = ptk_table[note][1];
+		}
 
-	/* crap */
-	Crap ("PM01:Promizer 0.1", BAD, BAD, out);
+		if (fwrite(pdata, 1, 1024, out) != 1024) {
+			return -1;
+		}
+	}
 
-	fflush (in);
-	fflush (out);
+	/* sample data */
+	pw_move_data(out, in, ssize);
 
-	printf ("done\n");
-	return;			/* useless ... but */
+	return 0;
 }
 
-#include 
-#include 
 
-void testPM01 (void)
+static int test_pm01(uint8 *data, char *t, int s)
 {
+	int i;
+	int len, psize, ssize = 0;
+
+	PW_REQUEST_DATA(s, 1024);
+
+#if 0
 	/* test #1 */
 	if (i < 3) {
-/*printf ( "#1 (i:%ld)\n" , i );*/
 		Test = BAD;
 		return;
 	}
+#endif
 
 	/* test #2 */
-	start = i - 3;
-	l = 0;
-	for (j = 0; j < 31; j++) {
-		k =
-			(((data[start + j * 8] << 8) +
-				 data[start + 1 +
-					j * 8]) * 2);
-		l += k;
-		/* finetune > 0x0f ? */
-		if (data[start + 2 + 8 * j] > 0x0f) {
-/*printf ( "#2 (start:%ld)\n" , start );*/
-			Test = BAD;
-			return;
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 8;
+		int size = readmem16b(data) << 1;
+		int start = readmem16b(data + 4) << 1;
+		int lsize = readmem16b(data + 6) << 1;
+
+		ssize += size;
+
+		if (d[2] > 0x0f) {		/* finetune > 0x0f ? */
+			return -1;
 		}
+
 		/* loop start > size ? */
-		if ((((data[start + 4 + j * 8] << 8) +
-					data[start + 5 +
-						j * 8]) * 2) > k) {
-			Test = BAD;
-/*printf ( "#2,1 (start:%ld)\n" , start );*/
-			return;
+		if (start > size || lsize > size) {
+			return -1;
+		}
+
+		if (lsize <= 2) {
+			return -1;
 		}
-	}
-	if (l <= 2) {
-/*printf ( "#2,2 (start:%ld)\n" , start );*/
-		Test = BAD;
-		return;
 	}
 
 	/* test #3   about size of pattern list */
-	l =
-		(data[start + 248] << 8) +
-		data[start + 249];
-	k = l / 4;
-	if ((k * 4) != l) {
-/*printf ( "#3 (start:%ld)(l:%ld)(k:%ld)\n" , start,l,k );*/
-		Test = BAD;
-		return;
-	}
-	if (k > 127) {
-/*printf ( "#3,1 (start:%ld)\n" , start );*/
-		Test = BAD;
-		return;
+	len = readmem16b(data + 248);
+	if (len & 0x03) {
+		return -1;
 	}
-	if (l == 0) {
-/*printf ( "#3,2 (start:%ld)\n" , start );*/
-		Test = BAD;
-		return;
+	len >>= 2;
+
+	if (len == 0 || len > 127) {
+		return -1;
 	}
 
 	/* test #4  size of all the pattern data */
 	/* k contains the size of the pattern list */
-	l = (data[start + 762] << 24)
-		+ (data[start + 743] << 16)
-		+ (data[start + 764] << 8)
-		+ data[start + 765];
-	if ((l < 1024) || (l > 131072)) {
-/*printf ( "#4 (start:%ld)\n" , start );*/
-		Test = BAD;
-		return;
+	psize = readmem32b(data + 762);
+	if (psize < 1024 || psize > 131072) {
+		return -1;
 	}
 
 	/* test #5  first pattern address != $00000000 ? */
-	l = (data[start + 250] << 24)
-		+ (data[start + 251] << 16)
-		+ (data[start + 252] << 8)
-		+ data[start + 253];
-	if (l != 0) {
-/*printf ( "#5 (start:%ld)\n" , start );*/
-		Test = BAD;
-		return;
+	if (readmem32b(data + 250) != 0) {
+		return -1;
 	}
 
 	/* test #6  pattern addresses */
-	/* k is still ths size of the pattern list */
-	for (j = 0; j < k; j++) {
-		l =
-			(data[start + 250 +
-				 j * 4] << 24) +
-			(data[start + 251 +
-				j * 4] << 16) +
-			(data[start + 252 + j * 4] << 8)
-			+ data[start + 253 + j * 4];
-		if (l > 131072) {
-/*printf ( "#6 (start:%ld)\n" , start );*/
-			Test = BAD;
-			return;
-		}
-		if (((l / 1024) * 1024) != l) {
-			Test = BAD;
-			return;
+	for (i = 0; i < len; i++) {
+		int addr = readmem32b(data + 250 + i * 4);
+		if (addr & 0x3ff || addr > 131072) {
+			return -1;
 		}
 	}
 
 	/* test #7  last patterns in pattern table != $00000000 ? */
-	j += 4;		/* just to be sure */
-	while (j != 128) {
-		l =
-			(data[start + 250 +
-				 j * 4] << 24) +
-			(data[start + 251 +
-				j * 4] << 16) +
-			(data[start + 252 + j * 4] << 8)
-			+ data[start + 253 + j * 4];
-		if (l != 0) {
-/*printf ( "#7 (start:%ld)\n" , start );*/
-			Test = BAD;
-			return;
+	i += 4;		/* just to be sure */
+	for (; i < 128; i++) {
+		int addr = readmem32b(data + 250 + i * 4);
+		if (addr != 0) {
+			return -1;
 		}
-		j += 1;
 	}
 
-	Test = GOOD;
+	return 0;
 }
+
+const struct pw_format pw_pm01 = {
+	"Promizer 0.1",
+	test_pm01,
+	depack_pm01
+};
+
diff --git a/src/loaders/prowizard/pm10c.c b/src/loaders/prowizard/pm10c.c
index b03c591..12b2a67 100644
--- a/src/loaders/prowizard/pm10c.c
+++ b/src/loaders/prowizard/pm10c.c
@@ -1,42 +1,37 @@
 /*
  * Promizer_10c.c   Copyright (C) 1997 Asle / ReDoX
- *                  Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Converts PM10c packed MODs back to PTK MODs
  *
- * claudio's note: Now this one can be *heavily* optimized...
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
 #include 
 #include "prowiz.h"
 
-#define ON  0
-#define OFF 1
 
-static int depack_p10c(FILE *in, FILE *out)
+static int depack_p10c(HIO_HANDLE *in, FILE *out)
 {
-	uint8 c1, c2, c3;
-	short pat_max = 0;
-	long tmp_ptr, tmp1, tmp2;
-	short refmax = 0;
+	uint8 c1, c2;
+	int pat_max;
+	int tmp_ptr, tmp1, tmp2;
+	int refmax;
 	uint8 pnum[128];
 	uint8 pnum1[128];
 	int paddr[128];
 	int paddr1[128];
 	int paddr2[128];
 	short pptr[64][256];
-	uint8 NOP = 0x00;	/* number of pattern */
+	int num_pat;
 	uint8 *reftab;
 	uint8 pat[128][1024];
 	int i, j, k, l;
-	int size, ssize = 0;
+	int size, ssize;
 	int psize;
-	int SDAV;
-	uint8 FLAG = OFF;
+	int smp_ofs;
 	uint8 fin[31];
 	uint8 oldins[4];
-	short per;
 
 	memset(pnum, 0, 128);
 	memset(pnum1, 0, 128);
@@ -53,28 +48,36 @@ static int depack_p10c(FILE *in, FILE *out)
 	pw_write_zero(out, 20);				/* title */
 
 	/* bypass replaycode routine */
-	fseek(in, 4460, SEEK_SET);
+	hio_seek(in, 4460, SEEK_SET);
 
+	ssize = 0;
 	for (i = 0; i < 31; i++) {
 		pw_write_zero(out, 22);			/*sample name */
-		write16b(out, size = read16b(in));	/* size */
+		write16b(out, size = hio_read16b(in));	/* size */
 		ssize += size * 2;
-		write8(out, fin[i] = read8(in));	/* fin */
-		write8(out, read8(in));			/* volume */
-		write16b(out, read16b(in));		/* loop start */
-		write16b(out, read16b(in));		/* loop size */
+		write8(out, fin[i] = hio_read8(in));	/* fin */
+		write8(out, hio_read8(in));			/* volume */
+		write16b(out, hio_read16b(in));		/* loop start */
+		write16b(out, hio_read16b(in));		/* loop size */
 	}
 
-	write8(out, NOP = read16b(in) / 4);		/* pat table lenght */
+	num_pat = hio_read16b(in) / 4;			/* pat table length */
+
+	/* Sanity check */
+	if (num_pat > 128) {
+		return -1;
+	}
+
+	write8(out, num_pat);
 	write8(out, 0x7f);				/* NoiseTracker byte */
 
 	for (i = 0; i < 128; i++)
-		paddr[i] = read32b(in);
+		paddr[i] = hio_read32b(in);
 
 	/* ordering of patterns addresses */
 
 	tmp_ptr = 0;
-	for (i = 0; i < NOP; i++) {
+	for (i = 0; i < num_pat; i++) {
 		if (i == 0) {
 			pnum[0] = 0;
 			tmp_ptr++;
@@ -94,11 +97,11 @@ static int depack_p10c(FILE *in, FILE *out)
 	pat_max = tmp_ptr - 1;
 
 	/* correct re-order */
-	for (i = 0; i < NOP; i++)
+	for (i = 0; i < num_pat; i++)
 		paddr1[i] = paddr[i];
 
 restart:
-	for (i = 0; i < NOP; i++) {
+	for (i = 0; i < num_pat; i++) {
 		for (j = 0; j < i; j++) {
 			if (paddr1[i] < paddr1[j]) {
 				tmp2 = pnum[j];
@@ -112,7 +115,7 @@ static int depack_p10c(FILE *in, FILE *out)
 		}
 	}
 
-	for (j = i = 0; i < NOP; i++) {
+	for (j = i = 0; i < num_pat; i++) {
 		if (i == 0) {
 			paddr2[j] = paddr1[i];
 			continue;
@@ -123,194 +126,85 @@ static int depack_p10c(FILE *in, FILE *out)
 		paddr2[++j] = paddr1[i];
 	}
 
-	for (c1 = 0; c1 < NOP; c1++) {
-		for (c2 = 0; c2 < NOP; c2++) {
+	for (c1 = 0; c1 < num_pat; c1++) {
+		for (c2 = 0; c2 < num_pat; c2++) {
 			if (paddr[c1] == paddr2[c2])
 				pnum1[c1] = c2;
 		}
 	}
 
-	for (i = 0; i < NOP; i++)
+	for (i = 0; i < num_pat; i++)
 		pnum[i] = pnum1[i];
 
 	/* write pattern table */
-	for (c1 = 0x00; c1 < 128; c1++)
-		fwrite(&pnum[c1], 1, 1, out);
+	fwrite(pnum, 128, 1, out);
 
 	write32b(out, PW_MOD_MAGIC);
 
 	/* a little pre-calc code ... no other way to deal with these unknown
 	 * pattern data sizes ! :(
 	 */
-	fseek(in, 4456, SEEK_SET);
-	psize = read32b(in);
+	hio_seek(in, 4456, SEEK_SET);
+	psize = hio_read32b(in);
 
 	/* go back to pattern data starting address */
-	fseek(in, 5222, SEEK_SET);
+	hio_seek(in, 5222, SEEK_SET);
+
 	/* now, reading all pattern data to get the max value of note */
+	refmax = 0;
 	for (j = 0; j < psize; j += 2) {
-		int x;
-		if ((x = read16b(in)) > refmax)
+		int x = hio_read16b(in);
+		if (x > refmax)
 			refmax = x;
 	}
 
 	/* read "reference Table" */
-	refmax += 1;		/* coz 1st value is 0 ! */
+	refmax++;		/* coz 1st value is 0 ! */
 	i = refmax * 4;		/* coz each block is 4 bytes long */
 	reftab = (uint8 *) malloc(i);
-	fread(reftab, i, 1, in);
+	hio_read(reftab, i, 1, in);
 
 	/* go back to pattern data starting address */
-	fseek(in, 5222, SEEK_SET);
+	hio_seek(in, 5222, SEEK_SET);
 
-	for (k = j = 0; j <= pat_max; j++) {
+	for (j = 0; j <= pat_max; j++) {
+		int flag = 0;
 		for (i = 0; i < 64; i++) {
-			int x, y = i * 16;
+			for (k = 0; k < 4; k++) {
+				uint8 *p = &pat[j][i * 16 + k * 4];
+				int x = hio_read16b(in) << 2;
+				int fine, ins, per, fxt;
 
-			/* VOICE #1 */
+				memcpy(p, &reftab[x], 4);
 
-			x = read16b(in);
-			k += 2;
-			pat[j][y + 0] = reftab[x * 4];
-			pat[j][y + 1] = reftab[x * 4 + 1];
-			pat[j][y + 2] = reftab[x * 4 + 2];
-			pat[j][y + 3] = reftab[x * 4 + 3];
-
-			c3 = ((pat[j][y + 2] >> 4) & 0x0f) | (pat[j][y] & 0xf0);
-
-			if (c3 != 0) {
-				oldins[0] = c3;
-			}
-			per = ((pat[j][y] & 0x0f) << 8) + pat[j][y + 1];
-
-			if ((per != 0) && (fin[oldins[0] - 1] != 0)) {
-				for (l = 0; l < 36; l++) {
-					if (tun_table[fin[oldins[0] - 1]][l] ==
-					    per) {
-						pat[j][y] &= 0xf0;
-						pat[j][y] |=
-						    ptk_table[l + 1][0];
-						pat[j][y + 1] =
-						    ptk_table[l + 1][1];
-						break;
-					}
+				ins = ((p[2] >> 4) & 0x0f) | (p[0] & 0xf0);
+				if (ins != 0) {
+					oldins[k] = ins;
 				}
-			}
-
-			if (((pat[j][y + 2] & 0x0f) == 0x0d) ||
-			    ((pat[j][y + 2] & 0x0f) == 0x0b)) {
-				FLAG = ON;
-			}
-
-			/* VOICE #2 */
-
-			x = read16b(in);
-			k += 2;
-			pat[j][y + 4] = reftab[x * 4];
-			pat[j][y + 5] = reftab[x * 4 + 1];
-			pat[j][y + 6] = reftab[x * 4 + 2];
-			pat[j][y + 7] = reftab[x * 4 + 3];
 
-			c3 = ((pat[j][y + 6] >> 4) & 0x0f) |
-					(pat[j][y + 4] & 0xf0);
-
-			if (c3 != 0) {
-				oldins[1] = c3;
-			}
-			per = ((pat[j][y + 4] & 0x0f) << 8) + pat[j][y + 5];
-
-			if ((per != 0) && (fin[oldins[1] - 1] != 0x00)) {
-				for (l = 0; l < 36; l++) {
-					if (tun_table[fin[oldins[1] - 1]][l] ==
-					    per) {
-						pat[j][y + 4] &= 0xf0;
-						pat[j][y + 4] |=
-						    ptk_table[l + 1][0];
-						pat[j][y + 5] =
-						    ptk_table[l + 1][1];
-						break;
+				per = ((p[0] & 0x0f) << 8) | p[1];
+				fxt = p[2] & 0x0f;
+				fine = fin[oldins[k] - 1];
+
+				if (per != 0 && oldins[k] > 0 && fine != 0) {
+					for (l = 0; l < 36; l++) {
+						if (tun_table[fine][l] == per) {
+							p[0] &= 0xf0;
+							p[0] |=
+						     	    ptk_table[l + 1][0];
+							p[1] =
+							    ptk_table[l + 1][1];
+							break;
+						}
 					}
 				}
-			}
 
-			if (((pat[j][y + 6] & 0x0f) == 0x0d) ||
-			    ((pat[j][y + 6] & 0x0f) == 0x0b)) {
-				FLAG = ON;
-			}
-
-			/* VOICE #3 */
-
-			x = read16b(in);
-			k += 2;
-			pat[j][y + 8] = reftab[x * 4];
-			pat[j][y + 9] = reftab[x * 4 + 1];
-			pat[j][y + 10] = reftab[x * 4 + 2];
-			pat[j][y + 11] = reftab[x * 4 + 3];
-
-			c3 = ((pat[j][y + 10] >> 4) & 0x0f) |
-					(pat[j][y + 8] & 0xf0);
-
-			if (c3 != 0) {
-				oldins[2] = c3;
-			}
-			per = ((pat[j][y + 8] & 0x0f) << 8) + pat[j][y + 9];
-
-			if ((per != 0) && (fin[oldins[2] - 1] != 0x00)) {
-				for (l = 0; l < 36; l++) {
-					if (tun_table[fin[oldins[2] - 1]][l] ==
-					    per) {
-						pat[j][y + 8] &= 0xf0;
-						pat[j][y + 8] |=
-						    ptk_table[l + 1][0];
-						pat[j][y + 9] =
-						    ptk_table[l + 1][1];
-						break;
-					}
+				if (fxt == 0x0d || fxt == 0x0b) {
+					flag = 1;
 				}
 			}
 
-			if (((pat[j][y + 10] & 0x0f) == 0x0d) ||
-			    ((pat[j][y + 10] & 0x0f) == 0x0b)) {
-				FLAG = ON;
-			}
-
-			/* VOICE #4 */
-
-			x = read16b(in);
-			k += 2;
-			pat[j][y + 12] = reftab[x * 4];
-			pat[j][y + 13] = reftab[x * 4 + 1];
-			pat[j][y + 14] = reftab[x * 4 + 2];
-			pat[j][y + 15] = reftab[x * 4 + 3];
-
-			c3 = ((pat[j][y + 14] >> 4) & 0x0f) |
-					(pat[j][y + 12] & 0xf0);
-
-			if (c3 != 0) {
-				oldins[3] = c3;
-			}
-			per = ((pat[j][y + 12] & 0x0f) << 8) + pat[j][y + 13];
-
-			if ((per != 0) && (fin[oldins[3] - 1] != 0x00)) {
-				for (l = 0; l < 36; l++)
-					if (tun_table[fin[oldins[3] - 1]][l] ==
-					    per) {
-						pat[j][y + 12] &= 0xf0;
-						pat[j][y + 12] |=
-						    ptk_table[l + 1][0];
-						pat[j][y + 13] =
-						    ptk_table[l + 1][1];
-						break;
-					}
-			}
-
-			if (((pat[j][y + 14] & 0x0f) == 0x0d) ||
-			    ((pat[j][y + 14] & 0x0f) == 0x0b)) {
-				FLAG = ON;
-			}
-
-			if (FLAG == ON) {
-				FLAG = OFF;
+			if (flag == 1) {
 				break;
 			}
 		}
@@ -319,9 +213,9 @@ static int depack_p10c(FILE *in, FILE *out)
 
 	free(reftab);
 
-	fseek(in, 4452, SEEK_SET);
-	SDAV = read32b(in);
-	fseek(in, 4456 + SDAV, SEEK_SET);
+	hio_seek(in, 4452, SEEK_SET);
+	smp_ofs = hio_read32b(in);
+	hio_seek(in, 4456 + smp_ofs, SEEK_SET);
 
 	pw_move_data(out, in, ssize);
 
@@ -330,7 +224,6 @@ static int depack_p10c(FILE *in, FILE *out)
 
 static int test_p10c(uint8 *data, char *t, int s)
 {
-	int start = 0;
 	uint8 magic[] = {
 		0x60, 0x38, 0x60, 0x00, 0x00, 0xa0, 0x60, 0x00,
 		0x01, 0x3e, 0x60, 0x00, 0x01, 0x0c, 0x48, 0xe7
@@ -339,32 +232,32 @@ static int test_p10c(uint8 *data, char *t, int s)
 	/* test 1 */
 	PW_REQUEST_DATA(s, 22);
 
-	if (memcmp(data + start, magic, 16) != 0)
+	if (memcmp(data, magic, 16) != 0)
 		return -1;
 
 	/* test 2 */
-	if (data[start + 21] != 0xce)
+	if (data[21] != 0xce)
 		return -1;
 
 	PW_REQUEST_DATA(s, 4714);
 
 #if 0
 	/* test 3 */
-	j = readmem32b(data + start + 4452);
-	if ((start + j + 4452) > in_size)
+	j = readmem32b(data + 4452);
+	if (j + 4452 > in_size)
 		return -1;
 #endif
 
 	/* test 4 */
-	if (readmem16b(data + start + 4712) & 0x03)
+	if (readmem16b(data + 4712) & 0x03)
 		return -1;
 
 	/* test 5 */
-	if (data[start + 36] != 0x10)
+	if (data[36] != 0x10)
 		return -1;
 
 	/* test 6 */
-	if (data[start + 37] != 0xfc)
+	if (data[37] != 0xfc)
 		return -1;
 
 	pw_read_title(NULL, t, 0);
diff --git a/src/loaders/prowizard/pm18a.c b/src/loaders/prowizard/pm18a.c
index a1e2a11..99b47a8 100644
--- a/src/loaders/prowizard/pm18a.c
+++ b/src/loaders/prowizard/pm18a.c
@@ -1,77 +1,78 @@
 /*
  * Promizer_18a.c   Copyright (C) 1997 Asle / ReDoX
- *		    Modified by Claudio Matsuoka
  *
  * Converts PM18a packed MODs back to PTK MODs
  * thanks to Gryzor and his ProWizard tool ! ... without it, this prog
  * would not exist !!!
  *
- * claudio's note: this code asks for heavy optimization. maybe later
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
 #include 
 #include "prowiz.h"
 
-#define ON  0
-#define OFF 1
 
-static int depack_p18a(FILE *in, FILE *out)
+static int depack_p18a(HIO_HANDLE *in, FILE *out)
 {
-	uint8 c3;
 	short pat_max;
 	int tmp_ptr;
 	int refmax;
 	uint8 pnum[128];
 	int paddr[128];
 	short pptr[64][256];
-	uint8 NOP = 0x00;	/* number of pattern */
+	int num_pat;
 	uint8 *reftab;
 	uint8 pat[128][1024];
-	int i = 0, j = 0, k = 0, l = 0;
+	int i, j, k, l;
 	int size, ssize;
 	int psize;
-	int SDAV;
-	uint8 FLAG = OFF;
+	int smp_ofs;
 	uint8 fin[31];
-	uint8 oins[4];
-	short per;
+	uint8 oldins[4];
 
 	memset(pnum, 0, 128);
 	memset(pptr, 0, 64 << 8);
 	memset(pat, 0, 128 * 1024);
 	memset(fin, 0, 31);
-	memset(oins, 0, 4);
+	memset(oldins, 0, 4);
 	memset(paddr, 0, 128 * 4);
 
-	pw_write_zero(out, 20);			/* title */
+	pw_write_zero(out, 20);				/* title */
 
 	/* bypass replaycode routine */
-	fseek(in, 4464, 0);	/* SEEK_SET */
+	hio_seek(in, 4464, SEEK_SET);
 
 	ssize = 0;
 	for (i = 0; i < 31; i++) {
-		pw_write_zero(out, 22);		/* sample name */
-		write16b(out, size = read16b(in));
+		pw_write_zero(out, 22);			/* sample name */
+		write16b(out, size = hio_read16b(in));
 		ssize += size * 2;
-		write8(out, fin[i] = read8(in)); /* finetun_table */
-		write8(out, read8(in));		/* volume */
-		write16b(out, read16b(in));	/* loop start */
-		write16b(out, read16b(in));	/* loop size */
+		write8(out, fin[i] = hio_read8(in));	/* finetune table */
+		write8(out, hio_read8(in));		/* volume */
+		write16b(out, hio_read16b(in));		/* loop start */
+		write16b(out, hio_read16b(in));		/* loop size */
 	}
 
-	write8(out, NOP = read16b(in) / 4);	/* pattern table length */
-	write8(out, 0x7f);			/* NoiseTracker restart byte */
+	num_pat = hio_read16b(in) / 4;			/* pat table length */
+
+	/* Sanity check */
+	if (num_pat > 128) {
+		return -1;
+	}
+
+	write8(out, num_pat);
+	write8(out, 0x7f);				/* NoiseTracker byte */
 
 	for (i = 0; i < 128; i++)
-		paddr[i] = read32b(in);
+		paddr[i] = hio_read32b(in);
 
 	/* ordering of patterns addresses */
 
 	tmp_ptr = 0;
-	for (i = 0; i < NOP; i++) {
+	for (i = 0; i < num_pat; i++) {
 		if (i == 0) {
-			pnum[0] = 0x00;
+			pnum[0] = 0;
 			tmp_ptr++;
 			continue;
 		}
@@ -94,14 +95,17 @@ static int depack_p18a(FILE *in, FILE *out)
 	/* a little pre-calc code ... no other way to deal with these unknown
 	 * pattern data sizes ! :(
 	 */
-	fseek(in, 4460, SEEK_SET);
-	psize = read32b(in);
-	fseek(in, 5226, SEEK_SET);	/* back to pattern data start */
+	hio_seek(in, 4460, SEEK_SET);
+	psize = hio_read32b(in);
+	hio_seek(in, 5226, SEEK_SET);	/* back to pattern data start */
 
 	/* now, reading all pattern data to get the max value of note */
 	refmax = 0;
 	for (j = 0; j < psize; j += 2) {
-		int x = read16b(in);
+		int x = hio_read16b(in);
+		if (hio_error(in)) {
+			return -1;
+		}
 		if (x > refmax)
 			refmax = x;
 	}
@@ -109,140 +113,61 @@ static int depack_p18a(FILE *in, FILE *out)
 	/* read "reference table" */
 	refmax += 1;			/* 1st value is 0 ! */
 	i = refmax * 4;			/* each block is 4 bytes long */
-	reftab = (uint8 *) malloc(i);
-	fread(reftab, i, 1, in);
-	fseek(in, 5226, SEEK_SET);	/* back to pattern data start */
+	if ((reftab = (uint8 *)malloc(i)) == NULL) {
+		return -1;
+	}
+	
+	hio_read(reftab, i, 1, in);
+	hio_seek(in, 5226, SEEK_SET);	/* back to pattern data start */
 
-	k = 0;
 	for (j = 0; j <= pat_max; j++) {
-		fseek(in, paddr[j] + 5226, 0);
+		int flag = 0;
+		hio_seek(in, paddr[j] + 5226, 0);
 		for (i = 0; i < 64; i++) {
-			/* VOICE #1 */
-			int x = read16b(in) * 4;
-			int y = i * 16;
-
-			k += 2;
-			pat[j][y] = reftab[x];
-			pat[j][y + 1] = reftab[x + 1];
-			pat[j][y + 2] = reftab[x + 2];
-			pat[j][y + 3] = reftab[x + 3];
-
-			c3 = ((pat[j][y + 2] >> 4) & 0x0f) | (pat[j][y] & 0xf0);
-
-			if (c3)
-				oins[0] = c3;
-
-			per = ((pat[j][y] & 0x0f) << 8) + pat[j][y + 1];
-
-			if (per && fin[oins[0] - 1]) {
-				for (l = 0; l < 36; l++)
-					if (tun_table[fin[oins[0] - 1]][l] == per) {
-						pat[j][y] &= 0xf0;
-						pat[j][y] |= ptk_table[l + 1][0];
-						pat[j][y + 1] = ptk_table[l + 1][1];
-						break;
+			for (k = 0; k < 4; k++) {
+				uint8 *p = &pat[j][i * 16 + k * 4];
+				int x = hio_read16b(in) << 2;
+				int fine, ins, per, fxt;
+
+				memcpy(p, &reftab[x], 4);
+
+				ins = ((p[2] >> 4) & 0x0f) | (p[0] & 0xf0);
+				if (ins != 0) {
+					oldins[k] = ins;
+				}
+
+				per = ((p[0] & 0x0f) << 8) | p[1];
+				fxt = p[2] & 0x0f;
+				if (oldins[k] > 0 && oldins[k] < 32) {
+					fine = fin[oldins[k] - 1];
+				} else {
+					fine = 0;
+				}
+
+				/* Sanity check */
+				if (fine >= 16) {
+					goto err;
+				}
+
+				if (per != 0 && oldins[k] > 0 && fine != 0) {
+					for (l = 0; l < 36; l++) {
+						if (tun_table[fine][l] == per) {
+							p[0] &= 0xf0;
+							p[0] |=
+							    ptk_table[l + 1][0];
+							p[1] =
+							    ptk_table[l + 1][1];
+							break;
+						}
 					}
-			}
-
-			if (((pat[j][y + 2] & 0x0f) == 0x0d) ||
-			    ((pat[j][y + 2] & 0x0f) == 0x0b)) {
-				FLAG = ON;
-			}
+				}
 
-			/* VOICE #2 */
-
-			x = read16b(in) * 4;
-			k += 2;
-			pat[j][y + 4] = reftab[x];
-			pat[j][y + 5] = reftab[x + 1];
-			pat[j][y + 6] = reftab[x + 2];
-			pat[j][y + 7] = reftab[x + 3];
-			c3 = ((pat[j][y + 6] >> 4) & 0x0f) |
-			    (pat[j][y + 4] & 0xf0);
-
-			if (c3)
-				oins[1] = c3;
-
-			per = ((pat[j][y + 4] & 0x0f) << 8) + pat[j][y + 5];
-			if ((per != 0) && (fin[oins[1] - 1] != 0x00)) {
-				for (l = 0; l < 36; l++)
-					if (tun_table[fin[oins[1] - 1]][l] == per) {
-						pat[j][y + 4] &= 0xf0;
-						pat[j][y + 4] |= ptk_table[l + 1][0];
-						pat[j][y + 5] = ptk_table[l + 1][1];
-						break;
-					}
+				if (fxt == 0x0d || fxt == 0x0b) {
+					flag = 1;
+				}
 			}
 
-			if (((pat[j][y + 6] & 0x0f) == 0x0d) ||
-			    ((pat[j][y + 6] & 0x0f) == 0x0b)) {
-				FLAG = ON;
-			}
-
-			/* VOICE #3 */
-
-			x = read16b(in) * 4;
-			k += 2;
-			pat[j][y + 8] = reftab[x];
-			pat[j][y + 9] = reftab[x + 1];
-			pat[j][y + 10] = reftab[x + 2];
-			pat[j][y + 11] = reftab[x + 3];
-			c3 = ((pat[j][y + 10] >> 4) & 0x0f) |
-			    (pat[j][y + 8] & 0xf0);
-
-			if (c3)
-				oins[2] = c3;
-
-			per = ((pat[j][y + 8] & 0x0f) << 8) + pat[j][y + 9];
-			if ((per != 0)
-			    && (fin[oins[2] - 1] != 0x00)) {
-				for (l = 0; l < 36; l++)
-					if (tun_table[fin[oins[2] - 1]][l] == per) {
-						pat[j][y + 8] &= 0xf0;
-						pat[j][y + 8] |=
-						    ptk_table[l + 1][0];
-						pat[j][y + 9] =
-						    ptk_table[l + 1][1];
-						break;
-					}
-			}
-
-			if (((pat[j][y + 10] & 0x0f) == 0x0d) ||
-			    ((pat[j][y + 10] & 0x0f) == 0x0b)) {
-				FLAG = ON;
-			}
-
-			/* VOICE #4 */
-
-			x = read16b(in) * 4;
-			k += 2;
-			pat[j][y + 12] = reftab[x];
-			pat[j][y + 13] = reftab[x + 1];
-			pat[j][y + 14] = reftab[x + 2];
-			pat[j][y + 15] = reftab[x + 3];
-			c3 = ((pat[j][y + 14] >> 4) & 0x0f) | (pat[j][y + 12] & 0xf0);
-			if (c3 != 0x00)
-				oins[3] = c3;
-
-			per = ((pat[j][y + 12] & 0x0f) << 8) + pat[j][y + 13];
-			if ((per != 0)
-			    && (fin[oins[3] - 1] != 0x00)) {
-				for (l = 0; l < 36; l++)
-					if (tun_table[fin[oins[3] - 1]][l] == per) {
-						pat[j][y + 12] &= 0xf0;
-						pat[j][y + 12] |= ptk_table[l + 1][0];
-						pat[j][y + 13] = ptk_table[l + 1][1];
-						break;
-					}
-			}
-
-			if (((pat[j][y + 14] & 0x0f) == 0x0d) ||
-			    ((pat[j][y + 14] & 0x0f) == 0x0b)) {
-				FLAG = ON;
-			}
-
-			if (FLAG == ON) {
-				FLAG = OFF;
+			if (flag == 1) {
 				break;
 			}
 		}
@@ -253,43 +178,42 @@ static int depack_p18a(FILE *in, FILE *out)
 
 	free(reftab);
 
-	fseek(in, 4456, SEEK_SET);
-	SDAV = read32b(in);
-	fseek(in, 4460 + SDAV, SEEK_SET);
+	hio_seek(in, 4456, SEEK_SET);
+	smp_ofs = hio_read32b(in);
+	hio_seek(in, 4460 + smp_ofs, SEEK_SET);
 
 	/* Now, it's sample data ... though, VERY quickly handled :) */
 	pw_move_data(out, in, ssize);
 
 	return 0;
+
+    err:
+	free(reftab);
+	return -1;
 }
 
 static int test_p18a(uint8 * data, char *t, int s)
 {
-	int i = 0, j, k;
-	int start = 0;
+	uint8 magic[] = {
+		0x60, 0x38, 0x60, 0x00, 0x00, 0xa0, 0x60, 0x00,
+		0x01, 0x3e, 0x60, 0x00, 0x01, 0x0c, 0x48, 0xe7
+	};
 
 	/* test 1 */
 	PW_REQUEST_DATA(s, 22);
 
-	if (data[i] != 0x60 || data[i + 1] != 0x38 || data[i + 2] != 0x60 ||
-	    data[i + 3] != 0x00 || data[i + 4] != 0x00 ||
-	    data[i + 5] != 0xa0 || data[i + 6] != 0x60 ||
-	    data[i + 7] != 0x00 || data[i + 8] != 0x01 ||
-	    data[i + 9] != 0x3e || data[i + 10] != 0x60 ||
-	    data[i + 11] != 0x00 || data[i + 12] != 0x01 ||
-	    data[i + 13] != 0x0c || data[i + 14] != 0x48 ||
-	    data[i + 15] != 0xe7)
+	if (memcmp(data, magic, 16) != 0)
 		return -1;
 
 	/* test 2 */
-	if (data[start + 21] != 0xd2)
+	if (data[21] != 0xd2)
 		return -1;
 
+#if 0
 	/* test 3 */
 	PW_REQUEST_DATA(s, 4460);
-	j = readmem32b(data + start + 4456);
+	j = readmem32b(data + 4456);
 
-#if 0
 	if ((start + j + 4456) > in_size) {
 		Test = BAD;
 		return;
@@ -298,16 +222,15 @@ static int test_p18a(uint8 * data, char *t, int s)
 
 	/* test 4 */
 	PW_REQUEST_DATA(s, 4714);
-	k = readmem16b(data + start + 4712);
-	if (k & 0x03)
+	if (readmem16b(data + 4712) & 0x03)
 		return -1;
 
 	/* test 5 */
-	if (data[start + 36] != 0x11)
+	if (data[36] != 0x11)
 		return -1;
 
 	/* test 6 */
-	if (data[start + 37] != 0x00)
+	if (data[37] != 0x00)
 		return -1;
 
 	pw_read_title(NULL, t, 0);
diff --git a/src/loaders/prowizard/pm20.c b/src/loaders/prowizard/pm20.c
index f41c1c0..2c30ee5 100644
--- a/src/loaders/prowizard/pm20.c
+++ b/src/loaders/prowizard/pm20.c
@@ -39,7 +39,7 @@ void Depack_PM20 (FILE * in, FILE * out)
 	uint8 FLAG = OFF;
 	uint8 ptk_table[37][2];
 	uint8 note, ins;
-	// FILE *in,*out;
+	// HIO_HANDLE *in,*out;
 
 	if (Save_Status == BAD)
 		return;
diff --git a/src/loaders/prowizard/pm40.c b/src/loaders/prowizard/pm40.c
index 66dd29a..55728fb 100644
--- a/src/loaders/prowizard/pm40.c
+++ b/src/loaders/prowizard/pm40.c
@@ -38,7 +38,7 @@ void Depack_PM40 (FILE * in, FILE * out)
 	uint8 FLAG = OFF;
 	uint8 ptk_table[37][2];
 	uint8 note, ins;
-	// FILE *in,*out;
+	// HIO_HANDLE *in,*out;
 
 	if (Save_Status == BAD)
 		return;
diff --git a/src/loaders/prowizard/pp10.c b/src/loaders/prowizard/pp10.c
index c9e63a0..05581da 100644
--- a/src/loaders/prowizard/pp10.c
+++ b/src/loaders/prowizard/pp10.c
@@ -1,267 +1,190 @@
 /*
- *   ProPacker_v1.0   1997 (c) Asle / ReDoX
+ * ProPacker_v1.0 Copyright (C) 1997 Asle / ReDoX
  *
  * Converts back to ptk ProPacker v1 MODs
  *
-*/
+ * Modified in 2016 by Claudio Matsuoka
+ */
 
 #include 
 #include 
+#include "prowiz.h"
 
-void Depack_PP10 (FILE * in, FILE * out)
+static int depack_pp10(HIO_HANDLE *in, FILE *out)
 {
-	uint8 c1 = 0x00, c2 = 0x00, c3 = 0x00, c4 = 0x00;
-	uint8 Tracks_Numbers[4][128];
-	uint8 pat_pos;
-	uint8 *tmp;
-	uint8 Pattern[1024];
-	short Max;
-	long i = 0, j = 0, k = 0;
-	long ssize = 0;
-	// FILE *in,*out;
-
-	if (Save_Status == BAD)
-		return;
-
-	memset(Tracks_Numbers, 0, 128 * 4);
+	uint8 c1;
+	uint8 trk_num[4][128];
+	uint8 len;
+	uint8 tmp[8];
+	uint8 pdata[1024];
+	int i, j, k;
+	int ntrk, size, ssize = 0;
 
-	// in = fdopen (fd_in, "rb");
-	// sprintf ( Depacked_OutName , "%ld.mod" , Cpt_Filename-1 );
-	// out = fdopen (fd_out, "w+b");
+	memset(trk_num, 0, 128 * 4);
 
-	/* write title */
-	for (i = 0; i < 20; i++)
-		fwrite (&c1, 1, 1, out);
+	pw_write_zero(out, 20);				/* write title */
 
 	/* read and write sample descriptions */
 	for (i = 0; i < 31; i++) {
-		c1 = 0x00;
-		for (j = 0; j < 22; j++)	/*sample name */
-			fwrite (&c1, 1, 1, out);
-
-		fread (&c1, 1, 1, in);	/* size */
-		fread (&c2, 1, 1, in);
-		ssize += (((c1 << 8) + c2) * 2);
-		fwrite (&c1, 1, 1, out);
-		fwrite (&c2, 1, 1, out);
-		fread (&c1, 1, 1, in);	/* finetune */
-		fwrite (&c1, 1, 1, out);
-		fread (&c1, 1, 1, in);	/* volume */
-		fwrite (&c1, 1, 1, out);
-		fread (&c1, 1, 1, in);	/* loop start */
-		fread (&c2, 1, 1, in);
-		fwrite (&c1, 1, 1, out);
-		fwrite (&c2, 1, 1, out);
-		fread (&c1, 1, 1, in);	/* loop size */
-		fread (&c2, 1, 1, in);
-		if ((c1 == 0x00) && (c2 == 0x00))
-			c2 = 0x01;
-		fwrite (&c1, 1, 1, out);
-		fwrite (&c2, 1, 1, out);
+
+		if (hio_read(tmp, 1, 8, in) != 8) {
+			return -1;
+		}
+
+		pw_write_zero(out, 22);			/* sample name */
+
+		size = readmem16b(tmp);			/* size */
+		ssize += size * 2;
+
+		if (tmp[4] == 0 && tmp[5] == 0) {	/* loop size */
+			tmp[5] = 1;
+		}
+
+		if (fwrite(tmp, 1, 8, out) != 8) {
+			return -1;
+		}
 	}
-	/*printf ( "Whole sample size : %ld\n" , ssize ); */
 
-	/* read and write pattern table lenght */
-	fread (&pat_pos, 1, 1, in);
-	fwrite (&pat_pos, 1, 1, out);
-	/*printf ( "Size of pattern list : %d\n" , pat_pos ); */
+	len = hio_read8(in);			/* pattern table lenght */
+	write8(out, len);
 
-	/* read and write NoiseTracker byte */
-	fread (&c1, 1, 1, in);
-	fwrite (&c1, 1, 1, out);
+	c1 = hio_read8(in);			/* Noisetracker byte */
+	write8(out, c1);
 
 	/* read track list and get highest track number */
-	Max = 0;
-	for (j = 0; j < 4; j++) {
+	for (ntrk = j = 0; j < 4; j++) {
 		for (i = 0; i < 128; i++) {
-			fread (&Tracks_Numbers[j][i], 1, 1, in);
-			if (Tracks_Numbers[j][i] > Max)
-				Max = Tracks_Numbers[j][i];
+			trk_num[j][i] = hio_read8(in);
+			if (trk_num[j][i] > ntrk) {
+				ntrk = trk_num[j][i];
+			}
 		}
 	}
-	/*printf ( "highest track number : %d\n" , Max+1 ); */
 
 	/* write pattern table "as is" ... */
-	for (c1 = 0x00; c1 < pat_pos; c1++)
-		fwrite (&c1, 1, 1, out);
-	c2 = 0x00;
-	for (; c1 < 128; c1++)
-		fwrite (&c2, 1, 1, out);
-
-	/* write ptk's ID */
-	c1 = 'M';
-	c2 = '.';
-	c3 = 'K';
-	fwrite (&c1, 1, 1, out);
-	fwrite (&c2, 1, 1, out);
-	fwrite (&c3, 1, 1, out);
-	fwrite (&c2, 1, 1, out);
+	for (i = 0; i < len; i++) {
+		write8(out, i);
+	}
+	pw_write_zero(out, 128 - i);
+	write32b(out, PW_MOD_MAGIC);		/* ID string */
 
 	/* track/pattern data */
-
-	for (i = 0; i < pat_pos; i++) {
-/*fprintf ( info , "\n\n\nPattern %ld :\n" , i );*/
-		memset(Pattern, 0, 1024);
+	for (i = 0; i < len; i++) {
+		memset(pdata, 0, 1024);
 		for (j = 0; j < 4; j++) {
-			fseek (in, 762 + (Tracks_Numbers[j][i] << 8), 0);	/* SEEK_SET */
-/*fprintf ( info , "Voice %ld :\n" , j );*/
+			hio_seek(in, 762 + (trk_num[j][i] << 8), SEEK_SET);
 			for (k = 0; k < 64; k++) {
-				fread (&c1, 1, 1, in);
-				fread (&c2, 1, 1, in);
-				fread (&c3, 1, 1, in);
-				fread (&c4, 1, 1, in);
-/*fprintf ( info , "%2x , %2x , %2x  (%ld)\n" , c2 , c3 , c4 ,ftell (in));*/
-				Pattern[k * 16 + j * 4] = c1;
-				Pattern[k * 16 + j * 4 + 1] = c2;
-				Pattern[k * 16 + j * 4 + 2] = c3;
-				Pattern[k * 16 + j * 4 + 3] = c4;
+				hio_read(pdata + k * 16 + j * 4, 1, 4, in);
 			}
 		}
-		fwrite (Pattern, 1024, 1, out);
-		/*printf ( "+" ); */
+		fwrite(pdata, 1024, 1, out);
 	}
-	/*printf ( "\n" ); */
-
 
 	/* now, lets put file pointer at the beginning of the sample datas */
-	fseek (in, 762 + ((Max + 1) << 8), 0);	/* SEEK_SET */
+	if (hio_seek(in, 762 + ((ntrk + 1) << 8), SEEK_SET) < 0) {
+		return -1;
+	}
 
 	/* sample data */
-	tmp = (uint8 *) malloc (ssize);
-	fread (tmp, ssize, 1, in);
-	fwrite (tmp, ssize, 1, out);
-	free (tmp);
+	pw_move_data(out, in, ssize);
 
-	/* crap */
-	Crap ("PP10:ProPacker v1.0", BAD, BAD, out);
-
-	fflush (in);
-	fflush (out);
-
-	printf ("done\n");
-	return;			/* useless ... but */
+	return 0;
 }
 
-
-void testPP10 (void)
+static int test_pp10(uint8 *data, char *t, int s)
 {
+	int i;
+	int ntrk, ssize;
+
+	PW_REQUEST_DATA(s, 1024);
+
+#if 0
 	/* test #1 */
 	if (i < 3) {
-/*printf ( "#1 (i:%ld)\n" , i );*/
 		Test = BAD;
 		return;
 	}
 	start = i - 3;
+#endif
 
 	/* noisetracker byte */
-	if (data[start + 249] > 0x7f) {
-		Test = BAD;
-/*printf ( "#1,1 (start:%ld)\n" , start );*/
-		return;
+	if (data[249] > 0x7f) {
+		return -1;
 	}
 
 	/* test #2 */
 	ssize = 0;
-	for (j = 0; j < 31; j++) {
-		k =
-			(((data[start + j * 8] << 8) +
-				 data[start + 1 +
-					j * 8]) * 2);
-		l =
-			(((data[start + j * 8 + 4] << 8) +
-				 data[start + 5 +
-					j * 8]) * 2);
-		/* loop size */
-		m =
-			(((data[start + j * 8 + 6] << 8) +
-				 data[start + 7 +
-					j * 8]) * 2);
-		if (m == 0) {
-/*printf ( "#1,98 (start:%ld) (k:%ld) (l:%ld) (m:%ld)\n" , start,k,l,m );*/
-			Test = BAD;
-			return;
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 8;
+		int size = readmem16b(d) << 1;
+		int start = readmem16b(d + 4) << 1;
+		int lsize = readmem16b(d + 6) << 1;
+
+		ssize += size;
+
+		if (lsize == 0) {
+			return -1;
 		}
-		if ((l != 0) && (m <= 2)) {
-/*printf ( "#1,99 (start:%ld) (k:%ld) (l:%ld) (m:%ld)\n" , start,k,l,m );*/
-			Test = BAD;
-			return;
+		if (start != 0 && lsize <= 2) {
+			return -1;
 		}
-		if ((l + m) > (k + 2)) {
-/*printf ( "#2,0 (start:%ld) (k:%ld) (l:%ld) (m:%ld)\n" , start,k,l,m );*/
-			Test = BAD;
-			return;
+		if (start + lsize > size + 2) {
+			return -1;
 		}
-		if ((l != 0) && (m == 0)) {
-/*printf ( "#2,01 (start:%ld)\n" , start );*/
-			Test = BAD;
-			return;
+#if 0
+		if (start != 0 && lsize == 0) {
+			return -1;
 		}
-		ssize += k;
-		/* finetune > 0x0f ? */
-		if (data[start + 2 + 8 * j] > 0x0f) {
-/*printf ( "#2 (start:%ld)\n" , start );*/
-			Test = BAD;
-			return;
+#endif
+		if (d[2] > 0x0f) {		/* finetune > 0x0f ? */
+			return -1;
 		}
-		/* volume > 0x40 ? */
-		if (data[start + 3 + 8 * j] > 0x40) {
-/*printf ( "#2,1 (start:%ld)\n" , start );*/
-			Test = BAD;
-			return;
+
+		if (d[3] > 0x40) {		/* volume > 0x40 ? */
+			return -1;
 		}
-		/* loop start > size ? */
-		if ((((data[start + 4 + j * 8] << 8) +
-					data[start + 5 +
-						j * 8]) * 2) > k) {
-			Test = BAD;
-/*printf ( "#2,2 (start:%ld)\n" , start );*/
-			return;
+
+		if (start > size) {		/* loop start > size ? */
+			return -1;
 		}
-		/* size > 0xffff ? */
-		if (k > 0xFFFF) {
-			Test = BAD;
-/*printf ( "#2,3 (start:%ld)\n" , start );*/
-			return;
+
+		if (size > 0xffff) {		/* size > 0xffff ? */
+			return -1;
 		}
 	}
+
 	if (ssize <= 2) {
-/*printf ( "#2,4 (start:%ld)\n" , start );*/
-		Test = BAD;
-		return;
+		return -1;
 	}
-	/* ssize = whole sample size */
 
 	/* test #3   about size of pattern list */
-	l = data[start + 248];
-	if ((l > 127) || (l == 0)) {
-/*printf ( "#3 (start:%ld)\n" , start );*/
-		Test = BAD;
-		return;
+	if (data[248] == 0 || data[248] > 127) {
+		return -1;
 	}
 
 	/* get the highest track value */
-	k = 0;
-	for (j = 0; j < 512; j++) {
-		l = data[start + 250 + j];
-		if (l > k)
-			k = l;
+	for (ntrk = i = 0; i < 512; i++) {
+		if (data[250 + i] > ntrk) {
+			ntrk = data[250 + i];
+		}
 	}
-	/* k is the highest track number */
-	k += 1;
-	k *= 64;
-
-	/* track data test */
-	for (j = 0; j < k; j++) {
-		if (data[start + 762 + j * 4] > 0x13) {
-			Test = BAD;
-			ssize = 0;
-/*printf ( "#3,1 (start:%ld)\n" , start );*/
-			return;
+
+	PW_REQUEST_DATA(s, 762 + ntrk * 64);
+
+	ntrk++;
+
+	for (i = 0; i < ntrk * 64; i++) {
+		if (data[762 + i * 4] > 0x13) {
+			return -1;
 		}
 	}
-	k *= 4;
 
-	/* ssize is the sample data size */
-	/* k is the track data size */
-	Test = GOOD;
+	return 0;
 }
+
+const struct pw_format pw_pp10 = {
+	"ProPacker 1.0",
+	test_pp10,
+	depack_pp10
+};
+
diff --git a/src/loaders/prowizard/pp21.c b/src/loaders/prowizard/pp21.c
index 6bfe461..1b55248 100644
--- a/src/loaders/prowizard/pp21.c
+++ b/src/loaders/prowizard/pp21.c
@@ -1,10 +1,15 @@
 /*
  * ProPacker_21.c   Copyright (C) 1997 Sylvain "Asle" Chipaux
- *		    Copyright (C) 2006-2009 Claudio Matsuoka
  *
  * Converts PP21 packed MODs back to PTK MODs
  * thanks to Gryzor and his ProWizard tool ! ... without it, this prog
  * would not exist !!!
+ *
+ * Modified in 2006,2009,2014 by Claudio Matsuoka
+ * - Code cleanup
+ *
+ * Modified in 2015 by Claudio Matsuoka
+ * - Add PP30 support
  */
 
 #include 
@@ -12,7 +17,7 @@
 #include "prowiz.h"
 
 
-static int depack_pp21(FILE *in, FILE *out)
+static int depack_pp21_pp30(HIO_HANDLE *in, FILE *out, int is_30)
 {
 	uint8 ptable[128];
 	int max = 0;
@@ -23,32 +28,40 @@ static int depack_pp21(FILE *in, FILE *out)
 	uint8 buf[1024];
 	int i, j;
 	int size;
-	int ssize = 0;
-	int tabsize = 0;		/* Reference Table Size */
+	int ssize;
+	int tabsize;		/* Reference Table Size */
 
 	memset(ptable, 0, 128);
 	memset(trk, 0, 4 * 128);
-	memset(tptr, 0, 512 * 128);
+	memset(tptr, 0, 512 * 64 * sizeof (int));
 
 	pw_write_zero(out, 20);			/* title */
 
+	ssize = 0;
 	for (i = 0; i < 31; i++) {
 		pw_write_zero(out, 22);		/* sample name */
-		write16b(out, size = read16b(in));
+		write16b(out, size = hio_read16b(in));
 		ssize += size * 2;
-		write8(out, read8(in));		/* finetune */
-		write8(out, read8(in));		/* volume */
-		write16b(out, read16b(in));	/* loop start */
-		write16b(out, read16b(in));	/* loop size */
+		write8(out, hio_read8(in));	/* finetune */
+		write8(out, hio_read8(in));	/* volume */
+		write16b(out, hio_read16b(in));	/* loop start */
+		write16b(out, hio_read16b(in));	/* loop size */
 	}
 
-	write8(out, numpat = read8(in));	/* number of patterns */
-	write8(out, read8(in));			/* NoiseTracker restart byte */
+	numpat = hio_read8(in);			/* number of patterns */
+
+	/* Sanity check */
+	if (numpat > 128) {
+		return -1;
+	}
+
+	write8(out, numpat);			/* number of patterns */
+	write8(out, hio_read8(in));		/* NoiseTracker restart byte */
 
 	max = 0;
 	for (j = 0; j < 4; j++) {
 		for (i = 0; i < 128; i++) {
-			trk[j][i] = read8(in);
+			trk[j][i] = hio_read8(in);
 			if (trk[j][i] > max)
 				max = trk[j][i];
 		}
@@ -61,21 +74,27 @@ static int depack_pp21(FILE *in, FILE *out)
 
 	write32b(out, PW_MOD_MAGIC);		/* M.K. */
 
-
 	/* PATTERN DATA code starts here */
 
 	/*printf ("Highest track number : %d\n", max); */
 	for (j = 0; j <= max; j++) {
-		for (i = 0; i < 64; i++)
-			tptr[j][i] = read16b(in);
+		for (i = 0; i < 64; i++) {
+			tptr[j][i] = hio_read16b(in);
+			if (is_30) {
+				tptr[j][i] >>= 2;
+			}
+		}
 	}
 
 	/* read "reference table" size */
-	tabsize = read32b(in);
+	tabsize = hio_read32b(in);
+	if (tabsize == 0) {
+		return -1;
+	}
 
 	/* read "reference Table" */
 	tab = (uint8 *)malloc(tabsize);
-	fread(tab, tabsize, 1, in);
+	hio_read(tab, tabsize, 1, in);
 
 	for (i = 0; i < numpat; i++) {
 		memset(buf, 0, 1024);
@@ -97,65 +116,182 @@ static int depack_pp21(FILE *in, FILE *out)
 	return 0;
 }
 
+static int depack_pp21(HIO_HANDLE *in, FILE *out)
+{
+	return depack_pp21_pp30(in, out, 0);
+}
+
+static int depack_pp30(HIO_HANDLE *in, FILE *out)
+{
+	return depack_pp21_pp30(in, out, 1);
+}
+
 static int test_pp21(uint8 *data, char *t, int s)
 {
-	int j, k, l;
-	int start = 0;
-	int ssize;
+	int i;
+	int ssize, tsize, npat, max_ref;
+
+	ssize = 0;
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 8;
+		int len = readmem16b(d) << 1;
+		int start = readmem16b(d + 4) << 1;
 
-	l = 0;
-	for (j = 0; j < 31; j++) {
-		k = ((data[start + j * 8] << 8) + data[start + 1 + j * 8]) * 2;
-		l += k;
+		ssize += len;
 
 		/* finetune > 0x0f ? */
-		if (data[start + 2 + 8 * j] > 0x0f)
+		if (d[2] > 0x0f)
+			return -1;
+
+		/* volume > 0x40 ? */
+		if (d[3] > 0x40)
 			return -1;
 
 		/* loop start > size ? */
-		if ((((data[start + 4 + j * 8] << 8) + data[start + 5 + j * 8]) * 2) > k)
+		if (start > len)
 			return -1;
 	}
 
-	if (l <= 2)
+	if (ssize <= 2)
 		return -1;
 
 	/* test #3   about size of pattern list */
-	l = data[start + 248];
-	if (l > 127 || l == 0)
+	npat = data[248];
+	if (npat == 0 || npat > 127)
 		return -1;
 
 	/* get the highest track value */
-	k = 0;
-	for (j = 0; j < 512; j++) {
-		l = data[start + 250 + j];
-		if (l > k)
-			k = l;
+	tsize = 0;
+	for (i = 0; i < 512; i++) {
+		int trk = data[250 + i];
+		if (trk > tsize)
+			tsize = trk;
 	}
-	/* k is the highest track number */
-	k += 1;
-	k *= 64;
+
+	tsize++;
+	tsize <<= 6;
 
 	/* test #4  track data value > $4000 ? */
-	/* ssize used as a variable .. set to 0 afterward */
+	max_ref = 0;
+	for (i = 0; i < tsize; i++) {
+		int ref = readmem16b(data + i * 2 + 762);
+
+		if (ref > 0x4000)
+			return -1;
+
+		if (ref > max_ref)
+			max_ref = ref;
+
+	}
+
+	/* test #5  reference table size *4 ? */
+	if (readmem32b(data + (tsize << 1) + 762) != (max_ref + 1) * 4)
+		return -1;
+
+	pw_read_title(NULL, t, 0);
+
+	return 0;
+}
+
+
+static int test_pp30(uint8 *data, char *t, int s)
+{
+	int i;
+	int ssize, tsize, npat, max_ref, ref_size;
+
 	ssize = 0;
-	for (j = 0; j < k; j++) {
-		l = (data[start + 762 + j * 2] << 8) + data[start + 763 + j * 2];
-		if (l > ssize)
-			ssize = l;
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 8;
+		int len = readmem16b(d) << 1;
+		int start = readmem16b(d + 4) << 1;
 
-		if (l > 0x4000)
+		ssize += len;
+
+		/* finetune > 0x0f ? */
+		if (d[2] > 0x0f)
+			return -1;
+
+		/* volume > 0x40 ? */
+		if (d[3] > 0x40)
+			return -1;
+
+		/* loop start > size ? */
+		if (start > len)
+			return -1;
+	}
+
+	if (ssize <= 2)
+		return -1;
+
+	/* test #3   about size of pattern list */
+	npat = data[248];
+	if (npat == 0 || npat > 127)
+		return -1;
+
+	/* get the highest track value */
+	tsize = 0;
+	for (i = 0; i < 512; i++) {
+		int trk = data[250 + i];
+		if (trk > tsize)
+			tsize = trk;
+	}
+
+	tsize++;
+	tsize <<= 6;
+
+	/* test #4  track data value *4 ? */
+	max_ref = 0;
+	for (i = 0; i < tsize; i++) {
+		int ref = readmem16b(data + i * 2 + 762);
+
+		if (ref > max_ref)
+			max_ref = ref;
+
+		if (ref & 0x0003) {
 			return -1;
+		}
 	}
+	max_ref >>= 2;
 
 	/* test #5  reference table size *4 ? */
-	/* ssize is the highest reference number */
-	k *= 2;
-	l = (data[start + k + 762] << 24) + (data[start + k + 763] << 16) +
-			(data[start + k + 764] << 8) + data[start + k + 765];
+	ref_size = readmem32b(data + (tsize << 1) + 762);
 
-	if (l != ((ssize + 1) * 4))
+	if (ref_size > 0xffff) {
 		return -1;
+	}
+
+	if (ref_size != ((max_ref + 1) << 2)) {
+		return -1;
+	}
+
+	ref_size >>= 2;
+
+	/* test #6  data in reference table ... */
+	for (i = 0; i < ref_size; i++) {
+		uint8 *d = data + tsize + 766 + i * 4;
+		uint8 fxt = d[2] & 0x0f;
+		uint8 fxp = d[3];
+
+		/* volume > 41 ? */
+		if (fxt == 0x0c && fxp > 0x41) {
+			return -1;
+		}
+
+		/* break > 40 ? */
+		if (fxt == 0x0d && fxp > 0x40) {
+			return -1;
+		}
+
+		/* jump > 128 */
+		if (fxt == 0x0b && fxp > 0x7f) {
+			return -1;
+		}
+
+		/* smp > 1f ? */
+		if ((d[0] & 0xf0) > 0x10) {
+			return -1;
+		}
+	}
 
 	pw_read_title(NULL, t, 0);
 
@@ -167,3 +303,9 @@ const struct pw_format pw_pp21 = {
 	test_pp21,
 	depack_pp21
 };
+
+const struct pw_format pw_pp30 = {
+	"ProPacker 3.0",
+	test_pp30,
+	depack_pp30
+};
diff --git a/src/loaders/prowizard/pp30.c b/src/loaders/prowizard/pp30.c
index e542ed0..56f79d3 100644
--- a/src/loaders/prowizard/pp30.c
+++ b/src/loaders/prowizard/pp30.c
@@ -23,7 +23,7 @@ void Depack_PP30 (FILE * in, FILE * out)
 	long i = 0, j = 0;
 	long ssize = 0;
 	long RTS = 0;		/* Reference Table Size */
-	// FILE *in,*out;
+	// HIO_HANDLE *in,*out;
 
 	if (Save_Status == BAD)
 		return;
diff --git a/src/loaders/prowizard/prowiz.c b/src/loaders/prowizard/prowiz.c
index 7ad9eca..56761c6 100644
--- a/src/loaders/prowizard/prowiz.c
+++ b/src/loaders/prowizard/prowiz.c
@@ -34,6 +34,8 @@ const struct pw_format *const pw_format[NUM_PW_FORMATS + 1] = {
 	&pw_wn,
 	&pw_unic_id,
 	&pw_tp3,
+	&pw_tp2,
+	&pw_tp1,
 	&pw_skyt,
 
 	/* No signature */
@@ -43,6 +45,8 @@ const struct pw_format *const pw_format[NUM_PW_FORMATS + 1] = {
 	&pw_eu,
 	&pw_p4x,
 	&pw_pp21,
+	&pw_pp30,
+	&pw_pp10,
 	&pw_p50a,
 	&pw_p60a,
 	&pw_p61a,
@@ -58,13 +62,23 @@ const struct pw_format *const pw_format[NUM_PW_FORMATS + 1] = {
 	&pw_tdd,
 	&pw_starpack,
 	&pw_gmc,
+	/* &pw_pm01, */
 	&pw_titanics,
 	NULL
 };
 
-int pw_move_data(FILE *out, FILE *in, int len)
+int pw_move_data(FILE *out, HIO_HANDLE *in, int len)
 {
-	return move_data(out, in, len);
+	uint8 buf[1024];
+	int l;
+
+	do {
+		l = hio_read(buf, 1, len > 1024 ? 1024 : len, in);
+		fwrite(buf, 1, l, out);
+		len -= l;
+	} while (l > 0 && len > 0);
+
+	return 0;
 }
 
 int pw_write_zero(FILE *out, int len)
@@ -82,39 +96,26 @@ int pw_write_zero(FILE *out, int len)
 	return 0;
 }
 
-int pw_wizardry(int in, int out, char **name)
+int pw_wizardry(HIO_HANDLE *file_in, FILE *file_out, char **name)
 {
-	struct stat st;
-	int size = -1, in_size;
+	int in_size;
 	uint8 *data;
-	FILE *file_in, *file_out;
 	char title[21];
 	int i;
 
-	file_in = fdopen(dup(in), "rb");
-	if (file_in == NULL)
-		return -1;
-
-	file_out = fdopen(dup(out), "w+b");
-	if (file_out == NULL)
-		return -1;
-
-	if (fstat(fileno(file_in), &st) < 0)
-		in_size = -1;
-	else
-		in_size = st.st_size;
+	in_size = hio_size(file_in);
 
 	/* printf ("input file size : %d\n", in_size); */
-	if (in_size < MIN_FILE_LENGHT)
+	if (in_size < MIN_FILE_LENGHT) {
 		return -2;
+	}
 
-	/* alloc mem */
-	data = (uint8 *)malloc (in_size + 4096);	/* slack added */
-	if (data == NULL) {
-		perror("Couldn't allocate memory");
-		return -1;
+	if ((data = (uint8 *)malloc(in_size)) == NULL) {
+		goto err;
+	}
+	if (hio_read(data, 1, in_size, file_in) != in_size) {
+		goto err2;
 	}
-	fread(data, in_size, 1, file_in);
 
 
   /********************************************************************/
@@ -128,20 +129,23 @@ int pw_wizardry(int in, int out, char **name)
 	}
 
 	if (pw_format[i] == NULL) {
-		free(data);
-		return -1;
+		goto err2;
 	}
 
-	fseek(file_in, 0, SEEK_SET);
-	size = pw_format[i]->depack(file_in, file_out);
+	if (hio_error(file_in)) {
+		/* reset error flag */
+	}
 
-	if (size < 0) {
-		return -1;
+	hio_seek(file_in, 0, SEEK_SET);
+	if (pw_format[i]->depack(file_in, file_out) < 0) {
+		goto err2;
 	}
 
-	fclose(file_out);
-	fclose(file_in);
+	if (hio_error(file_in)) {
+		goto err2;
+	}
 
+	fflush(file_out);
 	free(data);
 
 	if (name != NULL) {
@@ -149,6 +153,11 @@ int pw_wizardry(int in, int out, char **name)
 	}
 
 	return 0;
+
+    err2:
+	free(data);
+    err:
+	return -1;
 }
 
 int pw_check(unsigned char *b, int s, struct xmp_test_info *info)
@@ -166,7 +175,7 @@ int pw_check(unsigned char *b, int s, struct xmp_test_info *info)
 			if (info != NULL) {
 				memcpy(info->name, title, 21);
 				strncpy(info->type, pw_format[i]->name,
-							XMP_NAME_SIZE);
+							XMP_NAME_SIZE - 1);
 			}
 			return 0;
 		}
diff --git a/src/loaders/prowizard/prowiz.h b/src/loaders/prowizard/prowiz.h
index d11bfbd..a8f5a14 100644
--- a/src/loaders/prowizard/prowiz.h
+++ b/src/loaders/prowizard/prowiz.h
@@ -5,6 +5,7 @@
 #include "list.h"
 #include "common.h"
 #include "format.h"
+#include "hio.h"
 
 #define MIN_FILE_LENGHT 2048
 
@@ -27,12 +28,12 @@
 struct pw_format {
 	char *name;
 	int (*test)(uint8 *, char *, int);
-	int (*depack)(FILE *, FILE *);
+	int (*depack)(HIO_HANDLE *, FILE *);
 	struct list_head list;
 };
 
-int pw_wizardry(int, int, char **);
-int pw_move_data(FILE *, FILE *, int);
+int pw_wizardry(HIO_HANDLE *, FILE *, char **);
+int pw_move_data(FILE *, HIO_HANDLE *, int);
 int pw_write_zero(FILE *, int);
 /* int pw_enable(char *, int); */
 int pw_check(unsigned char *, int, struct xmp_test_info *);
@@ -60,7 +61,7 @@ extern const struct pw_format pw_np2;
 extern const struct pw_format pw_np3;
 extern const struct pw_format pw_nru;
 extern const struct pw_format pw_ntp;
-extern const struct pw_format pw_p01;
+extern const struct pw_format pw_pm01;
 extern const struct pw_format pw_p10c;
 extern const struct pw_format pw_p18a;
 extern const struct pw_format pw_p20;
@@ -69,7 +70,9 @@ extern const struct pw_format pw_p50a;
 extern const struct pw_format pw_p60a;
 extern const struct pw_format pw_p61a;
 extern const struct pw_format pw_pha;
+extern const struct pw_format pw_pp10;
 extern const struct pw_format pw_pp21;
+extern const struct pw_format pw_pp30;
 extern const struct pw_format pw_pru1;
 extern const struct pw_format pw_pru2;
 extern const struct pw_format pw_skyt;
@@ -77,6 +80,8 @@ extern const struct pw_format pw_starpack;
 extern const struct pw_format pw_stim;
 extern const struct pw_format pw_tdd;
 extern const struct pw_format pw_titanics;
+extern const struct pw_format pw_tp1;
+extern const struct pw_format pw_tp2;
 extern const struct pw_format pw_tp3;
 extern const struct pw_format pw_unic_emptyid;
 extern const struct pw_format pw_unic_id;
diff --git a/src/loaders/prowizard/prun1.c b/src/loaders/prowizard/prun1.c
index d71e288..02a7b47 100644
--- a/src/loaders/prowizard/prun1.c
+++ b/src/loaders/prowizard/prun1.c
@@ -1,8 +1,9 @@
 /*
  * ProRunner1.c   Copyright (C) 1996 Asle / ReDoX
- *                Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Converts MODs packed with Prorunner v1.0
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -10,7 +11,7 @@
 #include "prowiz.h"
 
 
-static int depack_pru1 (FILE *in, FILE *out)
+static int depack_pru1 (HIO_HANDLE *in, FILE *out)
 {
 	uint8 header[2048];
 	uint8 c1, c2, c3, c4;
@@ -23,7 +24,7 @@ static int depack_pru1 (FILE *in, FILE *out)
 	memset(ptable, 0, 128);
 
 	/* read and write whole header */
-	fread(header, 950, 1, in);
+	hio_read(header, 950, 1, in);
 	fwrite(header, 950, 1, out);
 
 	/* get whole sample size */
@@ -32,12 +33,12 @@ static int depack_pru1 (FILE *in, FILE *out)
 	}
 
 	/* read and write size of pattern list */
-	write8(out, npat = read8(in));
+	write8(out, npat = hio_read8(in));
 
 	memset(header, 0, 2048);
 
 	/* read and write ntk byte and pattern list */
-	fread(header, 129, 1, in);
+	hio_read(header, 129, 1, in);
 	fwrite(header, 129, 1, out);
 
 	/* write ID */
@@ -51,13 +52,19 @@ static int depack_pru1 (FILE *in, FILE *out)
 	}
 
 	/* pattern data */
-	fseek (in, 1084, SEEK_SET);
+	hio_seek(in, 1084, SEEK_SET);
 	for (i = 0; i <= max; i++) {
 		for (j = 0; j < 256; j++) {
-			header[0] = read8(in);
-			header[1] = read8(in);
-			header[2] = read8(in);
-			header[3] = read8(in);
+			header[0] = hio_read8(in);
+			header[1] = hio_read8(in);
+			header[2] = hio_read8(in);
+			header[3] = hio_read8(in);
+
+			/* Sanity check */
+			if (header[1] >= 37) {
+				return -1;
+			}
+
 			c1 = header[0] & 0xf0;
 			c3 = (header[0] & 0x0f) << 4;
 			c3 |= header[2];
@@ -79,20 +86,17 @@ static int depack_pru1 (FILE *in, FILE *out)
 
 static int test_pru1(uint8 *data, char *t, int s)
 {
-	int start = 0;
-
-	PW_REQUEST_DATA(s, 1080);
+	PW_REQUEST_DATA(s, 1084);
 
-	if (data[1080] != 'S' || data[1081] != 'N' ||
-		data[1082] != 'T' || data[1083] != '.')
+	if (readmem32b(data + 1080) != 0x534e542e)	/* "SNT." */
 		return -1;
 
 	/* test 2 */
-	if (data[start + 951] != 0x7f)
+	if (data[951] != 0x7f)
 		return -1;
 
 	/* test 3 */
-	if (data[start + 950] > 0x7f)
+	if (data[950] > 0x7f)
 		return -1;
 
 	pw_read_title(data, t, 20);
diff --git a/src/loaders/prowizard/prun2.c b/src/loaders/prowizard/prun2.c
index 00bd9e0..994336f 100644
--- a/src/loaders/prowizard/prun2.c
+++ b/src/loaders/prowizard/prun2.c
@@ -1,8 +1,9 @@
 /*
  * ProRunner2.c   Copyright (C) 1996-1999 Asle / ReDoX
- *                Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Converts ProRunner v2 packed MODs back to Protracker
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -10,10 +11,9 @@
 #include "prowiz.h"
 
 
-static int depack_pru2(FILE *in, FILE *out)
+static int depack_pru2(HIO_HANDLE *in, FILE *out)
 {
 	uint8 header[2048];
-	uint8 c1, c2, c3, c4;
 	uint8 npat;
 	uint8 ptable[128];
 	uint8 max = 0;
@@ -23,84 +23,69 @@ static int depack_pru2(FILE *in, FILE *out)
 
 	memset(header, 0, 2048);
 	memset(ptable, 0, 128);
+	memset(v, 0, 16);
 
 	pw_write_zero(out, 20);				/* title */
 
-	fseek(in, 8, SEEK_SET);
+	hio_seek(in, 8, SEEK_SET);
 
 	for (i = 0; i < 31; i++) {
 		pw_write_zero(out, 22);			/*sample name */
-		write16b(out, size = read16b(in));	/* size */
+		write16b(out, size = hio_read16b(in));	/* size */
 		ssize += size * 2;
-		write8(out, read8(in));			/* finetune */
-		write8(out, read8(in));			/* volume */
-		write16b(out, read16b(in));		/* loop start */
-		write16b(out, read16b(in));		/* loop size */
+		write8(out, hio_read8(in));		/* finetune */
+		write8(out, hio_read8(in));		/* volume */
+		write16b(out, hio_read16b(in));		/* loop start */
+		write16b(out, hio_read16b(in));		/* loop size */
 	}
 
-	write8(out, npat = read8(in));			/* number of patterns */
-	write8(out, read8(in));				/* noisetracker byte */
+	write8(out, npat = hio_read8(in));		/* number of patterns */
+	write8(out, hio_read8(in));			/* noisetracker byte */
 
 	for (i = 0; i < 128; i++) {
-		write8(out, c1 = read8(in));
-		max = (c1 > max) ? c1 : max;
+		uint8 x;
+		write8(out, x = hio_read8(in));
+		max = (x > max) ? x : max;
 	}
 
 	write32b(out, PW_MOD_MAGIC);
 
 	/* pattern data stuff */
-	fseek(in, 770, SEEK_SET);
+	hio_seek(in, 770, SEEK_SET);
 
 	for (i = 0; i <= max; i++) {
 		for (j = 0; j < 256; j++) {
-			c1 = c2 = c3 = c4 = 0;
-			header[0] = read8(in);
+			uint8 c[4];
+			memset(c, 0, 4);
+			header[0] = hio_read8(in);
 			if (header[0] == 0x80) {
 				write32b(out, 0);
-			} else if (header[0] == 0xC0) {
+			} else if (header[0] == 0xc0) {
 				fwrite(v[0], 4, 1, out);
-				c1 = v[0][0];
-				c2 = v[0][1];
-				c3 = v[0][2];
-				c4 = v[0][3];
-			} else if (header[0] != 0xC0 && header[0] != 0xC0) {
-				header[1] = read8(in);
-				header[2] = read8(in);
-
-				c1 = (header[1] & 0x80) >> 3;
-				c1 |= ptk_table[(header[0] >> 1)][0];
-				c2 = ptk_table[(header[0] >> 1)][1];
-				c3 = (header[1] & 0x70) << 1;
-				c3 |= (header[0] & 0x01) << 4;
-				c3 |= (header[1] & 0x0f);
-				c4 = header[2];
-
-				write8(out, c1);
-				write8(out, c2);
-				write8(out, c3);
-				write8(out, c4);
+				memcpy(c, v[0], 4);
+			} else if (header[0] >= 74) {
+				return -1;
+			} else {
+				header[1] = hio_read8(in);
+				header[2] = hio_read8(in);
+
+				c[0] = (header[1] & 0x80) >> 3;
+				c[0] |= ptk_table[(header[0] >> 1)][0];
+				c[1] = ptk_table[(header[0] >> 1)][1];
+				c[2] = (header[1] & 0x70) << 1;
+				c[2] |= (header[0] & 0x01) << 4;
+				c[2] |= (header[1] & 0x0f);
+				c[3] = header[2];
+
+				fwrite(c, 1, 4, out);
 			}
 
 			/* rol previous values */
-			v[0][0] = v[1][0];
-			v[0][1] = v[1][1];
-			v[0][2] = v[1][2];
-			v[0][3] = v[1][3];
-
-			v[1][0] = v[2][0];
-			v[1][1] = v[2][1];
-			v[1][2] = v[2][2];
-			v[1][3] = v[2][3];
-
-			v[2][0] = v[3][0];
-			v[2][1] = v[3][1];
-			v[2][2] = v[3][2];
-			v[2][3] = v[3][3];
-
-			v[3][0] = c1;
-			v[3][1] = c2;
-			v[3][2] = c3;
-			v[3][3] = c4;
+			memcpy(&v[0], &v[1], 4);
+			memcpy(&v[1], &v[2], 4);
+			memcpy(&v[2], &v[3], 4);
+
+			memcpy(v[3], c, 4);
 		}
 	}
 
@@ -113,11 +98,10 @@ static int depack_pru2(FILE *in, FILE *out)
 static int test_pru2(uint8 *data, char *t, int s)
 {
 	int k;
-	int start = 0;
 
 	PW_REQUEST_DATA(s, 12 + 31 * 8);
 
-	if (data[0]!='S' || data[1]!='N' || data[2]!='T' || data[3]!='!')
+	if (readmem32b(data) != 0x534e5421)
 		return -1;
 
 #if 0
@@ -130,13 +114,13 @@ static int test_pru2(uint8 *data, char *t, int s)
 
 	/* test volumes */
 	for (k = 0; k < 31; k++) {
-		if (data[start + 11 + k * 8] > 0x40)
+		if (data[11 + k * 8] > 0x40)
 			return -1;
 	}
 
 	/* test finetunes */
 	for (k = 0; k < 31; k++) {
-		if (data[start + 10 + k * 8] > 0x0F)
+		if (data[10 + k * 8] > 0x0F)
 			return -1;
 	}
 
diff --git a/src/loaders/prowizard/ptk.c b/src/loaders/prowizard/ptk.c
new file mode 100644
index 0000000..5e44416
--- /dev/null
+++ b/src/loaders/prowizard/ptk.c
@@ -0,0 +1,127 @@
+
+#include 
+#include 
+
+void testPTK (void)
+{
+	/* test 1 */
+	if (i < 1080) {
+/*printf ( "#1 (i:%ld)\n" , i );*/
+		Test = BAD;
+		return;
+	}
+
+	/* test 2 */
+	start = i - 1080;
+	for (k = 0; k < 31; k++) {
+		/* size */
+		j =
+			(((data[start + 42 + k * 30] << 8) +
+				 data[start + 43 +
+					k * 30]) * 2);
+		/* loop start */
+		m =
+			(((data[start + 46 + k * 30] << 8) +
+				 data[start + 47 +
+					k * 30]) * 2);
+		/* loop size */
+		n =
+			(((data[start + 48 + k * 30] << 8) +
+				 data[start + 49 +
+					k * 30]) * 2);
+
+		/* size = 0 & loop start != 0 */
+		if ((j == 0) && (m != 0)) {
+/*printf ( "#2 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+		/* loop size =0 & loop start != 0 ? */
+		if ((m != 0) && (n == 0)) {
+/*printf ( "#2,1\n" );*/
+			Test = BAD;
+			return;
+		}
+		/* loop size > size ? */
+		if ((j + 2) < n) {
+/*printf ( "#2,2 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+
+	}
+
+	/* test #3  finetunes & volumes */
+	for (k = 0; k < 31; k++) {
+		if ((data[start + 44 + k * 30] > 0x0f)
+			|| (data[start + 45 + k * 30] >
+				0x40)) {
+/*printf ( "#3 (Start:%ld)(smp:%ld)(Fine:%d)(vol:%d)\n"
+         ,start
+         ,k
+         ,data[start+44+k*30]
+         ,data[start+45+k*30] );*/
+			Test = BAD;
+			return;
+		}
+	}
+
+	/* test #4  pattern list size */
+	l = data[start + 950];
+	if ((l > 127) || (l == 0)) {
+/*printf ( "#4,0 (Start:%ld)\n" , start );*/
+		Test = BAD;
+		return;
+	}
+	/* l holds the size of the pattern list */
+	k = 0;
+	for (j = 0; j < 128; j++) {
+		if (data[start + 952 + j] > k)
+			k = data[start + 952 + j];
+		if (data[start + 952 + j] > 127) {
+/*printf ( "#4,1 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+	}
+	/* k holds the highest pattern number */
+	/* test last patterns of the pattern list = 0 ? */
+	j += 2;		/* found some obscure ptk :( */
+	while (j < 128) {
+		if (data[start + 952 + j] > 0x7f) {
+/*printf ( "#4,2 (Start:%ld) (j:%ld) (at:%ld)\n" , start,j ,start+952+j );*/
+			Test = BAD;
+			return;
+		}
+		j += 1;
+	}
+	/* k is the number of pattern in the file (-1) */
+	k += 1;
+
+
+	/* test #5 pattern data ... */
+	if (((k * 1024) + 1084 + start) > in_size) {
+/*printf ( "#5,0 (Start:%ld)\n" , start );*/
+		Test = BAD;
+		return;
+	}
+	for (j = 0; j < (k << 8); j++) {
+		/* sample > 1f   or   pitch > 358 ? */
+		if (data[start + 1084 + j * 4] > 0x13) {
+/*printf ( "#5.1 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+		l =
+			((data[start + 1084 +
+					 j * 4] & 0x0f) << 8) +
+			data[start + 1085 + j * 4];
+		if ((l > 0) && (l < 0x1C)) {
+/*printf ( "#5,2 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+	}
+
+	Test = GOOD;
+}
diff --git a/src/loaders/prowizard/qc.c b/src/loaders/prowizard/qc.c
new file mode 100644
index 0000000..ce994f8
--- /dev/null
+++ b/src/loaders/prowizard/qc.c
@@ -0,0 +1,307 @@
+/*
+ * QuadraComposer.c   Copyright (C) 1999 Asle / ReDoX
+ *                    Modified by Claudio Matsuoka
+ *
+ * Converts QC MODs back to PTK MODs
+ */
+
+#include 
+#include 
+#include "prowiz.h"
+
+static int test_emod (uint8 *, int);
+static int depack_emod (FILE *, FILE *);
+
+const struct pw_format pw_emod = {
+	"QuadraComposer",
+	test_emod,
+	depack_emod
+};
+
+static int depack_emod (HIO_HANDLE *in, FILE *out)
+{
+	uint8 c1, c2, c3, c4, c5;
+	uint8 pat_pos;
+	uint8 pat_max = 0x00;
+	uint8 Real_pat_max = 0x00;
+	uint8 *tmp;
+	uint8 Row[16];
+	uint8 Pattern[1024];
+	uint8 nins = 0x00;
+	uint8 Realnins = 0x00;
+	uint8 nrow[128];
+	long iaddr[32];
+	long isize[32];
+	long paddr[128];
+	long i = 0, j = 0, k = 0;
+
+	memset(iaddr, 0, 32 * 4);
+	memset(isize, 0, 32 * 4);
+	memset(paddr, 0, 128 * 4);
+	memset(nrow, 0, 128);
+
+	/* bypass ID's and chunk sizes */
+	fseek (in, 22, 0);
+
+	/* read and write title */
+	for (i = 0; i < 20; i++) {
+		fread (&c1, 1, 1, in);
+		fwrite (&c1, 1, 1, out);
+	}
+
+	/* bypass composer and tempo */
+	fseek (in, 21, 1);
+
+	/* read number of samples */
+	fread (&nins, 1, 1, in);
+
+	/* write empty 930 sample header */
+	tmp = (uint8 *) malloc (930);
+	memset(tmp, 0, 930);
+	/* puts some $01 for replen */
+	for (i = 0; i < 31; i++)
+		tmp[i * 30 + 29] = 0x01;
+	fwrite (tmp, 930, 1, out);
+	free (tmp);
+
+	/* read and write sample descriptions */
+/*printf ( "sample number:" );*/
+	for (i = 0; i < nins; i++) {
+		/* read sample number byte */
+		fread (&c5, 1, 1, in);
+		if (c5 > Realnins)
+			Realnins = c5;
+/*printf ( "%d," , c5 );*/
+		fseek (out, 20 + (c5 - 1) * 30, 0);
+
+		/* read volume */
+		fread (&c4, 1, 1, in);
+
+		/* read size (/2 like ptk) */
+		fread (&c1, 1, 1, in);
+		fread (&c2, 1, 1, in);
+		isize[c5] = (((c1 << 8) + c2) * 2);
+
+		/* read/write sample name */
+		for (j = 0; j < 20; j++) {
+			fread (&c3, 1, 1, in);
+			fwrite (&c3, 1, 1, out);
+		}
+		/* fill to 22 with $00 */
+		c3 = 0x00;
+		fwrite (&c3, 1, 1, out);
+		fwrite (&c3, 1, 1, out);
+
+		/* write size */
+		fwrite (&c1, 1, 1, out);
+		fwrite (&c2, 1, 1, out);
+
+		/* bypass control byte */
+		fseek (in, 1, 1);
+
+		/* read/write finetune */
+		fread (&c1, 1, 1, in);
+		fwrite (&c1, 1, 1, out);
+
+		/* write volume */
+		fwrite (&c4, 1, 1, out);
+
+		/* read/write loops (start & len) */
+		fread (&c1, 1, 1, in);
+		fread (&c2, 1, 1, in);
+		fwrite (&c1, 1, 1, out);
+		fwrite (&c2, 1, 1, out);
+		fread (&c1, 1, 1, in);
+		fread (&c2, 1, 1, in);
+		if ((c1 == 0x00) && (c2 == 0x00))
+			c2 = 0x01;
+		fwrite (&c1, 1, 1, out);
+		fwrite (&c2, 1, 1, out);
+
+		/* read address of this sample in the file */
+		fread (&c1, 1, 1, in);
+		fread (&c2, 1, 1, in);
+		fread (&c3, 1, 1, in);
+		fread (&c4, 1, 1, in);
+		iaddr[c5] = ((c1 << 24) +
+			(c2 << 16) + (c3 << 8) + (c4));
+	}
+/*printf ( "\n" );*/
+	fseek (out, 0, 2);
+
+	/* patterns now */
+	/* bypass "pad" ?!? */
+	fread (&c1, 1, 1, in);
+	if (c1 != 0x00)
+		fseek (in, -1, 1);
+
+	/* read number of pattern */
+	fread (&pat_max, 1, 1, in);
+/*  printf ( "\npat_max : %d (at %x)\n" , Pat_Max , ftell ( in ) );*/
+
+	/* read patterns info */
+/*printf ( "pattern numbers:" );*/
+	for (i = 0; i < pat_max; i++) {
+		/* read pattern number */
+		fread (&c5, 1, 1, in);
+/*printf ("%d," , c5);*/
+		/* read number of rows for each pattern */
+		fread (&nrow[c5], 1, 1, in);
+
+		/* bypass pattern name */
+		fseek (in, 20, 1);
+
+		/* read pattern address */
+		fread (&c1, 1, 1, in);
+		fread (&c2, 1, 1, in);
+		fread (&c3, 1, 1, in);
+		fread (&c4, 1, 1, in);
+		paddr[c5] = ((c1 << 24) + (c2 << 16) + (c3 << 8) + (c4));
+	}
+
+	/* pattern list */
+	/* bypass "pad" ?!? */
+	fread (&c1, 1, 1, in);
+	if (c1 != 0x00)
+		fseek (in, -1, 1);
+
+	/* read/write number of position */
+	fread (&pat_pos, 1, 1, in);
+	fwrite (&pat_pos, 1, 1, out);
+
+	/* write noisetracker byte */
+	c1 = 0x7f;
+	fwrite (&c1, 1, 1, out);
+
+	/* read/write pattern list */
+	for (i = 0; i < pat_pos; i++) {
+		fread (&c1, 1, 1, in);
+		fwrite (&c1, 1, 1, out);
+		if (c1 > Real_pat_max)
+			Real_pat_max = c1;
+	}
+	/* fill up to 128 */
+	c2 = 0x00;
+	while (i < 128) {
+		fwrite (&c2, 1, 1, out);
+		i++;
+	}
+
+	/* write ptk's ID */
+	c1 = 'M';
+	c2 = '.';
+	c3 = 'K';
+	fwrite (&c1, 1, 1, out);
+	fwrite (&c2, 1, 1, out);
+	fwrite (&c3, 1, 1, out);
+	fwrite (&c2, 1, 1, out);
+
+
+	/* pattern data */
+	for (i = 0; i <= Real_pat_max; i++) {
+		memset(Pattern, 0, 1024);
+		if (paddr[i] == 0l) {
+			fwrite (Pattern, 1024, 1, out);
+			printf ("-");
+			continue;
+		}
+		fseek (in, paddr[i], 0);
+		for (j = 0; j <= nrow[i]; j++) {
+			memset(Row, 0, 16);
+			fread (Row, 16, 1, in);
+			for (k = 0; k < 4; k++) {
+				/* fxt */
+				Pattern[j * 16 + k * 4 + 2] = Row[k * 4 + 2];
+
+				/* fxt args */
+				switch (Pattern[j * 16 + k * 4 + 2]) {
+				case 0x09:
+					/*printf ( "#" ); */
+					Pattern[j * 16 + k * 4 + 3] =
+						(Row[k * 4 + 3] * 2);
+					break;
+				case 0x0b:
+					/*printf ( "!" ); */
+					c4 = Row[k * 4 + 3] % 10;
+					c3 = Row[k * 4 + 3] / 10;
+					Pattern[j * 16 + k * 4 + 3] = 16;
+					Pattern[j * 16 + k * 4 + 3] *= c3;
+					Pattern[j * 16 + k * 4 + 3] += c4;
+					break;
+				case 0x0E:
+					if ((Row[k * 4 + 3] & 0xf0) == 0xf0)
+						Pattern[j * 16 + k * 4 + 3] =
+							(Row[k * 4 + 3] -
+							0x10);
+					break;
+				default:
+					Pattern[j * 16 + k * 4 + 3] =
+						Row[k * 4 + 3];
+				}
+
+				/* smp nbr (4 lower bits) */
+				Pattern[j * 16 + k * 4 + 2] |=
+					((Row[k * 4] << 4) & 0xf0);
+				/* notes */
+				c1 = Row[k * 4 + 1];
+				if (c1 != 0xff) {
+					Pattern[j * 16 + k * 4] = ptk_table[c1][0];
+					Pattern[j * 16 + k * 4 + 1] =
+						ptk_table[c1][1];
+				}
+				/* smp nbr (4 higher bits) */
+				Pattern[j * 16 + k * 4] |=
+					(Row[k * 4] & 0xf0);
+			}
+		}
+		fwrite (Pattern, 1024, 1, out);
+	}
+
+	/* sample data */
+	for (i = 1; i <= Realnins; i++) {
+		if (isize[i] == 0) {
+			continue;
+		}
+		fseek (in, iaddr[i], 0);
+		tmp = (uint8 *) malloc (isize[i]);
+		fread (tmp, isize[i], 1, in);
+		fwrite (tmp, isize[i], 1, out);
+		free (tmp);
+	}
+
+	return 0;
+}
+
+
+static int test_emod (uint8 *data, int s)
+{
+	int start = 0;
+	int l;
+
+#if 0
+	/* test #1 */
+	if (i < 8) {
+		Test = BAD;
+		return;
+	}
+	start = i - 8;
+#endif
+
+	/* test #2 "FORM" & "EMIC" */
+	if (data[start] != 'F' ||
+		data[start + 1] != 'O' ||
+		data[start + 2] != 'R' ||
+		data[start + 3] != 'M' ||
+		data[start + 12] != 'E' ||
+		data[start + 13] != 'M' ||
+		data[start + 14] != 'I' ||
+		data[start + 15] != 'C')
+		return -1;
+
+	/* test number of samples */
+	l = data[start + 63];
+	if (l == 0x00 || l > 0x20)
+		return -1;
+
+	return 0;
+}
diff --git a/src/loaders/prowizard/skyt.c b/src/loaders/prowizard/skyt.c
index 13e2f48..d0eb50e 100644
--- a/src/loaders/prowizard/skyt.c
+++ b/src/loaders/prowizard/skyt.c
@@ -1,6 +1,7 @@
 /*
  *   Skyt_Packer.c   Copyright (C) 1997 Asle / ReDoX
- *   Changes for xmp Copyright (C) 2009 Claudio Matsuoka
+ *
+ *   Modified in 2009,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -8,7 +9,7 @@
 #include "prowiz.h"
 
 
-static int depack_skyt(FILE *in, FILE *out)
+static int depack_skyt(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1, c2, c3, c4;
 	uint8 ptable[128];
@@ -27,50 +28,56 @@ static int depack_skyt(FILE *in, FILE *out)
 	/* read and write sample descriptions */
 	for (i = 0; i < 31; i++) {
 		pw_write_zero(out, 22);			/*sample name */
-		write16b(out, size = read16b(in));	/* sample size */
+		write16b(out, size = hio_read16b(in));	/* sample size */
 		ssize += size * 2;
-		write8(out, read8(in));			/* finetune */
-		write8(out, read8(in));			/* volume */
-		write16b(out, read16b(in));		/* loop start */
-		write16b(out, read16b(in));		/* loop size */
+		write8(out, hio_read8(in));			/* finetune */
+		write8(out, hio_read8(in));			/* volume */
+		write16b(out, hio_read16b(in));		/* loop start */
+		write16b(out, hio_read16b(in));		/* loop size */
 	}
 
-	read32b(in);			/* bypass 8 empty bytes */
-	read32b(in);
-	read32b(in);			/* bypass "SKYT" ID */
+	hio_read32b(in);			/* bypass 8 empty bytes */
+	hio_read32b(in);
+	hio_read32b(in);			/* bypass "SKYT" ID */
 
-	write8(out, pat_pos = read8(in) + 1);	/* pattern table lenght */
+	pat_pos = hio_read8(in) + 1;		/* pattern table lenght */
+	if (pat_pos >= 128) {
+		return -1;
+	}
+	write8(out, pat_pos);
 	write8(out, 0x7f);			/* write NoiseTracker byte */
 
 	/* read track numbers ... and deduce pattern list */
 	for (i = 0; i < pat_pos; i++) {
-		for (j = 0; j < 4; j++)
-			trkval[i][j] = read16b(in);
+		for (j = 0; j < 4; j++) {
+			trkval[i][j] = hio_read16b(in);
+		}
 	}
 
 	/* write pseudo pattern list */
-	for (i = 0; i < 128; i++)
+	for (i = 0; i < 128; i++) {
 		write8(out, i < pat_pos ? i : 0);
+	}
 
 	write32b(out, PW_MOD_MAGIC);		/* write ptk's ID */
 
-	read8(in);				/* bypass $00 unknown byte */
+	hio_read8(in);				/* bypass $00 unknown byte */
 
 	/* get track address */
-	trk_addr = ftell(in);
+	trk_addr = hio_tell(in);
 
 	/* track data */
 	for (i = 0; i < pat_pos; i++) {
 		memset(pat, 0, 1024);
 		for (j = 0; j < 4; j++) {
-			fseek(in, trk_addr + ((trkval[i][j] - 1)<<8), SEEK_SET);
+			hio_seek(in, trk_addr + ((trkval[i][j] - 1)<<8), SEEK_SET);
 			for (k = 0; k < 64; k++) {
 				int x = k * 16 + j * 4;
 
-				c1 = read8(in);
-				c2 = read8(in);
-				c3 = read8(in);
-				c4 = read8(in);
+				c1 = hio_read8(in);
+				c2 = hio_read8(in);
+				c3 = hio_read8(in);
+				c4 = hio_read8(in);
 
 				pat[x] = (c2 & 0xf0) | ptk_table[c1][0];
 				pat[x + 1] = ptk_table[c1][1];
@@ -89,18 +96,17 @@ static int depack_skyt(FILE *in, FILE *out)
 
 static int test_skyt(uint8 *data, char *t, int s)
 {
-	int start = 0;
 	int i;
 
 	PW_REQUEST_DATA(s, 8 * 31 + 12);
 
 	/* test 2 */
 	for (i = 0; i < 31; i++) {
-		if (data[start + 8 * i + 4] > 0x40)
+		if (data[8 * i + 4] > 0x40)
 			return -1;
 	}
 
-	if (readmem32b(data + start + 256) != MAGIC4('S','K','Y','T'))
+	if (readmem32b(data + 256) != MAGIC4('S','K','Y','T'))
 		return -1;
 
 	pw_read_title(NULL, t, 0);
diff --git a/src/loaders/prowizard/soundfx.c b/src/loaders/prowizard/soundfx.c
new file mode 100644
index 0000000..a35063c
--- /dev/null
+++ b/src/loaders/prowizard/soundfx.c
@@ -0,0 +1,336 @@
+/*
+ *   SoundFX.c   1999 (c) Sylvain "Asle" Chipaux
+ *
+ * Depacks musics in the SoundFX format and saves in ptk.
+ *
+*/
+
+#include 
+#include 
+
+void Depack_SoundFX13 (FILE * in, FILE * out)
+{
+	uint8 *tmp;
+	uint8 c0 = 0x00, c1 = 0x00, c2 = 0x00, c3 = 0x00;
+	uint8 Max = 0x00;
+	uint8 PatPos;
+	long ssize = 0;
+	long i = 0, j = 0;
+	// HIO_HANDLE *in,*out;
+
+	if (Save_Status == BAD)
+		return;
+
+	// in = fdopen (fd_in, "rb");
+	// sprintf ( Depacked_OutName , "%ld.mod" , Cpt_Filename-1 );
+	// out = fdopen (fd_out, "w+b");
+
+	/* title */
+	tmp = (uint8 *) malloc (20);
+	memset(tmp, 0, 20);
+	fwrite (tmp, 20, 1, out);
+	free (tmp);
+
+	/* read and write whole header */
+	for (i = 0; i < 15; i++) {
+		fseek (in, 0x50 + i * 30, 0);
+		/* write name */
+		for (j = 0; j < 22; j++) {
+			fread (&c1, 1, 1, in);
+			fwrite (&c1, 1, 1, out);
+		}
+		/* size */
+		fseek (in, i * 4 + 1, 0);
+		fread (&c0, 1, 1, in);
+		fread (&c1, 1, 1, in);
+		fread (&c2, 1, 1, in);
+		c2 /= 2;
+		c3 = c1 / 2;
+		if ((c3 * 2) != c1)
+			c2 += 0x80;
+		if (c0 != 0x00)
+			c3 += 0x80;
+		fseek (in, 0x50 + i * 30 + 24, 0);
+		fwrite (&c3, 1, 1, out);
+		fwrite (&c2, 1, 1, out);
+		ssize += (((c3 << 8) + c2) * 2);
+		/* finetune */
+		fread (&c1, 1, 1, in);
+		fwrite (&c1, 1, 1, out);
+		/* volume */
+		fread (&c1, 1, 1, in);
+		fwrite (&c1, 1, 1, out);
+		/* loop start */
+		fread (&c1, 1, 1, in);
+		fread (&c2, 1, 1, in);
+		c2 /= 2;
+		c3 = c1 / 2;
+		if ((c3 * 2) != c1)
+			c2 += 0x80;
+		fwrite (&c3, 1, 1, out);
+		fwrite (&c2, 1, 1, out);
+		/* loop size */
+		fread (&c1, 1, 1, in);
+		fread (&c2, 1, 1, in);
+		fwrite (&c1, 1, 1, out);
+		fwrite (&c2, 1, 1, out);
+	}
+	tmp = (uint8 *) malloc (30);
+	memset(tmp, 0, 30);
+	tmp[29] = 0x01;
+	for (i = 0; i < 16; i++)
+		fwrite (tmp, 30, 1, out);
+	free (tmp);
+
+	/* pattern list size */
+	fread (&PatPos, 1, 1, in);
+	fwrite (&PatPos, 1, 1, out);
+
+	/* ntk byte */
+	fseek (in, 1, 1);
+	c1 = 0x7f;
+	fwrite (&c1, 1, 1, out);
+
+	/* read and write pattern list */
+	Max = 0x00;
+	for (i = 0; i < PatPos; i++) {
+		fread (&c1, 1, 1, in);
+		fwrite (&c1, 1, 1, out);
+		if (c1 > Max)
+			Max = c1;
+	}
+	c1 = 0x00;
+	while (i != 128) {
+		fwrite (&c1, 1, 1, out);
+		i += 1;
+	}
+
+	/* write ID */
+	c1 = 'M';
+	c2 = '.';
+	c3 = 'K';
+	fwrite (&c1, 1, 1, out);
+	fwrite (&c2, 1, 1, out);
+	fwrite (&c3, 1, 1, out);
+	fwrite (&c2, 1, 1, out);
+
+
+	/* pattern data */
+	fseek (in, 0x294, 0);
+	tmp = (uint8 *) malloc (1024);
+	for (i = 0; i <= Max; i++) {
+		memset(tmp, 0, 1024);
+		fread (tmp, 1024, 1, in);
+		for (j = 0; j < 256; j++) {
+			if (tmp[(j * 4)] == 0xff) {
+				if (tmp[(j * 4) + 1] != 0xfe)
+					printf
+						("Volume unknown : (at:%ld) (fx:%x,%x,%x,%x)\n",
+						ftell (in)
+						, tmp[(j * 4)]
+						, tmp[(j * 4) + 1]
+						, tmp[(j * 4) + 2]
+						, tmp[(j * 4) + 3]);
+				tmp[(j * 4)] = 0x00;
+				tmp[(j * 4) + 1] = 0x00;
+				tmp[(j * 4) + 2] = 0x0C;
+				tmp[(j * 4) + 3] = 0x00;
+				continue;
+			}
+			switch (tmp[(j * 4) + 2] & 0x0f) {
+			case 1:	/* arpeggio */
+				tmp[(j * 4) + 2] &= 0xF0;
+				break;
+			case 7:	/* slide up */
+			case 8:	/* slide down */
+				tmp[(j * 4) + 2] -= 0x06;
+				break;
+			case 3:	/* empty ... same as followings ... but far too much to "printf" it */
+			case 6:	/* and Noiseconverter puts 00 instead ... */
+				tmp[(j * 4) + 2] &= 0xF0;
+				tmp[(j * 4) + 3] = 0x00;
+				break;
+			case 2:
+			case 4:
+			case 5:
+			case 9:
+			case 0x0a:
+			case 0x0b:
+			case 0x0c:
+			case 0x0d:
+			case 0x0e:
+			case 0x0f:
+				printf
+					("unsupported effect : (at:%ld) (fx:%d)\n",
+					ftell (in),
+					tmp[(j * 4) + 2] & 0x0f);
+				tmp[(j * 4) + 2] &= 0xF0;
+				tmp[(j * 4) + 3] = 0x00;
+				break;
+			default:
+				break;
+			}
+		}
+		fwrite (tmp, 1024, 1, out);
+		fflush (stdout);
+	}
+	free (tmp);
+	fflush (stdout);
+
+
+	/* sample data */
+	tmp = (uint8 *) malloc (ssize);
+	memset(tmp, 0, ssize);
+	fread (tmp, ssize, 1, in);
+	fwrite (tmp, ssize, 1, out);
+	free (tmp);
+	fflush (stdout);
+
+
+	/* crap */
+	Crap ("     Sound FX     ", BAD, BAD, out);
+
+	fflush (in);
+	fflush (out);
+	// fclose ( in );
+	// fclose ( out );
+
+	printf ("done\n"
+		"  WARNING: This is only an under devellopment converter !\n"
+		"           output could sound strange...\n");
+	return;			/* useless ... but */
+
+}
+
+#include 
+#include 
+
+void testSoundFX13 (void)
+{
+	/* test 1 */
+	if (i < 0x3C) {
+/*printf ( "#1 (i:%ld)\n" , i );*/
+		Test = BAD;
+		return;
+	}
+
+	/* test 2 */
+	/* samples tests */
+	start = i - 0x3C;
+	for (k = 0; k < 15; k++) {
+		/* size */
+		j =
+			((data[start + k * 4 + 2] << 8) +
+			data[start + k * 4 + 3]);
+		/* loop start */
+		m =
+			((data[start + 106 + k * 30] << 8) +
+			data[start + 107 + k * 30]);
+		/* loop size */
+		n =
+			(((data[start + 108 +
+						 k * 30] << 8) +
+				 data[start + 109 +
+					k * 30]) * 2);
+		/* all sample sizes */
+
+		/* size,loopstart,replen > 64k ? */
+		if ((j > 0xFFFF) || (m > 0xFFFF) || (n > 0xFFFF)) {
+/*printf ( "#2,0 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+		/* replen > size ? */
+		if (n > (j + 2)) {
+/*printf ( "#2 (Start:%ld) (smp:%ld) (size:%ld) (replen:%ld)\n"
+         , start , k+1 , j , n );*/
+			Test = BAD;
+			return;
+		}
+		/* loop start > size ? */
+		if (m > j) {
+/*printf ( "#2,0 (Start:%ld) (smp:%ld) (size:%ld) (lstart:%ld)\n"
+         , start , k+1 , j , m );*/
+			Test = BAD;
+			return;
+		}
+		/* loop size =0 & loop start != 0 ? */
+		if ((m != 0) && (n == 0)) {
+/*printf ( "#2,1 (start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+		/* size & loopstart !=0 & size=loopstart ? */
+		if ((j != 0) && (j == m)) {
+/*printf ( "#2,15 (start:%ld) (smp:%ld) (siz:%ld) (lstart:%ld)\n"
+         , start,k+1,j,m );*/
+			Test = BAD;
+			return;
+		}
+		/* size =0 & loop start !=0 */
+		if ((j == 0) && (m != 0)) {
+/*printf ( "#2,2 (start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+	}
+
+	/* get real whole sample size */
+	ssize = 0;
+	for (j = 0; j < 15; j++) {
+		k =
+			((data[start +
+					 j * 4] << 24) +
+			(data[start + j * 4 +
+					1] << 16) +
+			(data[start + j * 4 + 2] << 8) +
+			data[start + j * 4 + 3]);
+		if (k > 131072) {
+/*printf ( "#2,4 (start:%ld) (smp:%ld) (size:%ld)\n"
+         , start,j,k );*/
+			Test = BAD;
+			return;
+		}
+		ssize += k;
+	}
+
+	/* test #3  finetunes & volumes */
+	for (k = 0; k < 15; k++) {
+		if (data[start + 105 + k * 30] > 0x40) {
+/*printf ( "#3 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+	}
+
+	/* test #4  pattern list size */
+	l = data[start + 0x212];
+	if ((l > 127) || (l == 0)) {
+/*printf ( "#4,0 (Start:%ld)\n" , start );*/
+		Test = BAD;
+		return;
+	}
+	/* l holds the size of the pattern list */
+	k = 0;
+	for (j = 0; j < l; j++) {
+		if (data[start + 0x214 + j] > k)
+			k = data[start + 0x214 + j];
+		if (data[start + 0x214 + j] > 127) {
+/*printf ( "#4,1 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+	}
+	/* k is the number of pattern in the file (-1) */
+	k += 1;
+
+
+	/* test #5 pattern data ... */
+	if (((k * 1024) + 0x294 + start) > in_size) {
+/*printf ( "#5,0 (Start:%ld)\n" , start );*/
+		Test = BAD;
+		return;
+	}
+
+	Test = GOOD;
+}
diff --git a/src/loaders/prowizard/soundtk.c b/src/loaders/prowizard/soundtk.c
new file mode 100644
index 0000000..93c1d57
--- /dev/null
+++ b/src/loaders/prowizard/soundtk.c
@@ -0,0 +1,155 @@
+
+/* Empty file */
+
+#include 
+#include 
+
+void testSoundTracker (void)
+{
+	/* test 1 */
+	/* start of stk before start of file ? */
+	if (i < 45) {
+/*printf ( "#1 (i:%ld)\n" , i );*/
+		Test = BAD;
+		return;
+	}
+
+	/* test 2 */
+	/* samples tests */
+	start = i - 45;
+	o = 0;
+	for (k = 0; k < 15; k++) {
+		/* size */
+		j =
+			(((data[start + 42 + k * 30] << 8) +
+				 data[start + 43 +
+					k * 30]) * 2);
+		/* loop start */
+		m =
+			(((data[start + 46 + k * 30] << 8) +
+				 data[start + 47 +
+					k * 30]) * 2);
+		/* loop size */
+		n =
+			(((data[start + 48 + k * 30] << 8) +
+				 data[start + 49 +
+					k * 30]) * 2);
+		/* all sample sizes */
+		o += j;
+
+		/* size,loopstart,replen > 64k ? */
+		if ((j > 0xFFFF) || (m > 0xFFFF) || (n > 0xFFFF)) {
+/*printf ( "#2,0 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+		/* replen > size ? */
+		if (n > (j + 2)) {
+/*printf ( "#2 (Start:%ld) (smp:%ld) (size:%ld) (replen:%ld)\n"
+         , start , k+1 , j , n );*/
+			Test = BAD;
+			return;
+		}
+		/* loop start > size ? */
+		if (m > j) {
+/*printf ( "#2,0 (Start:%ld) (smp:%ld) (size:%ld) (lstart:%ld)\n"
+         , start , k+1 , j , m );*/
+			Test = BAD;
+			return;
+		}
+		/* loop size =0 & loop start != 0 ? */
+		if ((m != 0) && (n == 0)) {
+/*printf ( "#2,1\n" );*/
+			Test = BAD;
+			return;
+		}
+		/* size & loopstart !=0 & size=loopstart ? */
+		if ((j != 0) && (j == m)) {
+/*printf ( "#2,15\n" );*/
+			Test = BAD;
+			return;
+		}
+		/* size =0 & loop start !=0 */
+		if ((j == 0) && (m != 0)) {
+/*printf ( "#2,2\n" );*/
+			Test = BAD;
+			return;
+		}
+	}
+	/* all sample sizes < 8 ? */
+	if (o < 8) {
+/*printf ( "#2,3\n" );*/
+		Test = BAD;
+		return;
+	}
+
+	/* test #3  finetunes & volumes */
+	for (k = 0; k < 15; k++) {
+		if ((data[start + 44 + k * 30] > 0x0f)
+			|| (data[start + 45 + k * 30] >
+				0x40)) {
+/*printf ( "#3 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+	}
+
+	/* test #4  pattern list size */
+	l = data[start + 470];
+	if ((l > 127) || (l == 0)) {
+/*printf ( "#4,0 (Start:%ld)\n" , start );*/
+		Test = BAD;
+		return;
+	}
+	/* l holds the size of the pattern list */
+	k = 0;
+	for (j = 0; j < l; j++) {
+		if (data[start + 472 + j] > k)
+			k = data[start + 472 + j];
+		if (data[start + 472 + j] > 127) {
+/*printf ( "#4,1 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+	}
+	/* k holds the highest pattern number */
+	/* test last patterns of the pattern list = 0 ? */
+	j += 2;		/* found some obscure stk :( */
+	while (j != 128) {
+		if (data[start + 472 + j] != 0) {
+/*printf ( "#4,2 (Start:%ld) (j:%ld) (at:%ld)\n" , start,j ,start+472+j );*/
+			Test = BAD;
+			return;
+		}
+		j += 1;
+	}
+	/* k is the number of pattern in the file (-1) */
+	k += 1;
+
+
+	/* test #5 pattern data ... */
+	if (((k * 1024) + 600 + start) > in_size) {
+/*printf ( "#5,0 (Start:%ld)\n" , start );*/
+		Test = BAD;
+		return;
+	}
+	for (j = 0; j < (k << 8); j++) {
+		/* sample > 1f   or   pitch > 358 ? */
+		if (data[start + 600 + j * 4] > 0x13) {
+/*printf ( "#5.1 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+		l =
+			((data[start + 600 +
+					 j * 4] & 0x0f) << 8) +
+			data[start + 601 + j * 4];
+		if ((l > 0) && (l < 0x71)) {
+/*printf ( "#5,2 (Start:%ld)\n" , start );*/
+			Test = BAD;
+			return;
+		}
+	}
+
+	Test = GOOD;
+}
diff --git a/src/loaders/prowizard/starpack.c b/src/loaders/prowizard/starpack.c
index 9231b71..4a1a4f0 100644
--- a/src/loaders/prowizard/starpack.c
+++ b/src/loaders/prowizard/starpack.c
@@ -1,8 +1,9 @@
 /*
  * StarTrekker_Packer.c   Copyright (C) 1997 Sylvain "Asle" Chipaux
- *                        Copyright (C) 2006-2009 Claudio Matsuoka
  *
  * Converts back to ptk StarTrekker packed MODs
+ *
+ * Modified in 2006,2009,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -10,9 +11,8 @@
 #include "prowiz.h"
 
 
-static int depack_starpack(FILE *in, FILE *out)
+static int depack_starpack(HIO_HANDLE *in, FILE *out)
 {
-	uint8 c1, c2, c3, c4, c5;
 	uint8 pnum[128];
 	uint8 pnum_tmp[128];
 	uint8 pat_pos;
@@ -36,27 +36,32 @@ static int depack_starpack(FILE *in, FILE *out)
 
 	for (i = 0; i < 31; i++) {
 		pw_write_zero(out, 22);		/* sample name */
-		write16b(out, size = read16b(in));	/* size */
+		write16b(out, size = hio_read16b(in));	/* size */
 		ssize += 2 * size;
-		write8(out, read8(in));		/* finetune */
-		write8(out, read8(in));		/* volume */
-		write16b(out, read16b(in));	/* loop start */
-		write16b(out, read16b(in));	/* loop size */
+		write8(out, hio_read8(in));	/* finetune */
+		write8(out, hio_read8(in));	/* volume */
+		write16b(out, hio_read16b(in));	/* loop start */
+		write16b(out, hio_read16b(in));	/* loop size */
 	}
 
-	pat_pos = read16b(in);			/* size of pattern table */
+	pat_pos = hio_read16b(in);		/* size of pattern table */
 
-	fseek(in, 2, SEEK_CUR);			/* bypass $0000 unknown bytes */
+	if (pat_pos >= 128) {
+		return -1;
+	}
 
-	for (i = 0; i < 128; i++)
-		paddr[i] = read32b(in);
+	hio_seek(in, 2, SEEK_CUR);		/* bypass $0000 unknown bytes */
+
+	for (i = 0; i < 128; i++) {
+		paddr[i] = hio_read32b(in);
+	}
 
 	/* ordering of patterns addresses */
 
 	tmp_ptr = 0;
 	for (i = 0; i < pat_pos; i++) {
 		if (i == 0) {
-			pnum[0] = 0x00;
+			pnum[0] = 0;
 			tmp_ptr++;
 			continue;
 		}
@@ -140,8 +145,8 @@ static int depack_starpack(FILE *in, FILE *out)
 	write32b(out, PW_MOD_MAGIC);		/* M.K. */
 
 	/* read sample data address */
-	fseek(in, 0x310, SEEK_SET);
-	smp_addr = read32b(in) + 0x314;
+	hio_seek(in, 0x310, SEEK_SET);
+	smp_addr = hio_read32b(in) + 0x314;
 
 	/* pattern data */
 	num_pat += 1;
@@ -149,13 +154,15 @@ static int depack_starpack(FILE *in, FILE *out)
 		memset(buffer, 0, 1024);
 		for (j = 0; j < 64; j++) {
 			for (k = 0; k < 4; k++) {
+				uint8 c1, c2, c3, c4, c5;
 				int ofs = j * 16 + k * 4;
-				c1 = read8(in);
+
+				c1 = hio_read8(in);
 				if (c1 == 0x80)
 					continue;
-				c2 = read8(in);
-				c3 = read8(in);
-				c4 = read8(in);
+				c2 = hio_read8(in);
+				c3 = hio_read8(in);
+				c4 = hio_read8(in);
 				buffer[ofs] = c1 & 0x0f;
 				buffer[ofs + 1] = c2;
 				buffer[ofs + 2] = c3 & 0x0f;
@@ -172,7 +179,7 @@ static int depack_starpack(FILE *in, FILE *out)
 	/*printf ( "\n" ); */
 
 	/* sample data */
-	fseek(in, smp_addr, 0);
+	hio_seek(in, smp_addr, 0);
 	pw_move_data(out, in, ssize);
 
 	return 0;
@@ -180,9 +187,8 @@ static int depack_starpack(FILE *in, FILE *out)
 
 static int test_starpack(uint8 *data, char *t, int s)
 {
-	int start = 0;
-	int j, k, l, m;
-	int ssize;
+	int i;
+	int plist_size, len, sdata_ofs, pdata_ofs;
 
 #if 0
 	/* test 1 */
@@ -193,110 +199,93 @@ static int test_starpack(uint8 *data, char *t, int s)
 #endif
 
 	/* test 2 */
-	l = (data[start + 268] << 8) + data[start + 269];
-	if (l & 0x03)
+	plist_size = readmem16b(data + 268);
+	if (plist_size & 0x03)
 		return -1;
 
-	k = l / 4;
-	if (k == 0 || k > 127)
+	len = plist_size >> 2;
+	if (len == 0 || len > 127)
 		return -1;
 
-	if (data[start + 784] != 0)
+	if (data[784] != 0)
 		return -1;
 
 	/* test #3  smp size < loop start + loop size ? */
-	/* l is still the size of the pattern list */
-	for (k = 0; k < 31; k++) {
-		j = (((data[start + 20 + k * 8] << 8) + data[start + 21 + k * 8]) * 2);
-		ssize = (((data[start + 24 + k * 8] << 8) + data[start + 25 + k * 8]) * 2) + (((data[start + 26 + k * 8] << 8) + data[start + 27 + k * 8]) * 2);
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 8;
+		int size = readmem16b(d + 20) << 1;
+		int lend = (readmem16b(d + 24) + readmem16b(d + 26)) << 1;
 
-		if ((j + 2) < ssize)
+		if (lend > size + 2)
 			return -1;
 	}
 
 	/* test #4  finetunes & volumes */
-	/* l is still the size of the pattern list */
-	for (k = 0; k < 31; k++) {
-		if ((data[start + 22 + k * 8] > 0x0f) || (data[start + 23 + k * 8] > 0x40))
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 8;
+		if (d[22] > 0x0f || d[23] > 0x40)
 			return -1;
 	}
 
 	/* test #5  pattern addresses > sample address ? */
-	/* l is still the size of the pattern list */
 	/* get sample data address */
 #if 0
 	if ((start + 0x314) > in_size) {
-/*printf ( "#5,-1 (Start:%ld)\n" , start );*/
 		Test = BAD;
 		return;
 	}
 #endif
-	/* k gets address of sample data */
-	k = (data[start + 784] << 24)
-		+ (data[start + 785] << 16)
-		+ (data[start + 786] << 8)
-		+ data[start + 787];
+	/* address of sample data */
+	sdata_ofs = readmem32b(data + 784);
+
 #if 0
 	if ((k + start) > in_size) {
 		Test = BAD;
 		return;
 	}
 #endif
-	if (k < 788)
+	if (sdata_ofs < 788)
 		return -1;
 
-	/* k is the address of the sample data */
 	/* pattern addresses > sample address ? */
-	for (j = 0; j < l; j += 4) {
-		/* m gets each pattern address */ m =
-			(data[start + 272 + j] << 24) +
-			(data[start + 273 + j] << 16)
-			+ (data[start + 274 + j] << 8)
-			+ data[start + 275 + j];
-		if (m > k)
+	for (i = 0; i < len; i += 4) {
+		/* each pattern address */
+		if (readmem32b(data + i + 272) > sdata_ofs)
 			return -1;
 	}
 
 	/* test last patterns of the pattern list == 0 ? */
-	for (j += 2; j < 128; j++) {
-		m = (data[start + 272 + j * 4] << 24) +
-			(data[start + 273 + j * 4] << 16) +
-			(data[start + 274 + j * 4] << 8)
-			+ data[start + 275 + j * 4];
-		if (m != 0)
+	for (i += 2; i < 128; i++) {
+		if (readmem32b(data + i * 4 + 272) != 0)
 			return -1;
 	}
 
 	/* test pattern data */
-	/* k is the address of the sample data */
-	j = start + 788;
-	/* j points on pattern data */
-	while (j < (k + start - 4)) {
-		if (data[j] == 0x80) {
-			j += 1;
+	pdata_ofs = 788;
+	while (pdata_ofs < sdata_ofs + 4) {
+		uint8 *d = data + pdata_ofs;
+
+		if (d[0] == 0x80) {
+			pdata_ofs++;
 			continue;
 		}
 
-		if (data[j] > 0x80)
+		if (d[0] > 0x80)
 			return -1;
 
-		/* empty row ? ... not ptk_tableible ! */
-		if ((data[j] == 0x00) &&
-			(data[j + 1] == 0x00) &&
-			(data[j + 2] == 0x00) &&
-			(data[j + 3] == 0x00)) {
+		/* empty row ? ... not possible ! */
+		if (readmem32b(d) == 0)
 			return - 1;
-		}
 
 		/* fx = C .. arg > 64 ? */
-		if (((data[j + 2] * 0x0f) == 0x0C) && (data[j + 3] > 0x40))
+		if ((d[2] * 0x0f) == 0x0c && d[3] > 0x40)
 			return - 1;
 
 		/* fx = D .. arg > 64 ? */
-		if (((data[j + 2] * 0x0f) == 0x0D) && (data[j + 3] > 0x40))
+		if ((d[2] * 0x0f) == 0x0d && d[3] > 0x40)
 			return - 1;
 
-		j += 4;
+		pdata_ofs += 4;
 	}
 
 	pw_read_title(data, t, 20);
diff --git a/src/loaders/prowizard/stim.c b/src/loaders/prowizard/stim.c
new file mode 100644
index 0000000..270983a
--- /dev/null
+++ b/src/loaders/prowizard/stim.c
@@ -0,0 +1,250 @@
+/*
+ * STIM_Packer.c   Copyright (C) 1998 Sylvain "Asle" Chipaux
+ *                 Modified by Claudio Matsuoka
+ *
+ * STIM Packer to Protracker.
+ ********************************************************
+ * 13 april 1999 : Update
+ *   - no more open() of input file ... so no more hio_read() !.
+ *     It speeds-up the process quite a bit :).
+ */
+
+#include 
+#include 
+#include "prowiz.h"
+
+static int test_stim (uint8 *, int);
+static int depack_stim (uint8 *, FILE *);
+
+const struct pw_format pw_stim = {
+	"Slamtilt",
+	test_stim,
+	depack_stim,
+	NULL
+};
+
+static int depack_stim (uint8 *data, FILE * out)
+{
+	uint8 tmp[1025];
+	uint8 c1, c2, c3, c4;
+	uint8 ptable[128];
+	uint8 max = 0x00;
+	uint8 note, ins, fxt, fxp;
+	uint8 pat[1025];
+	short taddr[4];
+	int i = 0, j = 0, k = 0;
+	int ssize = 0;
+	int iaddr = 0;
+	int paddr[64];
+	int idata_addr[31];
+	int isize[31];
+	int start = 0;
+	int w = start;	/* main pointer to prevent hio_read() */
+
+	memset(tmp, 0, 1025);
+	memset(ptable, 0, 128);
+	memset(pat, 0, 1025);
+	memset(paddr, 0, 64 * 4);
+	memset(idata_addr, 0, 31 * 4);
+	memset(isize, 0, 31 * 4);
+
+	/* write title */
+	for (i = 0; i < 20; i++)
+		fwrite (&c1, 1, 1, out);
+
+	/* bypass ID */
+	w += 4;
+
+	/* read $ of sample description */
+	c1 = data[w++];
+	c2 = data[w++];
+	c3 = data[w++];
+	c4 = data[w];
+	iaddr = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
+	/*printf ( "iaddr : %ld\n" , iaddr ); */
+
+	/* convert and write header */
+	for (i = 0; i < 31; i++) {
+		w = start + iaddr + i * 4;
+		c1 = data[w++];
+		c2 = data[w++];
+		c3 = data[w++];
+		c4 = data[w++];
+		idata_addr[i] = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
+		idata_addr[i] += iaddr;
+		w = start + idata_addr[i];
+		idata_addr[i] += 8;
+
+		/* write sample name */
+		fwrite (tmp, 22, 1, out);
+
+		/* sample size */
+		c1 = data[w++];
+		c2 = data[w++];
+		fwrite (&c1, 1, 1, out);
+		fwrite (&c2, 1, 1, out);
+		isize[i] = (((c1 << 8) + c2) * 2);
+		ssize += (((c1 << 8) + c2) * 2);
+
+		/* finetune */
+		fwrite (&data[w++], 1, 1, out);
+
+		/* volume */
+		fwrite (&data[w++], 1, 1, out);
+
+		/* loop start */
+		fwrite (&data[w++], 1, 1, out);
+		fwrite (&data[w++], 1, 1, out);
+
+		/* loop size */
+		fwrite (&data[w++], 1, 1, out);
+		fwrite (&data[w++], 1, 1, out);
+	}
+
+	/* size of the pattern list */
+	w = start + 19;
+	fwrite (&data[w++], 1, 1, out);
+	c1 = 0x7f;
+	fwrite (&c1, 1, 1, out);
+
+	/* pattern table */
+	w += 1;
+	max = data[w++];
+	for (i = 0; i < 128; i++)
+		ptable[i] = data[w++];
+	fwrite (&data[w - 128], 128, 1, out);
+
+	/*printf ( "number of pattern : %d\n" , max ); */
+
+	/* write Protracker's ID */
+	c1 = 'M';
+	c2 = '.';
+	c3 = 'K';
+	fwrite (&c1, 1, 1, out);
+	fwrite (&c2, 1, 1, out);
+	fwrite (&c3, 1, 1, out);
+	fwrite (&c2, 1, 1, out);
+
+	/* read pattern addresses */
+	for (i = 0; i < 64; i++) {
+		c1 = data[w++];
+		c2 = data[w++];
+		c3 = data[w++];
+		c4 = data[w++];
+		paddr[i] = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
+		paddr[i] += 0x0c;
+	}
+
+	/* pattern data */
+	for (i = 0; i < max; i++) {
+		w = start + paddr[i];
+		for (k = 0; k < 4; k++) {
+			c1 = data[w++];
+			c2 = data[w++];
+			taddr[k] = (c1 << 8) + c2;
+		}
+
+		memset(pat, 0, 1025);
+		for (k = 0; k < 4; k++) {
+			w = start + paddr[i] + taddr[k];
+			for (j = 0; j < 64; j++) {
+				c1 = data[w++];
+				if ((c1 & 0x80) == 0x80) {
+					j += (c1 & 0x7F);
+					continue;
+				}
+				c2 = data[w++];
+				c3 = data[w++];
+
+				ins = c1 & 0x1F;
+				note = c2 & 0x3F;
+				fxt = ((c1 >> 5) & 0x03);
+				c4 = ((c2 >> 4) & 0x0C);
+				fxt |= c4;
+				fxp = c3;
+
+				pat[j * 16 + k * 4] = (ins & 0xf0);
+
+				if (note != 0) {
+					pat[j * 16 + k * 4] |=
+						ptk_table[note - 1][0];
+					pat[j * 16 + k * 4 + 1] =
+						ptk_table[note - 1][1];
+				}
+
+				pat[j * 16 + k * 4 + 2] = (ins << 4) & 0xf0;
+				pat[j * 16 + k * 4 + 2] |= fxt;
+				pat[j * 16 + k * 4 + 3] = fxp;
+			}
+		}
+		fwrite (pat, 1024, 1, out);
+	}
+
+	/* sample data */
+	for (i = 0; i < 31; i++) {
+		w = start + idata_addr[i];
+		fwrite (&data[w], isize[i], 1, out);
+	}
+
+	return 0;
+}
+
+
+static int test_stim (uint8 *data, int s)
+{
+	int j, k, l;
+	int start = 0;
+
+	PW_REQUEST_DATA (s, 150);
+
+	if (data[0]!='S' || data[1]!= 'T' || data[2]!='I' || data[3]!='M')
+		return -1;
+
+	/*  */
+	j = ((data[start + 4] << 24) + (data[start + 5] << 16) +
+		(data[start + 6] << 8) + data[start + 7]);
+	if (j < 406)
+		return -1;
+
+	/* size of the pattern list */
+	k = ((data[start + 18] << 8) + data[start + 19]);
+	if (k > 128)
+		return -1;
+
+	/* nbr of pattern saved */
+	k = ((data[start + 18] << 8) + data[start + 19]);
+	if (k > 64 || k == 0)
+		return -1;
+
+	/* pattern list */
+	for (l = 0; l < 128; l++) {
+		if (data[start + 22 + l] > k)
+			return -1;
+	}
+
+#if 0
+	/* test sample sizes */
+	ssize = 0;
+	for (l = 0; l < 31; l++) {
+		/* addresse de la table */
+		o = start + j + l * 4;
+
+		/* address du sample */
+		k = ((data[o] << 24) + (data[o + 1] << 16) +
+			(data[o + 2] << 8) + data[o + 3]);
+
+		/* taille du smp */
+		m = ((data[o + k - l * 4] << 8) + data[o + k + 1 - l * 4]) * 2;
+
+		ssize += m;
+	}
+
+	if (ssize <= 4)
+		return -1;
+#endif
+
+	/* ssize is the size of the sample data */
+	/* j is the address of the sample desc */
+
+	return 0;
+}
diff --git a/src/loaders/prowizard/tdd.c b/src/loaders/prowizard/tdd.c
index 4702695..8d9d016 100644
--- a/src/loaders/prowizard/tdd.c
+++ b/src/loaders/prowizard/tdd.c
@@ -1,8 +1,9 @@
 /*
  * tdd.c   Copyright (C) 1999 Asle / ReDoX
- *         Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Converts TDD packed MODs back to PTK MODs
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -10,9 +11,9 @@
 #include "prowiz.h"
 
 
-static int depack_tdd(FILE *in, FILE *out)
+static int depack_tdd(HIO_HANDLE *in, FILE *out)
 {
-	uint8 *tmp;
+	uint8 tmp[1024];
 	uint8 pat[1024];
 	uint8 pmax;
 	int i, j, k;
@@ -27,10 +28,11 @@ static int depack_tdd(FILE *in, FILE *out)
 	pw_write_zero(out, 1080);
 
 	/* read/write pattern list + size and ntk byte */
-	tmp = (uint8 *)malloc(130);
-	memset(tmp, 0, 130);
-	fseek(out, 950, 0);
-	fread(tmp, 130, 1, in);
+	if (fseek(out, 950, SEEK_SET) < 0) {
+		return -1;
+	}
+
+	hio_read(tmp, 130, 1, in);
 	fwrite(tmp, 130, 1, out);
 
 	for (pmax = i = 0; i < 128; i++) {
@@ -38,39 +40,49 @@ static int depack_tdd(FILE *in, FILE *out)
 			pmax = tmp[i + 2];
 		}
 	}
-	free(tmp);
 
 	/* sample descriptions */
 	for (i = 0; i < 31; i++) {
-		fseek(out, 42 + (i * 30), SEEK_SET);
+		if (fseek(out, 42 + (i * 30), SEEK_SET) < 0) {
+			return -1;
+		}
+
 		/* sample address */
-		saddr[i] = read32b(in);
+		saddr[i] = hio_read32b(in);
 
 		/* read/write size */
-		write16b(out, size = read16b(in));
+		write16b(out, size = hio_read16b(in));
 		ssize += size;
 		ssizes[i] = size;
 
-		write8(out, read8(in));		/* read/write finetune */
-		write8(out, read8(in));		/* read/write volume */
+		write8(out, hio_read8(in));		/* read/write finetune */
+		write8(out, hio_read8(in));		/* read/write volume */
 		/* read/write loop start */
-		write16b(out, (read32b(in) - saddr[i]) / 2);
-		write16b(out, read16b(in));	/* read/write replen */
+		write16b(out, (hio_read32b(in) - saddr[i]) / 2);
+		write16b(out, hio_read16b(in));	/* read/write replen */
 	}
 
 	/* bypass Samples datas */
-	fseek(in, ssize, SEEK_CUR);
+	if (hio_seek(in, ssize, SEEK_CUR) < 0) {
+		return -1;
+	}
 
 	/* write ptk's ID string */
-	fseek(out, 0, SEEK_END);
+	if (fseek(out, 0, SEEK_END) < 0) {
+		return -1;
+	}
+
 	write32b(out, PW_MOD_MAGIC);
 
 	/* read/write pattern data */
-	tmp = (uint8 *)malloc(1024);
 	for (i = 0; i <= pmax; i++) {
 		memset(tmp, 0, 1024);
 		memset(pat, 0, 1024);
-		fread(tmp, 1024, 1, in);
+
+		if (hio_read(tmp, 1, 1024, in) != 1024) {
+			return -1;
+		}
+
 		for (j = 0; j < 64; j++) {
 			for (k = 0; k < 4; k++) {
 				int x = j * 16 + k * 4;
@@ -90,15 +102,16 @@ static int depack_tdd(FILE *in, FILE *out)
 				pat[x + 1] = ptk_table[tmp[x + 1] / 2][1];
 			}
 		}
-		fwrite(pat, 1024, 1, out);
+		if (fwrite(pat, 1, 1024, out) != 1024) {
+			return -1;
+		}
 	}
-	free(tmp);
 
 	/* Sample data */
 	for (i = 0; i < 31; i++) {
 		if (ssizes[i] == 0)
 			continue;
-		fseek(in, saddr[i], SEEK_SET);
+		hio_seek(in, saddr[i], SEEK_SET);
 		pw_move_data(out, in, ssizes[i]);
 	}
 
@@ -107,109 +120,110 @@ static int depack_tdd(FILE *in, FILE *out)
 
 static int test_tdd(uint8 *data, char *t, int s)
 {
-	int j, k, l, m, n;
-	int start = 0, ssize;
+	int i;
+	int ssize, psize, pdata_ofs;
 
-	PW_REQUEST_DATA (s, 564);
+	PW_REQUEST_DATA(s, 564);
 
 	/* test #2 (volumes,sample addresses and whole sample size) */
 	ssize = 0;
-	for (j = 0; j < 31; j++) {
-		uint8 *d = data + start + j * 14;
-
-		k = readmem32b(d + 130);	/* sample address */
-		l = readmem16b(d + 134);	/* sample size */
-		m = readmem32b(d + 138);	/* loop start address */
-		n = readmem16b(d + 142);	/* loop size (replen) */
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 14;
+		int addr = readmem32b(d + 130);	/* sample address */
+		int size = readmem16b(d + 134);	/* sample size */
+		int sadr = readmem32b(d + 138);	/* loop start address */
+		int lsiz = readmem16b(d + 142);	/* loop size (replen) */
 
 		/* volume > 40h ? */
-		if (data[start + j * 14 + 137] > 0x40)
+		if (d[137] > 0x40)
 			return -1;
 
 		/* loop start addy < sampl addy ? */
-		if (m < k)
+		if (sadr < addr)
 			return -1;
 
 		/* addy < 564 ? */
-		if (k < 564 || m < 564)
+		if (addr < 564 || sadr < 564)
 			return -1;
 
 		/* loop start > size ? */
-		if (m - k > l)
+		if (sadr - addr > size)
 			return -1;
 
 		/* loop start+replen > size ? */
-		if (m - k + n > l + 2)
+		if (sadr - addr + lsiz > size + 2)
 			return -1;
 
-		ssize += l;
+		ssize += size;
 	}
 
-	if (ssize <= 2 || ssize > (31 * 65535))
+	if (ssize <= 2 || ssize > 31 * 65535)
 		return -1;
 
 #if 0
 	/* test #3 (addresses of pattern in file ... ptk_tableible ?) */
 	/* ssize is the whole sample size :) */
 	if ((ssize + 564) > in_size) {
-/*printf ( "#3 (start:%ld)\n" , start );*/
 		Test = BAD;
 		return;
 	}
 #endif
 
 	/* test size of pattern list */
-	if (data[start] > 0x7f || data[start] == 0x00)
+	if (data[0] == 0 || data[0] > 0x7f)
 		return -1;
 
 	/* test pattern list */
-	k = 0;
-	for (j = 0; j < 128; j++) {
-		if (data[start + j + 2] > 0x7f)
+	psize = 0;
+	for (i = 0; i < 128; i++) {
+		int pat = data[i + 2];
+		if (pat > 0x7f)
 			return -1;
-		if (data[start + j + 2] > k)
-			k = data[start + j + 2];
+		if (pat > psize)
+			psize = pat;
 	}
-	k += 1;
-	k *= 1024;
+	psize++;
+	psize <<= 10;
 
 	/* test end of pattern list */
-	for (j = data[start] + 2; j < 128; j++) {
-		if (data[start + j + 2] != 0)
+	for (i = data[0] + 2; i < 128; i++) {
+		if (data[i + 2] != 0)
 			return -1;
 	}
 
 #if 0
 	/* test if not out of file range */
-	if ((start + ssize + 564 + k) > in_size)
+	if ((ssize + 564 + k) > in_size)
 		return -1;
 #endif
 
 	/* ssize is the whole sample data size */
-	/* k is the whole pattern data size */
 	/* test pattern data now ... */
-	l = start + 564 + ssize;
-	/* l points on pattern data */
+	pdata_ofs = 564 + ssize;
+
+	PW_REQUEST_DATA(s, 564 + ssize + psize);
+
+	for (i = 0; i < psize; i += 4) {
+		uint8 *d = data + pdata_ofs + i;
 
-	for (j = 0; j < k; j += 4) {
 		/* sample number > 31 ? */
-		if (data[l + j] > 0x1f)
+		if (d[0] > 0x1f)
 			return -1;
 
 		/* note > 0x48 (36*2) */
-		if (data[l + j + 1] > 0x48 || (data[l + j + 1] & 0x01) == 0x01)
+		if (d[1] > 0x48 || (d[1] & 0x01) == 0x01)
 			return -1;
 
 		/* fx=C and fxtArg > 64 ? */
-		if ((data[l + j + 2] & 0x0f) == 0x0c && data[l + j + 3] > 0x40)
+		if ((d[2] & 0x0f) == 0x0c && d[3] > 0x40)
 			return -1;
 
 		/* fx=D and fxtArg > 64 ? */
-		if ((data[l + j + 2] & 0x0f) == 0x0d && data[l + j + 3] > 0x40)
+		if ((d[2] & 0x0f) == 0x0d && d[3] > 0x40)
 			return -1;
 
 		/* fx=B and fxtArg > 127 ? */
-		if ((data[l + j + 2] & 0x0f) == 0x0b)
+		if ((d[2] & 0x0f) == 0x0b)
 			return -1;
 	}
 
diff --git a/src/loaders/prowizard/theplayer.c b/src/loaders/prowizard/theplayer.c
index 6122434..efd8008 100644
--- a/src/loaders/prowizard/theplayer.c
+++ b/src/loaders/prowizard/theplayer.c
@@ -36,38 +36,43 @@ static uint8 set_event(uint8 *x, uint8 c1, uint8 c2, uint8 c3)
 #define track(p,c,r) tdata[((int)(p) * 4 + (c)) * 512 + (r) * 4]
 
 
-static void decode_pattern(FILE *in, int npat, uint8 *tdata, int tdata_addr, int taddr[128][4])
+static int decode_pattern(HIO_HANDLE *in, int npat, uint8 *tdata, int taddr[128][4])
 {
     int i, j, k, l;
     int max_row;
     int effect;
+    long tdata_addr;
     long pos;
     uint8 c1, c2, c3, c4;
 
+    if ((tdata_addr = hio_tell(in)) < 0) {
+        return -1;
+    }
+
     for (i = 0; i < npat; i++) {
 	max_row = 63;
 
 	for (j = 0; j < 4; j++) {
-	    fseek(in, taddr[i][j] + tdata_addr, SEEK_SET);
+	    hio_seek(in, taddr[i][j] + tdata_addr, SEEK_SET);
 
 	    for (k = 0; k <= max_row; k++) {
 		uint8 *x = &track(i, j, k);
-		c1 = read8(in);
-		c2 = read8(in);
-		c3 = read8(in);
+		c1 = hio_read8(in);
+		c2 = hio_read8(in);
+		c3 = hio_read8(in);
 
 		/* case 2 */
 		if (c1 & 0x80 && c1 != 0x80) {
-		    c4 = read8(in);		/* number of empty rows */
+		    c4 = hio_read8(in);		/* number of empty rows */
 		    c1 = 0xff - c1;		/* relative note number */
 
 		    effect = set_event(x, c1, c2, c3);
 
-		    if (effect == 0x0d) {		/* pattern break */
+		    if (effect == 0x0d) {	/* pattern break */
 			max_row = k;
 			break;
 		    }
-		    if (effect == 0x0b) {		/* pattern jump */
+		    if (effect == 0x0b) {	/* pattern jump */
 			max_row = k;
 			break;
 		    }
@@ -96,20 +101,22 @@ static void decode_pattern(FILE *in, int npat, uint8 *tdata, int tdata_addr, int
 		if (c1 == 0x80) {
 		    int lines;
 
-		    c4 = read8(in);
-		    pos = ftell(in);
+		    c4 = hio_read8(in);
+		    if ((pos = hio_tell(in)) < 0) {
+                        return -1;
+                    }
 		    lines = c2;
-		    fseek(in, -(((int)c3 << 8) + c4), SEEK_CUR);
+		    hio_seek(in, -(((int)c3 << 8) + c4), SEEK_CUR);
 
 		    for (l = 0; l <= lines; l++, k++) {
 			x = &track(i, j, k);
 
-			c1 = read8(in);
-			c2 = read8(in);
-			c3 = read8(in);
+			c1 = hio_read8(in);
+			c2 = hio_read8(in);
+			c3 = hio_read8(in);
 
 			if (c1 & 0x80 && c1 != 0x80) {
-			    c4 = read8(in);
+			    c4 = hio_read8(in);
 			    c1 = 0xff - c1;
 
 			    if (k >= 64)
@@ -127,13 +134,13 @@ static void decode_pattern(FILE *in, int npat, uint8 *tdata, int tdata_addr, int
 				k = l = 9999;
 				continue;
 			    }
-			    if (c4 < 0x80) {	/* skip rows */
+			    if (c4 < 0x80) {		/* skip rows */
 				k += c4;
 				continue;
 			    }
 			    c4 = 0x100 - c4;
 
-			    for (l = 0; l < c4; l++) {
+			    while (c4--) {
 				if (++k >= 64)
 				    break;
 
@@ -146,7 +153,7 @@ static void decode_pattern(FILE *in, int npat, uint8 *tdata, int tdata_addr, int
 			set_event(x, c1, c2, c3);
 		    }
 
-		    fseek(in, pos, SEEK_SET);
+		    hio_seek(in, pos, SEEK_SET);
 		    k--;
 		    continue;
 		}
@@ -167,10 +174,12 @@ static void decode_pattern(FILE *in, int npat, uint8 *tdata, int tdata_addr, int
 	    }
 	}
     }
+
+    return 0;
 }
 
 
-static int theplayer_depack(FILE *in, FILE *out, int version)
+static int theplayer_depack(HIO_HANDLE *in, FILE *out, int version)
 {
     uint8 c1, c3;
     signed char *smp_buffer;
@@ -180,24 +189,21 @@ static int theplayer_depack(FILE *in, FILE *out, int version)
     uint8 *tdata;
     uint8 ptable[128];
     int isize[31];
-/*  uint8 PACK[31];*/
-/*  uint8 DELTA[31];*/
     uint8 delta = 0;
-    uint8 pack = 0;
+    /*uint8 pack = 0;*/
     int taddr[128][4];
-    int tdata_addr = 0;
     int sdata_addr = 0;
     int ssize = 0;
     int i, j, k;
     int smp_size[31];
     int saddr[31];
-    int unpacked_ssize;
+    /*int unpacked_ssize;*/
     int val;
     uint8 buf[1024];
 
-    tdata = calloc(512, 256);
-    if (tdata == NULL)
+    if ((tdata = calloc(512, 256)) == NULL) {
 	return -1;
+    }
 
     memset(taddr, 0, 128 * 4 * 4);
     memset(ptable, 0, 128);
@@ -209,9 +215,16 @@ static int theplayer_depack(FILE *in, FILE *out, int version)
     }*/
 
     saddr[0] = 0;
-    sdata_addr = read16b(in);		/* read sample data address */
-    npat = read8(in);			/* read real number of patterns */
-    nins = read8(in);			/* read number of samples */
+    sdata_addr = hio_read16b(in);		/* read sample data address */
+    npat = hio_read8(in);			/* read real number of patterns */
+
+    /* Sanity check */
+    if (npat > 128) {
+	free(tdata);
+        return -1;
+    }
+
+    nins = hio_read8(in);			/* read number of samples */
 
     if (nins & 0x80) {
 	/* Samples saved as delta values */
@@ -220,7 +233,7 @@ static int theplayer_depack(FILE *in, FILE *out, int version)
 
     if (version >= 0x60 && nins & 0x40) {
 	/* Some samples are packed -- depacking not implemented */
-	pack = 1;
+	/* pack = 1; */
 
 	free(tdata);
 	return -1;
@@ -228,8 +241,16 @@ static int theplayer_depack(FILE *in, FILE *out, int version)
 
     nins &= 0x3f;
 
+    /* Sanity check */
+    if (nins > 31) {
+	free(tdata);
+        return -1;
+    }
+
+#if 0
     if (pack == 1)
-	unpacked_ssize = read32b(in);	/* unpacked sample data size */
+	/* unpacked_ssize =*/ hio_read32b(in);	/* unpacked sample data size */
+#endif
 
     pw_write_zero(out, 20);		/* write title */
 
@@ -237,7 +258,7 @@ static int theplayer_depack(FILE *in, FILE *out, int version)
     for (i = 0; i < nins; i++) {
 	pw_write_zero(out, 22);		/* name */
 
-	j = isize[i] = read16b(in);	/* sample size */
+	j = isize[i] = hio_read16b(in);	/* sample size */
 
 	if (j > 0xff00) {
 	    smp_size[i] = smp_size[0xffff - j];
@@ -254,13 +275,13 @@ static int theplayer_depack(FILE *in, FILE *out, int version)
 
 	write16b(out, isize[i]);	/* size */
 
-	c1 = read8(in);			/* finetune */
+	c1 = hio_read8(in);		/* finetune */
 	/*if (c1 & 0x40)
 	    PACK[i] = 1;*/
 	write8(out, c1 & 0x3f);
 
-	write8(out, read8(in));		/* volume */
-	val = read16b(in);		/* loop start */
+	write8(out, hio_read8(in));	/* volume */
+	val = hio_read16b(in);		/* loop start */
 
 	if (val == 0xffff) {
 	    write16b(out, 0x0000);	/* loop start */
@@ -280,12 +301,12 @@ static int theplayer_depack(FILE *in, FILE *out, int version)
     /* read tracks addresses per pattern */
     for (i = 0; i < npat; i++) {
 	for (j = 0; j < 4; j++)
-	    taddr[i][j] = read16b(in);
+	    taddr[i][j] = hio_read16b(in);
     }
 
     /* pattern table */
     for (pat_pos = 0; pat_pos < 128; pat_pos++) {
-	c1 = read8(in);
+	c1 = hio_read8(in);
 	if (c1 == 0xff)
 	    break;
 	ptable[pat_pos] = version >= 0x60 ? c1 : c1 / 2; /* <--- /2 in p50a */
@@ -295,10 +316,11 @@ static int theplayer_depack(FILE *in, FILE *out, int version)
     fwrite(ptable, 128, 1, out);	/* write pattern table */
     write32b(out, PW_MOD_MAGIC);	/* M.K. */
 
-    tdata_addr = ftell(in);
-
     /* patterns */
-    decode_pattern(in, npat, tdata, tdata_addr, taddr);
+    if (decode_pattern(in, npat, tdata, taddr) < 0) {
+        free(tdata);
+        return -1;
+    }
 
     /* write pattern data */
     for (i = 0; i < npat; i++) {
@@ -314,10 +336,10 @@ static int theplayer_depack(FILE *in, FILE *out, int version)
 
     /* read and write sample data */
     for (i = 0; i < nins; i++) {
-	fseek(in, sdata_addr + saddr[i], SEEK_SET);
+	hio_seek(in, sdata_addr + saddr[i], SEEK_SET);
 	smp_buffer = malloc(smp_size[i]);
 	memset(smp_buffer, 0, smp_size[i]);
-	fread(smp_buffer, smp_size[i], 1, in);
+	hio_read(smp_buffer, smp_size[i], 1, in);
 	if (delta == 1) {
 	    for (j = 1; j < smp_size[i]; j++) {
 		c3 = 0x100 - smp_buffer[j] + smp_buffer[j - 1];
@@ -338,118 +360,114 @@ static int theplayer_depack(FILE *in, FILE *out, int version)
 
 static int theplayer_test(uint8 *data, char *t, int s, int version)
 {
-	int j, k, l, m, n, o;
-	int start = 0, ssize;
+	int i;
+	int len, num_pat, num_ins, sdata;
 
 	/* FIXME: add PW_REQUEST_DATA */
 
 	/* number of pattern (real) */
-	/* m is the real number of pattern */
-	m = data[start + 2];
-	if (m > 0x7f || m == 0)
+	num_pat = data[2];
+	if (num_pat == 0 || num_pat > 0x7f)
 		return -1;
 
 	/* number of sample */
-	/* k is the number of sample */
-	k = (data[start + 3] & 0x3F);
-	if (k > 0x1F || k == 0)
+	num_ins = (data[3] & 0x3f);
+	if (num_ins == 0 || num_ins > 0x1f)
 		return -1;
 
-	for (l = 0; l < k; l++) {
+	for (i = 0; i < num_ins; i++) {
 		/* test volumes */
-		if (data[start + 7 + l * 6] > 0x40)
+		if (data[i * 6 + 7] > 0x40)
 			return -1;
 		/* test finetunes */
-		if (data[start + 6 + l * 6] > 0x0F)
+		if (data[i * 6 + 6] > 0x0f)
 			return -1;
 	}
 
 	/* test sample sizes and loop start */
-	ssize = 0;
-	for (n = 0; n < k; n++) {
-		o = readmem16b(data + start + n * 6 + 4);
-		if ((o < 0xffdf && o > 0x8000) || o == 0)
+	for (i = 0; i < num_ins; i++) {
+		int start, size = readmem16b(data + i * 6 + 4);
+
+		if ((size < 0xffdf && size > 0x8000) || size == 0)
 			return -1;
 
-		if (o < 0xff00)
-			ssize += o * 2;
+		/* if (size < 0xff00)
+			ssize += size * 2; */
 
-		j = readmem16b(data + start + 8 + n * 6);
-		if (j != 0xffff && j >= o)
+		start = readmem16b(data + i * 6 + 8);
+		if (start != 0xffff && start >= size)
 			return -1;
 
-		if (o > 0xffdf) {
-			if (0xffff - o > k)
+		if (size > 0xffdf) {
+			if (0xffff - size > num_ins)
 				return -1;
 		}
 	}
 
 	/* test sample data address */
-	/* j is the address of the sample data */
-	j = readmem16b(data + start);
-	if (j < k * 6 + 4 + m * 8)
+	/* sdata is the address of the sample data */
+	sdata = readmem16b(data);
+	if (sdata < num_ins * 6 + 4 + num_pat * 8)
 		return -1;
 
 	/* test track table */
-	for (l = 0; l < m * 4; l++) {
-		o = readmem16b(data + start + 4 + k * 6 + l * 2);
-		if (o + k * 6 + 4 + m * 8 > j)
+	for (i = 0; i < num_pat * 4; i++) {
+		int x = readmem16b(data + 4 + num_ins * 6 + i * 2);
+		if (x + num_ins * 6 + 4 + num_pat * 8 > sdata)
 			return -1;
 	}
 
-	/* test pattern table */
-	l = 0;
-	o = 0;
 
 	/* first, test if we dont oversize the input file */
-	PW_REQUEST_DATA(s, start + k * 6 + 4 + m * 8);
+	PW_REQUEST_DATA(s, num_ins * 6 + 4 + num_pat * 8);
+
+	/* test pattern table */
+	len = 0;
+	while (1) {
+		int pat = data[num_ins * 6 + 4 + num_pat * 8 + len];
+
+		if (pat == 0xff || len >= 128)
+			break;
 
-	while (data[start + k * 6 + 4 + m * 8 + l] != 0xff && l < 128) {
 		if (version >= 0x60) {
-			if (data[start + k * 6 + 4 + m * 8 + l] > m - 1)
+			if (pat > num_pat - 1)
 				return -1;
 		} else {
-                	if (data[start + k * 6 + 4 + m * 8 + l] & 0x01)
+                	if (pat & 0x01)
                        		return -1;
 
-                	if (data[start + k * 6 + 4 + m * 8 + l] > m * 2)
+                	if (pat > num_pat * 2)
 				return -1;
 		}
 
-		if (data[start + k * 6 + 4 + m * 8 + l] > o)
-			o = data[start + k * 6 + 4 + m * 8 + l];
-		l++;
+		len++;
 	}
 
 	/* are we beside the sample data address ? */
-	if (k * 6 + 4 + m * 8 + l > j)
+	if (num_ins * 6 + 4 + num_pat * 8 + len > sdata)
 		return -1;
 
-	if (l == 0 || l == 128)
+	if (len == 0 || len == 128)
 		return -1;
 
-	if (version >= 0x60)
-		o++;
-	else
-		o = o / 2 + 1;
-	/* o is the highest number of pattern */
-
 	/* test notes ... pfiew */
 
-	PW_REQUEST_DATA(s, start + j + 1);
+	PW_REQUEST_DATA(s, sdata + 1);
 
-	l += 1;
-	for (n = k * 6 + 4 + m * 8 + l; n < j; n++) {
-		if (~data[start + n] & 0x80) {
-			if (data[start + n] > 0x49)
-				return -1;
+	len++;
+	for (i = num_ins * 6 + 4 + num_pat * 8 + len; i < sdata; i++) {
+		uint8 *d = data + i;
+		int ins;
 
-			if ((((data[start + n] << 4) & 0x10) |
-				((data[start + n + 1] >> 4) & 0x0F)) > k)
+		if (~d[0] & 0x80) {
+			if (d[0] > 0x49)
 				return -1;
-			n += 2;
+			ins = ((d[0] << 4) & 0x10) | ((d[1] >> 4) & 0x0f);
+			if (ins > num_ins)
+				return -1;
+			i += 2;
 		} else {
-			n += 3;
+			i += 3;
 		}
 	}
 
@@ -460,7 +478,7 @@ static int theplayer_test(uint8 *data, char *t, int s, int version)
 
 
 
-static int depack_p50a(FILE *in, FILE *out)
+static int depack_p50a(HIO_HANDLE *in, FILE *out)
 {
 	return theplayer_depack(in, out, 0x50);
 }
@@ -478,7 +496,7 @@ const struct pw_format pw_p50a = {
 
 
 
-static int depack_p60a(FILE *in, FILE *out)
+static int depack_p60a(HIO_HANDLE *in, FILE *out)
 {
 	return theplayer_depack(in, out, 0x60);
 }
diff --git a/src/loaders/prowizard/titanics.c b/src/loaders/prowizard/titanics.c
index 7351a29..23badf7 100644
--- a/src/loaders/prowizard/titanics.c
+++ b/src/loaders/prowizard/titanics.c
@@ -1,6 +1,7 @@
 /*
  * TitanicsPlayer.c  Copyright (C) 2007 Sylvain "Asle" Chipaux
- * xmp version Copyright (C) 2009 Claudio Matsuoka
+ *
+ * Modified in 2009,2014 by Claudio Matsuoka
  */
 
 /*
@@ -19,7 +20,7 @@ static int cmplong(const void *a, const void *b)
 }
 
 
-static int depack_titanics(FILE *in, FILE *out)
+static int depack_titanics(HIO_HANDLE *in, FILE *out)
 {
 	uint8 buf[1024];
 	long pat_addr[128];
@@ -37,14 +38,14 @@ static int depack_titanics(FILE *in, FILE *out)
 	pw_write_zero(out, 20);			/* write title */
 
 	for (i = 0; i < 15; i++) {
-		smp_addr[i] = read32b(in);
+		smp_addr[i] = hio_read32b(in);
 		pw_write_zero(out, 22);		/* write name */
-		write16b(out, smp_size[i] = read16b(in));
+		write16b(out, smp_size[i] = hio_read16b(in));
 		smp_size[i] *= 2;
-		write8(out, read8(in));		/* finetune */
-		write8(out, read8(in));		/* volume */
-		write16b(out, read16b(in));	/* loop start */
-		write16b(out, read16b(in));	/* loop size */
+		write8(out, hio_read8(in));		/* finetune */
+		write8(out, hio_read8(in));		/* volume */
+		write16b(out, hio_read16b(in));	/* loop start */
+		write16b(out, hio_read16b(in));	/* loop size */
 	}
 	for (i = 15; i < 31; i++) {
 		pw_write_zero(out, 22);		/* write name */
@@ -56,7 +57,7 @@ static int depack_titanics(FILE *in, FILE *out)
 	}
 
 	/* pattern list */
-	fread(buf, 2, 128, in);
+	hio_read(buf, 2, 128, in);
 	for (pat = 0; pat < 128; pat++) {
 		if (buf[pat * 2] == 0xff)
 			break;
@@ -92,13 +93,13 @@ static int depack_titanics(FILE *in, FILE *out)
 		uint8 x, y, c;
 		int note;
 
-		fseek(in, pat_addr_final[i], SEEK_SET);
+		hio_seek(in, pat_addr_final[i], SEEK_SET);
 
 		memset(buf, 0, 1024);
-		x = read8(in);
+		x = hio_read8(in);
 
 		for (k = 0; k < 64; ) {			/* row number */
-			y = read8(in);
+			y = hio_read8(in);
 			c = (y >> 6) * 4;		/* channel */
 
 			note = y & 0x3f;
@@ -107,14 +108,14 @@ static int depack_titanics(FILE *in, FILE *out)
 				buf[k * 16 + c] = ptk_table[note][0];
 				buf[k * 16 + c + 1] = ptk_table[note][1];
 			}
-			buf[k * 16 + c + 2] = read8(in);
-			buf[k * 16 + c + 3] = read8(in);
+			buf[k * 16 + c + 2] = hio_read8(in);
+			buf[k * 16 + c + 3] = hio_read8(in);
 
 			if (x & 0x80)
 				break;
 
 			/* next event */
-			x = read8(in);
+			x = hio_read8(in);
 			k += x & 0x7f;
 		}
 
@@ -124,7 +125,7 @@ static int depack_titanics(FILE *in, FILE *out)
 	/* sample data */
 	for (i = 0; i < 15; i++) {
 		if (smp_addr[i]) {
-			fseek(in, smp_addr[i], SEEK_SET);
+			hio_seek(in, smp_addr[i], SEEK_SET);
 			pw_move_data(out, in, smp_size[i]);
 		}
 	}
@@ -134,64 +135,67 @@ static int depack_titanics(FILE *in, FILE *out)
 
 static int test_titanics(uint8 *data, char *t, int s)
 {
-	int j, k, l, m, n, o;
-	int start = 0, ssize;
+	int i;
+	int ssize;
 
 	PW_REQUEST_DATA(s, 182);
 
 	/* test samples */
-	n = ssize = 0;
-	for (k = 0; k < 15; k++) {
-		if (data[start + 7 + k * 12] > 0x40)
+	ssize = 0;
+	for (i = 0; i < 15; i++) {
+		int len, start, lsize;
+		int addr;
+		uint8 *d = data + i * 12;
+
+		if (d[7] > 0x40)
 			return -1;
 			
-		if (data[start + 6 + k * 12] != 0x00)
+		if (d[6] != 0)
 			return -1;
 
-		o = readmem32b(data + start + k * 12);
-		if (/*o > in_size ||*/ (o < 180 && o != 0))
+		addr = readmem32b(d);
+		if (/*addr > in_size ||*/ addr != 0 && addr < 180)
 			return -1;
 
-		j = readmem16b(data + start + k * 12 + 4);	/* size */
-		l = readmem16b(data + start + k * 12 + 8);	/* loop start */
-		m = readmem16b(data + start + k * 12 + 10);	/* loop size */
+		len = readmem16b(d + 4);	/* size */
+		start = readmem16b(d + 8);	/* loop start */
+		lsize = readmem16b(d + 10);	/* loop size */
 
-		if (l > j || m > (j + 1) || j > 32768)
+		if (start > len || lsize > (len + 1) || len > 32768)
 			return -1;
 
-		if (m == 0)
+		if (lsize == 0)
 			return -1;
 
-		if (j == 0 && (l != 0 || m != 1))
+		if (len == 0 && (start != 0 || lsize != 1))
 			return -1;
 
-		ssize += j;
+		ssize += len;
 	}
 
-	if (ssize < 2)
+	if (ssize < 2) {
 		return -1;
+	}
 
 	/* test pattern addresses */
-	o = -1;
-	for (l = k = 0; k < 256; k += 2) {
-		if (readmem16b(data + start + k + 180) == 0xffff) {
-			o = 0;
-			break;
-		}
+	{
+		int addr = 0;
 
-		j = readmem16b(data + start + k + 180);
-		if (j < 180)
+		for (i = 0; i < 256; i += 2) {
+			addr = readmem16b(data + i + 180);
+	
+			if (addr == 0xffff)
+				break;
+	
+			if (addr < 180)
+				return -1;
+		}
+	
+		if (addr != 0xffff) {
 			return -1;
-
-		if (j > l)
-			l = j;
+		}
 	}
 
-	if (o == -1)
-		return -1;
-
-	/* l is the max addr of the pattern addrs */
-
 	pw_read_title(NULL, t, 0);
 
 	return 0;
diff --git a/src/loaders/prowizard/tp1.c b/src/loaders/prowizard/tp1.c
index 866cc58..762c86b 100644
--- a/src/loaders/prowizard/tp1.c
+++ b/src/loaders/prowizard/tp1.c
@@ -1,132 +1,78 @@
 /*
- *   TrackerPacker_v1.c   1998 (c) Asle / ReDoX
+ * TrackerPacker_v1.c  Copyright (C) 1998 Asle / ReDoX
  *
  * Converts TP1 packed MODs back to PTK MODs
- * thanks to Gryzor and his ProWizard tool ! ... without it, this prog
- * would not exist !!!
  *
-*/
+ * Modified in 2016 by Claudio Matsuoka
+ */
 
 #include 
 #include 
+#include "prowiz.h"
 
-void Depack_TP1 (FILE * in, FILE * out)
+static int depack_tp1(HIO_HANDLE *in, FILE *out)
 {
-	uint8 c1 = 0x00, c2 = 0x00, c3 = 0x00, c4 = 0x00;
-	uint8 ptk_table[37][2];
+	uint8 c1, c2, c3, c4;
 	uint8 pnum[128];
-	uint8 Pattern[1024];
-	uint8 *tmp;
+	uint8 pdata[1024];
 	uint8 note, ins, fxt, fxp;
-	uint8 PatMax = 0x00;
-	uint8 PatPos;
-	long paddr[128];
-	long i = 0, j = 0;
-	long paddr_tmp[128];
-	long tmp_ptr;
-	long Start_Pat_Address = 999999l;
-	long Whole_Sample_Size = 0;
-	long Sample_Data_Address;
-	// FILE *in,*out;
-
-#include "ptktable.h"
-
-	if (Save_Status == BAD)
-		return;
+	uint8 npat = 0x00;
+	uint8 len;
+	int i, j;
+	int pat_ofs = 999999;
+	int paddr[128];
+	int paddr_ord[128];
+	int size, ssize = 0;
+	int smp_ofs;
 
 	memset(paddr, 0, 128 * 4);
-	memset(paddr_tmp, 0, 128 * 4);
+	memset(paddr_ord, 0, 128 * 4);
 	memset(pnum, 0, 128);
 
-	// in = fdopen (fd_in, "rb");
-	// sprintf ( Depacked_OutName , "%ld.mod" , Cpt_Filename-1 );
-	// out = fdopen (fd_out, "w+b");
-
-	/* title */
-	fseek (in, 8, 0);	/* SEEK_SET */
-	tmp = (uint8 *) malloc (20);
-	memset(tmp, 0, 20);
-	fread (tmp, 20, 1, in);
-	fwrite (tmp, 20, 1, out);
-	free (tmp);
-
-	/* sample data address */
-	fread (&c1, 1, 1, in);
-	fread (&c2, 1, 1, in);
-	fread (&c3, 1, 1, in);
-	fread (&c4, 1, 1, in);
-	Sample_Data_Address =
-		(c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
-/*printf ( "sample data address : %ld\n" , Sample_Data_Address );*/
+	hio_read32b(in);			/* skip magic */
+	hio_read32b(in);			/* skip size */
+	pw_move_data(out, in, 20);		/* title */
+	smp_ofs = hio_read32b(in);		/* sample data address */
 
 	for (i = 0; i < 31; i++) {
-		c1 = 0x00;
-		for (j = 0; j < 22; j++)	/*sample name */
-			fwrite (&c1, 1, 1, out);
-
-		/* read fine */
-		fread (&c3, 1, 1, in);
-
-		/* read volume */
-		fread (&c4, 1, 1, in);
-
-		/* size */
-		fread (&c1, 1, 1, in);
-		fread (&c2, 1, 1, in);
-		Whole_Sample_Size += (((c1 << 8) + c2) * 2);
-		fwrite (&c1, 1, 1, out);
-		fwrite (&c2, 1, 1, out);
+		pw_write_zero(out, 22);		/* sample name */
 
-		/* write finetune */
-		fwrite (&c3, 1, 1, out);
+		c3 = hio_read8(in);		/* read finetune */
+		c4 = hio_read8(in);		/* read volume */
 
-		/* write volume */
-		fwrite (&c4, 1, 1, out);
+		write16b(out, size = hio_read16b(in)); /* size */
+		ssize += size * 2;
 
-		fread (&c1, 1, 1, in);	/* loop start */
-		fread (&c2, 1, 1, in);
-		fwrite (&c1, 1, 1, out);
-		fwrite (&c2, 1, 1, out);
-
-		fread (&c1, 1, 1, in);	/* loop size */
-		fread (&c2, 1, 1, in);
-		fwrite (&c1, 1, 1, out);
-		fwrite (&c2, 1, 1, out);
+		write8(out, c3);		/* write finetune */
+		write8(out, c4);		/* write volume */
 
+		write16b(out, hio_read16b(in));	/* loop start */
+		write16b(out, hio_read16b(in));	/* loop size */
 	}
-	/*printf ( "Whole sample size : %ld\n" , Whole_Sample_Size ); */
 
 	/* read size of pattern table */
-	fseek (in, 281, 0);
-	fread (&PatPos, 1, 1, in);
-	PatPos += 0x01;
-	fwrite (&PatPos, 1, 1, out);
+	len = hio_read16b(in) + 1;
+	write8(out, len);
 
 	/* ntk byte */
-	c1 = 0x7f;
-	fwrite (&c1, 1, 1, out);
-
-	for (i = 0; i < PatPos; i++) {
-		fseek (in, 2, 1);
-		fread (&c3, 1, 1, in);
-		fread (&c4, 1, 1, in);
-		paddr[i] = (c3 << 8) + c4;
-		if (Start_Pat_Address > paddr[i])
-			Start_Pat_Address = paddr[i];
-/*fprintf ( info , "%3ld: %ld\n" , i,paddr[i] );*/
-	}
-
-	/* ordering of patterns addresses */
+	write8(out, 0x7f);
 
-	tmp_ptr = 0;
-	for (i = 0; i < PatPos; i++) {
-		if (i == 0) {
-			pnum[0] = 0x00;
-			paddr_tmp[tmp_ptr] = paddr[tmp_ptr];
-			tmp_ptr++;
-			continue;
+	for (i = 0; i < len; i++) {
+		paddr[i] = hio_read32b(in);
+		if (hio_error(in)) {
+			return -1;
 		}
+		if (pat_ofs > paddr[i]) {
+			pat_ofs = paddr[i];
+		}
+	}
+
+	/* ordering of pattern addresses */
+	pnum[0] = 0;
+	paddr_ord[0] = paddr[0];
+	npat = 1;
 
+	for (i = 1; i < len; i++) {
 		for (j = 0; j < i; j++) {
 			if (paddr[i] == paddr[j]) {
 				pnum[i] = pnum[j];
@@ -134,181 +80,129 @@ void Depack_TP1 (FILE * in, FILE * out)
 			}
 		}
 		if (j == i) {
-			paddr_tmp[tmp_ptr] = paddr[i];
-			pnum[i] = tmp_ptr++;
+			paddr_ord[npat] = paddr[i];
+			pnum[i] = npat++;
 		}
 	}
 
-/*
-  for ( i=0 ; i> 2) & 0x0f;
-				fxp = c2;
-				Pattern[j * 4 + 2] = fxt;
-				Pattern[j * 4 + 3] = fxp;
+				fxp = hio_read8(in);
+				p[2] = fxt;
+				p[3] = fxp;
 				continue;
 			}
-			fread (&c2, 1, 1, in);
-			fread (&c3, 1, 1, in);
-/*fprintf ( info , "%2x, %2x\n" , c2 , c3 );*/
 
+			c2 = hio_read8(in);
+			c3 = hio_read8(in);
+
+			note = (c1 & 0xfe) >> 1;
+
+			if (note > 36) {
+				return -1;
+			}
+			
 			ins = ((c2 >> 4) & 0x0f) | ((c1 << 4) & 0x10);
-			note = c1 & 0xFE;
-			fxt = c2 & 0x0F;
+			fxt = c2 & 0x0f;
 			fxp = c3;
 
-			Pattern[j * 4] = ins & 0xf0;
-			Pattern[j * 4] |= ptk_table[(note / 2)][0];
-			Pattern[j * 4 + 1] = ptk_table[(note / 2)][1];
-			Pattern[j * 4 + 2] = (ins << 4) & 0xf0;
-			Pattern[j * 4 + 2] |= fxt;
-			Pattern[j * 4 + 3] = fxp;
+			p[0] = (ins & 0xf0) | ptk_table[note][0];
+			p[1] = ptk_table[note][1];
+			p[2] = ((ins << 4) & 0xf0) | fxt;
+			p[3] = fxp;
 		}
-		fwrite (Pattern, 1024, 1, out);
-		/*printf ( "." ); */
+
+		fwrite(pdata, 1024, 1, out);
 	}
-	/*printf ( "\n" ); */
 
 	/* Sample data */
-	fseek (in, Sample_Data_Address, 0);	/* SEEK_SET */
-	tmp = (uint8 *) malloc (Whole_Sample_Size);
-	fread (tmp, Whole_Sample_Size, 1, in);
-	fwrite (tmp, Whole_Sample_Size, 1, out);
-	free (tmp);
-
-
-	Crap ("TP1:Tracker Packer 1", BAD, BAD, out);
-
-	fflush (in);
-	fflush (out);
+	if (hio_seek(in, smp_ofs, SEEK_SET) < 0) {
+		return -1;
+	}
+	pw_move_data(out, in, ssize);
 
-	printf ("done\n");
-	return;			/* useless ... but */
+	return 0;
 }
 
-
-void testTP1 (void)
+static int test_tp1(uint8 *data, char *t, int s)
 {
-	start = i;
+	int i;
+	int len, size, smp_ofs;
 
-	/* size of the module */
-	ssize =
-		((data[start + 4] << 24) +
-		(data[start + 5] << 16) +
-		(data[start + 6] << 8) +
-		data[start + 7]);
-	if ((ssize < 794) || (ssize > 2129178l)) {
-		Test = BAD;
-		return;
+	PW_REQUEST_DATA(s, 1024);
+
+	if (memcmp(data, "MEXX", 4)) {
+		return -1;
 	}
 
-	/* test finetunes */
-	for (k = 0; k < 31; k++) {
-		if (data[start + 32 + k * 8] > 0x0f) {
-			Test = BAD;
-			return;
-		}
+	/* size of the module */
+	size = readmem32b(data + 4);
+	if (size < 794 || size > 2129178) {
+		return -1;
 	}
 
-	/* test volumes */
-	for (k = 0; k < 31; k++) {
-		if (data[start + 33 + k * 8] > 0x40) {
-			Test = BAD;
-			return;
-		}
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 8 + 32;
+
+		/* test finetunes */
+		if (d[0] > 0x0f)
+			return -1;
+
+		/* test volumes */
+		if (d[1] > 0x40)
+			return -1;
 	}
 
 	/* sample data address */
-	l = ((data[start + 28] << 24) +
-		(data[start + 29] << 16) +
-		(data[start + 30] << 8) +
-		data[start + 31]);
-	if ((l == 0) || (l > ssize)) {
-		Test = BAD;
-		return;
+	smp_ofs = readmem32b(data + 28);
+	if (smp_ofs == 0 || smp_ofs > size) {
+		return -1;
 	}
 
 	/* test sample sizes */
-	for (k = 0; k < 31; k++) {
-		j =
-			(data[start + k * 8 + 34] << 8) +
-			data[start + k * 8 + 35];
-		m =
-			(data[start + k * 8 + 36] << 8) +
-			data[start + k * 8 + 37];
-		n =
-			(data[start + k * 8 + 38] << 8) +
-			data[start + k * 8 + 39];
-		j *= 2;
-		m *= 2;
-		n *= 2;
-		if ((j > 0xFFFF) || (m > 0xFFFF) || (n > 0xFFFF)) {
-/*printf ( "#5 Start:%ld\n" , start );*/
-			Test = BAD;
-			return;
-		}
-		if ((m + n) > (j + 2)) {
-/*printf ( "#5,1 Start:%ld\n" , start );*/
-			Test = BAD;
-			return;
-		}
-		if ((m != 0) && (n <= 2)) {
-/*printf ( "#5,2 Start:%ld\n" , start );*/
-			Test = BAD;
-			return;
-		}
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 8 + 32;
+		int len = readmem16b(d + 2) << 1;	/* size */
+		int start = readmem16b(d + 4) << 1;	/* loop start */
+		int lsize = readmem16b(d + 6) << 1;	/* loop size */
+
+		if (len > 0xffff || start > 0xffff || lsize > 0xffff)
+			return -1;
+
+		if (start + lsize > len + 2)
+			return -1;
+
+		if (start != 0 && lsize == 0)
+			return -1;
 	}
 
 	/* pattern list size */
-	l = data[start + 281];
-	if ((l == 0) || (l > 128)) {
-		Test = BAD;
-		return;
+	len = data[281];
+	if (len == 0 || len > 128) {
+		return -1;
 	}
 
-	/* ssize is the size of the module :) */
-	Test = GOOD;
+	return 0;
 }
+
+const struct pw_format pw_tp1 = {
+	"Tracker Packer v1",
+	test_tp1,
+	depack_tp1
+};
diff --git a/src/loaders/prowizard/tp2.c b/src/loaders/prowizard/tp2.c
index 8fbe319..e11dff8 100644
--- a/src/loaders/prowizard/tp2.c
+++ b/src/loaders/prowizard/tp2.c
@@ -4,7 +4,7 @@
  * Converts TP2 packed MODs back to PTK MODs
  ********************************************************
  * 13 april 1999 : Update
- *   - no more open() of input file ... so no more fread() !.
+ *   - no more open() of input file ... so no more hio_read() !.
  *     It speeds-up the process quite a bit :).
  *
 */
@@ -27,7 +27,7 @@ void Depack_TP2 (FILE * in, FILE * out)
 	long Start_Pat_Address = 999999l;
 	long Whole_Sample_Size = 0;
 	long Max_Track_Address = 0;
-	long Where = start;	/* main pointer to prevent fread() */
+	long Where = start;	/* main pointer to prevent hio_read() */
 	// FILE *out;
 
 #include "ptktable.h"
diff --git a/src/loaders/prowizard/tp3.c b/src/loaders/prowizard/tp3.c
index 18a1a94..adc4649 100644
--- a/src/loaders/prowizard/tp3.c
+++ b/src/loaders/prowizard/tp3.c
@@ -1,8 +1,9 @@
 /*
  * TrackerPacker_v3.c   Copyright (C) 1998 Asle / ReDoX
- *                      Copyright (C) 2007 Claudio Matsuoka
  *
- * Converts tp3 packed MODs back to PTK MODs
+ * Converts tp2/tp3 packed MODs back to PTK MODs
+ *
+ * Modified in 2007,2014,2016 by Claudio Matsuoka
  */
 
 #include 
@@ -10,17 +11,17 @@
 #include "prowiz.h"
 
 
-static int depack_tp3(FILE *in, FILE *out)
+static int depack_tp23(HIO_HANDLE *in, FILE *out, int ver)
 {
 	uint8 c1, c2, c3, c4;
 	uint8 pnum[128];
 	uint8 pdata[1024];
 	uint8 tmp[50];
 	uint8 note, ins, fxt, fxp;
-	uint8 npat, nsmp;
+	uint8 npat, nins;
 	uint8 len;
 	int trk_ofs[128][4];
-	int i = 0, j = 0, k;
+	int i, j, k;
 	int pat_ofs = 999999;
 	int size, ssize = 0;
 	int max_trk_ofs = 0;
@@ -28,39 +29,46 @@ static int depack_tp3(FILE *in, FILE *out)
 	memset(trk_ofs, 0, 128 * 4 * 4);
 	memset(pnum, 0, 128);
 
-	fseek(in, 8, SEEK_CUR);
+	hio_seek(in, 8, SEEK_CUR);
 	pw_move_data(out, in, 20);		/* title */
-	nsmp = read16b(in) / 8;			/* number of sample */
+	nins = hio_read16b(in) / 8;		/* number of sample */
 
-	for (i = 0; i < nsmp; i++) {
+	for (i = 0; i < nins; i++) {
 		pw_write_zero(out, 22);		/*sample name */
 
-		c3 = read8(in);			/* read finetune */
-		c4 = read8(in);			/* read volume */
+		c3 = hio_read8(in);		/* read finetune */
+		c4 = hio_read8(in);		/* read volume */
 
-		write16b(out, size = read16b(in)); /* size */
+		write16b(out, size = hio_read16b(in)); /* size */
 		ssize += size * 2;
 
 		write8(out, c3);		/* write finetune */
 		write8(out, c4);		/* write volume */
 
-		write16b(out, read16b(in));	/* loop start */
-		write16b(out, read16b(in));	/* loop size */
+		write16b(out, hio_read16b(in));	/* loop start */
+		write16b(out, hio_read16b(in));	/* loop size */
 	}
 
 	memset(tmp, 0, 30);
 	tmp[29] = 0x01;
 
-	for (; i < 31; i++)
+	for (; i < 31; i++) {
 		fwrite(tmp, 30, 1, out);
+	}
 
 	/* read size of pattern table */
-	read8(in);
-	write8(out, len = read8(in));		/* sequence length */
+	hio_read8(in);
+	write8(out, len = hio_read8(in));	/* sequence length */
+
+	/* Sanity check */
+	if (len >= 128) {
+		return -1;
+	}
+
 	write8(out, 0x7f);			/* ntk byte */
 
 	for (npat = i = 0; i < len; i++) {
-		pnum[i] = read16b(in) / 8;
+		pnum[i] = hio_read16b(in) / 8;
 		if (pnum[i] > npat)
 			npat = pnum[i];
 	}
@@ -71,7 +79,7 @@ static int depack_tp3(FILE *in, FILE *out)
 
 	for (i = 0; i <= npat; i++) {
 		for (j = 0; j < 4; j++) {
-			trk_ofs[i][j] = read16b(in);
+			trk_ofs[i][j] = hio_read16b(in);
 			if (trk_ofs[i][j] > max_trk_ofs)
 				max_trk_ofs = trk_ofs[i][j];
 		}
@@ -80,7 +88,7 @@ static int depack_tp3(FILE *in, FILE *out)
 	fwrite(pnum, 128, 1, out);		/* write pattern list */
 	write32b(out, PW_MOD_MAGIC);		/* ID string */
 
-	pat_ofs = ftell(in) + 2;
+	pat_ofs = hio_tell(in) + 2;
 
 	/* pattern datas */
 	for (i = 0; i <= npat; i++) {
@@ -89,24 +97,27 @@ static int depack_tp3(FILE *in, FILE *out)
 		for (j = 0; j < 4; j++) {
 			int where;
 
-			fseek(in, pat_ofs + trk_ofs[i][j], SEEK_SET);
+			hio_seek(in, pat_ofs + trk_ofs[i][j], SEEK_SET);
 
-			for (k = 0; k < 64; k++) {
-				int x = k * 16 + j * 4;
+			for (k = 0; k >= 0 && k < 64; k++) {
+				uint8 *p = pdata + k * 16 + j * 4;
 
-				c1 = read8(in);
+				c1 = hio_read8(in);
 				if ((c1 & 0xc0) == 0xc0) {
-					k += (0x100 - c1);
-					k -= 1;
+					k += 0x100 - c1 - 1;
 					continue;
 				}
 
 				if ((c1 & 0xc0) == 0x80) {
-					c2 = read8(in);
-					fxt = (c1 >> 1) & 0x0f;
+					c2 = hio_read8(in);
+					if (ver == 2) {
+						fxt = (c1 >> 2) & 0x0f;
+					} else {
+						fxt = (c1 >> 1) & 0x0f;
+					}
 					fxp = c2;
 					if ((fxt == 0x05) || (fxt == 0x06)
-						|| (fxt == 0x0A)) {
+						|| (fxt == 0x0a)) {
 						if (fxp > 0x80)
 							fxp = 0x100 - fxp;
 						else if (fxp <= 0x80)
@@ -114,141 +125,185 @@ static int depack_tp3(FILE *in, FILE *out)
 					}
 					if (fxt == 0x08)
 						fxt = 0x00;
-					pdata[x + 2] = fxt;
-					pdata[x + 3] = fxp;
+					p[2] = fxt;
+					p[3] = fxp;
 					continue;
 				}
 
-				c2 = read8(in);
+				c2 = hio_read8(in);
 
 				ins = ((c2 >> 4) & 0x0f) | ((c1 >> 2) & 0x10);
 
-				if ((c1 & 0x40) == 0x40)
-					note = 0x7f - c1;
-				else
-					note = c1 & 0x3f;
+				if (ver == 2) {
+					note = (c1 & 0xfe) >> 1;
 
-				fxt = c2 & 0x0f;
+					if (note >= 37) {
+						return -1;
+					}
 
-				if (fxt == 0x00) {
-					pdata[x] = ins & 0xf0;
-					pdata[x] |= ptk_table[note][0];
-					pdata[x + 1] = ptk_table[note][1];
-					pdata[x + 2] = (ins << 4) & 0xf0;
-					continue;
+					fxt = c2 & 0x0f;
+
+					if (fxt == 0x00) {
+						p[0] = ins & 0xf0;
+						p[0] |= ptk_table[note][0];
+						p[1] = ptk_table[note][1];
+						p[2] = ((ins << 4) & 0xf0) | fxt;
+						continue;
+					}
+				} else {
+					if ((c1 & 0x40) == 0x40) {
+						note = 0x7f - c1;
+					} else {
+						note = c1 & 0x3f;
+					}
+	
+					if (note >= 37) {
+						return -1;
+					}
+	
+					fxt = c2 & 0x0f;
+	
+					if (fxt == 0x00) {
+						p[0] = ins & 0xf0;
+						p[0] |= ptk_table[note][0];
+						p[1] = ptk_table[note][1];
+						p[2] = (ins << 4) & 0xf0;
+						continue;
+					}
 				}
 
-				c3 = read8(in);
+				c3 = hio_read8(in);
 
 				if (fxt == 0x08)
 					fxt = 0x00;
 
 				fxp = c3;
-				if ((fxt == 0x05) || (fxt == 0x06)
-					|| (fxt == 0x0A)) {
-					if (fxp > 0x80)
+				if (fxt == 0x05 || fxt == 0x06 || fxt == 0x0a) {
+					if (fxp > 0x80) {
 						fxp = 0x100 - fxp;
-					else if (fxp <= 0x80)
+					} else if (fxp <= 0x80) {
 						fxp = (fxp << 4) & 0xf0;
+					}
 				}
 
-				pdata[x] = ins & 0xf0;
-				pdata[x] |= ptk_table[note][0];
-				pdata[x + 1] = ptk_table[note][1];
-				pdata[x + 2] = (ins << 4) & 0xf0;
-				pdata[x + 2] |= fxt;
-				pdata[x + 3] = fxp;
+				p[0] = (ins & 0xf0) | ptk_table[note][0];
+				p[1] = ptk_table[note][1];
+				p[2] = ((ins << 4) & 0xf0) | fxt;
+				p[3] = fxp;
 			}
-			where = ftell(in);
-			if (where > max_trk_ofs)
+			where = hio_tell(in);
+			if (where < 0) {
+				return -1;
+			}
+			if (where > max_trk_ofs) {
 				max_trk_ofs = where;
+			}
 		}
 		fwrite(pdata, 1024, 1, out);
 	}
 
 	/* Sample data */
-	if (max_trk_ofs & 0x01)
+	if (ver > 2 && max_trk_ofs & 0x01) {
 		max_trk_ofs += 1;
+	}
 
-	fseek(in, max_trk_ofs, SEEK_SET);
+	hio_seek(in, max_trk_ofs, SEEK_SET);
 	pw_move_data(out, in, ssize);
 
 	return 0;
 }
 
-static int test_tp3(uint8 *data, char *t, int s)
+static int depack_tp3(HIO_HANDLE *in, FILE *out)
 {
-	int start = 0;
-	int j, k, l, m, n;
-	int ssize;
+	return depack_tp23(in, out, 3);
+}
+
+static int depack_tp2(HIO_HANDLE *in, FILE *out)
+{
+	return depack_tp23(in, out, 2);
+}
+
+static int test_tp23(uint8 *data, char *t, int s, char *magic)
+{
+	int i;
+	int npat, nins, ssize;
 
 	PW_REQUEST_DATA(s, 1024);
 
-	if (memcmp(data, "CPLX_TP3", 8))
+	if (memcmp(data, magic, 8))
 		return -1;
 
 	/* number of sample */
-	l = readmem16b(data + start + 28);
+	nins = readmem16b(data + 28);
 
-	if (l & 0x07 || l == 0)
+	if (nins == 0 || nins & 0x07)
 		return -1;
 
-	l /= 8;
+	nins >>= 3;
 
-	/* l is the number of sample */
+	for (i = 0; i < nins; i++) {
+		uint8 *d = data + i * 8;
 
-	/* test finetunes */
-	for (k = 0; k < l; k++) {
-		if (data[start + 30 + k * 8] > 0x0f)
+		/* test finetunes */
+		if (d[30] > 0x0f)
 			return -1;
-	}
 
-	/* test volumes */
-	for (k = 0; k < l; k++) {
-		if (data[start + 31 + k * 8] > 0x40)
-			return - 1;
+		/* test volumes */
+		if (d[31] > 0x40)
+			return -1;
 	}
 
 	/* test sample sizes */
 	ssize = 0;
-	for (k = 0; k < l; k++) {
-		int x = start + k * 8;
+	for (i = 0; i < nins; i++) {
+		uint8 *d = data + i * 8;
+		int len = readmem16b(d + 32) << 1;	/* size */
+		int start = readmem16b(d + 34) << 1;	/* loop start */
+		int lsize = readmem16b(d + 36) << 1;	/* loop size */
 
-		j = readmem16b(data + x + 32) * 2;	/* size */
-		m = readmem16b(data + x + 34) * 2;	/* loop start */
-		n = readmem16b(data + x + 36) * 2;	/* loop size */
-
-		if (j > 0xffff || m > 0xffff || n > 0xffff)
+		if (len > 0xffff || start > 0xffff || lsize > 0xffff)
 			return -1;
 
-		if (m + n > j + 2)
+		if (start + lsize > len + 2)
 			return -1;
 
-		if (m != 0 && n == 0)
+		if (start != 0 && lsize == 0)
 			return -1;
 
-		ssize += j;
+		ssize += len;
 	}
 
 	if (ssize <= 4)
 		return -1;
 
 	/* pattern list size */
-	j = data[start + l * 8 + 31];
-	if (l == 0 || l > 128)
+	npat = data[nins * 8 + 31];
+	if (npat == 0 || npat > 128)
 		return -1;
 
-	/* j is the size of the pattern list */
-	/* l is the number of sample */
-	/* ssize is the sample data size */
-
 	pw_read_title(data + 8, t, 20);
 
 	return 0;
 }
 
+static int test_tp3(uint8 *data, char *t, int s)
+{
+	return test_tp23(data, t, s, "CPLX_TP3");
+}
+
+static int test_tp2(uint8 *data, char *t, int s)
+{
+	return test_tp23(data, t, s, "MEXX_TP2");
+}
+
 const struct pw_format pw_tp3 = {
 	"Tracker Packer v3",
 	test_tp3,
 	depack_tp3
 };
+
+const struct pw_format pw_tp2 = {
+	"Tracker Packer v2",
+	test_tp2,
+	depack_tp2
+};
diff --git a/src/loaders/prowizard/unic.c b/src/loaders/prowizard/unic.c
index b20c802..b6ca45c 100644
--- a/src/loaders/prowizard/unic.c
+++ b/src/loaders/prowizard/unic.c
@@ -1,9 +1,10 @@
 /*
  * Unic_Tracker.c   Copyright (C) 1997 Asle / ReDoX
- *		    Copyright (C) 2006-2007 Claudio Matsuoka
  * 
  * Unic tracked MODs to Protracker
  * both with or without ID Unic files will be converted
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -14,10 +15,8 @@
 #define MAGIC_M_K_	MAGIC4('M','.','K','.')
 #define MAGIC_0000	MAGIC4(0x0,0x0,0x0,0x0)
 
-#define ON 1
-#define OFF 2
 
-static int depack_unic (FILE *in, FILE *out)
+static int depack_unic(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1, c2, c3, c4;
 	uint8 npat;
@@ -25,21 +24,23 @@ static int depack_unic (FILE *in, FILE *out)
 	uint8 ins, note, fxt, fxp;
 	uint8 fine;
 	uint8 tmp[1025];
-	uint8 loop_status = OFF;	/* standard /2 */
-	int i = 0, j = 0, k = 0, l = 0;
-	int ssize = 0;
+	int i, j;
+	int ssize;
 	uint32 id;
 
 	pw_move_data(out, in, 20);		/* title */
 
+	ssize = 0;
 	for (i = 0; i < 31; i++) {
+		int len, start, lsize;
+
 		pw_move_data(out, in, 20);	/* sample name */
 		write8(out, 0);
 		write8(out, 0);
 
 		/* fine on ? */
-		c1 = read8(in);
-		c2 = read8(in);
+		c1 = hio_read8(in);
+		c2 = hio_read8(in);
 		j = (c1 << 8) + c2;
 		if (j != 0) {
 			if (j < 256)
@@ -51,29 +52,30 @@ static int depack_unic (FILE *in, FILE *out)
 		}
 
 		/* smp size */
-		write16b(out, l = read16b(in));
-		ssize += l * 2;
+		len = hio_read16b(in);
+		write16b(out, len);
+		ssize += len * 2;
 
-		read8(in);
+		hio_read8(in);
 		write8(out, fine);		/* fine */
-		write8(out, read8(in));		/* vol */
-		j = read16b(in);		/* loop start */
-		k = read16b(in);		/* loop size */
+		write8(out, hio_read8(in));		/* vol */
+		start = hio_read16b(in);		/* loop start */
+		lsize = hio_read16b(in);		/* loop size */
 
-		if ((((j * 2) + k) <= l) && (j != 0)) {
-			loop_status = ON;
-			j *= 2;
+		if (start * 2 + lsize <= len && start != 0) {
+			start <<= 1;
 		}
 
-		write16b(out, j);
-		write16b(out, k);
+		write16b(out, start);
+		write16b(out, lsize);
 	}
 
-	write8(out, npat = read8(in));		/* number of pattern */
+	npat = hio_read8(in);
+	write8(out, npat);			/* number of pattern */
 	write8(out, 0x7f);			/* noisetracker byte */
-	read8(in);
+	hio_read8(in);
 
-	fread(tmp, 128, 1, in);			/* pat table */
+	hio_read(tmp, 128, 1, in);			/* pat table */
 	fwrite(tmp, 128, 1, out);
 
 	/* get highest pattern number */
@@ -86,21 +88,31 @@ static int depack_unic (FILE *in, FILE *out)
 	write32b(out, PW_MOD_MAGIC);
 
 	/* verify UNIC ID */
-	fseek(in, 1080, SEEK_SET);
-	id = read32b(in);
+	hio_seek(in, 1080, SEEK_SET);
+	id = hio_read32b(in);
 
 	if (id && id != MAGIC_M_K_ && id != MAGIC_UNIC)
-		fseek(in, -4, SEEK_CUR);
+		hio_seek(in, -4, SEEK_CUR);
 
 	/* pattern data */
 	for (i = 0; i < max; i++) {
 		for (j = 0; j < 256; j++) {
-			c1 = read8(in);
-			c2 = read8(in);
-			c3 = read8(in);
+			c1 = hio_read8(in);
+			c2 = hio_read8(in);
+			c3 = hio_read8(in);
+
+			if (hio_error(in)) {
+				return -1;
+			}
 
 			ins = ((c1 >> 2) & 0x10) | ((c2 >> 4) & 0x0f);
 			note = c1 & 0x3f;
+
+			/* Sanity check */
+			if (note >= 37) {
+				return -1;
+			}
+
 			fxt = c2 & 0x0f;
 			fxp = c3;
 
@@ -124,194 +136,165 @@ static int depack_unic (FILE *in, FILE *out)
 	return 0;
 }
 
-static int test_unic_id (uint8 *data, char *t, int s)
+static int check_instruments(uint8 *data)
 {
-	int j, k, l, n;
-	int start = 0, ssize;
-
-	/* test 1 */
-	PW_REQUEST_DATA(s, 1084);
+	int ssize, max_ins;
+	int i;
 
-	if (readmem32b(data + start + 1080) != MAGIC_M_K_)
-		return -1;
-
-	/* test 2 */
 	ssize = 0;
-	for (k = 0; k < 31; k++) {
-		int x = start + k * 30;
+	max_ins = 0;
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 30;
+		int len = readmem16b(d + 42) << 1;
+		int start = readmem16b(d + 46) << 1;
+		int lsize = readmem16b(d + 48) << 1;
+		int fine;
 
-		j = readmem16b(data + x + 42) * 2;
-		ssize += j;
-		n = (readmem16b(data + x + 46) + readmem16b(data + x + 48)) * 2;
+		ssize += len;
+		if (lsize != 0 && (len + 2) < (start + lsize))
+			return -1;
 
-		if ((j + 2) < n)
+		/* samples too big ? */
+		if (len > 0xffff || start > 0xffff || lsize > 0xffff)
 			return -1;
-	}
 
-	if (ssize <= 2)
-		return -1;
+		/* volume too big */
+		if (d[45] > 0x40)
+			return -1;
 
-	/* test #3  finetunes & volumes */
-	for (k = 0; k < 31; k++) {
-		int x = start + k * 30;
+		/* finetune ... */
+		fine = readmem16b(d + 40);
+		if ((fine != 0 && len == 0) || (fine > 8 && fine < 247))
+			return -1;
 
-		if (data[x + 40] > 0x0f || data[x + 44] || data[x + 45] > 0x40)
+		/* loop start but no replen ? */
+		if (start != 0 && lsize <= 2)
+			return -1;
+
+		if (d[45] != 0 && len == 0)
 			return -1;
+
+		/* get the highest !0 sample */
+		if (len != 0)
+			max_ins = i + 1;
+	}
+	if (ssize <= 2) {
+		return -1;
 	}
 
+	return max_ins;
+}
+
+static int check_pattern_list_size(uint8 *data)
+{
+	int len, psize;
+	int i;
+
 	/* test #4  pattern list size */
-	l = data[start + 950];
-	if (l > 127 || l == 0)
+	len = data[950];
+	if (len == 0 || len > 127)
 		return -1;
-	/* l holds the size of the pattern list */
 
-	k = 0;
-	for (j = 0; j < l; j++) {
-		if (data[start + 952 + j] > k)
-			k = data[start + 952 + j];
-		if (data[start + 952 + j] > 127)
+	psize = 0;
+	for (i = 0; i < len; i++) {
+		int x = data[952 + i];
+		if (x > 127)
 			return -1;
+		if (x > psize)
+			psize = x;
 	}
-	/* k holds the highest pattern number */
 
 	/* test last patterns of the pattern list = 0 ? */
-	while (j != 128) {
-		if (data[start + 952 + j] != 0)
-			return -1;
-		j++;
-	}
-	/* k is the number of pattern in the file (-1) */
-	k++;
-
-	PW_REQUEST_DATA(s, 1084 + k * 256 * 3);
-
-#if 0
-	/* test #5 pattern data ... */
-	if (((k * 768) + 1084 + start) > in_size)
-		return -1;
-#endif
-
-	for (j = 0; j < (k << 8); j++) {
-		/* relative note number + last bit of sample > $34 ? */
-		if (data[start + 1084 + j * 3] > 0x74)
+	for (; i != 128; i++) {
+		if (data[952 + i] != 0)
 			return -1;
 	}
 
-	pw_read_title(data, t, 20);
+	psize++;
+	psize <<= 8;
 
-	return 0;
+	return psize;
 }
 
-static int test_unic_emptyid (uint8 *data, char *t, int s)
+static int check_pattern(uint8 *data, int s, int psize, int max_ins, int offset)
 {
-	int j, k, l, m, n, o;
-	int start = 0, ssize;
+	int i;
 
-	/* test 1 */
-	PW_REQUEST_DATA(s, 1084);
+	PW_REQUEST_DATA(s, offset + psize * 3 + 2);
 
-	/* test #2 ID = $00000000 ? */
-	if (readmem32b(data + start + 1080) != MAGIC_0000)
-		return -1;
-
-	/* test 2,5 :) */
-	ssize = 0;
-	o = 0;
-	for (k = 0; k < 31; k++) {
-		int x = start + k * 30, y;
+	for (i = 0; i < psize; i++) {
+		uint8 *d = data + offset + i * 3;
+		int ins;
 
-		j = readmem16b(data + x + 42) * 2;
-		m = readmem16b(data + x + 46) * 2;
-		n = readmem16b(data + x + 48) * 2;
-		ssize += j;
-
-		if (n != 0 && (j + 2) < (m + n))
+		/* relative note number + last bit of sample > $34 ? */
+		if (d[0] > 0x74)
 			return -1;
-
-		if (j > 0xffff || m > 0xffff || n > 0xffff)
+		if ((d[0] & 0x3F) > 0x24)
 			return -1;
-
-		if (data[x + 45] > 0x40)
+		if ((d[1] & 0x0F) == 0x0C && d[2] > 0x40)
 			return -1;
 
-		/* finetune ... */
-		y = readmem16b(data + x + 40);
-		if ((y != 0 && j == 0) || (y > 8 && y < 247))
+		if ((d[1] & 0x0F) == 0x0B && d[2] > 0x7F)
 			return -1;
 
-		/* loop start but no replen ? */
-		if (m != 0 && n <= 2)
+		if ((d[1] & 0x0F) == 0x0D && d[2] > 0x40)
 			return -1;
 
-		if (data[x + 45] != 0 && j == 0)
-			return -1;
+		ins = ((d[0] >> 2) & 0x30) | ((d[2] >> 4) & 0x0F);
 
-		/* get the highest !0 sample */
-		if (j != 0)
-			o = j + 1;
+		if (ins > max_ins)
+			return -1;
 	}
 
-	if (ssize <= 2)
-		return -1;
-
-	/* test #4  pattern list size */
-	l = data[start + 950];
-	if (l > 127 || l == 0)
-		return -1;
-	/* l holds the size of the pattern list */
+	return 0;
+}
 
-	k = 0;
-	for (j = 0; j < l; j++) {
-		if (data[start + 952 + j] > k)
-			k = data[start + 952 + j];
-		if (data[start + 952 + j] > 127)
-			return -1;
-	}
-	/* k holds the highest pattern number */
+static int test_unic_id(uint8 *data, char *t, int s)
+{
+	int i;
+	int psize, ssize;
 
-	/* test last patterns of the pattern list = 0 ? */
-	while (j != 128) {
-		if (data[start + 952 + j] != 0)
-			return -1;
-		j += 1;
-	}
-	/* k is the number of pattern in the file (-1) */
-	k += 1;
+	/* test 1 */
+	PW_REQUEST_DATA(s, 1084);
 
-#if 0
-	/* test #5 pattern data ... */
-	if ((k * 768 + 1084 + start) > in_size)
+	if (readmem32b(data + 1080) != MAGIC_M_K_)
 		return -1;
-#endif
 
-	PW_REQUEST_DATA(s, 1084 + k * 256 * 3 + 2);
-
-	for (j = 0; j < (k << 8); j++) {
-		int y = start + 1084 + j * 3;
+	/* test 2 */
+	ssize = 0;
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 30;
+		int size, end;
 
-		/* relative note number + last bit of sample > $34 ? */
-		if (data[y] > 0x74)
-			return -1;
+		size = readmem16b(d + 42) << 1;
+		ssize += size;
+		end = (readmem16b(d + 46) + readmem16b(d + 48)) << 1;
 
-		if ((data[y] & 0x3F) > 0x24)
+		if ((size + 2) < end)
 			return -1;
+	}
 
-		if ((data[y + 1] & 0x0F) == 0x0C
-			&& data[y + 2] > 0x40)
-			return -1;
+	if (ssize <= 2)
+		return -1;
 
-		if ((data[y + 1] & 0x0F) == 0x0B
-			&& data[y + 2] > 0x7F)
+	/* test #3  finetunes & volumes */
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 30;
+		if ((int8)d[40] < -8 || (int8)d[40] > 7)
 			return -1;
-
-		if ((data[y + 1] & 0x0F) == 0x0D
-			&& data[y + 2] > 0x40)
+		if (d[44] != 0 || d[45] > 0x40)
 			return -1;
+	}
 
-		n = ((data[y] >> 2) & 0x30) |
-			((data[start + 1085 + j * 3 + 1] >> 4) & 0x0F);
+	/* test #4  pattern list size */
+	psize = check_pattern_list_size(data);
+	if (psize < 0)
+		return -1;
 
-		if (n > o)
+	/* test #5 pattern data ... */
+	for (i = 0; i < psize; i++) {
+		/* relative note number + last bit of sample > $34 ? */
+		if (data[1084 + i * 3] > 0x74)
 			return -1;
 	}
 
@@ -320,123 +303,66 @@ static int test_unic_emptyid (uint8 *data, char *t, int s)
 	return 0;
 }
 
-static int test_unic_noid (uint8 *data, char *t, int s)
+static int test_unic_emptyid(uint8 *data, char *t, int s)
 {
-	int j, k, l, m, n, o;
-	int start = 0, ssize;
+	int psize, max_ins;
 
 	/* test 1 */
 	PW_REQUEST_DATA(s, 1084);
 
 	/* test #2 ID = $00000000 ? */
-	if (readmem32b(data + start + 1080) == MAGIC_0000)
+	if (readmem32b(data + 1080) != MAGIC_0000)
 		return -1;
 
 	/* test 2,5 :) */
-	ssize = 0;
-	o = 0;
-	for (k = 0; k < 31; k++) {
-		int x = start + k * 30, y;
-
-		j = readmem16b(data + x + 42) * 2;
-		m = readmem16b(data + x + 46) * 2;
-		n = readmem16b(data + x + 48) * 2;
-
-		ssize += j;
-		if (n != 0 && (j + 2) < (m + n))
-			return -1;
-
-		/* samples too big ? */
-		if (j > 0xffff || m > 0xffff || n > 0xffff)
-			return -1;
-
-		/* volume too big */
-		if (data[x + 45] > 0x40)
-			return -1;
-
-		/* finetune ... */
-		y = readmem16b(data + x + 40);
-		if ((y != 0 && j == 0) || (y > 8 && y < 247))
-			return -1;
-
-		/* loop start but no replen ? */
-		if (m != 0 && n <= 2)
-			return -1;
-
-		if (data[x + 45] != 0 && j == 0)
-			return -1;
-
-		/* get the highest !0 sample */
-		if (j != 0)
-			o = j + 1;
-	}
-	if (ssize <= 2)
+	max_ins = check_instruments(data);
+	if (max_ins < 0)
 		return -1;
 
 	/* test #4  pattern list size */
-	l = data[start + 950];
-	if (l > 127 || l == 0)
+	psize = check_pattern_list_size(data);
+	if (psize < 0)
 		return -1;
-	/* l holds the size of the pattern list */
-
-	k = 0;
-	for (j = 0; j < l; j++) {
-		if (data[start + 952 + j] > k)
-			k = data[start + 952 + j];
-		if (data[start + 952 + j] > 127)
-			return -1;
-	}
-	/* k holds the highest pattern number */
-
-	/* test last patterns of the pattern list = 0 ? */
-	while (j != 128) {
-		if (data[start + 952 + j] != 0)
-			return -1;
-		j += 1;
-	}
-	/* k is the number of pattern in the file (-1) */
-	k += 1;
 
 	/* test #5 pattern data ... */
-	/* o is the highest !0 sample */
+	if (check_pattern(data, s, psize, max_ins, 1084) < 0)
+		return -1;
 
-#if 0
-	if (((k * 768) + 1080 + start) > in_size) {
-		Test = BAD;
-		return;
-	}
-#endif
+	pw_read_title(data, t, 20);
 
-	PW_REQUEST_DATA(s, 1080 + k * 256 * 3 + 2);
+	return 0;
+}
 
-	for (j = 0; j < (k << 8); j++) {
-		int y = start + 1080 + j * 3;
+static int test_unic_noid(uint8 *data, char *t, int s)
+{
+	int i;
+	int psize, max_ins;
 
-		/* relative note number + last bit of sample > $34 ? */
-		if (data[y] > 0x74)
-			return -1;
-		if ((data[y] & 0x3F) > 0x24)
-			return -1;
-		if ((data[y + 1] & 0x0F) == 0x0C && data[y + 2] > 0x40)
-			return -1;
+	/* test 1 */
+	PW_REQUEST_DATA(s, 1084);
 
-		if ((data[y + 1] & 0x0F) == 0x0B && data[y + 2] > 0x7F)
-			return -1;
+	/* test #2 ID = $00000000 ? */
+	if (readmem32b(data + 1080) == MAGIC_0000)
+		return -1;
 
-		if ((data[y + 1] & 0x0F) == 0x0D && data[y + 2] > 0x40)
-			return -1;
+	/* test 2,5 :) */
+	max_ins = check_instruments(data);
+	if (max_ins < 0)
+		return -1;
 
-		n = ((data[y] >> 2) & 0x30) |
-			((data[start + 1081 + j * 3 + 1] >> 4) & 0x0F);
+	/* test #4  pattern list size */
+	psize = check_pattern_list_size(data);
+	if (psize < 0)
+		return -1;
 
-		if (n > o)
-			return -1;
-	}
+	/* test #5 pattern data ... */
+	if (check_pattern(data, s, psize, max_ins, 1080) < 0)
+		return -1;
 
 	/* test #6  title coherent ? */
-	for (j = 0; j < 20; j++) {
-		if ((data[start + j] != 0 && data[start + j] < 32) ||
-			data[start + j] > 180)
+	for (i = 0; i < 20; i++) {
+		if ((data[i] != 0 && data[i] < 32) ||
+			data[i] > 180)
 			return -1;
 	}
 
diff --git a/src/loaders/prowizard/unic2.c b/src/loaders/prowizard/unic2.c
index 35bbe4f..9624844 100644
--- a/src/loaders/prowizard/unic2.c
+++ b/src/loaders/prowizard/unic2.c
@@ -1,39 +1,41 @@
 /*
  * Unic_Tracker_2.c   Copyright (C) 1997 Asle / ReDoX
- *                    Copyright 2006-2007 Claudio Matsuoka
  *
  * Convert Unic Tracker 2 MODs to Protracker
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
 #include 
 #include "prowiz.h"
 
-#define ON 1
-#define OFF 2
 
-static int depack_unic2(FILE *in, FILE *out)
+static int depack_unic2(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1, c2, c3, c4;
 	uint8 npat, maxpat;
 	uint8 ins, note, fxt, fxp;
-	uint8 fine = 0;
+	uint8 fine;
 	uint8 tmp[1025];
-	uint8 loop_status = OFF;	/* standard /2 */
-	int i, j, k, l;
-	int ssize = 0;
+	int i, j;
+	int ssize;
 
 	pw_write_zero(out, 20);		/* title */
 
+	ssize = 0;
 	for (i = 0; i < 31; i++) {
+		int len, start, lsize;
+
 		pw_move_data(out, in, 20);	/* sample name */
 		write8(out, 0);
 		write8(out, 0);
 
 		/* fine on ? */
-		c1 = read8(in);
-		c2 = read8(in);
+		c1 = hio_read8(in);
+		c2 = hio_read8(in);
 		j = (c1 << 8) + c2;
+
 		if (j != 0) {
 			if (j < 256)
 				fine = 0x10 - c2;
@@ -44,30 +46,30 @@ static int depack_unic2(FILE *in, FILE *out)
 		}
 
 		/* smp size */
-		write16b(out, l = read16b(in));
-		ssize += l * 2;
+		len = hio_read16b(in);
+		write16b(out, len);
+		ssize += len << 1;
 
-		read8(in);
+		hio_read8(in);
 		write8(out, fine);		/* fine */
-		write8(out, read8(in));		/* vol */
+		write8(out, hio_read8(in));		/* vol */
 
-		j = read16b(in);		/* loop start */
-		k = read16b(in);		/* loop size */
+		start = hio_read16b(in);		/* loop start */
+		lsize = hio_read16b(in);		/* loop size */
 
-		if ((((j * 2) + k) <= l) && (j != 0)) {
-			loop_status = ON;
-			j *= 2;
+		if (start * 2 + lsize <= len && start != 0) {
+			start <<= 1;
 		}
 
-		write16b(out, j);
-		write16b(out, k);
+		write16b(out, start);
+		write16b(out, lsize);
 	}
 
-	write8(out, npat = read8(in));		/* number of pattern */
+	write8(out, npat = hio_read8(in));		/* number of pattern */
 	write8(out, 0x7f);			/* noisetracker byte */
-	read8(in);
+	hio_read8(in);
 
-	fread(tmp, 128, 1, in);
+	hio_read(tmp, 128, 1, in);
 	fwrite(tmp, 128, 1, out);		/* pat table */
 
 	/* get highest pattern number */
@@ -82,12 +84,18 @@ static int depack_unic2(FILE *in, FILE *out)
 	/* pattern data */
 	for (i = 0; i < maxpat; i++) {
 		for (j = 0; j < 256; j++) {
-			c1 = read8(in);
-			c2 = read8(in);
-			c3 = read8(in);
+			c1 = hio_read8(in);
+			c2 = hio_read8(in);
+			c3 = hio_read8(in);
 
 			ins = ((c1 >> 2) & 0x10) | ((c2 >> 4) & 0x0f);
 			note = c1 & 0x3f;
+
+			/* Sanity check */
+			if (note >= 37) {
+				return -1;
+			}
+
 			fxt = c2 & 0x0f;
 			fxp = c3;
 
@@ -112,106 +120,96 @@ static int depack_unic2(FILE *in, FILE *out)
 	return 0;
 }
 
-static int test_unic2 (uint8 *data, char *t, int s)
+static int test_unic2(uint8 *data, char *t, int s)
 {
-	int j, k, l, m, n, o;
-	int start = 0, ssize;
+	int i;
+	int len, psize, ssize, max_ins;
 
 	/* test 1 */
 	PW_REQUEST_DATA (s, 1084);
 
 	/* test #2 ID = $00000000 ? */
-	if (readmem32b(data + start + 1080) == 0x00000000)
+	if (readmem32b(data + 1080) == 0x00000000)
 		return -1;
 
 	/* test 2,5 :) */
-	o = 0;
 	ssize = 0;
-	for (k = 0; k < 31; k++) {
-		int x = start + k * 30;
+	max_ins = 0;
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + i * 30;
 
-		j = readmem16b(data + x + 22) * 2;
-		m = readmem16b(data + x + 26) * 2;
-		n = readmem16b(data + x + 28) * 2;
-		ssize += j;
+		int size = readmem16b(d + 22) << 1;
+		int start = readmem16b(d + 26) << 1;
+		int lsize = readmem16b(d + 28) << 1;
+		ssize += size;
 
-		if (j + 2 < m + n)
+		if (size + 2 < start + lsize)
 			return -1;
 
-		if (j > 0xffff || m > 0xffff || n > 0xffff)
+		if (size > 0xffff || start > 0xffff || lsize > 0xffff)
 			return -1;
 
-		if (data[x + 25] > 0x40)
+		if (d[25] > 0x40)
 			return -1;
 
-		if (readmem16b(data + x + 20) && j == 0)
+		if (readmem16b(d + 20) && size == 0)
 			return -1;
 
-		if (data[x + 25] != 0 && j == 0)
+		if (d[25] != 0 && size == 0)
 			return -1;
 
 		/* get the highest !0 sample */
-		if (j != 0)
-			o = j + 1;
+		if (size != 0)
+			max_ins = i + 1;
 	}
 
 	if (ssize <= 2)
 		return -1;
 
 	/* test #4  pattern list size */
-	l = data[start + 930];
-	if (l > 127 || l == 0)
+	len = data[930];
+	if (len == 0 || len > 127)
 		return -1;
-	/* l holds the size of the pattern list */
 
-	k = 0;
-	for (j = 0; j < l; j++) {
-		if (data[start + 932 + j] > k)
-			k = data[start + 932 + j];
-		if (data[start + 932 + j] > 127)
+	psize = 0;
+	for (i = 0; i < len; i++) {
+		int x = data[932 + i];
+		if (x > 127)
 			return -1;
+		if (x > psize)
+			psize = x;
 	}
-	/* k holds the highest pattern number */
 
 	/* test last patterns of the pattern list = 0 ? */
-	j += 2;		/* just to be sure .. */
-	while (j != 128) {
-		if (data[start + 932 + j] != 0)
+	for (i += 2; i != 128; i++) {
+		if (data[932 + i] != 0)
 			return -1;
-		j += 1;
 	}
-	/* k is the number of pattern in the file (-1) */
-	k += 1;
-
-#if 0
-	/* test #5 pattern data ... */
-	if (((k * 768) + 1060 + start) > in_size) {
-/*printf ( "#5,0 (Start:%ld)\n" , start );*/
-		Test = BAD;
-		return;
-	}
-#endif
 
-	PW_REQUEST_DATA (s, 1060 + k * 256 * 3 + 2);
+	psize++;
+	psize <<= 8;
+
+	PW_REQUEST_DATA (s, 1060 + psize * 3 + 2);
 
-	for (j = 0; j < (k << 8); j++) {
-		int y = start + 1060 + j * 3;
+	for (i = 0; i < psize; i++) {
+		uint8 *d = data + 1060 + i * 3;
+		int ins;
 
 		/* relative note number + last bit of sample > $34 ? */
-		if (data[y] > 0x74)
+		if (d[0] > 0x74)
 			return -1;
-		if ((data[y] & 0x3F) > 0x24)
+		if ((d[0] & 0x3F) > 0x24)
 			return -1;
-		if ((data[y + 1] & 0x0F) == 0x0C && data[y + 2] > 0x40)
+		if ((d[1] & 0x0F) == 0x0C && d[2] > 0x40)
 			return -1;
-		if ((data[y + 1] & 0x0F) == 0x0B && data[y + 2] > 0x7F)
+		if ((d[1] & 0x0F) == 0x0B && d[2] > 0x7F)
 			return -1;
-		if ((data[y + 1] & 0x0F) == 0x0D && data[y + 2] > 0x40)
+		if ((d[1] & 0x0F) == 0x0D && d[2] > 0x40)
 			return -1;
 
-		n = ((data[y] >> 2) & 0x30) | ((data[y + 2] >> 4) & 0x0f);
+		ins = ((d[0] >> 2) & 0x30) | ((d[2] >> 4) & 0x0f);
 
-		if (n > o)
+		if (ins > max_ins)
 			return -1;
 	}
 
diff --git a/src/loaders/prowizard/wn.c b/src/loaders/prowizard/wn.c
index 8aa55fb..1729fbc 100644
--- a/src/loaders/prowizard/wn.c
+++ b/src/loaders/prowizard/wn.c
@@ -1,8 +1,9 @@
 /*
  * Wanton_Packer.c   Copyright (C) 1997 Asle / ReDoX
- *                   Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Converts MODs converted with Wanton packer
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -10,7 +11,7 @@
 #include "prowiz.h"
 
 
-static int depack_wn(FILE *in, FILE * out)
+static int depack_wn(HIO_HANDLE *in, FILE * out)
 {
 	uint8 c1, c2, c3, c4;
 	uint8 npat, max;
@@ -23,15 +24,15 @@ static int depack_wn(FILE *in, FILE * out)
 
 	/* get whole sample size */
 	for (i = 0; i < 31; i++) {
-		fseek(in, 42 + i * 30, SEEK_SET);
-		ssize += read16b(in) * 2;
+		hio_seek(in, 42 + i * 30, SEEK_SET);
+		ssize += hio_read16b(in) * 2;
 	}
 
 	/* read size of pattern list */
-	fseek(in, 950, SEEK_SET);
-	write8(out, npat = read8(in));
+	hio_seek(in, 950, SEEK_SET);
+	write8(out, npat = hio_read8(in));
 
-	fread(tmp, 129, 1, in);
+	hio_read(tmp, 129, 1, in);
 	fwrite(tmp, 129, 1, out);
 
 	/* write ptk's ID */
@@ -45,13 +46,17 @@ static int depack_wn(FILE *in, FILE * out)
 	max++;
 
 	/* pattern data */
-	fseek(in, 1084, SEEK_SET);
+	hio_seek(in, 1084, SEEK_SET);
 	for (i = 0; i < max; i++) {
 		for (j = 0; j < 256; j++) {
-			c1 = read8(in);
-			c2 = read8(in);
-			c3 = read8(in);
-			c4 = read8(in);
+			c1 = hio_read8(in);
+			c2 = hio_read8(in);
+			c3 = hio_read8(in);
+			c4 = hio_read8(in);
+
+			if (hio_error(in) || c1 >= 74) {
+				return -1;
+			}
 
 			write8(out, c1 * 0xf0 | ptk_table[c1 / 2][0]);
 			write8(out, ptk_table[c1 / 2][1]);
@@ -68,8 +73,6 @@ static int depack_wn(FILE *in, FILE * out)
 
 static int test_wn(uint8 *data, char *t, int s)
 {
-	int start = 0;
-
 	PW_REQUEST_DATA(s, 1082);
 
 	/* test 1 */
@@ -77,11 +80,11 @@ static int test_wn(uint8 *data, char *t, int s)
 		return -1;
 
 	/* test 2 */
-	if (data[start + 951] != 0x7f)
+	if (data[951] != 0x7f)
 		return -1;
 
 	/* test 3 */
-	if (data[start + 950] > 0x7f)
+	if (data[950] > 0x7f)
 		return -1;
 
 	pw_read_title(data, t, 20);
diff --git a/src/loaders/prowizard/xann.c b/src/loaders/prowizard/xann.c
index ad0b347..93b4c29 100644
--- a/src/loaders/prowizard/xann.c
+++ b/src/loaders/prowizard/xann.c
@@ -1,8 +1,9 @@
 /*
  * XANN_Packer.c   Copyright (C) 1997 Asle / ReDoX
- *                 Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * XANN Packer to Protracker.
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -12,7 +13,7 @@
 #define PAT_DATA_ADDRESS 0x43C
 
 
-static int depack_xann(FILE *in, FILE *out)
+static int depack_xann(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1, c2, c5;
 	uint8 ptable[128];
@@ -20,7 +21,7 @@ static int depack_xann(FILE *in, FILE *out)
 	uint8 note, ins, fxt, fxp;
 	uint8 fine, vol;
 	uint8 pdata[1025];
-	int i, j, l;
+	int i, j, k;
 	int size, ssize = 0;
 	int lsize;
 
@@ -30,36 +31,36 @@ static int depack_xann(FILE *in, FILE *out)
 	pw_write_zero(out, 20);			/* title */
 
 	/* 31 samples */
-	fseek(in, SMP_DESC_ADDRESS, SEEK_SET);
+	hio_seek(in, SMP_DESC_ADDRESS, SEEK_SET);
 
 	for (i = 0; i < 31; i++) {
 		pw_write_zero(out, 22);		/* sample name */
 
-		fine = read8(in);		/* read finetune */
-		vol = read8(in);		/* read volume */
-		j = read32b(in);		/* read loop start address */
-		lsize = read16b(in);		/* read loop size */
-		l = read32b(in);		/* read sample address */
-		write16b(out, size = read16b(in)); 	/* sample size */
+		fine = hio_read8(in);		/* read finetune */
+		vol = hio_read8(in);		/* read volume */
+		j = hio_read32b(in);		/* read loop start address */
+		lsize = hio_read16b(in);		/* read loop size */
+		k = hio_read32b(in);		/* read sample address */
+		write16b(out, size = hio_read16b(in)); 	/* sample size */
 		ssize += size * 2;
 
-		j = j - l;			/* calculate loop start value */
+		j = j - k;			/* calculate loop start value */
 		write8(out, fine);		/* write fine */
 		write8(out, vol);		/* write vol */
 		write16b(out, j / 2);		/* write loop start */
 		write16b(out, lsize);		/* write loop size */
 
-		read16b(in);			/* bypass two unknown bytes */
+		hio_read16b(in);			/* bypass two unknown bytes */
 	}
 
 	/* pattern table */
-	fseek(in, 0, SEEK_SET);
+	hio_seek(in, 0, SEEK_SET);
 
 	for (pat = c5 = 0; c5 < 128; c5++) {
-		l = read32b(in);
-		if (l == 0)
+		k = hio_read32b(in);
+		if (k == 0)
 			break;
-		ptable[c5] = ((l - 0x3c) / 1024) - 1;
+		ptable[c5] = ((k - 0x3c) / 1024) - 1;
 		if (ptable[c5] > pat)
 			pat = ptable[c5];
 	}
@@ -72,14 +73,20 @@ static int depack_xann(FILE *in, FILE *out)
 	write32b(out, PW_MOD_MAGIC);	/* write Protracker's ID */
 
 	/* pattern data */
-	fseek(in, PAT_DATA_ADDRESS, SEEK_SET);
+	hio_seek(in, PAT_DATA_ADDRESS, SEEK_SET);
 
 	for (i = 0; i < pat; i++) {
 		for (j = 0; j < 256; j++) {
-			ins = (read8(in) >> 3) & 0x1f;
-			note = read8(in);
-			fxt = read8(in);
-			fxp = read8(in);
+			uint8 *p = pdata + j * 4;
+
+			ins = (hio_read8(in) >> 3) & 0x1f;
+			note = hio_read8(in);
+			fxt = hio_read8(in);
+			fxp = hio_read8(in);
+
+			if (hio_error(in) || note >= 74) {
+				return -1;
+			}
 
 			switch (fxt) {
 			case 0x00:	/* no fxt */
@@ -179,12 +186,12 @@ static int depack_xann(FILE *in, FILE *out)
 				break;
 			}
 
-			pdata[j * 4] = (ins & 0xf0);
-			pdata[j * 4] |= ptk_table[(note / 2)][0];
-			pdata[j * 4 + 1] = ptk_table[(note / 2)][1];
-			pdata[j * 4 + 2] = ((ins << 4) & 0xf0);
-			pdata[j * 4 + 2] |= fxt;
-			pdata[j * 4 + 3] = fxp;
+			p[0] = ins & 0xf0;
+			p[0] |= ptk_table[note >> 1][0];
+			p[1] = ptk_table[note >> 1][1];
+			p[2] = (ins << 4) & 0xf0;
+			p[2] |= fxt;
+			p[3] = fxp;
 		}
 
 		fwrite(pdata, 1024, 1, out);
@@ -198,56 +205,52 @@ static int depack_xann(FILE *in, FILE *out)
 
 static int test_xann(uint8 *data, char *t, int s)
 {
-	int i = 0, j, k, l, m;
-	int start = 0;
+	int i;
 
 	PW_REQUEST_DATA(s, 2048);
 
 	/* test 1 */
-	if (data[i + 3] != 0x3c)
+	if (data[3] != 0x3c)
 		return -1;
 
 	/* test 2 */
-	for (l = 0; l < 128; l++) {
-		j = (data[start + l * 4] << 24)
-			+ (data[start + l * 4 + 1] << 16)
-			+ (data[start + l * 4 + 2] << 8)
-			+ data[start + l * 4 + 3];
-		k = (j / 4) * 4;
+	for (i = 0; i < 128; i++) {
+		uint32 j = readmem32b(data + i * 4);
+		uint32 k = j & ~3;
 		if (k != j || j > 132156)
 			return -1;
 	}
 
 #if 0
 	/* test 3 */
-	if ((size - start) < 2108)
+	if (size < 2108)
 		return -1;
 #endif
 
 	/* test 4 */
-	for (j = 0; j < 64; j++) {
-		if (data[start + 3 + j * 4] != 0x3c &&
-			data[start + 3 + j * 4] != 0x00) {
+	for (i = 0; i < 64; i++) {
+		if (data[3 + i * 4] != 0x3c &&
+			data[3 + i * 4] != 0) {
 			return -1;
 		}
 	}
 
 	/* test 5 */
-	for (j = 0; j < 31; j++) {
-		if (data[start + 519 + 16 * j] > 0x40)
+	for (i = 0; i < 31; i++) {
+		if (data[519 + 16 * i] > 0x40)
 			return -1;
 	}
 
 	/* test #6  (address of samples) */
-	for (l = 0; l < 30; l++) {
-		k = readmem32b(data + start + 526 + 16 * l);
-		j = readmem16b(data + start + 524 + 16 * l) * 2;
-		m = readmem32b(data + start + 520 + 16 * (l + 1));
+	for (i = 0; i < 30; i++) {
+		uint32 j = readmem32b(data + 526 + 16 * i);
+		/* j = readmem16b(data + 524 + 16 * i) * 2; */
+		uint32 k = readmem32b(data + 520 + 16 * (i + 1));
 
-		if (k < 2108 || m < 2108)
+		if (j < 2108 || k < 2108)
 			return -1;
 
-		if (k > m)
+		if (j > k)
 			return -1;
 	}
 
@@ -255,12 +258,12 @@ static int test_xann(uint8 *data, char *t, int s)
 	/* test #7  first pattern data .. */
 	for (j = 0; j < 256; j++) {
 #if 0
-		k = data[start + j * 4 + 1085] / 2;
+		k = data[j * 4 + 1085] / 2;
 		l = k * 2;
-		if (data[start + j * 4 + 1085] != l)
+		if (data[j * 4 + 1085] != l)
 			return -1;
 #endif
-		if (data[start + j * 4 + 1085] & 1)
+		if (data[j * 4 + 1085] & 1)
 			return -1;
 	}
 #endif
diff --git a/src/loaders/prowizard/zen.c b/src/loaders/prowizard/zen.c
index 52c6f6c..32e173d 100644
--- a/src/loaders/prowizard/zen.c
+++ b/src/loaders/prowizard/zen.c
@@ -1,8 +1,9 @@
 /*
  * Zen_Packer.c   Copyright (C) 1998 Asle / ReDoX
- *                Copyright (C) 2006-2007 Claudio Matsuoka
  *
  * Converts ZEN packed MODs back to PTK MODs
+ *
+ * Modified in 2006,2007,2014 by Claudio Matsuoka
  */
 
 #include 
@@ -10,7 +11,7 @@
 #include "prowiz.h"
 
 
-static int depack_zen(FILE *in, FILE *out)
+static int depack_zen(HIO_HANDLE *in, FILE *out)
 {
 	uint8 c1, c2, c3, c4;
 	uint8 finetune, vol;
@@ -21,43 +22,49 @@ static int depack_zen(FILE *in, FILE *out)
 	uint8 ptable[128];
 	int size, ssize = 0;
 	int paddr[128];
-	int paddr_Real[128];
+	int paddr2[128];
 	int ptable_addr;
 	int sdata_addr = 999999l;
 	int i, j, k;
 
 	memset(paddr, 0, 128 * 4);
-	memset(paddr_Real, 0, 128 * 4);
+	memset(paddr2, 0, 128 * 4);
 	memset(ptable, 0, 128);
 
-	ptable_addr = read32b(in);	/* read pattern table address */
-	pat_max = read8(in);		/* read patmax */
-	pat_pos = read8(in);		/* read size of pattern table */
+	ptable_addr = hio_read32b(in);	/* read pattern table address */
+	pat_max = hio_read8(in);	/* read patmax */
+	pat_pos = hio_read8(in);	/* read size of pattern table */
+
+	/* Sanity check */
+	if (pat_pos >= 128 || pat_max >= 128) {
+		return -1;
+	}
 
 	pw_write_zero(out, 20);		/* write title */
 
 	for (i = 0; i < 31; i++) {
 		pw_write_zero(out, 22);			/* sample name */
 
-		finetune = read16b(in) / 0x48;		/* read finetune */
+		finetune = hio_read16b(in) / 0x48;	/* read finetune */
 
-		read8(in);
-		vol = read8(in);			/* read volume */
+		hio_read8(in);
+		vol = hio_read8(in);			/* read volume */
 
-		write16b(out, size = read16b(in));	/* read sample size */
+		write16b(out, size = hio_read16b(in));	/* read sample size */
 		ssize += size * 2;
 
 		write8(out, finetune);			/* write finetune */
 		write8(out, vol);			/* write volume */
 
-		size = read16b(in);			/* read loop size */
+		size = hio_read16b(in);			/* read loop size */
 
-		k = read32b(in);			/* sample start addr */
-		if (k < sdata_addr)
+		k = hio_read32b(in);			/* sample start addr */
+		if (k < sdata_addr) {
 			sdata_addr = k;
+		}
 
 		/* read loop start address */
-		j = (read32b(in) - k) / 2;
+		j = (hio_read32b(in) - k) / 2;
 
 		write16b(out, j);	/* write loop start */
 		write16b(out, size);	/* write loop size */
@@ -66,17 +73,17 @@ static int depack_zen(FILE *in, FILE *out)
 	write8(out, pat_pos);		/* write size of pattern list */
 	write8(out, 0x7f);		/* write ntk byte */
 
-	/* read pattern table .. */
-	fseek(in, ptable_addr, SEEK_SET);
+	/* read pattern table */
+	hio_seek(in, ptable_addr, SEEK_SET);
 	for (i = 0; i < pat_pos; i++)
-		paddr[i] = read32b(in);
+		paddr[i] = hio_read32b(in);
 
 	/* deduce pattern list */
 	c4 = 0;
 	for (i = 0; i < pat_pos; i++) {
 		if (i == 0) {
 			ptable[0] = 0;
-			paddr_Real[0] = paddr[0];
+			paddr2[0] = paddr[0];
 			c4++;
 			continue;
 		}
@@ -87,7 +94,7 @@ static int depack_zen(FILE *in, FILE *out)
 			}
 		}
 		if (j == i) {
-			paddr_Real[c4] = paddr[i];
+			paddr2[c4] = paddr[i];
 			ptable[i] = c4;
 			c4++;
 		}
@@ -100,33 +107,34 @@ static int depack_zen(FILE *in, FILE *out)
 	/*printf ( "converting pattern datas " ); */
 	for (i = 0; i <= pat_max; i++) {
 		memset(pat, 0, 1024);
-		fseek(in, paddr_Real[i], SEEK_SET);
+		hio_seek(in, paddr2[i], SEEK_SET);
 		for (j = 0; j < 256; j++) {
-			c1 = read8(in);
-			c2 = read8(in);
-			c3 = read8(in);
-			c4 = read8(in);
+			uint8 *p;
+
+			c1 = hio_read8(in);
+			c2 = hio_read8(in);
+			c3 = hio_read8(in);
+			c4 = hio_read8(in);
 
 			note = (c2 & 0x7f) / 2;
 			fxp = c4;
 			ins = ((c2 << 4) & 0x10) | ((c3 >> 4) & 0x0f);
 			fxt = c3 & 0x0f;
 
-			k = c1;
-			pat[k * 4] = ins & 0xf0;
-			pat[k * 4] |= ptk_table[note][0];
-			pat[k * 4 + 1] = ptk_table[note][1];
-			pat[k * 4 + 2] = fxt | ((ins << 4) & 0xf0);
-			pat[k * 4 + 3] = fxp;
+			p = pat + c1 * 4;
+			p[0] = ins & 0xf0;
+			p[0] |= ptk_table[note][0];
+			p[1] = ptk_table[note][1];
+			p[2] = fxt | ((ins << 4) & 0xf0);
+			p[3] = fxp;
+
 			j = c1;
 		}
 		fwrite (pat, 1024, 1, out);
-		/*printf ( "." ); */
 	}
-	/*printf ( " ok\n" ); */
 
 	/* sample data */
-	fseek(in, sdata_addr, SEEK_SET);
+	hio_seek(in, sdata_addr, SEEK_SET);
 	pw_move_data(out, in, ssize);
 
 	return 0;
@@ -134,68 +142,58 @@ static int depack_zen(FILE *in, FILE *out)
 
 static int test_zen(uint8 *data, char *t, int s)
 {
-	int j, k, l, m, n, o;
-	int start = 0, ssize;
+	int i;
+	int len, pat_ofs;
 
 	PW_REQUEST_DATA(s, 9 + 16 * 31);
 
 	/* test #2 */
-	l = readmem32b(data + start);
-	if (l < 502 || l > 2163190L)
+	pat_ofs = readmem32b(data);
+	if (pat_ofs < 502 || pat_ofs > 2163190L)
 		return -1;
-	/* l is the address of the pattern list */
 
-	for (k = 0; k < 31; k++) {
-		/* volumes */
-		if (data[start + 9 + (16 * k)] > 0x40)
+	for (i = 0; i < 31; i++) {
+		uint8 *d = data + 16 * i;
+		if (d[9] > 0x40)
 			return -1;
 
 		/* finetune */
-		if (readmem16b(data + start + 6 + (k * 16)) % 72)
+		if (readmem16b(d + 6) % 72)
 			return -1;
 	}
 
 	/* smp sizes .. */
-	n = 0;
-	for (k = 0; k < 31; k++) {
-		o = readmem16b(data + start + 10 + k * 16) * 2;
-		m = readmem16b(data + start + 12 + k * 16) * 2;
-		j = readmem32b(data + start + 14 + k * 16);
+	for (i = 0; i < 31; i++) {
+		int size = readmem16b(data + 10 + i * 16) << 1;
+		int lsize = readmem16b(data + 12 + i * 16) << 1;
+		int sdata = readmem32b(data + 14 + i * 16);
 
 		/* sample size and loop size > 64k ? */
-		if (o > 0xFFFF || m > 0xFFFF)
+		if (size > 0xffff || lsize > 0xffff)
 			return -1;
 
 		/* sample address < pattern table address? */
-		if (j < l)
+		if (sdata < pat_ofs)
 			return -1;
 
 #if 0
 		/* too big an address ? */
-		if (j > in_size) {
+		if (sdata > in_size) {
 			Test = BAD;
 			return;
 		}
 #endif
-
-		/* get the nbr of the highest sample address and its size */
-		if (j > n) {
-			n = j;
-			ssize = o;
-		}
 	}
-	/* n is the highest sample data address */
-	/* ssize is the size of the same sample */
 
 	/* test size of the pattern list */
-	j = data[start + 5];
-	if (j > 0x7f || j == 0)
+	len = data[5];
+	if (len == 0 || len > 0x7f)
 		return -1;
 
-	PW_REQUEST_DATA(s, start + l + j * 4 + 4);
+	PW_REQUEST_DATA(s, pat_ofs + len * 4 + 4);
 
 	/* test if the end of pattern list is $FFFFFFFF */
-	if (readmem32b(data + start + l + j * 4) != 0xffffffff)
+	if (readmem32b(data + pat_ofs + len * 4) != 0xffffffff)
 		return -1;
 
 	/* n is the highest address of a sample data */
diff --git a/src/loaders/psm_load.c b/src/loaders/psm_load.c
index a8083fb..97fde2e 100644
--- a/src/loaders/psm_load.c
+++ b/src/loaders/psm_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -15,7 +29,7 @@
 static int psm_test (HIO_HANDLE *, char *, const int);
 static int psm_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader psm_loader = {
+const struct format_loader libxmp_loader_psm = {
 	"Protracker Studio",
 	psm_test,
 	psm_load
@@ -26,7 +40,7 @@ static int psm_test(HIO_HANDLE *f, char *t, const int start)
 	if (hio_read32b(f) != MAGIC_PSM_)
 		return -1;
 
-	read_title(f, t, 60);
+	libxmp_read_title(f, t, 60);
 
 	return 0;
 }
@@ -42,36 +56,42 @@ static int psm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	uint8 buf[1024];
 	uint32 p_ord, p_chn, p_pat, p_ins;
 	uint32 p_smp[64];
-	int type, ver, mode;
+	int type, ver /*, mode*/;
  
 	LOAD_INIT();
 
 	hio_read32b(f);
 
 	hio_read(buf, 1, 60, f);
-	strncpy(mod->name, (char *)buf, XMP_NAME_SIZE);
+	strncpy(mod->name, (char *)buf, 60);
 
-	type = hio_read8(f);	/* song type */
+	type = hio_read8(f);		/* song type */
 	ver = hio_read8(f);		/* song version */
-	mode = hio_read8(f);	/* pattern version */
+	/*mode =*/ hio_read8(f);	/* pattern version */
 
-	if (type & 0x01)	/* song mode not supported */
+	if (type & 0x01)		/* song mode not supported */
 		return -1;
 
-	set_type(m, "Protracker Studio PSM %d.%02d", MSN(ver), LSN(ver));
+	libxmp_set_type(m, "Protracker Studio PSM %d.%02d", MSN(ver), LSN(ver));
 
 	mod->spd = hio_read8(f);
 	mod->bpm = hio_read8(f);
-	hio_read8(f);		/* master volume */
-	hio_read16l(f);		/* song length */
+	hio_read8(f);			/* master volume */
+	hio_read16l(f);			/* song length */
 	mod->len = hio_read16l(f);
 	mod->pat = hio_read16l(f);
 	mod->ins = hio_read16l(f);
-	hio_read16l(f);               /* ignore channels to play */
-	mod->chn = hio_read16l(f);    /* use channels to proceed */
+	hio_read16l(f);			/* ignore channels to play */
+	mod->chn = hio_read16l(f);	/* use channels to proceed */
 	mod->smp = mod->ins;
 	mod->trk = mod->pat * mod->chn;
 
+	/* Sanity check */
+	if (mod->len > 256 || mod->pat > 256 || mod->ins > 255 ||
+	    mod->chn > XMP_MAX_CHANNELS) {
+		return -1;
+        }
+
 	p_ord = hio_read32l(f);
 	p_chn = hio_read32l(f);
 	p_pat = hio_read32l(f);
@@ -80,6 +100,8 @@ static int psm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	/* should be this way but fails with Silverball song 6 */
 	//mod->flg |= ~type & 0x02 ? XXM_FLG_MODRNG : 0;
 
+	m->c4rate = C4_NTSC_RATE;
+
 	MODULE_INFO();
 
 	hio_seek(f, start + p_ord, SEEK_SET);
@@ -88,7 +110,7 @@ static int psm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	hio_seek(f, start + p_chn, SEEK_SET);
 	hio_read(buf, 1, 16, f);
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	hio_seek(f, start + p_ins, SEEK_SET);
@@ -96,13 +118,13 @@ static int psm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		uint16 flags, c2spd;
 		int finetune;
 
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 
 		hio_read(buf, 1, 13, f);	/* sample filename */
 		hio_read(buf, 1, 24, f);	/* sample description */
+		buf[24] = 0;			/* add string termination */
 		strncpy((char *)mod->xxi[i].name, (char *)buf, 24);
-		adjust_string((char *)mod->xxi[i].name);
 		p_smp[i] = hio_read32l(f);
 		hio_read32l(f);			/* memory location */
 		hio_read16l(f);			/* sample number */
@@ -112,12 +134,13 @@ static int psm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		mod->xxs[i].lpe = hio_read32l(f);
 		finetune = (int8)(hio_read8(f) << 4);
 		mod->xxi[i].sub[0].vol = hio_read8(f);
-		c2spd = 8363 * hio_read16l(f) / 8448;
+		c2spd = hio_read16l(f);
 		mod->xxi[i].sub[0].pan = 0x80;
 		mod->xxi[i].sub[0].sid = i;
 		mod->xxs[i].flg = flags & 0x80 ? XMP_SAMPLE_LOOP : 0;
 		mod->xxs[i].flg |= flags & 0x20 ? XMP_SAMPLE_LOOP_BIDIR : 0;
-		c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo,
+
+		libxmp_c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo,
 						&mod->xxi[i].sub[0].fin);
 		mod->xxi[i].sub[0].fin += finetune;
 
@@ -130,7 +153,7 @@ static int psm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			'L' : ' ', mod->xxi[i].sub[0].vol, c2spd);
 	}
 	
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	D_(D_INFO "Stored patterns: %d", mod->pat);
@@ -142,9 +165,15 @@ static int psm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		len = hio_read16l(f) - 4;
 		rows = hio_read8(f);
+		if (rows > 64) {
+			return -1;
+		}
 		chan = hio_read8(f);
+		if (chan > 32) {
+			return -1;
+		}
 
-		if (pattern_tracks_alloc(mod, i, rows) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
 			return -1;
 
 		for (r = 0; r < rows; r++) {
@@ -189,7 +218,7 @@ static int psm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	for (i = 0; i < mod->ins; i++) {
 		hio_seek(f, start + p_smp[i], SEEK_SET);
-		if (load_sample(m, f, SAMPLE_FLAG_DIFF,
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_DIFF,
 				&mod->xxs[mod->xxi[i].sub[0].sid], NULL) < 0)
 			return -1;
 	}
diff --git a/src/loaders/pt3_load.c b/src/loaders/pt3_load.c
index 1c6b084..1c3fbae 100644
--- a/src/loaders/pt3_load.c
+++ b/src/loaders/pt3_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include 
@@ -20,7 +34,7 @@ static int pt3_test(HIO_HANDLE *, char *, const int);
 static int pt3_load(struct module_data *, HIO_HANDLE *, const int);
 static int ptdt_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader pt3_loader = {
+const struct format_loader libxmp_loader_pt3 = {
 	"Protracker 3",
 	pt3_test,
 	pt3_load
@@ -45,9 +59,9 @@ static int pt3_test(HIO_HANDLE *f, char *t, const int start)
 	
 	if (hio_read32b(f) == MAGIC_INFO) {
 		hio_read32b(f);	/* skip size */
-		read_title(f, t, 32);
+		libxmp_read_title(f, t, 32);
 	} else {
-		read_title(f, t, 0);
+		libxmp_read_title(f, t, 0);
 	}
 
 	return 0;
@@ -66,7 +80,7 @@ static int pt3_test(HIO_HANDLE *f, char *t, const int start)
 static int get_info(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 {
 	struct xmp_module *mod = &m->mod;
-	int flags;
+	/* int flags; */
 	/* int day, month, year, hour, min, sec;
 	int dhour, dmin, dsec; */
 
@@ -76,7 +90,7 @@ static int get_info(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	mod->pat = hio_read16b(f);
 	mod->gvl = hio_read16b(f);
 	mod->bpm = hio_read16b(f);
-	flags = hio_read16b(f);
+	/*flags =*/ hio_read16b(f);
 	/*day   =*/ hio_read16b(f);
 	/*month =*/ hio_read16b(f);
 	/*year  =*/ hio_read16b(f);
@@ -87,6 +101,11 @@ static int get_info(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
 	/*dmin  =*/ hio_read16b(f);
 	/*dsec  =*/ hio_read16b(f);
 
+	/* Sanity check */
+	if (mod->ins > 255 || mod->len > 256 || mod->pat > 255) {
+		return -1;
+	}
+
 	MODULE_INFO();
 
 	/*D_(D_INFO "Creation date: %02d/%02d/%02d %02d:%02d:%02d",
@@ -125,29 +144,34 @@ static int pt3_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	hio_read32b(f);		/* VERS size */
 
 	hio_read(buf, 1, 10, f);
-	set_type(m, "%-6.6s IFFMODL", buf + 4);
+	libxmp_set_type(m, "%-6.6s IFFMODL", buf + 4);
 
-	handle = iff_new();
+	handle = libxmp_iff_new();
 	if (handle == NULL)
 		return -1;
 
 	/* IFF chunk IDs */
-	ret = iff_register(handle, "INFO", get_info);
-	ret |= iff_register(handle, "CMNT", get_cmnt);
-	ret |= iff_register(handle, "PTDT", get_ptdt);
+	ret = libxmp_iff_register(handle, "INFO", get_info);
+	ret |= libxmp_iff_register(handle, "CMNT", get_cmnt);
+	ret |= libxmp_iff_register(handle, "PTDT", get_ptdt);
 
 	if (ret != 0)
 		return -1;
 
-	iff_set_quirk(handle, IFF_FULL_CHUNK_SIZE);
+	libxmp_iff_set_quirk(handle, IFF_FULL_CHUNK_SIZE);
 
 	/* Load IFF chunks */
-	if (iff_load(handle, m, f, NULL) < 0) {
-		iff_release(handle);
+	if (libxmp_iff_load(handle, m, f, NULL) < 0) {
+		libxmp_iff_release(handle);
 		return -1;
 	}
 
-	iff_release(handle);
+	libxmp_iff_release(handle);
+
+	/* Sanity check */
+	if (m->mod.smp <= 0) {
+		return -1;
+	}
 
 	return 0;
 }
@@ -189,11 +213,11 @@ static int ptdt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->pat++;
 	mod->trk = mod->chn * mod->pat;
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	for (i = 0; i < mod->ins; i++) {
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 
 		mod->xxs[i].len = 2 * mh.ins[i].size;
@@ -210,7 +234,7 @@ static int ptdt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		mod->xxi[i].sub[0].sid = i;
 		mod->xxi[i].rls = 0xfff;
 
-		instrument_name(mod, i, mh.ins[i].name, 22);
+		libxmp_instrument_name(mod, i, mh.ins[i].name, 22);
 
 		D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d",
 				i, mod->xxi[i].name,
@@ -221,24 +245,24 @@ static int ptdt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				mod->xxi[i].sub[0].fin >> 4);
 	}
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	/* Load and convert patterns */
 	D_(D_INFO "Stored patterns: %d", mod->pat);
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 			return -1;
 
 		for (j = 0; j < (64 * 4); j++) {
 			event = &EVENT(i, j % 4, j / 4);
 			hio_read(mod_event, 1, 4, f);
-			decode_protracker_event(event, mod_event);
+			libxmp_decode_protracker_event(event, mod_event);
 		}
 	}
 
-	m->quirk |= QUIRK_MODRNG;
+	m->period_type = PERIOD_MODRNG;
 
 	/* Load samples */
 	D_(D_INFO "Stored samples: %d", mod->smp);
@@ -247,7 +271,7 @@ static int ptdt_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		if (!mod->xxs[i].len)
 			continue;
 
-		if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
 			return -1;
 	}
 
diff --git a/src/loaders/ptm_load.c b/src/loaders/ptm_load.c
index 45c2c71..ae4d256 100644
--- a/src/loaders/ptm_load.c
+++ b/src/loaders/ptm_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -23,7 +23,6 @@
 #include "loader.h"
 #include "period.h"
 
-
 #define PTM_CH_MASK	0x1f
 #define PTM_NI_FOLLOW	0x20
 #define PTM_VOL_FOLLOWS	0x80
@@ -69,276 +68,284 @@ struct ptm_instrument_header {
 
 #define MAGIC_PTMF	MAGIC4('P','T','M','F')
 
+static int ptm_test(HIO_HANDLE *, char *, const int);
+static int ptm_load(struct module_data *, HIO_HANDLE *, const int);
 
-static int ptm_test (HIO_HANDLE *, char *, const int);
-static int ptm_load (struct module_data *, HIO_HANDLE *, const int);
-
-const struct format_loader ptm_loader = {
-    "Poly Tracker",
-    ptm_test,
-    ptm_load
+const struct format_loader libxmp_loader_ptm = {
+	"Poly Tracker",
+	ptm_test,
+	ptm_load
 };
 
 static int ptm_test(HIO_HANDLE *f, char *t, const int start)
 {
-    hio_seek(f, start + 44, SEEK_SET);
-    if (hio_read32b(f) != MAGIC_PTMF)
-	return -1;
+	hio_seek(f, start + 44, SEEK_SET);
+	if (hio_read32b(f) != MAGIC_PTMF)
+		return -1;
 
-    hio_seek(f, start + 0, SEEK_SET);
-    read_title(f, t, 28);
+	hio_seek(f, start + 0, SEEK_SET);
+	libxmp_read_title(f, t, 28);
 
-    return 0;
+	return 0;
 }
 
-
 static const int ptm_vol[] = {
-     0,  5,  8, 10, 12, 14, 15, 17, 18, 20, 21, 22, 23, 25, 26,
-    27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40,
-    41, 42, 42, 43, 44, 45, 46, 46, 47, 48, 49, 49, 50, 51, 51,
-    52, 53, 54, 54, 55, 56, 56, 57, 58, 58, 59, 59, 60, 61, 61,
-    62, 63, 63, 64, 64
+	0, 5, 8, 10, 12, 14, 15, 17, 18, 20, 21, 22, 23, 25, 26,
+	27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40,
+	41, 42, 42, 43, 44, 45, 46, 46, 47, 48, 49, 49, 50, 51, 51,
+	52, 53, 54, 54, 55, 56, 56, 57, 58, 58, 59, 59, 60, 61, 61,
+	62, 63, 63, 64, 64
 };
 
-
 static int ptm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 {
-    struct xmp_module *mod = &m->mod;
-    int c, r, i, smp_ofs[256];
-    struct xmp_event *event;
-    struct ptm_file_header pfh;
-    struct ptm_instrument_header pih;
-    uint8 n, b;
-
-    LOAD_INIT();
-
-    /* Load and convert header */
-
-    hio_read(&pfh.name, 28, 1, f);	/* Song name */
-    pfh.doseof = hio_read8(f);		/* 0x1a */
-    pfh.vermin = hio_read8(f);		/* Minor version */
-    pfh.vermaj = hio_read8(f);		/* Major type */
-    pfh.rsvd1 = hio_read8(f);		/* Reserved */
-    pfh.ordnum = hio_read16l(f);	/* Number of orders (must be even) */
-    pfh.insnum = hio_read16l(f);	/* Number of instruments */
-    pfh.patnum = hio_read16l(f);	/* Number of patterns */
-    pfh.chnnum = hio_read16l(f);	/* Number of channels */
-    pfh.flags = hio_read16l(f);		/* Flags (set to 0) */
-    pfh.rsvd2 = hio_read16l(f);		/* Reserved */
-    pfh.magic = hio_read32b(f); 	/* 'PTMF' */
-
-#if 0
-    if (pfh.magic != MAGIC_PTMF)
-	return -1;
-#endif
-
-    hio_read(&pfh.rsvd3, 16, 1, f);	/* Reserved */
-    hio_read(&pfh.chset, 32, 1, f);	/* Channel settings */
-    hio_read(&pfh.order, 256, 1, f);	/* Orders */
-    for (i = 0; i < 128; i++)
-	pfh.patseg[i] = hio_read16l(f);
-
-    mod->len = pfh.ordnum;
-    mod->ins = pfh.insnum;
-    mod->pat = pfh.patnum;
-    mod->chn = pfh.chnnum;
-    mod->trk = mod->pat * mod->chn;
-    mod->smp = mod->ins;
-    mod->spd = 6;
-    mod->bpm = 125;
-    memcpy (mod->xxo, pfh.order, 256);
-
-    m->c4rate = C4_NTSC_RATE;
-
-    copy_adjust(mod->name, pfh.name, 28);
-    set_type(m, "Poly Tracker PTM %d.%02x",
-	pfh.vermaj, pfh.vermin);
-
-    MODULE_INFO();
-
-    if (instrument_init(mod) < 0)
-	return -1;
-
-    /* Read and convert instruments and samples */
-
-    for (i = 0; i < mod->ins; i++) {
-	struct xmp_instrument *xxi = &mod->xxi[i];
-	struct xmp_sample *xxs = &mod->xxs[i];
-	struct xmp_subinstrument *sub;
-
-	pih.type = hio_read8(f);		/* Sample type */
-	hio_read(&pih.dosname, 12, 1, f);	/* DOS file name */
-	pih.vol = hio_read8(f);			/* Volume */
-	pih.c4spd = hio_read16l(f);		/* C4 speed */
-	pih.smpseg = hio_read16l(f);		/* Sample segment (not used) */
-	pih.smpofs = hio_read32l(f);		/* Sample offset */
-	pih.length = hio_read32l(f);		/* Length */
-	pih.loopbeg = hio_read32l(f);		/* Loop begin */
-	pih.loopend = hio_read32l(f);		/* Loop end */
-	pih.gusbeg = hio_read32l(f);		/* GUS begin address */
-	pih.guslps = hio_read32l(f);		/* GUS loop start address */
-	pih.guslpe = hio_read32l(f);		/* GUS loop end address */
-	pih.gusflg = hio_read8(f);		/* GUS loop flags */
-	pih.rsvd1 = hio_read8(f);		/* Reserved */
-	hio_read(&pih.name, 28, 1, f);		/* Instrument name */
-	pih.magic = hio_read32b(f);		/* 'PTMS' */
-
-	if ((pih.type & 3) != 1)
-	    continue;
-
-	if (subinstrument_alloc(mod, i, 1) < 0)
-	    return -1;
-
-	sub = &xxi->sub[0];
-
-	smp_ofs[i] = pih.smpofs;
-	xxs->len = pih.length;
-	xxs->lps = pih.loopbeg;
-	xxs->lpe = pih.loopend;
-
-	if (mod->xxs[i].len > 0)
-		mod->xxi[i].nsm = 1;
-
-	xxs->flg = 0;
-	if (pih.type & 0x04) {
-	    xxs->flg |= XMP_SAMPLE_LOOP;
+	struct xmp_module *mod = &m->mod;
+	int c, r, i, smp_ofs[256];
+	struct xmp_event *event;
+	struct ptm_file_header pfh;
+	struct ptm_instrument_header pih;
+	uint8 n, b;
+
+	LOAD_INIT();
+
+	/* Load and convert header */
+
+	hio_read(&pfh.name, 28, 1, f);	/* Song name */
+	pfh.doseof = hio_read8(f);	/* 0x1a */
+	pfh.vermin = hio_read8(f);	/* Minor version */
+	pfh.vermaj = hio_read8(f);	/* Major type */
+	pfh.rsvd1 = hio_read8(f);	/* Reserved */
+	pfh.ordnum = hio_read16l(f);	/* Number of orders (must be even) */
+	pfh.insnum = hio_read16l(f);	/* Number of instruments */
+	pfh.patnum = hio_read16l(f);	/* Number of patterns */
+	pfh.chnnum = hio_read16l(f);	/* Number of channels */
+	pfh.flags = hio_read16l(f);	/* Flags (set to 0) */
+	pfh.rsvd2 = hio_read16l(f);	/* Reserved */
+	pfh.magic = hio_read32b(f);	/* 'PTMF' */
+
+	if (pfh.magic != MAGIC_PTMF)
+		return -1;
+
+	/* Sanity check */
+	if (pfh.ordnum > 256 || pfh.insnum > 255 || pfh.patnum > 128 ||
+	    pfh.chnnum > 32) {
+		return -1;
 	}
-	if (pih.type & 0x08) {
-	    xxs->flg |= XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR;
-	}
-	if (pih.type & 0x10) {
-	    xxs->flg |= XMP_SAMPLE_16BIT;
-	    xxs->len >>= 1;
-	    xxs->lps >>= 1;
-	    xxs->lpe >>= 1;
+
+	hio_read(&pfh.rsvd3, 16, 1, f);	/* Reserved */
+	hio_read(&pfh.chset, 32, 1, f);	/* Channel settings */
+	hio_read(&pfh.order, 256, 1, f);	/* Orders */
+	for (i = 0; i < 128; i++)
+		pfh.patseg[i] = hio_read16l(f);
+
+	mod->len = pfh.ordnum;
+	mod->ins = pfh.insnum;
+	mod->pat = pfh.patnum;
+	mod->chn = pfh.chnnum;
+	mod->trk = mod->pat * mod->chn;
+	mod->smp = mod->ins;
+	mod->spd = 6;
+	mod->bpm = 125;
+	memcpy(mod->xxo, pfh.order, 256);
+
+	m->c4rate = C4_NTSC_RATE;
+
+	libxmp_copy_adjust(mod->name, pfh.name, 28);
+	libxmp_set_type(m, "Poly Tracker PTM %d.%02x", pfh.vermaj, pfh.vermin);
+
+	MODULE_INFO();
+
+	if (libxmp_init_instrument(m) < 0) {
+		return -1;
 	}
 
-	sub->vol = pih.vol;
-	sub->pan = 0x80;
-	sub->sid = i;
-	pih.magic = 0;
-
-	instrument_name(mod, i, pih.name, 28);
-
-	D_(D_INFO "[%2X] %-28.28s %05x%c%05x %05x %c V%02x %5d",
-		i, mod->xxi[i].name, mod->xxs[i].len,
-		pih.type & 0x10 ? '+' : ' ',
-		xxs->lps, xxs->lpe, xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
-		sub->vol, pih.c4spd);
-
-	/* Convert C4SPD to relnote/finetune */
-	c2spd_to_note(pih.c4spd, &sub->xpo, &sub->fin);
-    }
-
-    if (pattern_init(mod) < 0)
-	return -1;
-
-    /* Read patterns */
-    D_(D_INFO "Stored patterns: %d", mod->pat);
-
-    for (i = 0; i < mod->pat; i++) {
-	if (!pfh.patseg[i])
-	    continue;
-
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
-	    return -1;
-
-	hio_seek(f, start + 16L * pfh.patseg[i], SEEK_SET);
-	r = 0;
-	while (r < 64) {
-	    b = hio_read8(f);
-	    if (!b) {
-		r++;
-		continue;
-	    }
-
-	    c = b & PTM_CH_MASK;
-	    if (c >= mod->chn)
-		continue;
-
-	    event = &EVENT (i, c, r);
-	    if (b & PTM_NI_FOLLOW) {
-		n = hio_read8(f);
-		switch (n) {
-		case 255:
-		    n = 0;
-		    break;	/* Empty note */
-		case 254:
-		    n = XMP_KEY_OFF;
-		    break;	/* Key off */
-		default:
-		    n += 12;
+	/* Read and convert instruments and samples */
+
+	for (i = 0; i < mod->ins; i++) {
+		struct xmp_instrument *xxi = &mod->xxi[i];
+		struct xmp_sample *xxs = &mod->xxs[i];
+		struct xmp_subinstrument *sub;
+
+		pih.type = hio_read8(f);	/* Sample type */
+		hio_read(&pih.dosname, 12, 1, f);	/* DOS file name */
+		pih.vol = hio_read8(f);		/* Volume */
+		pih.c4spd = hio_read16l(f);	/* C4 speed */
+		pih.smpseg = hio_read16l(f);	/* Sample segment (not used) */
+		pih.smpofs = hio_read32l(f);	/* Sample offset */
+		pih.length = hio_read32l(f);	/* Length */
+		pih.loopbeg = hio_read32l(f);	/* Loop begin */
+		pih.loopend = hio_read32l(f);	/* Loop end */
+		pih.gusbeg = hio_read32l(f);	/* GUS begin address */
+		pih.guslps = hio_read32l(f);	/* GUS loop start address */
+		pih.guslpe = hio_read32l(f);	/* GUS loop end address */
+		pih.gusflg = hio_read8(f);	/* GUS loop flags */
+		pih.rsvd1 = hio_read8(f);	/* Reserved */
+		hio_read(&pih.name, 28, 1, f);	/* Instrument name */
+		pih.magic = hio_read32b(f);	/* 'PTMS' */
+
+		if (hio_error(f)) {
+			return -1;
 		}
-		event->note = n;
-		event->ins = hio_read8(f);
-	    }
-	    if (b & PTM_FX_FOLLOWS) {
-		event->fxt = hio_read8(f);
-		event->fxp = hio_read8(f);
-
-		if (event->fxt > 0x17)
-			event->fxt = event->fxp = 0;
-
-		switch (event->fxt) {
-		case 0x0e:	/* Extended effect */
-		    if (MSN(event->fxp) == 0x8) {	/* Pan set */
-			event->fxt = FX_SETPAN;
-			event->fxp = LSN (event->fxp) << 4;
-		    }
-		    break;
-		case 0x10:	/* Set global volume */
-		    event->fxt = FX_GLOBALVOL;
-		    break;
-		case 0x11:	/* Multi retrig */
-		    event->fxt = FX_MULTI_RETRIG;
-		    break;
-		case 0x12:	/* Fine vibrato */
-		    event->fxt = FX_FINE_VIBRATO;
-		    break;
-		case 0x13:	/* Note slide down */
-		    event->fxt = FX_NSLIDE_DN;
-		    break;
-		case 0x14:	/* Note slide up */
-		    event->fxt = FX_NSLIDE_UP;
-		    break;
-		case 0x15:	/* Note slide down + retrig */
-		    event->fxt = FX_NSLIDE_R_DN;
-		    break;
-		case 0x16:	/* Note slide up + retrig */
-		    event->fxt = FX_NSLIDE_R_UP;
-		    break;
-		case 0x17:	/* Reverse sample */
-		    event->fxt = event->fxp = 0;
-		    break;
+
+		if ((pih.type & 3) != 1)
+			continue;
+
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0) {
+			return -1;
 		}
-	    }
-	    if (b & PTM_VOL_FOLLOWS) {
-		event->vol = hio_read8(f) + 1;
-	    }
+
+		sub = &xxi->sub[0];
+
+		smp_ofs[i] = pih.smpofs;
+		xxs->len = pih.length;
+		xxs->lps = pih.loopbeg;
+		xxs->lpe = pih.loopend;
+
+		if (mod->xxs[i].len > 0) {
+			mod->xxi[i].nsm = 1;
+		}
+
+		xxs->flg = 0;
+		if (pih.type & 0x04) {
+			xxs->flg |= XMP_SAMPLE_LOOP;
+		}
+		if (pih.type & 0x08) {
+			xxs->flg |= XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR;
+		}
+		if (pih.type & 0x10) {
+			xxs->flg |= XMP_SAMPLE_16BIT;
+			xxs->len >>= 1;
+			xxs->lps >>= 1;
+			xxs->lpe >>= 1;
+		}
+
+		sub->vol = pih.vol;
+		sub->pan = 0x80;
+		sub->sid = i;
+		pih.magic = 0;
+
+		libxmp_instrument_name(mod, i, pih.name, 28);
+
+		D_(D_INFO "[%2X] %-28.28s %05x%c%05x %05x %c V%02x %5d",
+		   i, mod->xxi[i].name, mod->xxs[i].len,
+		   pih.type & 0x10 ? '+' : ' ',
+		   xxs->lps, xxs->lpe, xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
+		   sub->vol, pih.c4spd);
+
+		/* Convert C4SPD to relnote/finetune */
+		libxmp_c2spd_to_note(pih.c4spd, &sub->xpo, &sub->fin);
 	}
-    }
 
-    D_(D_INFO "Stored samples: %d", mod->smp);
+	if (libxmp_init_pattern(mod) < 0)
+		return -1;
+
+	/* Read patterns */
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	for (i = 0; i < mod->pat; i++) {
+		if (!pfh.patseg[i])
+			continue;
+
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
+			return -1;
+
+		hio_seek(f, start + 16L * pfh.patseg[i], SEEK_SET);
+		r = 0;
+		while (r < 64) {
+			b = hio_read8(f);
+			if (!b) {
+				r++;
+				continue;
+			}
+
+			c = b & PTM_CH_MASK;
+			if (c >= mod->chn)
+				continue;
+
+			event = &EVENT(i, c, r);
+			if (b & PTM_NI_FOLLOW) {
+				n = hio_read8(f);
+				switch (n) {
+				case 255:
+					n = 0;
+					break;	/* Empty note */
+				case 254:
+					n = XMP_KEY_OFF;
+					break;	/* Key off */
+				default:
+					n += 12;
+				}
+				event->note = n;
+				event->ins = hio_read8(f);
+			}
+			if (b & PTM_FX_FOLLOWS) {
+				event->fxt = hio_read8(f);
+				event->fxp = hio_read8(f);
+
+				if (event->fxt > 0x17)
+					event->fxt = event->fxp = 0;
+
+				switch (event->fxt) {
+				case 0x0e:	/* Extended effect */
+					if (MSN(event->fxp) == 0x8) {	/* Pan set */
+						event->fxt = FX_SETPAN;
+						event->fxp =
+						    LSN(event->fxp) << 4;
+					}
+					break;
+				case 0x10:	/* Set global volume */
+					event->fxt = FX_GLOBALVOL;
+					break;
+				case 0x11:	/* Multi retrig */
+					event->fxt = FX_MULTI_RETRIG;
+					break;
+				case 0x12:	/* Fine vibrato */
+					event->fxt = FX_FINE_VIBRATO;
+					break;
+				case 0x13:	/* Note slide down */
+					event->fxt = FX_NSLIDE_DN;
+					break;
+				case 0x14:	/* Note slide up */
+					event->fxt = FX_NSLIDE_UP;
+					break;
+				case 0x15:	/* Note slide down + retrig */
+					event->fxt = FX_NSLIDE_R_DN;
+					break;
+				case 0x16:	/* Note slide up + retrig */
+					event->fxt = FX_NSLIDE_R_UP;
+					break;
+				case 0x17:	/* Reverse sample */
+					event->fxt = event->fxp = 0;
+					break;
+				}
+			}
+			if (b & PTM_VOL_FOLLOWS) {
+				event->vol = hio_read8(f) + 1;
+			}
+		}
+	}
+
+	D_(D_INFO "Stored samples: %d", mod->smp);
 
-    for (i = 0; i < mod->smp; i++) {
-	if (mod->xxi[i].nsm == 0)
-	    continue;
+	for (i = 0; i < mod->smp; i++) {
+		if (mod->xxi[i].nsm == 0)
+			continue;
 
-	if (mod->xxs[i].len == 0)
-	    continue;
+		if (mod->xxs[i].len == 0)
+			continue;
 
-	hio_seek(f, start + smp_ofs[i], SEEK_SET);
-	if (load_sample(m, f, SAMPLE_FLAG_8BDIFF, &mod->xxs[i], NULL) < 0)
-	    return -1;
-    }
+		hio_seek(f, start + smp_ofs[i], SEEK_SET);
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_8BDIFF, &mod->xxs[i], NULL) < 0)
+			return -1;
+	}
 
-    m->vol_table = (int *)ptm_vol;
+	m->vol_table = (int *)ptm_vol;
 
-    for (i = 0; i < mod->chn; i++)
-	mod->xxc[i].pan = pfh.chset[i] << 4;
+	for (i = 0; i < mod->chn; i++)
+		mod->xxc[i].pan = pfh.chset[i] << 4;
 
-    m->quirk |= QUIRKS_ST3;
-    m->read_event_type = READ_EVENT_ST3;
+	m->quirk |= QUIRKS_ST3;
+	m->read_event_type = READ_EVENT_ST3;
 
-    return 0;
+	return 0;
 }
diff --git a/src/loaders/pw_load.c b/src/loaders/pw_load.c
index d2240ec..8db0e7d 100644
--- a/src/loaders/pw_load.c
+++ b/src/loaders/pw_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include 
@@ -16,13 +30,14 @@
 #include "mod.h"
 #include "period.h"
 #include "prowizard/prowiz.h"
+#include "tempfile.h"
 
 extern struct list_head *checked_format;
 
 static int pw_test(HIO_HANDLE *, char *, const int);
 static int pw_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader pw_loader = {
+const struct format_loader libxmp_loader_pw = {
 	"prowizard",
 	pw_test,
 	pw_load
@@ -30,7 +45,7 @@ const struct format_loader pw_loader = {
 
 #define BUF_SIZE 0x10000
 
-int pw_test_format(FILE *f, char *t, const int start,
+int pw_test_format(HIO_HANDLE *f, char *t, const int start,
 		   struct xmp_test_info *info)
 {
 	unsigned char *b;
@@ -41,7 +56,7 @@ int pw_test_format(FILE *f, char *t, const int start,
 	if (b == NULL)
 		return -1;
 
-	fread(b, s, 1, f);
+	s = hio_read(b, 1, s, f);
 
 	while ((extra = pw_check(b, s, info)) > 0) {
 		unsigned char *buf = realloc(b, s + extra);
@@ -50,7 +65,12 @@ int pw_test_format(FILE *f, char *t, const int start,
 			return -1;
 		}
 		b = buf;
-		fread(b + s, extra, 1, f);
+
+		if (hio_read(b + s, extra, 1, f) == 0) {
+			free(b);
+			return -1;
+		}
+
 		s += extra;
 	}
 
@@ -61,49 +81,41 @@ int pw_test_format(FILE *f, char *t, const int start,
 
 static int pw_test(HIO_HANDLE *f, char *t, const int start)
 {
-	if (HIO_HANDLE_TYPE(f) != HIO_HANDLE_TYPE_FILE)
-		return -1;
-
-	return pw_test_format(f->handle.file, t, start, NULL);
+	return pw_test_format(f, t, start, NULL);
 }
 
-static int pw_load(struct module_data *m, HIO_HANDLE *f, const int start)
+static int pw_load(struct module_data *m, HIO_HANDLE *h, const int start)
 {
 	struct xmp_module *mod = &m->mod;
 	struct xmp_event *event;
 	struct mod_header mh;
 	uint8 mod_event[4];
+	HIO_HANDLE *f;
+	FILE *temp;
 	char *name;
-	char tmp[PATH_MAX];
+	char *temp_name;
 	int i, j;
-	int fd;
 
 	/* Prowizard depacking */
 
-	if (get_temp_dir(tmp, PATH_MAX) < 0)
-		return -1;
-
-	strncat(tmp, "xmp_XXXXXX", PATH_MAX - 10);
-
-	if ((fd = mkstemp(tmp)) < 0)
-		return -1;
-
-	if (pw_wizardry(fileno(f->handle.file), fd, &name) < 0) {
-		close(fd);
-		unlink(tmp);
-		return -1;
+	if ((temp = make_temp_file(&temp_name)) == NULL) {
+		goto err;
 	}
 
-	if ((f = hio_open_fd(fd, "w+b")) == NULL) {
-		close(fd);
-		unlink(tmp);
-		return -1;
+	if (pw_wizardry(h, temp, &name) < 0) {
+		fclose(temp);
+		goto err2;
 	}
-
-
+	
 	/* Module loading */
 
-	LOAD_INIT();
+	if ((f = hio_open_file(temp)) == NULL) {
+		goto err2;
+	}
+
+	if (hio_seek(f, 0, start) < 0) {
+		goto err3;
+	}
 
 	hio_read(&mh.name, 20, 1, f);
 	for (i = 0; i < 31; i++) {
@@ -119,8 +131,9 @@ static int pw_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	hio_read(&mh.order, 128, 1, f);
 	hio_read(&mh.magic, 4, 1, f);
 
-	if (memcmp(mh.magic, "M.K.", 4))
-		goto err;
+	if (memcmp(mh.magic, "M.K.", 4)) {
+		goto err3;
+	}
 		
 	mod->ins = 31;
 	mod->smp = mod->ins;
@@ -130,8 +143,6 @@ static int pw_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	memcpy(mod->xxo, mh.order, 128);
 
 	for (i = 0; i < 128; i++) {
-		if (mod->chn > 4)
-			mod->xxo[i] >>= 1;
 		if (mod->xxo[i] > mod->pat)
 			mod->pat = mod->xxo[i];
 	}
@@ -144,12 +155,13 @@ static int pw_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	snprintf(mod->type, XMP_NAME_SIZE, "%s", name);
 	MODULE_INFO();
 
-	if (instrument_init(mod) < 0)
-	    return -1;
+	if (libxmp_init_instrument(m) < 0) {
+		goto err3;
+	}
 
 	for (i = 0; i < mod->ins; i++) {
-		if (subinstrument_alloc(mod, i, 1) < 0)
-			return -1;
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			goto err3;
 
 		mod->xxs[i].len = 2 * mh.ins[i].size;
 		mod->xxs[i].lps = 2 * mh.ins[i].loop_start;
@@ -164,7 +176,7 @@ static int pw_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		if (mod->xxs[i].len > 0)
 			mod->xxi[i].nsm = 1;
 
-		instrument_name(mod, i, mh.ins[i].name, 22);
+		libxmp_instrument_name(mod, i, mh.ins[i].name, 22);
 
 		D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d",
 			     i, mod->xxi[i].name, mod->xxs[i].len,
@@ -174,39 +186,42 @@ static int pw_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			     mod->xxi[i].sub[0].fin >> 4);
 	}
 
-	if (pattern_init(mod) < 0)
-		return -1;
+	if (libxmp_init_pattern(mod) < 0) {
+		goto err3;
+	}
 
 	/* Load and convert patterns */
 	D_(D_INFO "Stored patterns: %d", mod->pat);
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
-			return -1;
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
+			goto err3;
 
 		for (j = 0; j < (64 * 4); j++) {
 			event = &EVENT(i, j % 4, j / 4);
 			hio_read(mod_event, 1, 4, f);
-			decode_protracker_event(event, mod_event);
+			libxmp_decode_protracker_event(event, mod_event);
 		}
 	}
 
-	m->quirk |= QUIRK_MODRNG;
+	m->period_type = PERIOD_MODRNG;
 
 	/* Load samples */
 
 	D_(D_INFO "Stored samples: %d", mod->smp);
 	for (i = 0; i < mod->smp; i++) {
-		if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
-			goto err;
+		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+			goto err3;
 	}
 
 	hio_close(f);
-	unlink(tmp);
+	unlink_temp_file(temp_name);
 	return 0;
 
-err:
+    err3:
 	hio_close(f);
-	unlink(tmp);
+    err2:
+	unlink_temp_file(temp_name);
+    err:
 	return -1;
 }
diff --git a/src/loaders/rad_load.c b/src/loaders/rad_load.c
index a8f7eda..9438df7 100644
--- a/src/loaders/rad_load.c
+++ b/src/loaders/rad_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -12,7 +26,7 @@
 static int rad_test(HIO_HANDLE *, char *, const int);
 static int rad_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader rad_loader = {
+const struct format_loader libxmp_loader_rad = {
 	"Reality Adlib Tracker",
 	rad_test,
 	rad_load
@@ -28,7 +42,7 @@ static int rad_test(HIO_HANDLE *f, char *t, const int start)
 	if (memcmp(buf, "RAD by REALiTY!!", 16))
 		return -1;
 
-	read_title(f, t, 0);
+	libxmp_read_title(f, t, 0);
 
 	return 0;
 }
@@ -44,7 +58,7 @@ static int rad_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	struct xmp_module *mod = &m->mod;
 	struct xmp_event *event;
 	int i, j;
-	uint8 sid[11];
+	uint8 *buf;
 	uint16 ppat[32];
 	uint8 b, r, c;
 	uint8 version;		/* Version in BCD */
@@ -66,7 +80,7 @@ static int rad_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		mod->spd = 6;
 	mod->smp = 0;
 
-	set_type(m, "RAD %d.%d", MSN(version), LSN(version));
+	libxmp_set_type(m, "RAD %d.%d", MSN(version), LSN(version));
 
 	MODULE_INFO();
 
@@ -78,40 +92,65 @@ static int rad_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	/* Read instruments */
 	D_(D_INFO "Read instruments");
 
-	pos = hio_tell(f);
+	if ((pos = hio_tell(f)) < 0) {
+		goto err;
+	}
 
 	mod->ins = 0;
 	while ((b = hio_read8(f)) != 0) {
-		mod->ins = b;
-		hio_read(sid, 1, 11, f);
+		if (b > mod->ins) {
+			mod->ins = b;
+		}
+		if (hio_seek(f, 11, SEEK_CUR) < 0) {
+			return -1;
+		}
 	}
 
 	hio_seek(f, pos, SEEK_SET);
 	mod->smp = mod->ins;
 
-	if (instrument_init(mod) < 0)
-		return -1;
+	if (libxmp_init_instrument(m) < 0) {
+		goto err;
+	}
+
+	if ((buf = calloc(mod->ins, 11)) == NULL) {
+		goto err;
+	}
 
 	while ((b = hio_read8(f)) != 0) {
-		hio_read(sid, 1, 11, f);
-		if (load_sample(m, f, SAMPLE_FLAG_ADLIB | SAMPLE_FLAG_HSC,
-					&mod->xxs[b - 1], (char *)sid) < 0) {
-			return -1;
+
+		/* Sanity check */
+		if (b > mod->ins || mod->xxs[b - 1].data != NULL) {
+			goto err2;
+		}
+
+		if (hio_read(&buf[(b - 1) * 11], 1, 11, f) != 11) {
+			goto err2;
+		}
+
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_ADLIB | SAMPLE_FLAG_HSC,
+					&mod->xxs[b - 1], &buf[(b - 1) * 11]) < 0) {
+			goto err2;
 		}
 	}
 
 	for (i = 0; i < mod->ins; i++) {
-		if (subinstrument_alloc(mod, i, 1) < 0)
-			return -1;
-		mod->xxi[i].sub[0].vol = 0x40;
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0) {
+			goto err2;
+		}
+		mod->xxi[i].sub[0].vol = 63 - (buf[i * 11 + 3] & 63);
 		mod->xxi[i].sub[0].pan = 0x80;
-		mod->xxi[i].sub[0].xpo = -1;
 		mod->xxi[i].sub[0].sid = i;
 		mod->xxi[i].nsm = 1;
 	}
 
+	free(buf);
+
 	/* Read orders */
 	mod->len = hio_read8(f);
+	if (hio_error(f) || mod->len >= 128) {
+		goto err;
+	}
 
 	for (j = i = 0; i < mod->len; i++) {
 		b = hio_read8(f);
@@ -131,31 +170,38 @@ static int rad_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	D_(D_INFO "Instruments: %d", mod->ins);
 	D_(D_INFO "Stored patterns: %d", mod->pat);
 
-	if (pattern_init(mod) < 0)
-		return -1;
+	if (libxmp_init_pattern(mod) < 0) {
+		goto err;
+	}
 
 	/* Read and convert patterns */
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
-			return -1;
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0) {
+			goto err;
+		}
 
-		if (ppat[i] == 0)
+		if (ppat[i] == 0) {
 			continue;
+		}
 
-		hio_seek(f, start + ppat[i], SEEK_SET);
+		if (hio_seek(f, start + ppat[i], SEEK_SET) < 0) {
+			goto err;
+		}
 
 		do {
 			r = hio_read8(f);		/* Row number */
 
 			if ((r & 0x7f) >= 64) {
 				D_(D_CRIT "** Whoops! row = %d\n", r);
+				goto err;
 			}
 
 			do {
 				c = hio_read8(f);	/* Channel number */
 
-				if ((c & 0x7f) >= mod->chn) {
-					D_(D_CRIT "** Whoops! channel = %d\n", c);
+				/* Sanity check */
+				if ((c & 0x7f) >= mod->chn || (r & 0x7f) >= 64) {
+					goto err;
 				}
 
 				event = &EVENT(i, c & 0x7f, r & 0x7f);
@@ -167,7 +213,7 @@ static int rad_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				if (event->note == 15)
 					event->note = XMP_KEY_OFF;
 				else if (event->note)
-					event->note += 26 +
+					event->note += 25 +
 						12 * ((b & 0x70) >> 4);
 
 				b = hio_read8(f);	/* Inst + effect */
@@ -177,10 +223,31 @@ static int rad_load(struct module_data *m, HIO_HANDLE *f, const int start)
 					b = hio_read8(f); /* Effect parameter */
 					event->fxp = b;
 
-					/* FIXME: tempo setting */
-					if (event->fxt == 0x0f
-					    && event->fxp <= 2)
-						event->fxp = 6;
+					switch (event->fxt) {
+					case 0x05:
+						if (event->fxp > 0 && event->fxp < 50) {
+							event->f2t = FX_VOLSLIDE_DN;
+						} else if (event->fxp > 50 && event->fxp < 100) {
+							event->f2t = FX_VOLSLIDE_UP;
+						}
+						event->f2p = event->fxp;
+						event->fxt = 0x03;
+						event->fxp = 0;
+						
+					case 0x0a:
+						if (event->fxp > 0 && event->fxp < 50) {
+							event->fxt = FX_VOLSLIDE_DN;
+						} else if (event->fxp > 50 && event->fxp < 100) {
+							event->fxt = FX_VOLSLIDE_UP;
+						}
+						break;
+					case 0x0f:
+						/* FIXME: tempo setting */
+					    	if (event->fxp <= 2) {
+							event->fxp = 6;
+						}
+						break;
+					}
 				}
 			} while (~c & 0x80);
 		} while (~r & 0x80);
@@ -193,7 +260,12 @@ static int rad_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	m->synth = &synth_adlib;
 
-	m->quirk |= QUIRK_LINEAR;
+	m->quirk |= QUIRK_LINEAR | QUIRK_VSALL | QUIRK_PBALL | QUIRK_VIBALL;
 
 	return 0;
+
+    err2:
+	free(buf);
+    err:
+	return -1;
 }
diff --git a/src/loaders/rtm_load.c b/src/loaders/rtm_load.c
index 6f04ee7..14346c3 100644
--- a/src/loaders/rtm_load.c
+++ b/src/loaders/rtm_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -115,7 +129,7 @@ struct RTSMHeader {		/* Real Tracker Sample */
 static int rtm_test(HIO_HANDLE *, char *, const int);
 static int rtm_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader rtm_loader = {
+const struct format_loader libxmp_loader_rtm = {
 	"Real Tracker",
 	rtm_test,
 	rtm_load
@@ -133,7 +147,7 @@ static int rtm_test(HIO_HANDLE *f, char *t, const int start)
 	if (hio_read8(f) != 0x20)
 		return -1;
 
-	read_title(f, t, 32);
+	libxmp_read_title(f, t, 32);
 
 	return 0;
 }
@@ -153,7 +167,8 @@ static int read_object_header(HIO_HANDLE *f, struct ObjectHeader *h, char *id)
 	h->rc = hio_read8(f);
 	if (h->rc != 0x20)
 		return -1;
-	hio_read(&h->name, 32, 1, f);
+	if (hio_read(&h->name, 1, 32, f) != 32)
+		return -1;
 	h->eof = hio_read8(f);
 	h->version = hio_read16l(f);
 	h->headerSize = hio_read16l(f);
@@ -197,11 +212,20 @@ static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	hio_read(&rh.panning, 32, 1, f);
 	rh.extraDataSize = hio_read32l(f);
 
+	/* Sanity check */
+	if (rh.nposition > 255 || rh.ntrack > 32 || rh.npattern > 255) {
+		return -1;
+	}
+
 	if (version >= 0x0112)
 		hio_seek(f, 32, SEEK_CUR);		/* skip original name */
 
-	for (i = 0; i < rh.nposition; i++)
+	for (i = 0; i < rh.nposition; i++) {
 		mod->xxo[i] = hio_read16l(f);
+		if (mod->xxo[i] >= rh.npattern) {
+			return -1;
+		}
+	}
 	
 	strncpy(mod->name, oh.name, 20);
 	snprintf(mod->type, XMP_NAME_SIZE, "%s RTM %x.%02x",
@@ -216,14 +240,15 @@ static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->spd = rh.speed;
 	mod->bpm = rh.tempo;
 
-	m->quirk |= rh.flags & 0x01 ? QUIRK_LINEAR : 0;
+	m->c4rate = C4_NTSC_RATE;
+	m->period_type = rh.flags & 0x01 ? PERIOD_LINEAR : PERIOD_AMIGA;
 
 	MODULE_INFO();
 
 	for (i = 0; i < mod->chn; i++)
 		mod->xxc[i].pan = rh.panning[i] & 0xff;
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	D_(D_INFO "Stored patterns: %d", mod->pat);
@@ -245,9 +270,14 @@ static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		rp.nrows = hio_read16l(f);
 		rp.datasize = hio_read32l(f);
 
+		/* Sanity check */
+		if (rp.ntrack > rh.ntrack || rp.nrows > 256) {
+			return -1;
+		}
+
 		offset += 42 + oh.headerSize + rp.datasize;
 
-		if (pattern_tracks_alloc(mod, i, rp.nrows) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, rp.nrows) < 0)
 			return -1;
 
 		for (r = 0; r < rp.nrows; r++) {
@@ -257,17 +287,21 @@ static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				if (c == 0)		/* next row */
 					break;
 
-				/* should never happen! */
+				/* Sanity check */
 				if (j >= rp.ntrack) {
-					D_(D_CRIT "error: decoding "
-						"pattern %d row %d", i, r);
-					break;
+					return -1;
 				}
 
 				event = &EVENT(i, j, r);
 
 				if (c & 0x01) {		/* set track */
 					j = hio_read8(f);
+
+					/* Sanity check */
+					if (j >= rp.ntrack) {
+						return -1;
+					}
+
 					event = &EVENT(i, j, r);
 				}
 				if (c & 0x02) {		/* read note */
@@ -303,7 +337,7 @@ static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	/* ESTIMATED value! We don't know the actual value at this point */
 	mod->smp = MAX_SAMP;
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	smpnum = 0;
@@ -315,7 +349,7 @@ static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			return -1;
 		}
 
-		instrument_name(mod, i, (uint8 *)&oh.name, 32);
+		libxmp_instrument_name(mod, i, (uint8 *)&oh.name, 32);
 
 		if (oh.headerSize == 0) {
 			D_(D_INFO "[%2X] %-26.26s %2d ", i,
@@ -326,9 +360,15 @@ static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		ri.nsample = hio_read8(f);
 		ri.flags = hio_read16l(f);	/* bit 0 : default panning enabled */
-		hio_read(&ri.table, 120, 1, f);
+		if (hio_read(&ri.table, 1, 120, f) != 120)
+			return -1;
 
 		ri.volumeEnv.npoint = hio_read8(f);
+
+		/* Sanity check */
+		if (ri.volumeEnv.npoint >= 12)
+			return -1;
+
 		for (j = 0; j < 12; j++) {
 			ri.volumeEnv.point[j].x = hio_read32l(f);
 			ri.volumeEnv.point[j].y = hio_read32l(f);
@@ -339,6 +379,11 @@ static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		ri.volumeEnv.flags = hio_read16l(f); /* bit 0:enable 1:sus 2:loop */
 		
 		ri.panningEnv.npoint = hio_read8(f);
+
+		/* Sanity check */
+		if (ri.panningEnv.npoint >= 12)
+			return -1;
+
 		for (j = 0; j < 12; j++) {
 			ri.panningEnv.point[j].x = hio_read32l(f);
 			ri.panningEnv.point[j].y = hio_read32l(f);
@@ -374,7 +419,7 @@ static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		if (xxi->nsm > 16)
 			xxi->nsm = 16;
 
-		if (subinstrument_alloc(mod, i, xxi->nsm) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, xxi->nsm) < 0)
 			return -1;
 
 		for (j = 0; j < 120; j++)
@@ -423,25 +468,25 @@ static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			rs.basenote = hio_read8(f);
 			rs.panning = hio_read8(f);
 
-			c2spd_to_note(rs.basefreq, &sub->xpo, &sub->fin);
+			libxmp_c2spd_to_note(rs.basefreq, &sub->xpo, &sub->fin);
 			sub->xpo += 48 - rs.basenote;
 			sub->vol = rs.defaultvolume * rs.basevolume / 0x40;
 			sub->pan = 0x80 + rs.panning * 2;
 			sub->vwf = ri.vibflg;
-			sub->vde = ri.vibdepth;
+			sub->vde = ri.vibdepth << 2;
 			sub->vra = ri.vibrate;
 			sub->vsw = ri.vibsweep;
 			sub->sid = smpnum;
 
 			if (smpnum >= mod->smp) {
-				 mod->xxs = realloc_samples(mod->xxs,
+				 mod->xxs = libxmp_realloc_samples(mod->xxs,
 						&mod->smp, mod->smp * 3 / 2);
 				if (mod->xxs == NULL)
 					return -1;
 			}
  			xxs = &mod->xxs[smpnum];
 
-			copy_adjust(xxs->name, (uint8 *)oh.name, 32);
+			libxmp_copy_adjust(xxs->name, (uint8 *)oh.name, 31);
 
 			xxs->len = rs.length;
 			xxs->lps = rs.loopbegin;
@@ -467,13 +512,13 @@ static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
 				sub->vol, sub->fin, sub->pan, sub->xpo);
 
-			if (load_sample(m, f, SAMPLE_FLAG_DIFF, xxs, NULL) < 0)
+			if (libxmp_load_sample(m, f, SAMPLE_FLAG_DIFF, xxs, NULL) < 0)
 				return -1;
 		}
 	}
 
 	/* Final sample number adjustment */
-	mod->xxs = realloc_samples(mod->xxs, &mod->smp, smpnum);
+	mod->xxs = libxmp_realloc_samples(mod->xxs, &mod->smp, smpnum);
 	if (mod->xxs == NULL)
 		return -1;
 
diff --git a/src/loaders/s3m.h b/src/loaders/s3m.h
index dff03ca..122e2d7 100644
--- a/src/loaders/s3m.h
+++ b/src/loaders/s3m.h
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
diff --git a/src/loaders/s3m_load.c b/src/loaders/s3m_load.c
index e2fd67c..61763c5 100644
--- a/src/loaders/s3m_load.c
+++ b/src/loaders/s3m_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -75,35 +75,34 @@
 #include "s3m.h"
 #include "period.h"
 
-#ifndef LIBXMP_CORE_PLAYER
-#include "synth.h"
-#endif
-
 #define MAGIC_SCRM	MAGIC4('S','C','R','M')
 #define MAGIC_SCRI	MAGIC4('S','C','R','I')
 #define MAGIC_SCRS	MAGIC4('S','C','R','S')
 
-static int s3m_test (HIO_HANDLE *, char *, const int);
-static int s3m_load (struct module_data *, HIO_HANDLE *, const int);
+static int s3m_test(HIO_HANDLE *, char *, const int);
+static int s3m_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader s3m_loader = {
-    "Scream Tracker 3",
-    s3m_test,
-    s3m_load
+const struct format_loader libxmp_loader_s3m = {
+	"Scream Tracker 3",
+	s3m_test,
+	s3m_load
 };
 
 static int s3m_test(HIO_HANDLE *f, char *t, const int start)
 {
-    hio_seek(f, start + 44, SEEK_SET);
-    if (hio_read32b(f) != MAGIC_SCRM)
-	return -1;
+	hio_seek(f, start + 44, SEEK_SET);
+	if (hio_read32b(f) != MAGIC_SCRM)
+		return -1;
 
-    hio_seek(f, start + 0, SEEK_SET);
-    read_title(f, t, 28);
+	hio_seek(f, start + 29, SEEK_SET);
+	if (hio_read8(f) != 0x10)
+		return -1;
 
-    return 0;
-}
+	hio_seek(f, start + 0, SEEK_SET);
+	libxmp_read_title(f, t, 28);
 
+	return 0;
+}
 
 #define NONE		0xff
 #define FX_S3M_EXTENDED	0xfe
@@ -114,8 +113,7 @@ static int s3m_test(HIO_HANDLE *f, char *t, const int start)
 	} while (0)
 
 /* Effect conversion table */
-static const uint8 fx[] =
-{
+static const uint8 fx[] = {
 	NONE,
 	FX_S3M_SPEED,		/* Axx  Set speed to xx (the default is 06) */
 	FX_JUMP,		/* Bxx  Jump to order xx (hexadecimal) */
@@ -140,446 +138,522 @@ static const uint8 fx[] =
 	FX_FINE_VIBRATO,	/* Uxx  Fine vibrato */
 	FX_GLOBALVOL,		/* Vxx  Set global volume */
 	NONE,
-	NONE,
+	FX_SETPAN,		/* Xxx  Set pan */
 	NONE,
 	NONE
 };
 
-
 /* Effect translation */
 static void xlat_fx(int c, struct xmp_event *e)
 {
-    uint8 h = MSN (e->fxp), l = LSN (e->fxp);
-
-    switch (e->fxt = fx[e->fxt]) {
-    case FX_S3M_EXTENDED:		/* Extended effects */
-	e->fxt = FX_EXTENDED;
-	switch (h) {
-	case 0x1:			/* Glissando */
-	    e->fxp = LSN (e->fxp) | (EX_GLISS << 4);
-	    break;
-	case 0x2:			/* Finetune */
-	    e->fxp = LSN (e->fxp) | (EX_FINETUNE << 4);
-	    break;
-	case 0x3:			/* Vibrato wave */
-	    e->fxp = LSN (e->fxp) | (EX_VIBRATO_WF << 4);
-	    break;
-	case 0x4:			/* Tremolo wave */
-	    e->fxp = LSN (e->fxp) | (EX_TREMOLO_WF << 4);
-	    break;
-	case 0x5:
-	case 0x6:
-	case 0x7:
-	case 0x9:
-	case 0xa:			/* Ignore */
-	    e->fxt = e->fxp = 0;
-	    break;
-	case 0x8:			/* Set pan */
-	    e->fxt = FX_SETPAN;
-	    e->fxp = l << 4;
-	    break;
-	case 0xb:			/* Pattern loop */
-	    e->fxp = LSN (e->fxp) | (EX_PATTERN_LOOP << 4);
-	    break;
-	case 0xc:
-	    if (!l)
+	uint8 h = MSN(e->fxp), l = LSN(e->fxp);
+
+	if (e->fxt > 26) {
+		D_(D_WARN "invalid effect %02x", e->fxt);
 		e->fxt = e->fxp = 0;
+		return;
 	}
-	break;
-    case NONE:				/* No effect */
-	e->fxt = e->fxp = 0;
-	break;
-    }
-}
 
+	switch (e->fxt = fx[e->fxt]) {
+	case FX_S3M_BPM:
+		if (e->fxp < 0x20) {
+			e->fxp = e->fxt = 0;
+		}
+		break;
+	case FX_S3M_EXTENDED:	/* Extended effects */
+		e->fxt = FX_EXTENDED;
+		switch (h) {
+		case 0x1:	/* Glissando */
+			e->fxp = LSN(e->fxp) | (EX_GLISS << 4);
+			break;
+		case 0x2:	/* Finetune */
+			e->fxp =
+			    ((LSN(e->fxp) - 8) & 0x0f) | (EX_FINETUNE << 4);
+			break;
+		case 0x3:	/* Vibrato wave */
+			e->fxp = LSN(e->fxp) | (EX_VIBRATO_WF << 4);
+			break;
+		case 0x4:	/* Tremolo wave */
+			e->fxp = LSN(e->fxp) | (EX_TREMOLO_WF << 4);
+			break;
+		case 0x5:
+		case 0x6:
+		case 0x7:
+		case 0x9:
+		case 0xa:	/* Ignore */
+			e->fxt = e->fxp = 0;
+			break;
+		case 0x8:	/* Set pan */
+			e->fxt = FX_SETPAN;
+			e->fxp = l << 4;
+			break;
+		case 0xb:	/* Pattern loop */
+			e->fxp = LSN(e->fxp) | (EX_PATTERN_LOOP << 4);
+			break;
+		case 0xc:
+			if (!l)
+				e->fxt = e->fxp = 0;
+		}
+		break;
+	case FX_SETPAN:
+		/* Saga Musix says: "The X effect in S3M files is not
+		 * exclusive to IT and clones. You will find tons of S3Ms made
+		 * with ST3 itself using this effect (and relying on an
+		 * external player being used). X in S3M also behaves
+		 * differently than in IT, which your code does not seem to
+		 * handle: X00 - X80 is left... right, XA4 is surround (like
+		 * S91 in IT), other values are not supposed to do anything.
+		 */
+		if (e->fxp == 0xa4) {
+			// surround
+			e->fxt = FX_SURROUND;
+			e->fxp = 1;
+		} else {
+			int pan = ((int)e->fxp) << 1;
+			if (pan > 0xff) {
+				pan = 0xff;
+			}
+			e->fxp = pan;
+		}
+		break;
+	case NONE:		/* No effect */
+		e->fxt = e->fxp = 0;
+		break;
+	}
+}
 
-static int s3m_load(struct module_data *m, HIO_HANDLE *f, const int start)
+static int s3m_load(struct module_data *m, HIO_HANDLE * f, const int start)
 {
-    struct xmp_module *mod = &m->mod;
-    int c, r, i;
-    struct xmp_event *event = 0, dummy;
-    struct s3m_file_header sfh;
-    struct s3m_instrument_header sih;
+	struct xmp_module *mod = &m->mod;
+	int c, r, i;
+	struct xmp_event *event = 0, dummy;
+	struct s3m_file_header sfh;
+	struct s3m_instrument_header sih;
 #ifndef LIBXMP_CORE_PLAYER
-    struct s3m_adlib_header sah;
-    char tracker_name[40];
-    int quirk87 = 0;
+	struct s3m_adlib_header sah;
+	char tracker_name[40];
+	int quirk87 = 0;
 #endif
-    int pat_len;
-    uint8 n, b, x8;
-    uint16 *pp_ins;		/* Parapointers to instruments */
-    uint16 *pp_pat;		/* Parapointers to patterns */
-    int ret;
-
-    LOAD_INIT();
-
-    hio_read(&sfh.name, 28, 1, f);	/* Song name */
-    hio_read8(f);			/* 0x1a */
-    sfh.type = hio_read8(f);		/* File type */
-    hio_read16l(f);			/* Reserved */
-    sfh.ordnum = hio_read16l(f);	/* Number of orders (must be even) */
-    sfh.insnum = hio_read16l(f);	/* Number of instruments */
-    sfh.patnum = hio_read16l(f);	/* Number of patterns */
-    sfh.flags = hio_read16l(f);		/* Flags */
-    sfh.version = hio_read16l(f);	/* Tracker ID and version */
-    sfh.ffi = hio_read16l(f);		/* File format information */
-    sfh.magic = hio_read32b(f);		/* 'SCRM' */
-    sfh.gv = hio_read8(f);		/* Global volume */
-    sfh.is = hio_read8(f);		/* Initial speed */
-    sfh.it = hio_read8(f);		/* Initial tempo */
-    sfh.mv = hio_read8(f);		/* Master volume */
-    sfh.uc = hio_read8(f);		/* Ultra click removal */
-    sfh.dp = hio_read8(f);		/* Default pan positions if 0xfc */
-    hio_read32l(f);			/* Reserved */
-    hio_read32l(f);			/* Reserved */
-    sfh.special = hio_read16l(f);	/* Ptr to special custom data */
-    hio_read(sfh.chset, 32, 1, f);	/* Channel settings */
+	int pat_len;
+	uint8 n, b, x8;
+	uint16 *pp_ins;			/* Parapointers to instruments */
+	uint16 *pp_pat;			/* Parapointers to patterns */
+	int ret;
+
+	LOAD_INIT();
+
+	hio_read(&sfh.name, 28, 1, f);	/* Song name */
+	hio_read8(f);			/* 0x1a */
+	sfh.type = hio_read8(f);	/* File type */
+	hio_read16l(f);			/* Reserved */
+	sfh.ordnum = hio_read16l(f);	/* Number of orders (must be even) */
+	sfh.insnum = hio_read16l(f);	/* Number of instruments */
+	sfh.patnum = hio_read16l(f);	/* Number of patterns */
+	sfh.flags = hio_read16l(f);	/* Flags */
+	sfh.version = hio_read16l(f);	/* Tracker ID and version */
+	sfh.ffi = hio_read16l(f);	/* File format information */
+
+	/* Sanity check */
+	if (hio_error(f)) {
+		goto err;
+	}
+	if (sfh.ffi != 1 && sfh.ffi != 2) {
+		goto err;
+	}
+	if (sfh.ordnum > 255 || sfh.insnum > 255 || sfh.patnum > 255) {
+		goto err;
+	}
 
+	sfh.magic = hio_read32b(f);	/* 'SCRM' */
+	sfh.gv = hio_read8(f);		/* Global volume */
+	sfh.is = hio_read8(f);		/* Initial speed */
+	sfh.it = hio_read8(f);		/* Initial tempo */
+	sfh.mv = hio_read8(f);		/* Master volume */
+	sfh.uc = hio_read8(f);		/* Ultra click removal */
+	sfh.dp = hio_read8(f);		/* Default pan positions if 0xfc */
+	hio_read32l(f);			/* Reserved */
+	hio_read32l(f);			/* Reserved */
+	sfh.special = hio_read16l(f);	/* Ptr to special custom data */
+	hio_read(sfh.chset, 32, 1, f);	/* Channel settings */
+
+	if (hio_error(f)) {
+		goto err;
+	}
 #if 0
-    if (sfh.magic != MAGIC_SCRM)
-	return -1;
+	if (sfh.magic != MAGIC_SCRM)
+		return -1;
 #endif
 
 #ifndef LIBXMP_CORE_PLAYER
-    /* S3M anomaly in return_of_litmus.s3m */
-    if (sfh.version == 0x1301 && sfh.name[27] == 0x87)
-	quirk87 = 1;
-
-    if (quirk87) {
-	fix87(sfh.name);
-	fix87(sfh.patnum);
-	fix87(sfh.flags);
-    }
+	/* S3M anomaly in return_of_litmus.s3m */
+	if (sfh.version == 0x1301 && sfh.name[27] == 0x87)
+		quirk87 = 1;
+
+	if (quirk87) {
+		fix87(sfh.name);
+		fix87(sfh.patnum);
+		fix87(sfh.flags);
+	}
 #endif
 
-    copy_adjust(mod->name, sfh.name, 28);
+	libxmp_copy_adjust(mod->name, sfh.name, 28);
 
-    pp_ins = calloc (2, sfh.insnum);
-    if (pp_ins == NULL)
-	goto err;
+	pp_ins = calloc(2, sfh.insnum);
+	if (pp_ins == NULL)
+		goto err;
 
-    pp_pat = calloc (2, sfh.patnum);
-    if (pp_pat == NULL)
-	goto err2;
+	pp_pat = calloc(2, sfh.patnum);
+	if (pp_pat == NULL)
+		goto err2;
 
-    if (sfh.flags & S3M_AMIGA_RANGE)
-	m->quirk |= QUIRK_MODRNG;
-    if (sfh.flags & S3M_ST300_VOLS)
-	m->quirk |= QUIRK_VSALL;
-    /* m->volbase = 4096 / sfh.gv; */
-    mod->spd = sfh.is;
-    mod->bpm = sfh.it;
+	if (sfh.flags & S3M_AMIGA_RANGE)
+		m->period_type = PERIOD_MODRNG;
+	if (sfh.flags & S3M_ST300_VOLS)
+		m->quirk |= QUIRK_VSALL;
+	/* m->volbase = 4096 / sfh.gv; */
+	mod->spd = sfh.is;
+	mod->bpm = sfh.it;
+	mod->chn = 0;
 
-    for (i = 0; i < 32; i++) {
-	if (sfh.chset[i] == S3M_CH_OFF)
-	    continue;
+	for (i = 0; i < 32; i++) {
+		if (sfh.chset[i] == S3M_CH_OFF)
+			continue;
 
-	mod->chn = i + 1;
+		mod->chn = i + 1;
 
-	if (sfh.mv & 0x80) {	/* stereo */
-		int x = sfh.chset[i] & S3M_CH_PAN;
-		mod->xxc[i].pan = (x & 0x0f) < 8 ? 0x30 : 0xc0;
-	} else {
-		mod->xxc[i].pan = 0x80;
+		if (sfh.mv & 0x80) {	/* stereo */
+			int x = sfh.chset[i] & S3M_CH_PAN;
+			mod->xxc[i].pan = (x & 0x0f) < 8 ? 0x30 : 0xc0;
+		} else {
+			mod->xxc[i].pan = 0x80;
+		}
 	}
-    }
-
-    if (sfh.ordnum <= XMP_MAX_MOD_LENGTH) {
-	mod->len = sfh.ordnum;
-	hio_read(mod->xxo, 1, mod->len, f);
-    } else {
-	mod->len = XMP_MAX_MOD_LENGTH;
-	hio_read(mod->xxo, 1, mod->len, f);
-	hio_seek(f, sfh.ordnum - XMP_MAX_MOD_LENGTH, SEEK_CUR);
-    }
-
-    mod->pat = -1;
-    for (i = 0; i < mod->len && mod->xxo[i] < 0xff; ++i) {
-	if (mod->xxo[i] > mod->pat)
-            mod->pat = mod->xxo[i];
-    }
-    mod->pat++;
-    if (mod->pat > sfh.patnum)
-	mod->pat = sfh.patnum;
-
-    mod->trk = mod->pat * mod->chn;
-    /* Load and convert header */
-    mod->ins = sfh.insnum;
-    mod->smp = mod->ins;
-
-    for (i = 0; i < sfh.insnum; i++)
-	pp_ins[i] = hio_read16l(f);
- 
-    for (i = 0; i < sfh.patnum; i++)
-	pp_pat[i] = hio_read16l(f);
-
-    /* Default pan positions */
-
-    for (i = 0, sfh.dp -= 0xfc; !sfh.dp /* && n */ && (i < 32); i++) {
-	uint8 x = hio_read8(f);
-	if (x & S3M_PAN_SET)
-	    mod->xxc[i].pan = (x << 4) & 0xff;
-	else
-	    mod->xxc[i].pan = sfh.mv % 0x80 ? 0x30 + 0xa0 * (i & 1) : 0x80;
-    }
-
-    m->c4rate = C4_NTSC_RATE;
-
-    if (sfh.version == 0x1300)
-	m->quirk |= QUIRK_VSALL;
 
-#ifndef LIBXMP_CORE_PLAYER
-    switch (sfh.version >> 12) {
-    case 1:
-	snprintf(tracker_name, 40, "Scream Tracker %d.%02x",
-		(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
-	m->quirk |= QUIRK_ST3GVOL;
-	break;
-    case 2:
-	snprintf(tracker_name, 40, "Imago Orpheus %d.%02x",
-		(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
-	break;
-    case 3:
-	if (sfh.version == 0x3216) {
-		strcpy(tracker_name, "Impulse Tracker 2.14v3");
-	} else if (sfh.version == 0x3217) {
-		strcpy(tracker_name, "Impulse Tracker 2.14v5");
+	if (sfh.ordnum <= XMP_MAX_MOD_LENGTH) {
+		mod->len = sfh.ordnum;
+		hio_read(mod->xxo, 1, mod->len, f);
 	} else {
-		snprintf(tracker_name, 40, "Impulse Tracker %d.%02x",
-			(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
+		mod->len = XMP_MAX_MOD_LENGTH;
+		hio_read(mod->xxo, 1, mod->len, f);
+		hio_seek(f, sfh.ordnum - XMP_MAX_MOD_LENGTH, SEEK_CUR);
 	}
-	break;
-    case 5:
-	snprintf(tracker_name, 40, "OpenMPT %d.%02x",
-		(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
-	break;
-    case 4:
-	if (sfh.version != 0x4100) {
-		snprintf(tracker_name, 40, "Schism Tracker %d.%02x",
-			(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
-		break;
+	if (hio_error(f)) {
+		goto err3;
 	}
-	/* fall through */
-    case 6:
-	snprintf(tracker_name, 40, "BeRoTracker %d.%02x",
-		(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
-	break;
-    default:
-	snprintf(tracker_name, 40, "unknown (%04x)", sfh.version);
-    }
-
-    set_type(m, "%s S3M", tracker_name);
-#else
-    set_type(m, "Scream Tracker 3");
-#endif
-
-    MODULE_INFO();
 
-    if (pattern_init(mod) < 0)
-	goto err3;
-
-    /* Read patterns */
+	/* Don't trust sfh.patnum */
+	mod->pat = -1;
+	for (i = 0; i < mod->len; ++i) {
+		if (mod->xxo[i] < 0xfe && mod->xxo[i] > mod->pat) {
+			mod->pat = mod->xxo[i];
+		}
+	}
+	mod->pat++;
+	if (mod->pat > sfh.patnum)
+		mod->pat = sfh.patnum;
+	if (mod->pat == 0)
+		goto err3;
 
-    D_(D_INFO "Stored patterns: %d", mod->pat);
+	mod->trk = mod->pat * mod->chn;
+	/* Load and convert header */
+	mod->ins = sfh.insnum;
+	mod->smp = mod->ins;
 
-    for (i = 0; i < mod->pat; i++) {
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
-	    goto err3;
+	for (i = 0; i < sfh.insnum; i++)
+		pp_ins[i] = hio_read16l(f);
 
-	if (pp_pat[i] == 0)
-	    continue;
+	for (i = 0; i < sfh.patnum; i++)
+		pp_pat[i] = hio_read16l(f);
 
-	hio_seek(f, start + pp_pat[i] * 16, SEEK_SET);
-	r = 0;
-	pat_len = hio_read16l(f) - 2;
+	/* Default pan positions */
 
-	while (pat_len >= 0 && r < mod->xxp[i]->rows) {
-	    b = hio_read8(f);
+	for (i = 0, sfh.dp -= 0xfc; !sfh.dp /* && n */  && (i < 32); i++) {
+		uint8 x = hio_read8(f);
+		if (x & S3M_PAN_SET) {
+			mod->xxc[i].pan = (x << 4) & 0xff;
+		} else {
+			mod->xxc[i].pan =
+			    sfh.mv % 0x80 ? 0x30 + 0xa0 * (i & 1) : 0x80;
+		}
+	}
 
-	    if (b == S3M_EOR) {
-		r++;
-		continue;
-	    }
+	m->c4rate = C4_NTSC_RATE;
 
-	    c = b & S3M_CH_MASK;
-	    event = c >= mod->chn ? &dummy : &EVENT (i, c, r);
+	if (sfh.version == 0x1300) {
+		m->quirk |= QUIRK_VSALL;
+	}
 
-	    if (b & S3M_NI_FOLLOW) {
-		switch(n = hio_read8(f)) {
-		case 255:
-		    n = 0;
-		    break;	/* Empty note */
-		case 254:
-		    n = XMP_KEY_OFF;
-		    break;	/* Key off */
-		default:
-		    n = 13 + 12 * MSN (n) + LSN (n);
+#ifndef LIBXMP_CORE_PLAYER
+	switch (sfh.version >> 12) {
+	case 1:
+		snprintf(tracker_name, 40, "Scream Tracker %d.%02x",
+			 (sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
+		m->quirk |= QUIRK_ST3BUGS;
+		break;
+	case 2:
+		snprintf(tracker_name, 40, "Imago Orpheus %d.%02x",
+			 (sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
+		break;
+	case 3:
+		if (sfh.version == 0x3216) {
+			strcpy(tracker_name, "Impulse Tracker 2.14v3");
+		} else if (sfh.version == 0x3217) {
+			strcpy(tracker_name, "Impulse Tracker 2.14v5");
+		} else {
+			snprintf(tracker_name, 40, "Impulse Tracker %d.%02x",
+				 (sfh.version & 0x0f00) >> 8,
+				 sfh.version & 0xff);
 		}
-		event->note = n;
-		event->ins = hio_read8(f);
-		pat_len -= 2;
-	    }
-
-	    if (b & S3M_VOL_FOLLOWS) {
-		event->vol = hio_read8(f) + 1;
-		pat_len--;
-	    }
-
-	    if (b & S3M_FX_FOLLOWS) {
-		event->fxt = hio_read8(f);
-		event->fxp = hio_read8(f);
-		xlat_fx(c, event);
-		pat_len -= 2;
-	    }
+		break;
+	case 5:
+		snprintf(tracker_name, 40, "OpenMPT %d.%02x",
+			 (sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
+		m->quirk |= QUIRK_ST3BUGS;
+		break;
+	case 4:
+		if (sfh.version != 0x4100) {
+			snprintf(tracker_name, 40, "Schism Tracker %d.%02x",
+				 (sfh.version & 0x0f00) >> 8,
+				 sfh.version & 0xff);
+			break;
+		}
+		/* fall through */
+	case 6:
+		snprintf(tracker_name, 40, "BeRoTracker %d.%02x",
+			 (sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
+		break;
+	default:
+		snprintf(tracker_name, 40, "unknown (%04x)", sfh.version);
 	}
-    }
 
-    D_(D_INFO "Stereo enabled: %s", sfh.mv & 0x80 ? "yes" : "no");
-    D_(D_INFO "Pan settings: %s", sfh.dp ? "no" : "yes");
+	libxmp_set_type(m, "%s S3M", tracker_name);
+#else
+	libxmp_set_type(m, "Scream Tracker 3");
+	m->quirk |= QUIRK_ST3BUGS;
+#endif
 
-    if (instrument_init(mod) < 0)
-	goto err3;
+	MODULE_INFO();
 
-    /* Read and convert instruments and samples */
+	if (libxmp_init_pattern(mod) < 0)
+		goto err3;
 
-    D_(D_INFO "Instruments: %d", mod->ins);
+	/* Read patterns */
+
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
+			goto err3;
+
+		if (pp_pat[i] == 0)
+			continue;
+
+		hio_seek(f, start + pp_pat[i] * 16, SEEK_SET);
+		r = 0;
+		pat_len = hio_read16l(f) - 2;
+
+		while (pat_len >= 0 && r < mod->xxp[i]->rows) {
+			b = hio_read8(f);
+
+			if (hio_error(f)) {
+				goto err3;
+			}
+
+			if (b == S3M_EOR) {
+				r++;
+				continue;
+			}
+
+			c = b & S3M_CH_MASK;
+			event = c >= mod->chn ? &dummy : &EVENT(i, c, r);
+
+			if (b & S3M_NI_FOLLOW) {
+				switch (n = hio_read8(f)) {
+				case 255:
+					n = 0;
+					break;	/* Empty note */
+				case 254:
+					n = XMP_KEY_OFF;
+					break;	/* Key off */
+				default:
+					n = 13 + 12 * MSN(n) + LSN(n);
+				}
+				event->note = n;
+				event->ins = hio_read8(f);
+				pat_len -= 2;
+			}
+
+			if (b & S3M_VOL_FOLLOWS) {
+				event->vol = hio_read8(f) + 1;
+				pat_len--;
+			}
+
+			if (b & S3M_FX_FOLLOWS) {
+				event->fxt = hio_read8(f);
+				event->fxp = hio_read8(f);
+				xlat_fx(c, event);
+
+				pat_len -= 2;
+			}
+		}
+	}
 
-    for (i = 0; i < mod->ins; i++) {
-	struct xmp_instrument *xxi = &mod->xxi[i];
-	struct xmp_sample *xxs = &mod->xxs[i];
-	struct xmp_subinstrument *sub;
+	D_(D_INFO "Stereo enabled: %s", sfh.mv & 0x80 ? "yes" : "no");
+	D_(D_INFO "Pan settings: %s", sfh.dp ? "no" : "yes");
 
-	xxi->sub = calloc(sizeof (struct xmp_subinstrument), 1);
-	if (xxi->sub == NULL)
-	    goto err3;
+	if (libxmp_init_instrument(m) < 0)
+		goto err3;
 
-	sub = &xxi->sub[0];
+	/* Read and convert instruments and samples */
 
-	hio_seek(f, start + pp_ins[i] * 16, SEEK_SET);
-	x8 = hio_read8(f);
-	sub->pan = 0x80;
-	sub->sid = i;
+	D_(D_INFO "Instruments: %d", mod->ins);
 
-	if (x8 >= 2) {
-#ifndef LIBXMP_CORE_PLAYER
-	    /* OPL2 FM instrument */
-
-	    hio_read(&sah.dosname, 12, 1, f);	/* DOS file name */
-	    hio_read(&sah.rsvd1, 3, 1, f);	/* 0x00 0x00 0x00 */
-	    hio_read(&sah.reg, 12, 1, f);	/* Adlib registers */
-	    sah.vol = hio_read8(f);
-	    sah.dsk = hio_read8(f);
-	    hio_read16l(f);
-	    sah.c2spd = hio_read16l(f);		/* C 4 speed */
-	    hio_read16l(f);
-	    hio_read(&sah.rsvd4, 12, 1, f);	/* Reserved */
-	    hio_read(&sah.name, 28, 1, f);	/* Instrument name */
-	    sah.magic = hio_read32b(f);		/* 'SCRI' */
-
-	    if (sah.magic != MAGIC_SCRI) {
-		D_(D_CRIT "error: FM instrument magic");
-		goto err3;
-	    }
-	    sah.magic = 0;
+	for (i = 0; i < mod->ins; i++) {
+		struct xmp_instrument *xxi = &mod->xxi[i];
+		struct xmp_sample *xxs = &mod->xxs[i];
+		struct xmp_subinstrument *sub;
 
-	    instrument_name(mod, i, sah.name, 28);
+		xxi->sub = calloc(sizeof(struct xmp_subinstrument), 1);
+		if (xxi->sub == NULL) {
+			goto err3;
+		}
 
-	    xxi->nsm = 1;
-	    sub->vol = sah.vol;
-	    c2spd_to_note(sah.c2spd, &sub->xpo, &sub->fin);
-	    sub->xpo += 12;
-	    ret = load_sample(m, f, SAMPLE_FLAG_ADLIB, xxs, (char *)&sah.reg);
-	    if (ret < 0)
-		goto err3;
+		sub = &xxi->sub[0];
 
-	    D_(D_INFO "[%2X] %-28.28s", i, xxi->name);
+		hio_seek(f, start + pp_ins[i] * 16, SEEK_SET);
+		x8 = hio_read8(f);
+		sub->pan = 0x80;
+		sub->sid = i;
 
-	    continue;
+		if (x8 >= 2) {
+#ifndef LIBXMP_CORE_PLAYER
+			/* OPL2 FM instrument */
+
+			hio_read(&sah.dosname, 12, 1, f); /* DOS file name */
+			hio_read(&sah.rsvd1, 3, 1, f);	/* 0x00 0x00 0x00 */
+			hio_read(&sah.reg, 12, 1, f);	/* Adlib registers */
+			sah.vol = hio_read8(f);
+			sah.dsk = hio_read8(f);
+			hio_read16l(f);
+			sah.c2spd = hio_read16l(f);	/* C 4 speed */
+			hio_read16l(f);
+			hio_read(&sah.rsvd4, 12, 1, f);	/* Reserved */
+			hio_read(&sah.name, 28, 1, f);	/* Instrument name */
+			sah.magic = hio_read32b(f);	/* 'SCRI' */
+
+			if (sah.magic != MAGIC_SCRI) {
+				D_(D_CRIT "error: FM instrument magic");
+				goto err3;
+			}
+			sah.magic = 0;
+
+			libxmp_instrument_name(mod, i, sah.name, 28);
+
+			xxi->nsm = 1;
+			sub->vol = sah.vol;
+			libxmp_c2spd_to_note(sah.c2spd, &sub->xpo, &sub->fin);
+			sub->xpo += 12;
+			ret =
+			    libxmp_load_sample(m, f, SAMPLE_FLAG_ADLIB, xxs,
+					(char *)&sah.reg);
+			if (ret < 0)
+				goto err3;
+
+			D_(D_INFO "[%2X] %-28.28s", i, xxi->name);
+
+			continue;
 #else
-	    goto err3;
+			goto err3;
 #endif
-	}
+		}
 
-	hio_read(&sih.dosname, 13, 1, f);	/* DOS file name */
-	sih.memseg = hio_read16l(f);		/* Pointer to sample data */
-	sih.length = hio_read32l(f);		/* Length */
-	sih.loopbeg = hio_read32l(f);		/* Loop begin */
-	sih.loopend = hio_read32l(f);		/* Loop end */
-	sih.vol = hio_read8(f);			/* Volume */
-	sih.rsvd1 = hio_read8(f);		/* Reserved */
-	sih.pack = hio_read8(f);		/* Packing type (not used) */
-	sih.flags = hio_read8(f);		/* Loop/stereo/16bit samples flags */
-	sih.c2spd = hio_read16l(f);		/* C 4 speed */
-	sih.rsvd2 = hio_read16l(f);		/* Reserved */
-	hio_read(&sih.rsvd3, 4, 1, f);		/* Reserved */
-	sih.int_gp = hio_read16l(f);		/* Internal - GUS pointer */
-	sih.int_512 = hio_read16l(f);		/* Internal - SB pointer */
-	sih.int_last = hio_read32l(f);		/* Internal - SB index */
-	hio_read(&sih.name, 28, 1, f);		/* Instrument name */
-	sih.magic = hio_read32b(f);		/* 'SCRS' */
-
-	if (x8 == 1 && sih.magic != MAGIC_SCRS) {
-	    D_(D_CRIT "error: instrument magic");
-	    goto err3;
-	}
+		hio_read(&sih.dosname, 13, 1, f); /* DOS file name */
+		sih.memseg = hio_read16l(f);	/* Pointer to sample data */
+		sih.length = hio_read32l(f);	/* Length */
+
+#if 0
+		/* ST3 limit */
+		if ((sfh.version >> 12) == 1 && sih.length > 64000)
+			sih.length = 64000;
+#endif
 
+		if (sih.length > MAX_SAMPLE_SIZE) {
+			goto err3;
+		}
+
+		sih.loopbeg = hio_read32l(f);	/* Loop begin */
+		sih.loopend = hio_read32l(f);	/* Loop end */
+		sih.vol = hio_read8(f);		/* Volume */
+		sih.rsvd1 = hio_read8(f);	/* Reserved */
+		sih.pack = hio_read8(f);	/* Packing type (not used) */
+		sih.flags = hio_read8(f);	/* Loop/stereo/16bit flags */
+		sih.c2spd = hio_read16l(f);	/* C 4 speed */
+		sih.rsvd2 = hio_read16l(f);	/* Reserved */
+		hio_read(&sih.rsvd3, 4, 1, f);	/* Reserved */
+		sih.int_gp = hio_read16l(f);	/* Internal - GUS pointer */
+		sih.int_512 = hio_read16l(f);	/* Internal - SB pointer */
+		sih.int_last = hio_read32l(f);	/* Internal - SB index */
+		hio_read(&sih.name, 28, 1, f);	/* Instrument name */
+		sih.magic = hio_read32b(f);	/* 'SCRS' */
+
+		if (x8 == 1 && sih.magic != MAGIC_SCRS) {
+			D_(D_CRIT "error: instrument magic");
+			goto err3;
+		}
 #ifndef LIBXMP_CORE_PLAYER
-	if (quirk87) {
-	    fix87(sih.length);
-	    fix87(sih.loopbeg);
-	    fix87(sih.loopend);
-	    fix87(sih.flags);
-	}
+		if (quirk87) {
+			fix87(sih.length);
+			fix87(sih.loopbeg);
+			fix87(sih.loopend);
+			fix87(sih.flags);
+		}
 #endif
 
-	xxs->len = sih.length;
-	xxi->nsm = sih.length > 0 ? 1 : 0;
-	xxs->lps = sih.loopbeg;
-	xxs->lpe = sih.loopend;
+		xxs->len = sih.length;
+		xxi->nsm = sih.length > 0 ? 1 : 0;
+		xxs->lps = sih.loopbeg;
+		xxs->lpe = sih.loopend;
 
-	xxs->flg = sih.flags & 1 ? XMP_SAMPLE_LOOP : 0;
+		xxs->flg = sih.flags & 1 ? XMP_SAMPLE_LOOP : 0;
 
-	if (sih.flags & 4) {
-	    xxs->flg |= XMP_SAMPLE_16BIT;
-	}
+		if (sih.flags & 4) {
+			xxs->flg |= XMP_SAMPLE_16BIT;
+		}
 
-	sub->vol = sih.vol;
-	sih.magic = 0;
+		sub->vol = sih.vol;
+		sih.magic = 0;
 
-	instrument_name(mod, i, sih.name, 28);
+		libxmp_instrument_name(mod, i, sih.name, 28);
 
-	D_(D_INFO "[%2X] %-28.28s %04x%c%04x %04x %c V%02x %5d",
-			i, mod->xxi[i].name, mod->xxs[i].len,
-			xxs->flg & XMP_SAMPLE_16BIT ?'+' : ' ',
-			xxs->lps, mod->xxs[i].lpe,
-			xxs->flg & XMP_SAMPLE_LOOP ?  'L' : ' ',
-			sub->vol, sih.c2spd);
+		D_(D_INFO "[%2X] %-28.28s %04x%c%04x %04x %c V%02x %5d",
+		   i, mod->xxi[i].name, mod->xxs[i].len,
+		   xxs->flg & XMP_SAMPLE_16BIT ? '+' : ' ',
+		   xxs->lps, mod->xxs[i].lpe,
+		   xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ', sub->vol, sih.c2spd);
 
-	c2spd_to_note(sih.c2spd, &sub->xpo, &sub->fin);
+		libxmp_c2spd_to_note(sih.c2spd, &sub->xpo, &sub->fin);
 
-	hio_seek(f, start + 16L * sih.memseg, SEEK_SET);
+		hio_seek(f, start + 16L * sih.memseg, SEEK_SET);
 
-	ret = load_sample(m, f, (sfh.ffi - 1) * SAMPLE_FLAG_UNS, xxs, NULL);
-	if (ret < 0)
-		goto err3;
-    }
+		ret = libxmp_load_sample(m, f, sfh.ffi == 1 ? 0 : SAMPLE_FLAG_UNS,
+								xxs, NULL);
+		if (ret < 0) {
+			goto err3;
+		}
+	}
 
-    free(pp_pat);
-    free(pp_ins);
+	free(pp_pat);
+	free(pp_ins);
 
-#ifndef LIBXMP_CORE_PLAYER
-    m->synth = &synth_adlib;
-#endif
-    m->quirk |= QUIRKS_ST3;
-    m->read_event_type = READ_EVENT_ST3;
+	m->quirk |= QUIRKS_ST3 | QUIRK_ARPMEM;
+	m->read_event_type = READ_EVENT_ST3;
 
-    return 0;
+	return 0;
 
-  err3:
-    free(pp_pat);
-  err2:
-    free(pp_ins);
-  err:
-    return -1;
+err3:
+	free(pp_pat);
+err2:
+	free(pp_ins);
+err:
+	return -1;
 }
-
diff --git a/src/loaders/sample.c b/src/loaders/sample.c
index f8877bf..22a538e 100644
--- a/src/loaders/sample.c
+++ b/src/loaders/sample.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -24,7 +24,6 @@
 #include "loader.h"
 
 #ifndef LIBXMP_CORE_PLAYER
-#include "synth.h"
 
 /*
  * From the Audio File Formats (version 2.5)
@@ -79,26 +78,6 @@ static void convert_vidc_to_linear(uint8 *p, int l)
 	}
 }
 
-/* Convert HSC OPL2 instrument data to SBI instrument data */
-static void convert_hsc_to_sbi(uint8 *a)
-{
-	uint8 b[11];
-	int i;
-
-	for (i = 0; i < 10; i += 2) {
-		uint8 x;
-		x = a[i];
-		a[i] = a[i + 1];
-		a[i + 1] = x;
-	}
-
-	memcpy(b, a, 11);
-	a[8] = b[10];
-	a[10] = b[9];
-	a[9] = b[8];
-}
-
-
 static void adpcm4_decoder(uint8 *inp, uint8 *outp, char *tab, int len)
 {
 	char delta = 0;
@@ -216,52 +195,41 @@ static void unroll_loop(struct xmp_sample *xxs)
 }
 
 
-int load_sample(struct module_data *m, HIO_HANDLE *f, int flags, struct xmp_sample *xxs, void *buffer)
+int libxmp_load_sample(struct module_data *m, HIO_HANDLE *f, int flags, struct xmp_sample *xxs, void *buffer)
 {
 	int bytelen, extralen, unroll_extralen, i;
 
 #ifndef LIBXMP_CORE_PLAYER
 	/* Adlib FM patches */
 	if (flags & SAMPLE_FLAG_ADLIB) {
-		const int size = 11;
-
-		if (flags & SAMPLE_FLAG_HSC) {
-			convert_hsc_to_sbi(buffer);
-		}
-
-		xxs->data = malloc(size + 4);
-		if (xxs->data == NULL)
-			return -1;
-
-		*(uint32 *)xxs->data = 0;
-		xxs->data += 4;
-
-		memcpy(xxs->data, buffer, size);
-
-		xxs->flg |= XMP_SAMPLE_SYNTH;
-		xxs->len = size;
-
 		return 0;
 	}
 #endif
 
-	/* Empty samples
+	/* Empty or invalid samples
 	 */
-	if (xxs->len == 0) {
+	if (xxs->len <= 0) {
 		return 0;
 	}
 
 	/* Skip sample loading
 	 * FIXME: fails for ADPCM samples
+	 *
+	 * + Sanity check: skip huge samples (likely corrupt module)
 	 */
-	if (m && m->smpctl & XMP_SMPCTL_SKIP) {
-		if (~flags & SAMPLE_FLAG_NOLOAD)
+	if (xxs->len > MAX_SAMPLE_SIZE || (m && m->smpctl & XMP_SMPCTL_SKIP)) {
+		if (~flags & SAMPLE_FLAG_NOLOAD) {
+			/* coverity[check_return] */
 			hio_seek(f, xxs->len, SEEK_CUR);
+		}
 		return 0;
 	}
 
 	/* Loop parameters sanity check
 	 */
+	if (xxs->lps < 0) {
+		xxs->lps = 0;
+	}
 	if (xxs->lpe > xxs->len) {
 		xxs->lpe = xxs->len;
 	}
@@ -302,8 +270,9 @@ int load_sample(struct module_data *m, HIO_HANDLE *f, int flags, struct xmp_samp
 
 	/* add guard bytes before the buffer for higher order interpolation */
 	xxs->data = malloc(bytelen + extralen + unroll_extralen + 4);
-	if (xxs->data == NULL)
-		return -1;
+	if (xxs->data == NULL) {
+		goto err;
+	}
 
 	*(uint32 *)xxs->data = 0;
 	xxs->data += 4;
@@ -316,8 +285,12 @@ int load_sample(struct module_data *m, HIO_HANDLE *f, int flags, struct xmp_samp
 		int x2 = (bytelen + 1) >> 1;
 		char table[16];
 
-		hio_read(table, 1, 16, f);
-		hio_read(xxs->data + x2, 1, x2, f);
+		if (hio_read(table, 1, 16, f) != 16) {
+			goto err2;
+		}
+		if (hio_read(xxs->data + x2, 1, x2, f) != x2) {
+			goto err2;
+		}
 		adpcm4_decoder((uint8 *)xxs->data + x2,
 			       (uint8 *)xxs->data, table, bytelen);
 	} else
@@ -325,7 +298,7 @@ int load_sample(struct module_data *m, HIO_HANDLE *f, int flags, struct xmp_samp
 	{
 		int x = hio_read(xxs->data, 1, bytelen, f);
 		if (x != bytelen) {
-			D_(D_WARN, "short read (%d) in sample load", x - bytelen);
+			D_(D_WARN "short read (%d) in sample load", x - bytelen);
 			memset(xxs->data + x, 0, bytelen - x);
 		}
 	}
@@ -412,27 +385,32 @@ int load_sample(struct module_data *m, HIO_HANDLE *f, int flags, struct xmp_samp
 
 	/* Fix sample at loop */
 	if (xxs->flg & XMP_SAMPLE_LOOP) {
-		if (xxs->flg & XMP_SAMPLE_16BIT) {
-			int lpe = xxs->lpe * 2;
-			int lps = xxs->lps * 2;
+		int lpe = xxs->lpe;
+		int lps = xxs->lps;
 
-			if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
-				lpe += (xxs->lpe - xxs->lps) * 2;
-			}
-			xxs->data[lpe] = xxs->data[lpe - 2];
-			xxs->data[lpe + 1] = xxs->data[lpe - 1];
-			for (i = 0; i < 6; i++) {
-				xxs->data[lpe + 2 + i] = xxs->data[lps + i];
+		if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
+			lpe += lpe - lps;
+		}
+
+		if (xxs->flg & XMP_SAMPLE_16BIT) {
+			lpe <<= 1;
+			lps <<= 1;
+			for (i = 0; i < 8; i++) {
+				xxs->data[lpe + i] = xxs->data[lps + i];
 			}
 		} else {
-			int lpe = xxs->lpe + unroll_extralen;
-			int lps = xxs->lps;
-			xxs->data[lpe] = xxs->data[lpe - 1];
-			for (i = 0; i < 3; i++) {
-				xxs->data[lpe + 1 + i] = xxs->data[lps + i];
+			for (i = 0; i < 4; i++) {
+				xxs->data[lpe + i] = xxs->data[lps + i];
 			}
 		}
 	}
 
 	return 0;
+
+#ifndef LIBXMP_CORE_PLAYER
+    err2:
+	free(xxs->data - 4);
+#endif
+    err:
+	return -1;
 }
diff --git a/src/loaders/sfx_load.c b/src/loaders/sfx_load.c
index 88116cc..59b5e54 100644
--- a/src/loaders/sfx_load.c
+++ b/src/loaders/sfx_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 /* Reverse engineered from the two SFX files in the Delitracker mods disk
@@ -16,217 +30,229 @@
  * uses 31 samples [instead of 15].
  */
 
-#include "period.h"
 #include "loader.h"
+#include "period.h"
 
 #define MAGIC_SONG	MAGIC4('S','O','N','G')
 
+static int sfx_test(HIO_HANDLE *, char *, const int);
+static int sfx_load(struct module_data *, HIO_HANDLE *, const int);
 
-static int sfx_test (HIO_HANDLE *, char *, const int);
-static int sfx_load (struct module_data *, HIO_HANDLE *, const int);
-
-const struct format_loader sfx_loader = {
-    "SoundFX v1.3/2.0",
-    sfx_test,
-    sfx_load
+const struct format_loader libxmp_loader_sfx = {
+	"SoundFX v1.3/2.0",
+	sfx_test,
+	sfx_load
 };
 
-static int sfx_test(HIO_HANDLE *f, char *t, const int start)
+static int sfx_test(HIO_HANDLE * f, char *t, const int start)
 {
-    uint32 a, b;
+	uint32 a, b;
 
-    hio_seek(f, 4 * 15, SEEK_CUR);
-    a = hio_read32b(f);
-    hio_seek(f, 4 * 15, SEEK_CUR);
-    b = hio_read32b(f);
+	hio_seek(f, 4 * 15, SEEK_CUR);
+	a = hio_read32b(f);
+	hio_seek(f, 4 * 15, SEEK_CUR);
+	b = hio_read32b(f);
 
-    if (a != MAGIC_SONG && b != MAGIC_SONG)
-	return -1;
+	if (a != MAGIC_SONG && b != MAGIC_SONG)
+		return -1;
 
-    read_title(f, t, 0);
+	libxmp_read_title(f, t, 0);
 
-    return 0;
+	return 0;
 }
 
-
 struct sfx_ins {
-    uint8 name[22];		/* Instrument name */
-    uint16 len;			/* Sample length in words */
-    uint8 finetune;		/* Finetune */
-    uint8 volume;		/* Volume (0-63) */
-    uint16 loop_start;		/* Sample loop start in bytes */
-    uint16 loop_length;		/* Sample loop length in words */
+	uint8 name[22];		/* Instrument name */
+	uint16 len;		/* Sample length in words */
+	uint8 finetune;		/* Finetune */
+	uint8 volume;		/* Volume (0-63) */
+	uint16 loop_start;	/* Sample loop start in bytes */
+	uint16 loop_length;	/* Sample loop length in words */
 };
 
 struct sfx_header {
-    uint32 magic;		/* 'SONG' */
-    uint16 delay;		/* Delay value (tempo), default is 0x38e5 */
-    uint16 unknown[7];		/* ? */
+	uint32 magic;		/* 'SONG' */
+	uint16 delay;		/* Delay value (tempo), default is 0x38e5 */
+	uint16 unknown[7];	/* ? */
 };
 
 struct sfx_header2 {
-    uint8 len;			/* Song length */
-    uint8 restart;		/* Restart pos (?) */
-    uint8 order[128];		/* Order list */
+	uint8 len;		/* Song length */
+	uint8 restart;		/* Restart pos (?) */
+	uint8 order[128];	/* Order list */
 };
 
-
-static int sfx_13_20_load(struct module_data *m, HIO_HANDLE *f, const int nins, const int start)
+static int sfx_13_20_load(struct module_data *m, HIO_HANDLE *f, const int nins,
+			  const int start)
 {
-    struct xmp_module *mod = &m->mod;
-    int i, j;
-    struct xmp_event *event;
-    struct sfx_header sfx;
-    struct sfx_header2 sfx2;
-    uint8 ev[4];
-    int ins_size[31];
-    struct sfx_ins ins[31];	/* Instruments */
-
-    LOAD_INIT();
-
-    for (i = 0; i < nins; i++)
-	ins_size[i] = hio_read32b(f);
-
-    sfx.magic = hio_read32b(f);
-    sfx.delay = hio_read16b(f);
-    if (sfx.delay < 178)//min value for 10000bpm
-	return -1;
-
-    hio_read(&sfx.unknown, 14, 1, f);
-
-    if (sfx.magic != MAGIC_SONG)
-	return -1;
-
-    mod->ins = nins;
-    mod->smp = mod->ins;
-    mod->bpm = 14565 * 122 / sfx.delay;
-
-    for (i = 0; i < mod->ins; i++) {
-	hio_read(&ins[i].name, 22, 1, f);
-	ins[i].len = hio_read16b(f);
-	ins[i].finetune = hio_read8(f);
-	ins[i].volume = hio_read8(f);
-	ins[i].loop_start = hio_read16b(f);
-	ins[i].loop_length = hio_read16b(f);
-    }
-
-    sfx2.len = hio_read8(f);
-    sfx2.restart = hio_read8(f);
-    hio_read(&sfx2.order, 128, 1, f);
-
-    mod->len = sfx2.len;
-    if (mod->len > 0x7f)
-	return -1;
-
-    memcpy (mod->xxo, sfx2.order, mod->len);
-    for (mod->pat = i = 0; i < mod->len; i++)
-	if (mod->xxo[i] > mod->pat)
-	    mod->pat = mod->xxo[i];
-    mod->pat++;
-
-    mod->trk = mod->chn * mod->pat;
-
-    if (mod->ins == 15) {
-        set_type(m, "SoundFX 1.3");
-    } else {
-        set_type(m, "SoundFX 2.0");
-    }
-
-    MODULE_INFO();
-
-    if (instrument_init(mod) < 0)
-	return -1;
-
-    for (i = 0; i < mod->ins; i++) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
-	    return -1;
-
-	mod->xxs[i].len = ins_size[i];
-	mod->xxs[i].lps = ins[i].loop_start;
-	mod->xxs[i].lpe = mod->xxs[i].lps + 2 * ins[i].loop_length;
-	mod->xxs[i].flg = ins[i].loop_length > 1 ? XMP_SAMPLE_LOOP : 0;
-	mod->xxi[i].nsm = 1;
-	mod->xxi[i].sub[0].vol = ins[i].volume;
-	mod->xxi[i].sub[0].fin = (int8)(ins[i].finetune << 4); 
-	mod->xxi[i].sub[0].pan = 0x80;
-	mod->xxi[i].sub[0].sid = i;
-
-	instrument_name(mod, i, ins[i].name, 22);
-
-	D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c  %02x %+d",
-		i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
-		mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol,
-		mod->xxi[i].sub[0].fin >> 4);
-    }
-
-    if (pattern_init(mod) < 0)
-	return -1;
-
-    D_(D_INFO "Stored patterns: %d", mod->pat);
-
-    for (i = 0; i < mod->pat; i++) {
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
-	    return -1;
-
-	for (j = 0; j < 64 * mod->chn; j++) {
-	    event = &EVENT(i, j % mod->chn, j / mod->chn);
-	    hio_read(ev, 1, 4, f);
-
-	    event->note = period_to_note((LSN (ev[0]) << 8) | ev[1]);
-	    event->ins = (MSN (ev[0]) << 4) | MSN (ev[2]);
-	    event->fxp = ev[3];
-
-	    switch (LSN(ev[2])) {
-	    case 0x1:			/* Arpeggio */
-		event->fxt = FX_ARPEGGIO;
-		break;
-	    case 0x02:			/* Pitch bend */
-		if (event->fxp >> 4) {
-		    event->fxt = FX_PORTA_DN;
-		    event->fxp >>= 4;
-		} else if (event->fxp & 0x0f) {
-		    event->fxt = FX_PORTA_UP;
-		    event->fxp &= 0x0f;
+	struct xmp_module *mod = &m->mod;
+	int i, j;
+	struct xmp_event *event;
+	struct sfx_header sfx;
+	struct sfx_header2 sfx2;
+	uint8 ev[4];
+	int ins_size[31];
+	struct sfx_ins ins[31];	/* Instruments */
+
+	LOAD_INIT();
+
+	for (i = 0; i < nins; i++)
+		ins_size[i] = hio_read32b(f);
+
+	sfx.magic = hio_read32b(f);
+	sfx.delay = hio_read16b(f);
+	if (sfx.delay < 178)	/* min value for 10000bpm */
+		return -1;
+
+	hio_read(&sfx.unknown, 14, 1, f);
+
+	if (sfx.magic != MAGIC_SONG)
+		return -1;
+
+	mod->chn = 4;
+	mod->ins = nins;
+	mod->smp = mod->ins;
+	mod->bpm = 14565 * 122 / sfx.delay;
+
+	for (i = 0; i < mod->ins; i++) {
+		hio_read(&ins[i].name, 22, 1, f);
+		ins[i].len = hio_read16b(f);
+		ins[i].finetune = hio_read8(f);
+		ins[i].volume = hio_read8(f);
+		ins[i].loop_start = hio_read16b(f);
+		ins[i].loop_length = hio_read16b(f);
+	}
+
+	sfx2.len = hio_read8(f);
+	sfx2.restart = hio_read8(f);
+	if (hio_read(&sfx2.order, 1, 128, f) != 128)
+		return -1;
+
+	mod->len = sfx2.len;
+	if (mod->len > 0x7f)
+		return -1;
+
+	memcpy(mod->xxo, sfx2.order, mod->len);
+	for (mod->pat = i = 0; i < mod->len; i++)
+		if (mod->xxo[i] > mod->pat)
+			mod->pat = mod->xxo[i];
+	mod->pat++;
+
+	mod->trk = mod->chn * mod->pat;
+
+	if (mod->ins == 15) {
+		libxmp_set_type(m, "SoundFX 1.3");
+	} else {
+		libxmp_set_type(m, "SoundFX 2.0");
+	}
+
+	MODULE_INFO();
+
+	if (libxmp_init_instrument(m) < 0)
+		return -1;
+
+	for (i = 0; i < mod->ins; i++) {
+		struct xmp_instrument *xxi;
+		struct xmp_subinstrument *sub;
+		struct xmp_sample *xxs;
+
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+
+		xxi = &mod->xxi[i];
+		xxs = &mod->xxs[i];
+		sub = &xxi->sub[0];
+
+		xxs->len = ins_size[i];
+		xxs->lps = ins[i].loop_start;
+		xxs->lpe = xxs->lps + 2 * ins[i].loop_length;
+		xxs->flg = ins[i].loop_length > 1 ? XMP_SAMPLE_LOOP : 0;
+		xxi->nsm = 1;
+		sub->vol = ins[i].volume;
+		sub->fin = (int8) (ins[i].finetune << 4);	/* unsure */
+		sub->pan = 0x80;
+		sub->sid = i;
+
+		libxmp_instrument_name(mod, i, ins[i].name, 22);
+
+		D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c  %02x %+d",
+		   i, xxi->name, xxs->len, xxs->lps, xxs->lpe,
+		   xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ', sub->vol,
+		   sub->fin >> 4);
+	}
+
+	if (libxmp_init_pattern(mod) < 0)
+		return -1;
+
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
+			return -1;
+
+		for (j = 0; j < 64 * mod->chn; j++) {
+			event = &EVENT(i, j % mod->chn, j / mod->chn);
+			hio_read(ev, 1, 4, f);
+
+			event->note = libxmp_period_to_note((LSN(ev[0]) << 8) | ev[1]);
+			event->ins = (MSN(ev[0]) << 4) | MSN(ev[2]);
+			event->fxp = ev[3];
+
+			switch (LSN(ev[2])) {
+			case 0x01:	/* Arpeggio */
+				event->fxt = FX_ARPEGGIO;
+				break;
+			case 0x02:	/* Pitch bend */
+				if (event->fxp >> 4) {
+					event->fxt = FX_PORTA_DN;
+					event->fxp >>= 4;
+				} else if (event->fxp & 0x0f) {
+					event->fxt = FX_PORTA_UP;
+					event->fxp &= 0x0f;
+				}
+				break;
+			case 0x5:	/* Add to volume */
+				event->fxt = FX_VOL_ADD;
+				break;
+			case 0x6:	/* Subtract from volume */
+				event->fxt = FX_VOL_SUB;
+				break;
+			case 0x7:	/* Add semitones to period */
+				event->fxt = FX_PITCH_ADD;
+				break;
+			case 0x8:	/* Subtract semitones from period */
+				event->fxt = FX_PITCH_SUB;
+				break;
+			case 0x3:	/* LED on */
+			case 0x4:	/* LED off */
+			default:
+				event->fxt = event->fxp = 0;
+				break;
+			}
 		}
-		break;
-	    case 0x5:			/* Volume up */
-		event->fxt = FX_VOLSLIDE_DN;
-		break;
-	    case 0x6:			/* Set volume (attenuation) */
-		event->fxt = FX_VOLSET;
-		event->fxp = 0x40 - ev[3];
-		break;
-	    case 0x3:			/* LED on */
-	    case 0x4:			/* LED off */
-	    case 0x7:			/* Set step up */
-	    case 0x8:			/* Set step down */
-	    default:
-		event->fxt = event->fxp = 0;
-		break;
-	    }
 	}
-    }
 
-    m->quirk |= QUIRK_MODRNG;
+	m->quirk |= QUIRK_PBALL;
+	m->period_type = PERIOD_MODRNG;
 
-    /* Read samples */
+	/* Read samples */
 
-    D_(D_INFO "Stored samples: %d", mod->smp);
+	D_(D_INFO "Stored samples: %d", mod->smp);
 
-    for (i = 0; i < mod->ins; i++) {
-	if (mod->xxs[i].len <= 2)
-	    continue;
-	if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
-	    return -1;
-    }
+	for (i = 0; i < mod->ins; i++) {
+		if (mod->xxs[i].len <= 2)
+			continue;
+		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+			return -1;
+	}
 
-    return 0;
+	return 0;
 }
 
-
 static int sfx_load(struct module_data *m, HIO_HANDLE *f, const int start)
 {
-    if (sfx_13_20_load(m, f, 15, start) < 0)
-	return sfx_13_20_load(m, f, 31, start);
-    return 0;
+	if (sfx_13_20_load(m, f, 15, start) < 0)
+		return sfx_13_20_load(m, f, 31, start);
+
+	return 0;
 }
diff --git a/src/loaders/ssmt_load.c b/src/loaders/ssmt_load.c
new file mode 100644
index 0000000..ea5a311
--- /dev/null
+++ b/src/loaders/ssmt_load.c
@@ -0,0 +1,216 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * This file is part of the Extended Module Player and is distributed
+ * under the terms of the GNU Lesser General Public License. See COPYING.LIB
+ * for more information.
+ */
+
+/* Format specs from MTPng 4.3.1 by Ian Schmitd and deMODifier by Bret Victor
+ * http://home.cfl.rr.com/ischmidt/warez.html
+ * http://worrydream.com/media/demodifier.tgz
+ */
+
+/* From the deMODifier readme:
+ *
+ * SoundSmith was arguably the most popular music authoring tool for the
+ * Apple IIgs.  Introduced in the IIgs's heyday (which was, accurately 
+ * enough, just about one day), this software inspired the creation
+ * of countless numbers of IIgs-specific tunes, several of which were 
+ * actually worth listening to.  
+ */
+
+#include 
+#include "loader.h"
+#include "asif.h"
+
+
+static int mtp_test (HIO_HANDLE *, char *, const int);
+static int mtp_load (struct module_data *, HIO_HANDLE *, const int);
+
+const struct format_loader libxmp_loader_mtp = {
+	"Soundsmith/MegaTracker (MTP)",
+	mtp_test,
+	mtp_load
+};
+
+static int mtp_test(HIO_HANDLE *f, char *t, const int start)
+{
+	char buf[6];
+
+	if (hio_read(buf, 1, 6, f) < 6)
+		return -1;
+
+	if (memcmp(buf, "SONGOK", 6) && memcmp(buf, "IAN92a", 6))
+		return -1;
+
+	libxmp_read_title(f, t, 0);
+
+	return 0;
+}
+
+
+
+
+#define NAME_SIZE 255
+
+
+static int mtp_load(struct module_data *m, HIO_HANDLE *f, const int start)
+{
+	struct xmp_module *mod = &m->mod;
+	struct xmp_event *event;
+	int i, j, k;
+	uint8 buffer[25];
+	int blocksize;
+
+	LOAD_INIT();
+
+	hio_read(buffer, 6, 1, f);
+
+	if (!memcmp(buffer, "SONGOK", 6))
+		libxmp_set_type(m, "IIgs SoundSmith");
+	else if (!memcmp(buffer, "IAN92a", 8))
+		libxmp_set_type(m, "IIgs MegaTracker");
+	else
+		return -1;
+
+	blocksize = hio_read16l(f);
+	mod->spd = hio_read16l(f);
+	hio_seek(f, 10, SEEK_CUR);		/* skip 10 reserved bytes */
+	
+	mod->ins = mod->smp = 15;
+	if (libxmp_init_instrument(m) < 0)
+		return -1;
+
+	for (i = 0; i < mod->ins; i++) {
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+
+		hio_read(buffer, 1, 22, f);
+		if (buffer[0]) {
+			buffer[buffer[0] + 1] = 0;
+			libxmp_instrument_name(mod, i, buffer + 1, 22);
+		}
+		hio_read16l(f);		/* skip 2 reserved bytes */
+		mod->xxi[i].sub[0].vol = hio_read8(f) >> 2;
+		mod->xxi[i].sub[0].pan = 0x80;
+		hio_seek(f, 5, SEEK_CUR);	/* skip 5 bytes */
+	}
+
+	mod->len = hio_read8(f) & 0x7f;
+	hio_read8(f);
+	hio_read(mod->xxo, 1, 128, f);
+
+	MODULE_INFO();
+
+	hio_seek(f, start + 600, SEEK_SET);
+
+	mod->chn = 14;
+	mod->pat = blocksize / (14 * 64);
+	mod->trk = mod->pat * mod->chn;
+
+	if (libxmp_init_pattern(mod) < 0)
+		return -1;
+
+	/* Read and convert patterns */
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	/* Load notes */
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
+			return -1;
+
+		for (j = 0; j < mod->xxp[i]->rows; j++) {
+			for (k = 0; k < mod->chn; k++) {
+				event = &EVENT(i, k, j);
+				event->note = hio_read8(f);;
+				if (event->note)
+					event->note += 24;
+			}
+		}
+	}
+
+	/* Load fx1 */
+	for (i = 0; i < mod->pat; i++) {
+		for (j = 0; j < mod->xxp[i]->rows; j++) {
+			for (k = 0; k < mod->chn; k++) {
+				uint8 x;
+				event = &EVENT(i, k, j);
+				x = hio_read8(f);;
+				event->ins = x >> 4;
+
+				switch (x & 0x0f) {
+				case 0x00:
+					event->fxt = FX_ARPEGGIO;
+					break;
+				case 0x03:
+					event->fxt = FX_VOLSET;
+					break;
+				case 0x05:
+					event->fxt = FX_VOLSLIDE_DN;
+					break;
+				case 0x06:
+					event->fxt = FX_VOLSLIDE_UP;
+					break;
+				case 0x0f:
+					event->fxt = FX_SPEED;
+					break;
+				}
+			}
+		}
+	}
+
+	/* Load fx2 */
+	for (i = 0; i < mod->pat; i++) {
+		for (j = 0; j < mod->xxp[i]->rows; j++) {
+			for (k = 0; k < mod->chn; k++) {
+				event = &EVENT(i, k, j);
+				event->fxp = hio_read8(f);;
+
+				switch (event->fxt) {
+				case FX_VOLSET:
+				case FX_VOLSLIDE_DN:
+				case FX_VOLSLIDE_UP:
+					event->fxp >>= 2;
+				}
+			}
+		}
+	}
+
+	/* Read instrument data */
+	D_(D_INFO "Instruments    : %d ", mod->ins);
+
+	for (i = 0; i < mod->ins; i++) {
+		HIO_HANDLE *s;
+		char filename[1024];
+
+		if (!mod->xxi[i].name[0])
+			continue;
+
+		strncpy(filename, m->dirname, NAME_SIZE);
+		if (*filename)
+			strncat(filename, "/", NAME_SIZE);
+		strncat(filename, (char *)mod->xxi[i].name, NAME_SIZE);
+
+		if ((s = hio_open_file(filename, "rb")) != NULL) {
+			asif_load(m, s, i);
+			hio_close(s);
+		}
+
+#if 0
+		mod->xxs[i].lps = 0;
+		mod->xxs[i].lpe = 0;
+		mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0;
+		mod->xxi[i].sub[0].fin = 0;
+		mod->xxi[i].sub[0].pan = 0x80;
+#endif
+
+		D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x", i,
+				mod->xxi[i].name,
+				mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
+				mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
+				mod->xxi[i].sub[0].vol);
+	}
+
+	return 0;
+}
diff --git a/src/loaders/st_load.c b/src/loaders/st_load.c
index 1ed30c3..143941d 100644
--- a/src/loaders/st_load.c
+++ b/src/loaders/st_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 /* Ultimate Soundtracker support based on the module format description
@@ -11,388 +25,421 @@
  */
 
 #include 
-#include 
-#include 
-
 #include "loader.h"
 #include "mod.h"
 #include "period.h"
 
-static int st_test (HIO_HANDLE *, char *, const int);
-static int st_load (struct module_data *, HIO_HANDLE *, const int);
+static int st_test(HIO_HANDLE *, char *, const int);
+static int st_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader st_loader = {
-    "Soundtracker",
-    st_test,
-    st_load
+const struct format_loader libxmp_loader_st = {
+	"Soundtracker",
+	st_test,
+	st_load
 };
 
 static const int period[] = {
-    856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
-    428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
-    214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
-    -1
+	856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
+	428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
+	214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
+	-1
 };
 
 static int st_test(HIO_HANDLE *f, char *t, const int start)
 {
-    int i, j, k;
-    int pat, smp_size;
-    struct st_header mh;
-    uint8 mod_event[4];
-    struct stat st;
-
-    hio_stat(f, &st);
-
-    if (st.st_size < 600)
-	return -1;
-
-    smp_size = 0;
-
-    hio_seek(f, start, SEEK_SET);
-    hio_read(mh.name, 1, 20, f);
-    if (test_name(mh.name, 20) < 0)
-	return -1;
-
-    for (i = 0; i < 15; i++) {
-	hio_read(mh.ins[i].name, 1, 22, f);
-	mh.ins[i].size = hio_read16b(f);
-	mh.ins[i].finetune = hio_read8(f);
-	mh.ins[i].volume = hio_read8(f);
-	mh.ins[i].loop_start = hio_read16b(f);
-	mh.ins[i].loop_size = hio_read16b(f);
-    }
-    mh.len = hio_read8(f);
-    mh.restart = hio_read8(f);
-    hio_read(mh.order, 1, 128, f);
-	
-    for (pat = i = 0; i < 128; i++) {
-	if (mh.order[i] > 0x7f)
-	    return -1;
-	if (mh.order[i] > pat)
-	    pat = mh.order[i];
-    }
-    pat++;
-
-    if (pat > 0x7f || mh.len == 0 || mh.len > 0x7f)
-	return -1;
-
-    for (i = 0; i < 15; i++) {
-	if (test_name(mh.ins[i].name, 22) < 0)
-	    return -1;
-
-	if (mh.ins[i].volume > 0x40)
-	    return -1;
-
-	if (mh.ins[i].finetune > 0x0f)
-	    return -1;
-
-	if (mh.ins[i].size > 0x8000)
-	    return -1;
-
-	if ((mh.ins[i].loop_start >> 1) > 0x8000)
-	    return -1;
-
-	if (mh.ins[i].loop_size > 0x8000)
-	    return -1;
-
-	/* This test fails in atmosfer.mod, disable it 
-	 *
-	 * if (mh.ins[i].loop_size > 1 && mh.ins[i].loop_size > mh.ins[i].size)
-	 *    return -1;
-	 */
+	int i, j, k;
+	int pat, ins, smp_size;
+	struct st_header mh;
+	uint8 mod_event[4];
+	long size;
 
-	if ((mh.ins[i].loop_start >> 1) > mh.ins[i].size)
-	    return -1;
+	size = hio_size(f);
 
-	if (mh.ins[i].size && (mh.ins[i].loop_start >> 1) == mh.ins[i].size)
-	    return -1;
+	if (size < 600) {
+		return -1;
+	}
 
-	if (mh.ins[i].size == 0 && mh.ins[i].loop_start > 0)
-	    return -1;
+	smp_size = 0;
 
-	smp_size += 2 * mh.ins[i].size;
-    }
+	hio_seek(f, start, SEEK_SET);
+	hio_read(mh.name, 1, 20, f);
+	if (libxmp_test_name(mh.name, 20) < 0) {
+		return -1;
+	}
 
-    if (smp_size < 8)
-	return -1;
+	for (i = 0; i < 15; i++) {
+		hio_read(mh.ins[i].name, 1, 22, f);
+		mh.ins[i].size = hio_read16b(f);
+		mh.ins[i].finetune = hio_read8(f);
+		mh.ins[i].volume = hio_read8(f);
+		mh.ins[i].loop_start = hio_read16b(f);
+		mh.ins[i].loop_size = hio_read16b(f);
+	}
+	mh.len = hio_read8(f);
+	mh.restart = hio_read8(f);
+	hio_read(mh.order, 1, 128, f);
+
+	for (pat = i = 0; i < 128; i++) {
+		if (mh.order[i] > 0x7f)
+			return -1;
+		if (mh.order[i] > pat)
+			pat = mh.order[i];
+	}
+	pat++;
 
-    if (st.st_size < (600 + pat * 1024 + smp_size))
-	return -1;
+	if (pat > 0x7f || mh.len == 0 || mh.len > 0x7f)
+		return -1;
 
-    for (i = 0; i < pat; i++) {
-	for (j = 0; j < (64 * 4); j++) {
-	    int p;
-	
-	    hio_read (mod_event, 1, 4, f);
+	for (i = 0; i < 15; i++) {
+		if (libxmp_test_name(mh.ins[i].name, 22) < 0)
+			return -1;
 
-	    if (MSN(mod_event[0]))	/* sample number > 15 */
-		return -1;
+		if (mh.ins[i].volume > 0x40)
+			return -1;
+
+		if (mh.ins[i].finetune > 0x0f)
+			return -1;
+
+		if (mh.ins[i].size > 0x8000)
+			return -1;
+
+		/* This test is always false, disable it
+		 *
+		 * if ((mh.ins[i].loop_start >> 1) > 0x8000)
+		 *    return -1;
+		 */
 
-	    p = 256 * LSN(mod_event[0]) + mod_event[1];
+		if (mh.ins[i].loop_size > 0x8000)
+			return -1;
 
-	    if (p == 0)
-		continue;
+		/* This test fails in atmosfer.mod, disable it 
+		 *
+		 * if (mh.ins[i].loop_size > 1 && mh.ins[i].loop_size > mh.ins[i].size)
+		 *    return -1;
+		 */
 
-	    if (p == 162)	/* used in Karsten Obarski's blueberry.mod */
-		continue;
+		if ((mh.ins[i].loop_start >> 1) > mh.ins[i].size)
+			return -1;
 
-	    for (k = 0; period[k] >= 0; k++) {
-		if (p == period[k])
-		    break;
-	    }
-	    if (period[k] < 0)
+		if (mh.ins[i].size
+		    && (mh.ins[i].loop_start >> 1) == mh.ins[i].size)
+			return -1;
+
+		if (mh.ins[i].size == 0 && mh.ins[i].loop_start > 0)
+			return -1;
+
+		smp_size += 2 * mh.ins[i].size;
+	}
+
+	if (smp_size < 8)
 		return -1;
+
+	for (ins = i = 0; i < pat; i++) {
+		for (j = 0; j < (64 * 4); j++) {
+			int p, s;
+
+			hio_read(mod_event, 1, 4, f);
+
+			s = (mod_event[0] & 0xf0) | MSN(mod_event[2]);
+
+			if (s > 15)	/* sample number > 15 */
+				return -1;
+
+			if (s > ins)	/* find highest used sample */
+				ins = s;
+
+			p = 256 * LSN(mod_event[0]) + mod_event[1];
+
+			if (p == 0)
+				continue;
+
+			if (p == 162)	/* used in Karsten Obarski's blueberry.mod */
+				continue;
+
+			for (k = 0; period[k] >= 0; k++) {
+				if (p == period[k])
+					break;
+			}
+			if (period[k] < 0)
+				return -1;
+		}
 	}
-    }
 
-    hio_seek(f, start, SEEK_SET);
-    read_title(f, t, 20);
+	/* Check if file was cut before any unused samples */
+	if (size < 600 + pat * 1024 + smp_size) {
+		int ss;
+		for (ss = i = 0; i < ins; i++) {
+			ss += 2 * mh.ins[i].size;
+		}
+
+		if (size < 600 + pat * 1024 + ss) {
+			return -1;
+		}
+	}
 
-    return 0;
+	hio_seek(f, start, SEEK_SET);
+	libxmp_read_title(f, t, 20);
+
+	return 0;
 }
 
 static int st_load(struct module_data *m, HIO_HANDLE *f, const int start)
 {
-    struct xmp_module *mod = &m->mod;
-    int i, j;
-    int smp_size;
-    struct xmp_event ev, *event;
-    struct st_header mh;
-    uint8 mod_event[4];
-    int ust = 1, serr = 0;
-    /* int lps_mult = m->fetch & XMP_CTL_FIXLOOP ? 1 : 2; */
-    char *modtype;
-    int fxused;
-    int pos;
-
-    LOAD_INIT();
-
-    mod->ins = 15;
-    mod->smp = mod->ins;
-    smp_size = 0;
-
-    hio_read(mh.name, 1, 20, f);
-    for (i = 0; i < 15; i++) {
-	hio_read(mh.ins[i].name, 1, 22, f);
-	mh.ins[i].size = hio_read16b(f);
-	mh.ins[i].finetune = hio_read8(f);
-	mh.ins[i].volume = hio_read8(f);
-	mh.ins[i].loop_start = hio_read16b(f);
-	mh.ins[i].loop_size = hio_read16b(f);
-    }
-    mh.len = hio_read8(f);
-    mh.restart = hio_read8(f);
-    hio_read(mh.order, 1, 128, f);
-	
-    mod->len = mh.len;
-    mod->rst = mh.restart;
-
-    /* UST: The byte at module offset 471 is BPM, not the song restart
-     *      The default for UST modules is 0x78 = 120 BPM = 48 Hz.
-     */
-    if (mod->rst < 0x40)	/* should be 0x20 */
-	ust = 0;
-
-    memcpy (mod->xxo, mh.order, 128);
-
-    for (i = 0; i < 128; i++)
-	if (mod->xxo[i] > mod->pat)
-	    mod->pat = mod->xxo[i];
-    mod->pat++;
-
-    for (i = 0; i < mod->ins; i++) {
-	/* UST: Volume word does not contain a "Finetuning" value in its
-	 * high-byte.
-	 */
-	if (mh.ins[i].finetune)
-	    ust = 0;
+	struct xmp_module *mod = &m->mod;
+	int i, j;
+	int smp_size;
+	struct xmp_event ev, *event;
+	struct st_header mh;
+	uint8 mod_event[4];
+	int ust = 1;
+	/* int lps_mult = m->fetch & XMP_CTL_FIXLOOP ? 1 : 2; */
+	char *modtype;
+	int fxused;
+	int pos;
+	int used_ins;		/* Number of samples actually used */
+	long size;
+
+	LOAD_INIT();
+
+	size = hio_size(f);
+
+	mod->chn = 4;
+	mod->ins = 15;
+	mod->smp = mod->ins;
+	smp_size = 0;
+
+	hio_read(mh.name, 1, 20, f);
+	for (i = 0; i < 15; i++) {
+		hio_read(mh.ins[i].name, 1, 22, f);
+		mh.ins[i].size = hio_read16b(f);
+		mh.ins[i].finetune = hio_read8(f);
+		mh.ins[i].volume = hio_read8(f);
+		mh.ins[i].loop_start = hio_read16b(f);
+		mh.ins[i].loop_size = hio_read16b(f);
+	}
+	mh.len = hio_read8(f);
+	mh.restart = hio_read8(f);
+	hio_read(mh.order, 1, 128, f);
 
-	/* if (mh.ins[i].size == 0 && mh.ins[i].loop_size == 1)
-	    nt = 1; */
+	mod->len = mh.len;
+	mod->rst = mh.restart;
 
-	/* UST: Maximum sample length is 9999 bytes decimal, but 1387 words
-	 * hexadecimal. Longest samples on original sample disk ST-01 were
-	 * 9900 bytes.
+	/* UST: The byte at module offset 471 is BPM, not the song restart
+	 *      The default for UST modules is 0x78 = 120 BPM = 48 Hz.
 	 */
-	if (mh.ins[i].size > 0x1387 || mh.ins[i].loop_start > 9999
-		|| mh.ins[i].loop_size > 0x1387)
-	    ust = 0;
-
-	smp_size += 2 * mh.ins[i].size;
-    }
-
-    if (instrument_init(mod) < 0)
-	return -1;
-
-    for (i = 0; i < mod->ins; i++) {
-	struct xmp_instrument *xxi = &mod->xxi[i];
-	struct xmp_sample *xxs = &mod->xxs[i];
-	struct xmp_subinstrument *sub;
-
-	if (subinstrument_alloc(mod, i, 1) < 0)
-	    return -1;
-
-	sub = &xxi->sub[0];
-
-	xxs->len = 2 * mh.ins[i].size - mh.ins[i].loop_start;
-	xxs->lps = 0;
-	xxs->lpe = xxs->lps + 2 * mh.ins[i].loop_size;
-	xxs->flg = mh.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0;
-	sub->fin = (int8)(mh.ins[i].finetune << 4);
-	sub->vol = mh.ins[i].volume;
-	sub->pan = 0x80;
-	sub->sid = i;
-	strncpy((char *)xxi->name, (char *)mh.ins[i].name, 22);
-	adjust_string((char *)xxi->name);
-
-	if (xxs->len > 0)
-		xxi->nsm = 1;
-    }
-
-    mod->trk = mod->chn * mod->pat;
-
-    strncpy (mod->name, (char *) mh.name, 20);
-
-    /* Scan patterns for tracker detection */
-    fxused = 0;
-    pos = hio_tell(f);
-
-    for (i = 0; i < mod->pat; i++) {
-	for (j = 0; j < (64 * mod->chn); j++) {
-	    hio_read (mod_event, 1, 4, f);
-
-	    decode_protracker_event (&ev, mod_event);
-
-	    if (ev.fxt)
-		fxused |= 1 << ev.fxt;
-	    else if (ev.fxp)
-		fxused |= 1;
-	    
-	    /* UST: Only effects 1 (arpeggio) and 2 (pitchbend) are
-	     * available.
-	     */
-	    if (ev.fxt && ev.fxt != 1 && ev.fxt != 2)
+	if (mod->rst < 0x40)	/* should be 0x20 */
 		ust = 0;
 
-	    /* Karsten Obarski's sleepwalk mod uses arpeggio 30 and 40 */
-	    if (ev.fxt == 1) {		/* unlikely arpeggio */
-		if (ev.fxp == 0x00)
-		    ust = 0;
-		/*if ((ev.fxp & 0x0f) == 0 || (ev.fxp & 0xf0) == 0)
-		    ust = 0;*/
-	    }
-
-	    if (ev.fxt == 2) {		/* bend up and down at same time? */
-		if ((ev.fxp & 0x0f) != 0 && (ev.fxp & 0xf0) != 0)
-		    ust = 0;
-	    }
+	memcpy(mod->xxo, mh.order, 128);
+
+	for (i = 0; i < 128; i++) {
+		if (mod->xxo[i] > mod->pat)
+			mod->pat = mod->xxo[i];
 	}
-    }
+	mod->pat++;
 
-    if (fxused & ~0x0006)
-	ust = 0;
+	for (i = 0; i < mod->ins; i++) {
+		/* UST: Volume word does not contain a "Finetuning" value in its
+		 * high-byte.
+		 */
+		if (mh.ins[i].finetune)
+			ust = 0;
+
+		/* if (mh.ins[i].size == 0 && mh.ins[i].loop_size == 1)
+		   nt = 1; */
+
+		/* UST: Maximum sample length is 9999 bytes decimal, but 1387
+		 * words hexadecimal. Longest samples on original sample disk
+		 * ST-01 were 9900 bytes.
+		 */
+		if (mh.ins[i].size > 0x1387 || mh.ins[i].loop_start > 9999
+		    || mh.ins[i].loop_size > 0x1387) {
+			ust = 0;
+		}
+
+		smp_size += 2 * mh.ins[i].size;
+	}
 
-    if (ust)
-	modtype = "Ultimate Soundtracker";
-    else if ((fxused & ~0xd007) == 0)
-	modtype = "Soundtracker IX";	/* or MasterSoundtracker? */
-    else if ((fxused & ~0xf807) == 0)
-	modtype = "D.O.C Soundtracker 2.0";
-    else
-	modtype = "unknown tracker";
+	if (libxmp_init_instrument(m) < 0) {
+		return -1;
+	}
 
-    snprintf(mod->type, XMP_NAME_SIZE, "%s", modtype);
+	for (i = 0; i < mod->ins; i++) {
+		struct xmp_instrument *xxi = &mod->xxi[i];
+		struct xmp_sample *xxs = &mod->xxs[i];
+		struct xmp_subinstrument *sub;
+
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+
+		sub = &xxi->sub[0];
+
+		xxs->len = 2 * mh.ins[i].size - mh.ins[i].loop_start;
+		xxs->lps = 0;
+		xxs->lpe = xxs->lps + 2 * mh.ins[i].loop_size;
+		xxs->flg = mh.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0;
+		sub->fin = (int8) (mh.ins[i].finetune << 4);
+		sub->vol = mh.ins[i].volume;
+		sub->pan = 0x80;
+		sub->sid = i;
+		strncpy((char *)xxi->name, (char *)mh.ins[i].name, 22);
+
+		if (xxs->len > 0) {
+			xxi->nsm = 1;
+		}
+	}
 
-    MODULE_INFO();
+	mod->trk = mod->chn * mod->pat;
 
-    if (serr) {
-	D_(D_CRIT "File size error: %d", serr);
-    }
+	strncpy(mod->name, (char *)mh.name, 20);
 
-    hio_seek(f, start + pos, SEEK_SET);
+	/* Scan patterns for tracker detection */
+	fxused = 0;
+	pos = hio_tell(f);
 
-    if (pattern_init(mod) < 0)
-	return -1;
+	for (i = 0; i < mod->pat; i++) {
+		for (j = 0; j < (64 * mod->chn); j++) {
+			hio_read(mod_event, 1, 4, f);
+
+			libxmp_decode_protracker_event(&ev, mod_event);
+
+			if (ev.fxt)
+				fxused |= 1 << ev.fxt;
+			else if (ev.fxp)
+				fxused |= 1;
+
+			/* UST: Only effects 1 (arpeggio) and 2 (pitchbend) are
+			 * available.
+			 */
+			if (ev.fxt && ev.fxt != 1 && ev.fxt != 2)
+				ust = 0;
+
+			/* Karsten Obarski's sleepwalk uses arpeggio 30 and 40 */
+			if (ev.fxt == 1) {	/* unlikely arpeggio */
+				if (ev.fxp == 0x00)
+					ust = 0;
+				/*if ((ev.fxp & 0x0f) == 0 || (ev.fxp & 0xf0) == 0)
+				   ust = 0; */
+			}
+
+			if (ev.fxt == 2) {  /* bend up and down at same time? */
+				if ((ev.fxp & 0x0f) != 0 && (ev.fxp & 0xf0) != 0)
+					ust = 0;
+			}
+		}
+	}
 
-    /* Load and convert patterns */
+	if (fxused & ~0x0006) {
+		ust = 0;
+	}
 
-    D_(D_INFO "Stored patterns: %d", mod->pat);
+	if (ust) {
+		modtype = "Ultimate Soundtracker";
+	} else if ((fxused & ~0xd007) == 0) {
+		modtype = "Soundtracker IX";	/* or MasterSoundtracker? */
+	} else if ((fxused & ~0xf807) == 0) {
+		modtype = "D.O.C Soundtracker 2.0";
+	} else {
+		modtype = "unknown tracker";
+	}
 
-    for (i = 0; i < mod->pat; i++) {
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
-	    return -1;
+	snprintf(mod->type, XMP_NAME_SIZE, "%s", modtype);
 
-	for (j = 0; j < (64 * mod->chn); j++) {
-	    event = &EVENT (i, j % mod->chn, j / mod->chn);
-	    hio_read (mod_event, 1, 4, f);
+	MODULE_INFO();
 
-	    decode_protracker_event(event, mod_event);
+	if (hio_seek(f, start + pos, SEEK_SET) < 0) {
+		return -1;
+	}
+
+	if (libxmp_init_pattern(mod) < 0) {
+		return -1;
 	}
-    }
 
-    for (i = 0; i < mod->ins; i++) {
-	D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d",
-		i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
-		mod->xxs[i].lpe, mh.ins[i].loop_size > 1 ? 'L' : ' ',
-		mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4);
-    }
+	/* Load and convert patterns */
+
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	used_ins = 0;
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
+			return -1;
+
+		for (j = 0; j < (64 * mod->chn); j++) {
+			event = &EVENT(i, j % mod->chn, j / mod->chn);
+			hio_read(mod_event, 1, 4, f);
 
-    m->quirk |= QUIRK_MODRNG;
+			libxmp_decode_protracker_event(event, mod_event);
 
-    /* Perform the necessary conversions for Ultimate Soundtracker */
-    if (ust) {
-	/* Fix restart & bpm */
-	mod->bpm = mod->rst;
-	mod->rst = 0;
+			if (ev.ins > used_ins)
+				used_ins = ev.ins;
+		}
+	}
 
-	/* Fix sample loops */
 	for (i = 0; i < mod->ins; i++) {
-	    /* FIXME */	
+		D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d",
+		   i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
+		   mod->xxs[i].lpe, mh.ins[i].loop_size > 1 ? 'L' : ' ',
+		   mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4);
 	}
 
-	/* Fix effects (arpeggio and pitchbending) */
-	for (i = 0; i < mod->pat; i++) {
-	    for (j = 0; j < (64 * mod->chn); j++) {
-		event = &EVENT(i, j % mod->chn, j / mod->chn);
-		if (event->fxt == 1)
-		    event->fxt = 0;
-		else if (event->fxt == 2 && (event->fxp & 0xf0) == 0)
-		    event->fxt = 1;
-		else if (event->fxt == 2 && (event->fxp & 0x0f) == 0)
-		    event->fxp >>= 4;
-	    }
+	m->quirk |= QUIRK_NOBPM;
+	m->period_type = PERIOD_MODRNG;
+
+	/* Perform the necessary conversions for Ultimate Soundtracker */
+	if (ust) {
+		/* Fix restart & bpm */
+		mod->bpm = mod->rst;
+		mod->rst = 0;
+
+		/* Fix sample loops */
+		for (i = 0; i < mod->ins; i++) {
+			/* FIXME */
+		}
+
+		/* Fix effects (arpeggio and pitchbending) */
+		for (i = 0; i < mod->pat; i++) {
+			for (j = 0; j < (64 * mod->chn); j++) {
+				event = &EVENT(i, j % mod->chn, j / mod->chn);
+				if (event->fxt == 1)
+					event->fxt = 0;
+				else if (event->fxt == 2
+					 && (event->fxp & 0xf0) == 0)
+					event->fxt = 1;
+				else if (event->fxt == 2
+					 && (event->fxp & 0x0f) == 0)
+					event->fxp >>= 4;
+			}
+		}
+	} else {
+		if (mod->rst >= mod->len)
+			mod->rst = 0;
 	}
-    } else {
-	if (mod->rst >= mod->len)
-	    mod->rst = 0;
-    }
-
-    /* Load samples */
-
-    D_(D_INFO "Stored samples: %d", mod->smp);
-
-    for (i = 0; i < mod->smp; i++) {
-	if (!mod->xxs[i].len)
-	    continue;
-
-	/* Skip transient part of sample.
-	 *
-	 * Dennis Lindroos  reports: One main thing is
-	 * sample-looping which on all trackers up to Noisetracker 1 (i
-	 * think it was Mahoney who actually changed the loopstart to be
-	 * in WORDS) never play looped samples from the beginning, i.e. only
-	 * plays the looped part. This can be heard in old modules especially
-	 * with "analogstring", "strings2" or "strings3" samples because
-	 * these have "slow attack" that is not part of the loop and thus
-	 * they sound "sharper"..
-	 */
-	hio_seek(f, mh.ins[i].loop_start, SEEK_CUR);
 
-	if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) {
-	    return -1;
+	/* Load samples */
+
+	D_(D_INFO "Stored samples: %d", mod->smp);
+
+	for (i = 0; i < mod->ins; i++) {
+		if (!mod->xxs[i].len)
+			continue;
+
+		/* Skip transient part of sample.
+		 *
+		 * Dennis Lindroos  reports: One main thing is
+		 * sample-looping which on all trackers up to Noisetracker 1 (i
+		 * think it was Mahoney who actually changed the loopstart to be
+		 * in WORDS) never play looped samples from the beginning, i.e.
+		 * only plays the looped part. This can be heard in old modules
+		 * especially with "analogstring", "strings2" or "strings3"
+		 * samples because these have "slow attack" that is not part of
+		 * the loop and thus they sound "sharper"..
+		 */
+		hio_seek(f, mh.ins[i].loop_start, SEEK_CUR);
+
+		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) {
+			return -1;
+		}
 	}
-    }
 
-    return 0;
+	return 0;
 }
diff --git a/src/loaders/stc_load.c b/src/loaders/stc_load.c
new file mode 100644
index 0000000..3c9d168
--- /dev/null
+++ b/src/loaders/stc_load.c
@@ -0,0 +1,361 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * This file is part of the Extended Module Player and is distributed
+ * under the terms of the GNU Lesser General Public License. See COPYING.LIB
+ * for more information.
+ */
+
+#include "loader.h"
+#include "period.h"
+#include "spectrum.h"
+
+/* ZX Spectrum Sound Tracker loader
+ * Sound Tracker written by Jarek Burczynski (Bzyk), 1990
+ */
+
+static int stc_test(HIO_HANDLE *, char *, const int);
+static int stc_load(struct module_data *, HIO_HANDLE *, const int);
+
+
+const struct format_loader libxmp_loader_stc = {
+	"ZX Spectrum Sound Tracker (STC)",
+	stc_test,
+	stc_load
+};
+
+
+#define MAX_PAT 32
+
+struct stc_ord {
+	int pattern;
+	int height;
+};
+
+struct stc_pat {
+	int ch[3];
+};
+
+static int stc_test(HIO_HANDLE * f, char *t, const int start)
+{
+	int pos_ptr, orn_ptr, pat_ptr;
+	int i, len, max_pat;
+
+	hio_seek(f, start, SEEK_SET);
+
+	if (hio_read8(f) > 0x20)			/* Check tempo */
+		return -1;
+
+	pos_ptr = hio_read16l(f);			/* Positions pointer */
+	orn_ptr = hio_read16l(f);			/* Ornaments pointer */
+	pat_ptr = hio_read16l(f);			/* Patterns pointer */
+
+	if (pos_ptr < 138 || orn_ptr < 138 || pat_ptr < 138)
+		return -1;
+
+	hio_seek(f, start + pos_ptr, SEEK_SET);
+	len = hio_read8(f) + 1;
+
+	for (max_pat = i = 0; i < len; i++) {
+		int pat = hio_read8(f);
+		if (pat > MAX_PAT)		/* Check orders */
+			return -1;
+		if (pat > max_pat)
+			max_pat = pat;
+		hio_read8(f);
+	}
+
+	hio_seek(f, pat_ptr, SEEK_SET);
+
+	for (i = 0; i < max_pat; i++) {
+		int num = hio_read8(f);		/* Check track pointers */
+		if (num != (i + 1))
+			return -1;
+		hio_read16l(f);
+		hio_read16l(f);
+		hio_read16l(f);
+	}
+
+	if (hio_read8(f) != 0xff)
+		return -1;
+
+	hio_seek(f, start + 7, SEEK_SET);
+	libxmp_read_title(f, t, 18);
+
+	return 0;
+}
+
+static int stc_load(struct module_data *m, HIO_HANDLE * f, const int start)
+{
+	struct xmp_module *mod = &m->mod;
+	struct xmp_event *event /*, *noise*/;
+	int i, j;
+	uint8 buf[100];
+	int pos_ptr, orn_ptr, pat_ptr;
+	struct stc_ord stc_ord[256];
+	struct stc_pat stc_pat[MAX_PAT];
+	int num, flag, orn;
+	int *decoded;
+	struct spectrum_extra *se;
+
+	LOAD_INIT();
+
+	mod->spd = hio_read8(f);		/* Speed */
+	pos_ptr = hio_read16l(f);		/* Positions pointer */
+	orn_ptr = hio_read16l(f);		/* Ornaments pointer */
+	pat_ptr = hio_read16l(f);		/* Patterns pointer */
+
+	hio_read(buf, 18, 1, f);		/* Title */
+	libxmp_copy_adjust(mod->name, (uint8 *)buf, 18);
+	libxmp_set_type(m, "ZX Spectrum Sound Tracker");
+
+	hio_read16l(f);			/* Size */
+
+	/* Read orders */
+
+	hio_seek(f, pos_ptr, SEEK_SET);
+	mod->len = hio_read8(f) + 1;
+
+	for (num = i = 0; i < mod->len; i++) {
+		stc_ord[i].pattern = hio_read8(f);
+		stc_ord[i].height = hio_read8s(f);
+		//printf("%d %d -- ", stc_ord[i].pattern, stc_ord[i].height);
+
+		for (flag = j = 0; j < i; j++) {
+			if (stc_ord[i].pattern == stc_ord[j].pattern &&
+				stc_ord[i].height == stc_ord[j].height)
+			{
+				mod->xxo[i] = mod->xxo[j];
+				flag = 1;
+				break;
+			}
+		}
+		if (!flag) {
+			mod->xxo[i] = num++;
+		}
+		//printf("%d\n", mod->xxo[i]);
+	}
+
+	mod->chn = 3;
+	mod->pat = num;
+	mod->trk = mod->pat * mod->chn;
+	mod->ins = 15;
+	mod->smp = mod->ins;
+	orn = (pat_ptr - orn_ptr) / 33;
+
+	MODULE_INFO();
+
+	/* Read patterns */
+
+	if (libxmp_init_pattern(mod) < 0)
+		return -1;
+
+	hio_seek(f, pat_ptr, SEEK_SET);
+	decoded = calloc(mod->pat, sizeof(int));
+	D_(D_INFO "Stored patterns: %d ", mod->pat);
+
+	for (i = 0; i < MAX_PAT; i++) {
+		if (hio_read8(f) == 0xff)
+			break;
+		stc_pat[i].ch[0] = hio_read16l(f);
+		stc_pat[i].ch[1] = hio_read16l(f);
+		stc_pat[i].ch[2] = hio_read16l(f);
+	}
+
+	for (i = 0; i < mod->len; i++) {		/* pattern */
+		int src = stc_ord[i].pattern - 1;
+		int dest = mod->xxo[i];
+		int trans = stc_ord[i].height;
+
+		if (decoded[dest])
+			continue;
+
+		//printf("%d/%d) Read pattern %d -> %d\n", i, mod->len, src, dest);
+
+		if (libxmp_alloc_pattern_tracks(mod, dest, 64) < 0)
+			return -1;
+
+		for (j = 0; j < 3; j++) {		/* row */
+			int row = 0;
+			int x;
+			int rowinc = 0;
+	
+			hio_seek(f, stc_pat[src].ch[j], SEEK_SET);
+
+			do {
+				for (;;) {
+					x = hio_read8(f);
+
+					if (x == 0xff)
+						break;
+	
+//printf("pat %d, channel %d, row %d, x = %02x\n", dest, j, row, x);
+					event = &EVENT(dest, j, row);
+				
+					if (x <= 0x5f) {
+						event->note = x + 18 + trans;
+						row += 1 + rowinc;
+						break;
+					}
+
+					if (x <= 0x6f) {
+						event->ins = x - 0x5f - 1;
+					} else if (x <= 0x7f) {
+						/* ornament*/
+						event->fxt = FX_SYNTH_0;
+						event->fxp = x - 0x70;
+					} else if (x == 0x80) {
+						event->note = XMP_KEY_OFF;
+						row += 1 + rowinc;
+						break;
+					} else if (x == 0x81) {
+						/* ? */
+						row += 1 + rowinc;
+					} else if (x == 0x82) {
+						/* disable ornament/envelope */
+						event->fxt = FX_SYNTH_0;
+						event->fxp = 0;
+						event->f2t = FX_SYNTH_2;
+						event->f2p = 0;
+					} else if (x <= 0x8e) {
+						/* envelope */
+						event->fxt = FX_SYNTH_0 +
+							x - 0x80;      /* R13 */
+						event->fxp = hio_read8(f); /* R11 */
+						event->f2t = FX_SYNTH_1;
+						event->f2p = hio_read8(f); /* R12 */
+					} else {
+						rowinc = x - 0xa1;
+					}
+				}
+			} while (x != 0xff);
+		}
+
+		decoded[dest] = 1;
+	}
+
+	free(decoded);
+
+	/* Read instruments */
+
+	if (libxmp_init_instrument(m) < 0)
+		return -1;
+
+	hio_seek(f, 27, SEEK_SET);
+
+	D_(D_INFO "Instruments: %d", mod->ins);
+	for (i = 0; i < mod->ins; i++) {
+		struct spectrum_sample ss;
+
+		memset(&ss, 0, sizeof (struct spectrum_sample));
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+		mod->xxi[i].nsm = 1;
+		mod->xxi[i].sub[0].vol = 0x40;
+		mod->xxi[i].sub[0].pan = 0x80;
+		mod->xxi[i].sub[0].xpo = -1;
+		mod->xxi[i].sub[0].sid = i;
+
+		hio_read(buf, 1, 99, f);
+
+		if (buf[97] == 0) {
+			ss.loop = 32;
+			ss.length = 33;
+		} else {
+			ss.loop = buf[97] - 1;
+			if (ss.loop > 31)
+				ss.loop = 31;
+			ss.length = buf[97] + buf[98];
+			if (ss.length > 32)
+				ss.length = 32;
+			if (ss.length == 0)
+				ss.length = 1;
+			if (ss.loop >= ss.length)
+				ss.loop = ss.length - 1;
+
+			if (ss.length < 32) {
+				ss.length += 33 - (ss.loop + 1);
+				ss.loop = 32;
+			}
+		}
+
+		/* Read sample ticks */
+
+		for (j = 0; j < 31; j++) {
+			struct spectrum_stick *sst = &ss.stick[j];
+			uint8 *chdata = &buf[1 + j * 3];
+			
+			memset(sst, 0, sizeof (struct spectrum_stick));
+
+			if (~chdata[1] & 0x80) {
+				sst->flags |= SPECTRUM_FLAG_MIXNOISE;
+				sst->noise_env_inc = chdata[1] & 0x1f;
+
+				if (sst->noise_env_inc & 0x10)
+					sst->noise_env_inc |= 0xf0;
+			}
+
+			if (~chdata[1] & 0x40)
+				sst->flags |= SPECTRUM_FLAG_MIXTONE;
+
+			sst->vol = chdata[0] & 0x0f;
+
+			sst->tone_inc = (((int)(chdata[0] & 0xf0)) << 4) |
+						chdata[2];
+
+			if (~chdata[1] & 0x20)
+				sst->tone_inc = -sst->tone_inc;
+
+			sst->flags |= SPECTRUM_FLAG_ENVELOPE;
+
+			/*if (j != 0) {
+				reportv(ctx, 1, "               ");
+			}
+			reportv(ctx, 1, "%02X %c%c%c %c%03x %x\n", j,
+				sst->flags & SPECTRUM_FLAG_MIXTONE ? 'T' : 't',
+				sst->flags & SPECTRUM_FLAG_MIXNOISE ? 'N' : 'n',
+				sst->flags & SPECTRUM_FLAG_ENVELOPE ? 'E' : 'e',
+				sst->tone_inc >= 0 ? '+' : '-',
+				sst->tone_inc >= 0 ?
+					sst->tone_inc : -sst->tone_inc,
+				sst->vol);*/
+			
+		}
+
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_SPECTRUM, &mod->xxs[i],
+							(char *)&ss) < 0) {
+			return -1;
+		}
+	}
+	
+	/* Read ornaments */
+
+	hio_seek(f, orn_ptr, SEEK_SET);
+	m->extra = calloc(1, sizeof (struct spectrum_extra));
+	se = m->extra;
+
+	D_(D_INFO "Ornaments: %d", orn);
+	for (i = 0; i < orn; i++) {
+		int index;
+		struct spectrum_ornament *so;
+
+		index = hio_read8(f);		
+
+		so = &se->ornament[index];
+		so->length = 32;
+		so->loop = 31;
+
+		for (j = 0; j < 32; j++) {
+			so->val[j] = hio_read8s(f);
+		}
+	}
+
+	for (i = 0; i < 4; i++) {
+		mod->xxc[i].pan = 0x80;
+		mod->xxc[i].flg = XMP_CHANNEL_SYNTH;
+	}
+	
+	m->synth = &synth_spectrum;
+
+	return 0;
+}
diff --git a/src/loaders/stim_load.c b/src/loaders/stim_load.c
index c6ac1d6..475464a 100644
--- a/src/loaders/stim_load.c
+++ b/src/loaders/stim_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -34,7 +34,7 @@
 static int stim_test(HIO_HANDLE *, char *, const int);
 static int stim_load(struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader stim_loader = {
+const struct format_loader libxmp_loader_stim = {
 	"Slamtilt",
 	stim_test,
 	stim_load
@@ -48,7 +48,7 @@ static int stim_test(HIO_HANDLE *f, char *t, const int start)
 	if (hio_read16b(f) > 16)
 		return -1;
 
-	read_title(f, t, 0);
+	libxmp_read_title(f, t, 0);
 
 	return 0;
 }
@@ -91,9 +91,19 @@ static int stim_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	sh.len = hio_read16b(f);
 	sh.pat = hio_read16b(f);
 	hio_read(&sh.order, 128, 1, f);
-	for (i = 0; i < 64; i++)
+
+	/* Sanity check */
+	if (sh.nos > 31 || sh.len > 128 || sh.pat > 64) {
+		return -1;
+	}
+
+	for (i = 0; i < 64; i++) {
 		sh.pataddr[i] = hio_read32b(f) + 0x0c;
+		if (sh.pataddr[i] > 0x00100000)
+			return -1;
+	}
 
+	mod->chn = 4;
 	mod->len = sh.len;
 	mod->pat = sh.pat;
 	mod->ins = sh.nos;
@@ -103,18 +113,18 @@ static int stim_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	for (i = 0; i < mod->len; i++)
 		mod->xxo[i] = sh.order[i];
 
-	set_type(m, "Slamtilt");
+	libxmp_set_type(m, "Slamtilt");
 
 	MODULE_INFO();
 
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	/* Load and convert patterns */
 	D_(D_INFO "Stored patterns: %d", mod->pat);
 
 	for (i = 0; i < mod->pat; i++) {
-		if (pattern_tracks_alloc(mod, i, 64) < 0)
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 			return -1;
 
 		hio_seek(f, start + sh.pataddr[i] + 8, SEEK_SET);
@@ -151,12 +161,12 @@ static int stim_load(struct module_data *m, HIO_HANDLE *f, const int start)
 				event->fxt = ((b2 >> 4) & 0x0c) | (b1 >> 5);
 				event->fxp = b3;
 
-				disable_continue_fx(event);
+				libxmp_disable_continue_fx(event);
 			}
 		}
 	}
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	D_(D_INFO "Stored samples: %d", mod->smp);
@@ -170,7 +180,7 @@ static int stim_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		si.loop_start = hio_read16b(f);
 		si.loop_size = hio_read16b(f);
 
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 
 		mod->xxs[i].len = 2 * si.size;
@@ -194,11 +204,11 @@ static int stim_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		if (!mod->xxs[i].len)
 			continue;
 
-		if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
 			return -1;
 	}
 
-	m->quirk |= QUIRK_MODRNG;
+	m->period_type = PERIOD_MODRNG;
 
 	return 0;
 }
diff --git a/src/loaders/stm_load.c b/src/loaders/stm_load.c
index a4ec942..c0359c4 100644
--- a/src/loaders/stm_load.c
+++ b/src/loaders/stm_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -55,42 +55,39 @@ struct stm_file_header {
 	struct stm_instrument_header ins[31];
 };
 
+static int stm_test(HIO_HANDLE *, char *, const int);
+static int stm_load(struct module_data *, HIO_HANDLE *, const int);
 
-static int stm_test (HIO_HANDLE *, char *, const int);
-static int stm_load (struct module_data *, HIO_HANDLE *, const int);
-
-const struct format_loader stm_loader = {
-    "Scream Tracker 2",
-    stm_test,
-    stm_load
+const struct format_loader libxmp_loader_stm = {
+	"Scream Tracker 2",
+	stm_test,
+	stm_load
 };
 
-static int stm_test(HIO_HANDLE *f, char *t, const int start)
+static int stm_test(HIO_HANDLE * f, char *t, const int start)
 {
-    char buf[8];
+	char buf[8];
 
-    hio_seek(f, start + 20, SEEK_SET);
-    if (hio_read(buf, 1, 8, f) < 8)
-	return -1;
-    if (memcmp(buf, "!Scream!", 8) && memcmp(buf, "BMOD2STM", 8))
-	return -1;
+	hio_seek(f, start + 20, SEEK_SET);
+	if (hio_read(buf, 1, 8, f) < 8)
+		return -1;
+	if (memcmp(buf, "!Scream!", 8) && memcmp(buf, "BMOD2STM", 8))
+		return -1;
 
-    hio_read8(f);
+	hio_read8(f);
 
-    if (hio_read8(f) != STM_TYPE_MODULE)
-	return -1;
+	if (hio_read8(f) != STM_TYPE_MODULE)
+		return -1;
 
-    if (hio_read8(f) < 1)		/* We don't want STX files */
-	return -1;
+	if (hio_read8(f) < 1)	/* We don't want STX files */
+		return -1;
 
-    hio_seek(f, start + 0, SEEK_SET);
-    read_title(f, t, 20);
+	hio_seek(f, start + 0, SEEK_SET);
+	libxmp_read_title(f, t, 20);
 
-    return 0;
+	return 0;
 }
 
-
-
 #define FX_NONE		0xff
 
 /*
@@ -104,175 +101,185 @@ static int stm_test(HIO_HANDLE *f, char *t, const int start)
  */
 
 static const uint8 fx[] = {
-    FX_NONE,		FX_SPEED,
-    FX_JUMP,		FX_BREAK,
-    FX_VOLSLIDE,	FX_PORTA_DN,
-    FX_PORTA_UP,	FX_TONEPORTA,
-    FX_VIBRATO,		FX_TREMOR,
-    FX_ARPEGGIO
+	FX_NONE,
+	FX_SPEED,	/* A - Set tempo to [INFO]. 60 normal. */
+	FX_JUMP,	/* B - Break pattern and jmp to order [INFO] */
+	FX_BREAK,	/* C - Break pattern */
+	FX_VOLSLIDE,	/* D - Slide volume; Hi-nibble=up, Lo-nibble=down */
+	FX_PORTA_DN,	/* E - Slide down at speed [INFO] */
+	FX_PORTA_UP,	/* F - Slide up at speed [INFO] */
+	FX_TONEPORTA,	/* G - Slide to the note specified at speed [INFO] */
+	FX_VIBRATO,	/* H - Vibrato; Hi-nibble, speed. Lo-nibble, size */
+	FX_TREMOR,	/* I - Tremor; Hi-nibble, ontime. Lo-nibble, offtime */
+	FX_ARPEGGIO	/* J - Arpeggio */
 };
 
-
-static int stm_load(struct module_data *m, HIO_HANDLE *f, const int start)
+static int stm_load(struct module_data *m, HIO_HANDLE * f, const int start)
 {
-    struct xmp_module *mod = &m->mod;
-    int i, j;
-    struct xmp_event *event;
-    struct stm_file_header sfh;
-    uint8 b;
-    int bmod2stm = 0;
-
-    LOAD_INIT();
-
-    hio_read(&sfh.name, 20, 1, f);		/* ASCIIZ song name */
-    hio_read(&sfh.magic, 8, 1, f);		/* '!Scream!' */
-    sfh.rsvd1 = hio_read8(f);			/* '\x1a' */
-    sfh.type = hio_read8(f);			/* 1=song, 2=module */
-    sfh.vermaj = hio_read8(f);			/* Major version number */
-    sfh.vermin = hio_read8(f);			/* Minor version number */
-    sfh.tempo = hio_read8(f);			/* Playback tempo */
-    sfh.patterns = hio_read8(f);		/* Number of patterns */
-    sfh.gvol = hio_read8(f);			/* Global volume */
-    hio_read(&sfh.rsvd2, 13, 1, f);		/* Reserved */
-
-    for (i = 0; i < 31; i++) {
-	hio_read(&sfh.ins[i].name, 12, 1, f);	/* ASCIIZ instrument name */
-	sfh.ins[i].id = hio_read8(f);		/* Id=0 */
-	sfh.ins[i].idisk = hio_read8(f);	/* Instrument disk */
-	sfh.ins[i].rsvd1 = hio_read16l(f);	/* Reserved */
-	sfh.ins[i].length = hio_read16l(f);	/* Sample length */
-	sfh.ins[i].loopbeg = hio_read16l(f);	/* Loop begin */
-	sfh.ins[i].loopend = hio_read16l(f);	/* Loop end */
-	sfh.ins[i].volume = hio_read8(f);	/* Playback volume */
-	sfh.ins[i].rsvd2 = hio_read8(f);	/* Reserved */
-	sfh.ins[i].c2spd = hio_read16l(f);	/* C4 speed */
-	sfh.ins[i].rsvd3 = hio_read32l(f);	/* Reserved */
-	sfh.ins[i].paralen = hio_read16l(f);	/* Length in paragraphs */
-    }
-
-    if (!strncmp ((char *)sfh.magic, "BMOD2STM", 8))
-	bmod2stm = 1;
-
-    mod->pat = sfh.patterns;
-    mod->trk = mod->pat * mod->chn;
-    mod->spd = MSN (sfh.tempo);
-    mod->ins = 31;
-    mod->smp = mod->ins;
-    m->c4rate = C4_NTSC_RATE;
-
-    copy_adjust(mod->name, sfh.name, 20);
-
-    if (bmod2stm) {
-	snprintf(mod->type, XMP_NAME_SIZE, "BMOD2STM STM");
-    } else {
-	snprintf(mod->type, XMP_NAME_SIZE, "Scream Tracker %d.%02d STM",
-						sfh.vermaj, sfh.vermin);
-    }
-
-    MODULE_INFO();
-
-    if (instrument_init(mod) < 0)
-	return -1;
-
-    /* Read and convert instruments and samples */
-    for (i = 0; i < mod->ins; i++) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
-	    return -1;
-
-	mod->xxs[i].len = sfh.ins[i].length;
-	mod->xxs[i].lps = sfh.ins[i].loopbeg;
-	mod->xxs[i].lpe = sfh.ins[i].loopend;
-	if (mod->xxs[i].lpe == 0xffff)
-	    mod->xxs[i].lpe = 0;
-	mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0;
-	mod->xxi[i].sub[0].vol = sfh.ins[i].volume;
-	mod->xxi[i].sub[0].pan = 0x80;
-	mod->xxi[i].sub[0].sid = i;
-
-	if (mod->xxs[i].len > 0)
-		mod->xxi[i].nsm = 1;
-
-	instrument_name(mod, i, sfh.ins[i].name, 12);
-
-	D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x %5d", i,
-		mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
-		mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
-		mod->xxi[i].sub[0].vol, sfh.ins[i].c2spd);
-
-	sfh.ins[i].c2spd = 8363 * sfh.ins[i].c2spd / 8448;
-	c2spd_to_note (sfh.ins[i].c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
-    }
-
-    hio_read(mod->xxo, 1, 128, f);
-
-    for (i = 0; i < 128; i++)
-	if (mod->xxo[i] >= mod->pat)
-	    break;
-
-    mod->len = i;
-
-    D_(D_INFO "Module length: %d", mod->len);
-
-    if (pattern_init(mod) < 0)
-	return -1;
-
-    /* Read and convert patterns */
-    D_(D_INFO "Stored patterns: %d", mod->pat);
-
-    for (i = 0; i < mod->pat; i++) {
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
-	    return -1;
-
-	for (j = 0; j < 64 * mod->chn; j++) {
-	    event = &EVENT (i, j % mod->chn, j / mod->chn);
-	    b = hio_read8(f);
-	    memset (event, 0, sizeof (struct xmp_event));
-	    switch (b) {
-	    case 251:
-	    case 252:
-	    case 253:
-		break;
-	    case 255:
-		b = 0;
-	    default:
-		event->note = b ? 13 + LSN(b) + 12 * (2 + MSN(b)) : 0;
-		b = hio_read8(f);
-		event->vol = b & 0x07;
-		event->ins = (b & 0xf8) >> 3;
-		b = hio_read8(f);
-		event->vol += (b & 0xf0) >> 1;
-		if (event->vol > 0x40)
-		    event->vol = 0;
-		else
-		    event->vol++;
-		event->fxt = fx[LSN(b)];
-		event->fxp = hio_read8(f);
-		switch (event->fxt) {
-		case FX_SPEED:
-		    event->fxp = MSN (event->fxp);
-		    break;
-		case FX_NONE:
-		    event->fxp = event->fxt = 0;
-		    break;
-		}
-	    }
+	struct xmp_module *mod = &m->mod;
+	int i, j;
+	struct xmp_event *event;
+	struct stm_file_header sfh;
+	uint8 b;
+	int bmod2stm = 0;
+
+	LOAD_INIT();
+
+	hio_read(&sfh.name, 20, 1, f);	/* ASCIIZ song name */
+	hio_read(&sfh.magic, 8, 1, f);	/* '!Scream!' */
+	sfh.rsvd1 = hio_read8(f);	/* '\x1a' */
+	sfh.type = hio_read8(f);	/* 1=song, 2=module */
+	sfh.vermaj = hio_read8(f);	/* Major version number */
+	sfh.vermin = hio_read8(f);	/* Minor version number */
+	sfh.tempo = hio_read8(f);	/* Playback tempo */
+	sfh.patterns = hio_read8(f);	/* Number of patterns */
+	sfh.gvol = hio_read8(f);	/* Global volume */
+	hio_read(&sfh.rsvd2, 13, 1, f);	/* Reserved */
+
+	for (i = 0; i < 31; i++) {
+		hio_read(&sfh.ins[i].name, 12, 1, f);	/* Instrument name */
+		sfh.ins[i].id = hio_read8(f);		/* Id=0 */
+		sfh.ins[i].idisk = hio_read8(f);	/* Instrument disk */
+		sfh.ins[i].rsvd1 = hio_read16l(f);	/* Reserved */
+		sfh.ins[i].length = hio_read16l(f);	/* Sample length */
+		sfh.ins[i].loopbeg = hio_read16l(f);	/* Loop begin */
+		sfh.ins[i].loopend = hio_read16l(f);	/* Loop end */
+		sfh.ins[i].volume = hio_read8(f);	/* Playback volume */
+		sfh.ins[i].rsvd2 = hio_read8(f);	/* Reserved */
+		sfh.ins[i].c2spd = hio_read16l(f);	/* C4 speed */
+		sfh.ins[i].rsvd3 = hio_read32l(f);	/* Reserved */
+		sfh.ins[i].paralen = hio_read16l(f);	/* Length in paragraphs */
 	}
-    }
 
-    /* Read samples */
-    D_(D_INFO "Stored samples: %d", mod->smp);
-
-    for (i = 0; i < mod->ins; i++) {
-	if (mod->xxs[i].len > 1) {
-	    if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+	if (hio_error(f)) {
 		return -1;
+	}
+
+	if (!strncmp((char *)sfh.magic, "BMOD2STM", 8))
+		bmod2stm = 1;
+
+	mod->chn = 4;
+	mod->pat = sfh.patterns;
+	mod->trk = mod->pat * mod->chn;
+	mod->spd = MSN(sfh.tempo);
+	mod->ins = 31;
+	mod->smp = mod->ins;
+	m->c4rate = C4_NTSC_RATE;
+
+	libxmp_copy_adjust(mod->name, sfh.name, 20);
+
+	if (bmod2stm) {
+		snprintf(mod->type, XMP_NAME_SIZE, "BMOD2STM STM");
 	} else {
-	    mod->xxi[i].nsm = 0;
+		snprintf(mod->type, XMP_NAME_SIZE, "Scream Tracker %d.%02d STM",
+			 sfh.vermaj, sfh.vermin);
+	}
+
+	MODULE_INFO();
+
+	if (libxmp_init_instrument(m) < 0)
+		return -1;
+
+	/* Read and convert instruments and samples */
+	for (i = 0; i < mod->ins; i++) {
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+
+		mod->xxs[i].len = sfh.ins[i].length;
+		mod->xxs[i].lps = sfh.ins[i].loopbeg;
+		mod->xxs[i].lpe = sfh.ins[i].loopend;
+		if (mod->xxs[i].lpe == 0xffff)
+			mod->xxs[i].lpe = 0;
+		mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0;
+		mod->xxi[i].sub[0].vol = sfh.ins[i].volume;
+		mod->xxi[i].sub[0].pan = 0x80;
+		mod->xxi[i].sub[0].sid = i;
+
+		if (mod->xxs[i].len > 0)
+			mod->xxi[i].nsm = 1;
+
+		libxmp_instrument_name(mod, i, sfh.ins[i].name, 12);
+
+		D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x %5d", i,
+		   mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
+		   mod->xxs[i].lpe,
+		   mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
+		   mod->xxi[i].sub[0].vol, sfh.ins[i].c2spd);
+
+		libxmp_c2spd_to_note(sfh.ins[i].c2spd, &mod->xxi[i].sub[0].xpo,
+			      &mod->xxi[i].sub[0].fin);
+	}
+
+	hio_read(mod->xxo, 1, 128, f);
+
+	for (i = 0; i < 128; i++)
+		if (mod->xxo[i] >= mod->pat)
+			break;
+
+	mod->len = i;
+
+	D_(D_INFO "Module length: %d", mod->len);
+
+	if (libxmp_init_pattern(mod) < 0)
+		return -1;
+
+	/* Read and convert patterns */
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
+			return -1;
+
+		for (j = 0; j < 64 * mod->chn; j++) {
+			event = &EVENT(i, j % mod->chn, j / mod->chn);
+			b = hio_read8(f);
+			memset(event, 0, sizeof(struct xmp_event));
+			switch (b) {
+			case 251:
+			case 252:
+			case 253:
+				break;
+			case 255:
+			default:
+				event->note = b == 255 ? 0 :
+					1 + LSN(b) + 12 * (3 + MSN(b));
+				b = hio_read8(f);
+				event->vol = b & 0x07;
+				event->ins = (b & 0xf8) >> 3;
+				b = hio_read8(f);
+				event->vol += (b & 0xf0) >> 1;
+				if (event->vol > 0x40)
+					event->vol = 0;
+				else
+					event->vol++;
+				event->fxt = fx[LSN(b)];
+				event->fxp = hio_read8(f);
+				switch (event->fxt) {
+				case FX_SPEED:
+					event->fxp = MSN(event->fxp);
+					break;
+				case FX_NONE:
+					event->fxp = event->fxt = 0;
+					break;
+				}
+			}
+		}
+	}
+
+	/* Read samples */
+	D_(D_INFO "Stored samples: %d", mod->smp);
+
+	for (i = 0; i < mod->ins; i++) {
+		if (mod->xxs[i].len > 1) {
+			if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+				return -1;
+		} else {
+			mod->xxi[i].nsm = 0;
+		}
 	}
-    }
 
-    m->quirk |= QUIRK_VSALL | QUIRKS_ST3;
-    m->read_event_type = READ_EVENT_ST3;
+	m->quirk |= QUIRK_VSALL | QUIRKS_ST3;
+	m->read_event_type = READ_EVENT_ST3;
 
-    return 0;
+	return 0;
 }
diff --git a/src/loaders/stx_load.c b/src/loaders/stx_load.c
index 96637bd..d7e27d4 100644
--- a/src/loaders/stx_load.c
+++ b/src/loaders/stx_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -38,7 +38,6 @@
 #include "s3m.h"
 #include "period.h"
 
-
 struct stx_file_header {
 	uint8 name[20];		/* Song name */
 	uint8 magic[8];		/* !Scream! */
@@ -83,286 +82,294 @@ struct stx_instrument_header {
 	uint8 magic[4];		/* Reserved (for 'SCRS') */
 };
 
+static int stx_test(HIO_HANDLE *, char *, const int);
+static int stx_load(struct module_data *, HIO_HANDLE *, const int);
 
-static int stx_test (HIO_HANDLE *, char *, const int);
-static int stx_load (struct module_data *, HIO_HANDLE *, const int);
-
-const struct format_loader stx_loader = {
-    "STMIK 0.2",
-    stx_test,
-    stx_load
+const struct format_loader libxmp_loader_stx = {
+	"STMIK 0.2",
+	stx_test,
+	stx_load
 };
 
-static int stx_test(HIO_HANDLE *f, char *t, const int start)
+static int stx_test(HIO_HANDLE * f, char *t, const int start)
 {
-    char buf[8];
+	char buf[8];
 
-    hio_seek(f, start + 20, SEEK_SET);
-    if (hio_read(buf, 1, 8, f) < 8)
-	return -1;
-    if (memcmp(buf, "!Scream!", 8) && memcmp(buf, "BMOD2STM", 8))
-	return -1;
+	hio_seek(f, start + 20, SEEK_SET);
+	if (hio_read(buf, 1, 8, f) < 8)
+		return -1;
+	if (memcmp(buf, "!Scream!", 8) && memcmp(buf, "BMOD2STM", 8))
+		return -1;
 
-    hio_seek(f, start + 60, SEEK_SET);
-    if (hio_read(buf, 1, 4, f) < 4)
-	return -1;
-    if (memcmp(buf, "SCRM", 4))
-	return -1;
+	hio_seek(f, start + 60, SEEK_SET);
+	if (hio_read(buf, 1, 4, f) < 4)
+		return -1;
+	if (memcmp(buf, "SCRM", 4))
+		return -1;
 
-    hio_seek(f, start + 0, SEEK_SET);
-    read_title(f, t, 20);
+	hio_seek(f, start + 0, SEEK_SET);
+	libxmp_read_title(f, t, 20);
 
-    return 0;
+	return 0;
 }
 
 #define FX_NONE 0xff
 
 static const uint8 fx[] = {
-    FX_NONE,		FX_SPEED,
-    FX_JUMP,		FX_BREAK,
-    FX_VOLSLIDE,	FX_PORTA_DN,
-    FX_PORTA_UP,	FX_TONEPORTA,
-    FX_VIBRATO,		FX_TREMOR,
-    FX_ARPEGGIO
+	FX_NONE, FX_SPEED,
+	FX_JUMP, FX_BREAK,
+	FX_VOLSLIDE, FX_PORTA_DN,
+	FX_PORTA_UP, FX_TONEPORTA,
+	FX_VIBRATO, FX_TREMOR,
+	FX_ARPEGGIO
 };
 
-
 static int stx_load(struct module_data *m, HIO_HANDLE *f, const int start)
 {
-    struct xmp_module *mod = &m->mod;
-    int c, r, i, broken = 0;
-    struct xmp_event *event = 0, dummy;
-    struct stx_file_header sfh;
-    struct stx_instrument_header sih;
-    uint8 n, b;
-    uint16 x16;
-    int bmod2stm = 0;
-    uint16 *pp_ins;		/* Parapointers to instruments */
-    uint16 *pp_pat;		/* Parapointers to patterns */
-
-    LOAD_INIT();
-
-    hio_read(&sfh.name, 20, 1, f);
-    hio_read(&sfh.magic, 8, 1, f);
-    sfh.psize = hio_read16l(f);
-    sfh.unknown1 = hio_read16l(f);
-    sfh.pp_pat = hio_read16l(f);
-    sfh.pp_ins = hio_read16l(f);
-    sfh.pp_chn = hio_read16l(f);
-    sfh.unknown2 = hio_read16l(f);
-    sfh.unknown3 = hio_read16l(f);
-    sfh.gvol = hio_read8(f);
-    sfh.tempo = hio_read8(f);
-    sfh.unknown4 = hio_read16l(f);
-    sfh.unknown5 = hio_read16l(f);
-    sfh.patnum = hio_read16l(f);
-    sfh.insnum = hio_read16l(f);
-    sfh.ordnum = hio_read16l(f);
-    sfh.unknown6 = hio_read16l(f);
-    sfh.unknown7 = hio_read16l(f);
-    sfh.unknown8 = hio_read16l(f);
-    hio_read(&sfh.magic2, 4, 1, f);
-
-    /* BMOD2STM does not convert pitch */
-    if (!strncmp ((char *) sfh.magic, "BMOD2STM", 8))
-	bmod2stm = 1;
+	struct xmp_module *mod = &m->mod;
+	int c, r, i, broken = 0;
+	struct xmp_event *event = 0, dummy;
+	struct stx_file_header sfh;
+	struct stx_instrument_header sih;
+	uint8 n, b;
+	uint16 x16;
+	int bmod2stm = 0;
+	uint16 *pp_ins;		/* Parapointers to instruments */
+	uint16 *pp_pat;		/* Parapointers to patterns */
+
+	LOAD_INIT();
+
+	hio_read(&sfh.name, 20, 1, f);
+	hio_read(&sfh.magic, 8, 1, f);
+	sfh.psize = hio_read16l(f);
+	sfh.unknown1 = hio_read16l(f);
+	sfh.pp_pat = hio_read16l(f);
+	sfh.pp_ins = hio_read16l(f);
+	sfh.pp_chn = hio_read16l(f);
+	sfh.unknown2 = hio_read16l(f);
+	sfh.unknown3 = hio_read16l(f);
+	sfh.gvol = hio_read8(f);
+	sfh.tempo = hio_read8(f);
+	sfh.unknown4 = hio_read16l(f);
+	sfh.unknown5 = hio_read16l(f);
+	sfh.patnum = hio_read16l(f);
+	sfh.insnum = hio_read16l(f);
+	sfh.ordnum = hio_read16l(f);
+	sfh.unknown6 = hio_read16l(f);
+	sfh.unknown7 = hio_read16l(f);
+	sfh.unknown8 = hio_read16l(f);
+	hio_read(&sfh.magic2, 4, 1, f);
+
+	/* Sanity check */
+	if (sfh.patnum > 254 || sfh.insnum > 256 || sfh.ordnum > 256)
+		return -1;
+
+	/* BMOD2STM does not convert pitch */
+	if (!strncmp((char *)sfh.magic, "BMOD2STM", 8))
+		bmod2stm = 1;
 
 #if 0
-    if ((strncmp ((char *) sfh.magic, "!Scream!", 8) &&
-	!bmod2stm) || strncmp ((char *) sfh.magic2, "SCRM", 4))
-	return -1;
+	if ((strncmp((char *)sfh.magic, "!Scream!", 8) &&
+	     !bmod2stm) || strncmp((char *)sfh.magic2, "SCRM", 4))
+		return -1;
 #endif
 
-    mod->ins = sfh.insnum;
-    mod->pat = sfh.patnum;
-    mod->trk = mod->pat * mod->chn;
-    mod->len = sfh.ordnum;
-    mod->spd = MSN (sfh.tempo);
-    mod->smp = mod->ins;
-    m->c4rate = C4_NTSC_RATE;
-
-    /* STM2STX 1.0 released with STMIK 0.2 converts STMs with the pattern
-     * length encoded in the first two bytes of the pattern (like S3M).
-     */
-    hio_seek(f, start + (sfh.pp_pat << 4), SEEK_SET);
-    x16 = hio_read16l(f);
-    hio_seek(f, start + (x16 << 4), SEEK_SET);
-    x16 = hio_read16l(f);
-    if (x16 == sfh.psize)
-	broken = 1;
-
-    strncpy(mod->name, (char *)sfh.name, 20);
-    if (bmod2stm)
-	set_type(m, "BMOD2STM STX");
-    else
-	snprintf(mod->type, XMP_NAME_SIZE, "STM2STX 1.%d", broken ? 0 : 1);
-
-    MODULE_INFO();
- 
-    pp_pat = calloc (2, mod->pat);
-    if (pp_pat == NULL)
-	goto err;
-
-    pp_ins = calloc (2, mod->ins);
-    if (pp_ins == NULL)
-	goto err2;
-
-    /* Read pattern pointers */
-    hio_seek(f, start + (sfh.pp_pat << 4), SEEK_SET);
-    for (i = 0; i < mod->pat; i++)
-	pp_pat[i] = hio_read16l(f);
-
-    /* Read instrument pointers */
-    hio_seek(f, start + (sfh.pp_ins << 4), SEEK_SET);
-    for (i = 0; i < mod->ins; i++)
-	pp_ins[i] = hio_read16l(f);
-
-    /* Skip channel table (?) */
-    hio_seek(f, start + (sfh.pp_chn << 4) + 32, SEEK_SET);
-
-    /* Read orders */
-    for (i = 0; i < mod->len; i++) {
-	mod->xxo[i] = hio_read8(f);
-	hio_seek(f, 4, SEEK_CUR);
-    }
- 
-    if (instrument_init(mod) < 0)
-	goto err3;
-
-    /* Read and convert instruments and samples */
-
-    for (i = 0; i < mod->ins; i++) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
-	    goto err3;
-
-	hio_seek(f, start + (pp_ins[i] << 4), SEEK_SET);
-
-	sih.type = hio_read8(f);
-	hio_read(&sih.dosname, 13, 1, f);
-	sih.memseg = hio_read16l(f);
-	sih.length = hio_read32l(f);
-	sih.loopbeg = hio_read32l(f);
-	sih.loopend = hio_read32l(f);
-	sih.vol = hio_read8(f);
-	sih.rsvd1 = hio_read8(f);
-	sih.pack = hio_read8(f);
-	sih.flags = hio_read8(f);
-	sih.c2spd = hio_read16l(f);
-	sih.rsvd2 = hio_read16l(f);
-	hio_read(&sih.rsvd3, 4, 1, f);
-	sih.int_gp = hio_read16l(f);
-	sih.int_512 = hio_read16l(f);
-	sih.int_last = hio_read32l(f);
-	hio_read(&sih.name, 28, 1, f);
-	hio_read(&sih.magic, 4, 1, f);
-
-	mod->xxs[i].len = sih.length;
-	mod->xxs[i].lps = sih.loopbeg;
-	mod->xxs[i].lpe = sih.loopend;
-	if (mod->xxs[i].lpe == 0xffff)
-	    mod->xxs[i].lpe = 0;
-	mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0;
-	mod->xxi[i].sub[0].vol = sih.vol;
-	mod->xxi[i].sub[0].pan = 0x80;
-	mod->xxi[i].sub[0].sid = i;
-	mod->xxi[i].nsm = 1;
-
-	instrument_name(mod, i, sih.name, 12);
-
-	D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x %5d\n", i,
-		mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
-		mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
-		mod->xxi[i].sub[0].vol, sih.c2spd);
-
-	sih.c2spd = 8363 * sih.c2spd / 8448;
-	c2spd_to_note(sih.c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
-    }
-
-    if (pattern_init(mod) < 0)
-	goto err3;
-
-    /* Read and convert patterns */
-    D_(D_INFO "Stored patterns: %d", mod->pat);
-
-    for (i = 0; i < mod->pat; i++) {
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
-	    goto err3;
-
-	if (pp_pat[i] == 0)
-	    continue;
-
-	hio_seek(f, start + (pp_pat[i] << 4), SEEK_SET);
-	if (broken)
-	    hio_seek(f, 2, SEEK_CUR);
-
-	for (r = 0; r < 64; ) {
-	    b = hio_read8(f);
-
-	    if (b == S3M_EOR) {
-		r++;
-		continue;
-	    }
-
-	    c = b & S3M_CH_MASK;
-	    event = c >= mod->chn ? &dummy : &EVENT (i, c, r);
-
-	    if (b & S3M_NI_FOLLOW) {
-		n = hio_read8(f);
-
-		switch (n) {
-		case 255:
-		    n = 0;
-		    break;	/* Empty note */
-		case 254:
-		    n = XMP_KEY_OFF;
-		    break;	/* Key off */
-		default:
-		    n = 37 + 12 * MSN (n) + LSN (n);
-		}
+	mod->ins = sfh.insnum;
+	mod->pat = sfh.patnum;
+	mod->trk = mod->pat * mod->chn;
+	mod->len = sfh.ordnum;
+	mod->spd = MSN(sfh.tempo);
+	mod->smp = mod->ins;
+	m->c4rate = C4_NTSC_RATE;
+
+	/* STM2STX 1.0 released with STMIK 0.2 converts STMs with the pattern
+	 * length encoded in the first two bytes of the pattern (like S3M).
+	 */
+	hio_seek(f, start + (sfh.pp_pat << 4), SEEK_SET);
+	x16 = hio_read16l(f);
+	hio_seek(f, start + (x16 << 4), SEEK_SET);
+	x16 = hio_read16l(f);
+	if (x16 == sfh.psize)
+		broken = 1;
+
+	strncpy(mod->name, (char *)sfh.name, 20);
+	if (bmod2stm)
+		libxmp_set_type(m, "BMOD2STM STX");
+	else
+		snprintf(mod->type, XMP_NAME_SIZE, "STM2STX 1.%d",
+			 broken ? 0 : 1);
+
+	MODULE_INFO();
+
+	pp_pat = calloc(2, mod->pat);
+	if (pp_pat == NULL)
+		goto err;
+
+	pp_ins = calloc(2, mod->ins);
+	if (pp_ins == NULL)
+		goto err2;
+
+	/* Read pattern pointers */
+	hio_seek(f, start + (sfh.pp_pat << 4), SEEK_SET);
+	for (i = 0; i < mod->pat; i++)
+		pp_pat[i] = hio_read16l(f);
+
+	/* Read instrument pointers */
+	hio_seek(f, start + (sfh.pp_ins << 4), SEEK_SET);
+	for (i = 0; i < mod->ins; i++)
+		pp_ins[i] = hio_read16l(f);
+
+	/* Skip channel table (?) */
+	hio_seek(f, start + (sfh.pp_chn << 4) + 32, SEEK_SET);
+
+	/* Read orders */
+	for (i = 0; i < mod->len; i++) {
+		mod->xxo[i] = hio_read8(f);
+		hio_seek(f, 4, SEEK_CUR);
+	}
 
-		event->note = n;
-		event->ins = hio_read8(f);;
-	    }
-
-	    if (b & S3M_VOL_FOLLOWS) {
-		event->vol = hio_read8(f) + 1;
-	    }
-
-	    if (b & S3M_FX_FOLLOWS) {
-		event->fxt = fx[hio_read8(f)];
-		event->fxp = hio_read8(f);
-		switch (event->fxt) {
-		case FX_SPEED:
-		    event->fxp = MSN (event->fxp);
-		    break;
-		case FX_NONE:
-		    event->fxp = event->fxt = 0;
-		    break;
+	if (libxmp_init_instrument(m) < 0)
+		goto err3;
+
+	/* Read and convert instruments and samples */
+
+	for (i = 0; i < mod->ins; i++) {
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			goto err3;
+
+		hio_seek(f, start + (pp_ins[i] << 4), SEEK_SET);
+
+		sih.type = hio_read8(f);
+		hio_read(&sih.dosname, 13, 1, f);
+		sih.memseg = hio_read16l(f);
+		sih.length = hio_read32l(f);
+		sih.loopbeg = hio_read32l(f);
+		sih.loopend = hio_read32l(f);
+		sih.vol = hio_read8(f);
+		sih.rsvd1 = hio_read8(f);
+		sih.pack = hio_read8(f);
+		sih.flags = hio_read8(f);
+		sih.c2spd = hio_read16l(f);
+		sih.rsvd2 = hio_read16l(f);
+		hio_read(&sih.rsvd3, 4, 1, f);
+		sih.int_gp = hio_read16l(f);
+		sih.int_512 = hio_read16l(f);
+		sih.int_last = hio_read32l(f);
+		hio_read(&sih.name, 28, 1, f);
+		hio_read(&sih.magic, 4, 1, f);
+
+		mod->xxs[i].len = sih.length;
+		mod->xxs[i].lps = sih.loopbeg;
+		mod->xxs[i].lpe = sih.loopend;
+		if (mod->xxs[i].lpe == 0xffff)
+			mod->xxs[i].lpe = 0;
+		mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0;
+		mod->xxi[i].sub[0].vol = sih.vol;
+		mod->xxi[i].sub[0].pan = 0x80;
+		mod->xxi[i].sub[0].sid = i;
+		mod->xxi[i].nsm = 1;
+
+		libxmp_instrument_name(mod, i, sih.name, 12);
+
+		D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x %5d\n", i,
+		   mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
+		   mod->xxs[i].lpe,
+		   mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
+		   mod->xxi[i].sub[0].vol, sih.c2spd);
+
+		libxmp_c2spd_to_note(sih.c2spd, &mod->xxi[i].sub[0].xpo,
+			      &mod->xxi[i].sub[0].fin);
+	}
+
+	if (libxmp_init_pattern(mod) < 0)
+		goto err3;
+
+	/* Read and convert patterns */
+	D_(D_INFO "Stored patterns: %d", mod->pat);
+
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
+			goto err3;
+
+		if (pp_pat[i] == 0)
+			continue;
+
+		hio_seek(f, start + (pp_pat[i] << 4), SEEK_SET);
+		if (broken)
+			hio_seek(f, 2, SEEK_CUR);
+
+		for (r = 0; r < 64;) {
+			b = hio_read8(f);
+
+			if (b == S3M_EOR) {
+				r++;
+				continue;
+			}
+
+			c = b & S3M_CH_MASK;
+			event = c >= mod->chn ? &dummy : &EVENT(i, c, r);
+
+			if (b & S3M_NI_FOLLOW) {
+				n = hio_read8(f);
+
+				switch (n) {
+				case 255:
+					n = 0;
+					break;	/* Empty note */
+				case 254:
+					n = XMP_KEY_OFF;
+					break;	/* Key off */
+				default:
+					n = 37 + 12 * MSN(n) + LSN(n);
+				}
+
+				event->note = n;
+				event->ins = hio_read8(f);;
+			}
+
+			if (b & S3M_VOL_FOLLOWS) {
+				event->vol = hio_read8(f) + 1;
+			}
+
+			if (b & S3M_FX_FOLLOWS) {
+				int t = hio_read8(f);
+				int p = hio_read8(f);
+				if (t <= 10) {
+					event->fxt = fx[t];
+					event->fxp = p;
+					switch (event->fxt) {
+					case FX_SPEED:
+						event->fxp = MSN(event->fxp);
+						break;
+					case FX_NONE:
+						event->fxp = event->fxt = 0;
+						break;
+					}
+				}
+			}
 		}
-	    }
 	}
-    }
 
-    free (pp_ins);
-    free (pp_pat);
+	free(pp_ins);
+	free(pp_pat);
 
-    /* Read samples */
-    D_(D_INFO "Stored samples: %d", mod->smp);
+	/* Read samples */
+	D_(D_INFO "Stored samples: %d", mod->smp);
 
-    for (i = 0; i < mod->ins; i++) {
-	if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
-	    goto err;
-    }
+	for (i = 0; i < mod->ins; i++) {
+		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+			goto err;
+	}
 
-    m->quirk |= QUIRK_VSALL | QUIRKS_ST3;
-    m->read_event_type = READ_EVENT_ST3;
+	m->quirk |= QUIRK_VSALL | QUIRKS_ST3;
+	m->read_event_type = READ_EVENT_ST3;
 
-    return 0;
+	return 0;
 
-  err3:
-    free(pp_ins);
-  err2:
-    free(pp_pat);
-  err:
-    return -1;
+err3:
+	free(pp_ins);
+err2:
+	free(pp_pat);
+err:
+	return -1;
 }
diff --git a/src/loaders/sym_load.c b/src/loaders/sym_load.c
index 85187c7..e82a0b8 100644
--- a/src/loaders/sym_load.c
+++ b/src/loaders/sym_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -13,7 +27,7 @@
 static int sym_test(HIO_HANDLE *, char *, const int);
 static int sym_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader sym_loader = {
+const struct format_loader libxmp_loader_sym = {
 	"Digital Symphony",
 	sym_test,
 	sym_load
@@ -53,7 +67,7 @@ static int sym_test(HIO_HANDLE *f, char *t, const int start)
 			hio_read24l(f);
 	}
 
-	read_title(f, t, hio_read8(f));
+	libxmp_read_title(f, t, hio_read8(f));
 
 	return 0;
 }
@@ -235,7 +249,7 @@ static int sym_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	struct xmp_module *mod = &m->mod;
 	struct xmp_event *event;
 	int i, j;
-	int ver, infolen, sn[64];
+	int /*ver,*/ infolen, sn[64];
 	uint32 a, b;
 	uint8 *buf;
 	int size, ret;
@@ -245,21 +259,26 @@ static int sym_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 	hio_seek(f, 8, SEEK_CUR);	/* BASSTRAK */
 
-	ver = hio_read8(f);
-	set_type(m, "Digital Symphony");
+	/*ver =*/ hio_read8(f);
+	libxmp_set_type(m, "Digital Symphony");
 
 	mod->chn = hio_read8(f);
 	mod->len = mod->pat = hio_read16l(f);
+
+	/* Sanity check */
+	if (mod->chn > 8 || mod->pat > 256)
+		return -1;
+
 	mod->trk = hio_read16l(f);	/* Symphony patterns are actually tracks */
 	infolen = hio_read24l(f);
 
 	mod->ins = mod->smp = 63;
 
-	if (instrument_init(mod) < 0)
+	if (libxmp_init_instrument(m) < 0)
 		return -1;
 
 	for (i = 0; i < mod->ins; i++) {
-		if (subinstrument_alloc(mod, i, 1) < 0)
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 			return -1;
 
 		sn[i] = hio_read8(f);	/* sample name length */
@@ -267,18 +286,27 @@ static int sym_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		if (~sn[i] & 0x80) {
 			mod->xxs[i].len = hio_read24l(f) << 1;
 			mod->xxi[i].nsm = 1;
+
+			/* Sanity check */
+			if (mod->xxs[i].len > 0x80000)
+				return -1;
 		}
 	}
 
 	a = hio_read8(f);		/* track name length */
+	if (a > 32) {
+		hio_read(mod->name, 1, 32, f);
+		hio_seek(f, a - 32, SEEK_SET);
+	} else {
+		hio_read(mod->name, 1, a, f);
+	}
 
-	hio_read(mod->name, 1, a, f);
 	hio_read(&allowed_effects, 1, 8, f);
 
 	MODULE_INFO();
 
 	mod->trk++;			/* alloc extra empty track */
-	if (pattern_init(mod) < 0)
+	if (libxmp_init_pattern(mod) < 0)
 		return -1;
 
 	/* Sequence */
@@ -294,18 +322,21 @@ static int sym_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		return -1;
 
 	if (a) {
-		unsigned char *x = read_lzw_dynamic(f->handle.file, buf,
+		unsigned char *x = libxmp_read_lzw_dynamic(f->handle.file, buf,
 					13, 0, size, size, XMP_LZW_QUIRK_DSYM);
 		if (x == NULL) {
 			free(buf);
 			return -1;
 		}
 	} else {
-		hio_read(buf, 1, size, f);
+		if (hio_read(buf, 1, size, f) != size) {
+			free(buf);
+			return -1;
+		}
 	}
 
 	for (i = 0; i < mod->len; i++) {	/* len == pat */
-		if (pattern_alloc(mod, i) < 0) {
+		if (libxmp_alloc_pattern(mod, i) < 0) {
 			free(buf);
 			return -1;
 		}
@@ -313,11 +344,18 @@ static int sym_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		for (j = 0; j < mod->chn; j++) {
 			int idx = 2 * (i * mod->chn + j);
-			mod->xxp[i]->index[j] = readptr16l(&buf[idx]);
+			int t = readptr16l(&buf[idx]);
 
-			if (mod->xxp[i]->index[j] == 0x1000) /* empty trk */
-				mod->xxp[i]->index[j] = mod->trk - 1;
+			/* Sanity check */
+			if (t >= mod->trk - 1) {
+				free(buf);
+				return -1;
+			}
+	
+			if (t == 0x1000) /* empty trk */
+				t = mod->trk - 1;
 
+			mod->xxp[i]->index[j] = t;
 		}
 		mod->xxo[i] = i;
 	}
@@ -338,18 +376,21 @@ static int sym_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		return -1;
 
 	if (a) {
-		unsigned char *x = read_lzw_dynamic(f->handle.file, buf,
+		unsigned char *x = libxmp_read_lzw_dynamic(f->handle.file, buf,
 					13, 0, size, size, XMP_LZW_QUIRK_DSYM);
 		if (x == NULL) {
 			free(buf);
 			return -1;
 		}
 	} else {
-		hio_read(buf, 1, size, f);
+		if (hio_read(buf, 1, size, f) != size) {
+			free(buf);
+			return -1;
+		}
 	}
 
 	for (i = 0; i < mod->trk - 1; i++) {
-		if (track_alloc(mod, i, 64) < 0) {
+		if (libxmp_alloc_track(mod, i, 64) < 0) {
 			free(buf);
 			return -1;
 		}
@@ -378,7 +419,7 @@ static int sym_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	free(buf);
 
 	/* Extra track */
-	if (track_alloc(mod, i, 64) < 0)
+	if (libxmp_alloc_track(mod, i, 64) < 0)
 		return -1;
 
 	/* Load and convert instruments */
@@ -390,7 +431,7 @@ static int sym_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		memset(buf, 0, 128);
 		hio_read(buf, 1, sn[i] & 0x7f, f);
-		instrument_name(mod, i, buf, 32);
+		libxmp_instrument_name(mod, i, buf, 32);
 
 		if (~sn[i] & 0x80) {
 			int looplen;
@@ -426,18 +467,18 @@ static int sym_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
 		if (a == 1) {
 			uint8 *b = malloc(mod->xxs[i].len);
-			read_lzw_dynamic(f->handle.file, b, 13, 0,
+			libxmp_read_lzw_dynamic(f->handle.file, b, 13, 0,
 					mod->xxs[i].len, mod->xxs[i].len,
 					XMP_LZW_QUIRK_DSYM);
-			ret = load_sample(m, NULL,
+			ret = libxmp_load_sample(m, NULL,
 					SAMPLE_FLAG_NOLOAD | SAMPLE_FLAG_DIFF,
 					&mod->xxs[i], (char*)b);
 			free(b);
 		/*} else if (a == 4) {
-			ret = load_sample(m, f, SAMPLE_FLAG_VIDC,
+			ret = libxmp_load_sample(m, f, SAMPLE_FLAG_VIDC,
 					&mod->xxs[i], NULL);*/
 		} else {
-			ret = load_sample(m, f, SAMPLE_FLAG_VIDC,
+			ret = libxmp_load_sample(m, f, SAMPLE_FLAG_VIDC,
 					&mod->xxs[i], NULL);
 		}
 
@@ -445,8 +486,9 @@ static int sym_load(struct module_data *m, HIO_HANDLE *f, const int start)
 			return -1;
 	}
 
-	for (i = 0; i < mod->chn; i++)
-		mod->xxc[i].pan = (((i + 3) / 2) % 2) * 0xff;
+	for (i = 0; i < mod->chn; i++) {
+		mod->xxc[i].pan = DEFPAN((((i + 3) / 2) % 2) * 0xff);
+	}
 
 	return 0;
 }
diff --git a/src/loaders/tcb_load.c b/src/loaders/tcb_load.c
new file mode 100644
index 0000000..c01c0a7
--- /dev/null
+++ b/src/loaders/tcb_load.c
@@ -0,0 +1,201 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * From http://www.tscc.de/ucm24/tcb2pro.html:
+ * There are two different TCB-Tracker module formats. Older format and
+ * newer format. They have different headers "AN COOL." and "AN COOL!".
+ *
+ * We only support the old format --claudio
+ */
+
+#include "loader.h"
+
+
+static int tcb_test(HIO_HANDLE *, char *, const int);
+static int tcb_load (struct module_data *, HIO_HANDLE *, const int);
+
+const struct format_loader libxmp_loader_tcb = {
+	"TCB Tracker",
+	tcb_test,
+	tcb_load
+};
+
+static int tcb_test(HIO_HANDLE *f, char *t, const int start)
+{
+	uint8 buffer[10];
+
+	if (hio_read(buffer, 1, 8, f) < 8)
+		return -1;
+	if (memcmp(buffer, "AN COOL.", 8) && memcmp(buffer, "AN COOL!", 8))
+		return -1;
+
+	libxmp_read_title(f, t, 0);
+
+	return 0;
+}
+
+static int tcb_load(struct module_data *m, HIO_HANDLE *f, const int start)
+{
+	struct xmp_module *mod = &m->mod;
+	struct xmp_event *event;
+	int i, j, k;
+	uint8 buffer[10];
+	int base_offs, soffs[16];
+	uint8 unk1[16], unk2[16], unk3[16];
+
+	LOAD_INIT();
+
+	hio_read(buffer, 8, 1, f);
+
+	libxmp_set_type(m, "TCB Tracker", buffer);
+
+	hio_read16b(f);	/* ? */
+	mod->pat = hio_read16b(f);
+	mod->ins = 16;
+	mod->smp = mod->ins;
+	mod->chn = 4;
+	mod->trk = mod->pat * mod->chn;
+
+	m->quirk |= QUIRK_MODRNG;
+
+	hio_read16b(f);	/* ? */
+
+	for (i = 0; i < 128; i++)
+		mod->xxo[i] = hio_read8(f);
+
+	mod->len = hio_read8(f);
+	hio_read8(f);	/* ? */
+	hio_read16b(f);	/* ? */
+
+	MODULE_INFO();
+
+	if (libxmp_init_instrument(m) < 0)
+		return -1;
+
+	/* Read instrument names */
+	for (i = 0; i < mod->ins; i++) {
+		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
+			return -1;
+		hio_read(buffer, 8, 1, f);
+		libxmp_instrument_name(mod, i, buffer, 8);
+	}
+
+	hio_read16b(f);	/* ? */
+	for (i = 0; i < 5; i++)
+		hio_read16b(f);
+	for (i = 0; i < 5; i++)
+		hio_read16b(f);
+	for (i = 0; i < 5; i++)
+		hio_read16b(f);
+
+	if (libxmp_init_pattern(mod) < 0)
+		return -1;
+
+	/* Read and convert patterns */
+	D_(D_INFO "Stored patterns: %d ", mod->pat);
+
+	for (i = 0; i < mod->pat; i++) {
+		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
+			return -1;
+
+		for (j = 0; j < mod->xxp[i]->rows; j++) {
+			for (k = 0; k < mod->chn; k++) {
+				int b;
+				event = &EVENT (i, k, j);
+
+				b = hio_read8(f);
+				if (b) {
+					event->note = 12 * (b >> 4);
+					event->note += (b & 0xf) + 36;
+				}
+				b = hio_read8(f);
+				event->ins = b >> 4;
+				if (event->ins)
+					event->ins += 1;
+				if (b &= 0x0f) {
+					switch (b) {
+					case 0xd:
+						event->fxt = FX_BREAK;
+						event->fxp = 0;
+						break;
+					default:
+						printf("---> %02x\n", b);
+					}
+				}
+			}
+		}
+	}
+
+	base_offs = hio_tell(f);
+	hio_read32b(f);	/* remaining size */
+
+	/* Read instrument data */
+
+	for (i = 0; i < mod->ins; i++) {
+		mod->xxi[i].sub[0].vol = hio_read8(f) / 2;
+		mod->xxi[i].sub[0].pan = 0x80;
+		unk1[i] = hio_read8(f);
+		unk2[i] = hio_read8(f);
+		unk3[i] = hio_read8(f);
+	}
+
+
+	for (i = 0; i < mod->ins; i++) {
+		soffs[i] = hio_read32b(f);
+		mod->xxs[i].len = hio_read32b(f);
+	}
+
+	hio_read32b(f);
+	hio_read32b(f);
+	hio_read32b(f);
+	hio_read32b(f);
+
+	for (i = 0; i < mod->ins; i++) {
+		mod->xxi[i].nsm = !!(mod->xxs[i].len);
+		mod->xxs[i].lps = 0;
+		mod->xxs[i].lpe = 0;
+		mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0;
+		mod->xxi[i].sub[0].fin = 0;
+		mod->xxi[i].sub[0].pan = 0x80;
+		mod->xxi[i].sub[0].sid = i;
+
+		D_(D_INFO "[%2X] %-8.8s  %04x %04x %04x %c "
+						"V%02x  %02x %02x %02x\n",
+				i, mod->xxi[i].name,
+				mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
+				mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
+				mod->xxi[i].sub[0].vol, unk1[i], unk2[i], unk3[i]);
+	}
+
+	/* Read samples */
+
+	D_(D_INFO "Stored samples: %d", mod->smp);
+
+	for (i = 0; i < mod->ins; i++) {
+		hio_seek(f, start + base_offs + soffs[i], SEEK_SET);
+		if (libxmp_load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
+			return -1;
+	}
+
+	return 0;
+}
diff --git a/src/loaders/ult_load.c b/src/loaders/ult_load.c
index f877007..0ee7547 100644
--- a/src/loaders/ult_load.c
+++ b/src/loaders/ult_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 /* Based on the format description by FreeJack of The Elven Nation
@@ -15,14 +29,14 @@
  * - MAS_UTrack_V004: Ultra Tracker version 1.6
  */
 
-#include "period.h"
 #include "loader.h"
+#include "period.h"
 
 
 static int ult_test (HIO_HANDLE *, char *, const int);
 static int ult_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader ult_loader = {
+const struct format_loader libxmp_loader_ult = {
     "Ultra Tracker",
     ult_test,
     ult_load
@@ -41,7 +55,7 @@ static int ult_test(HIO_HANDLE *f, char *t, const int start)
     if (buf[14] < '0' || buf[14] > '4')
 	return -1;
 
-    read_title(f, t, 32);
+    libxmp_read_title(f, t, 32);
 
     return 0;
 }
@@ -107,7 +121,9 @@ static int ult_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     strncpy(mod->name, (char *)ufh.name, 32);
     ufh.name[0] = 0;
-    set_type(m, "Ultra Tracker %s ULT V%04d", verstr[ver - 1], ver);
+    libxmp_set_type(m, "Ultra Tracker %s ULT V%04d", verstr[ver - 1], ver);
+
+    m->c4rate = C4_NTSC_RATE;
 
     MODULE_INFO();
 
@@ -118,13 +134,13 @@ static int ult_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     /* Read and convert instruments */
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     D_(D_INFO "Instruments: %d", mod->ins);
 
     for (i = 0; i < mod->ins; i++) {
-	if (subinstrument_alloc(mod, i, 1) < 0)
+	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
 	    return -1;
 
 	hio_read(&uih.name, 32, 1, f);
@@ -192,7 +208,7 @@ static int ult_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	mod->xxi[i].sub[0].pan = 0x80;
 	mod->xxi[i].sub[0].sid = i;
 
-	instrument_name(mod, i, uih.name, 24);
+	libxmp_instrument_name(mod, i, uih.name, 24);
 
 	D_(D_INFO "[%2X] %-32.32s %05x%c%05x %05x %c V%02x F%04x %5d",
 		i, uih.name, mod->xxs[i].len,
@@ -202,7 +218,7 @@ static int ult_load(struct module_data *m, HIO_HANDLE *f, const int start)
 		mod->xxi[i].sub[0].vol, uih.finetune, uih.c2spd);
 
 	if (ver > 3)
-	    c2spd_to_note(uih.c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
+	    libxmp_c2spd_to_note(uih.c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
     }
 
     hio_read(&ufh2.order, 256, 1, f);
@@ -226,11 +242,11 @@ static int ult_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	    x8 = hio_read8(f);
 	    mod->xxc[i].pan = 255 * x8 / 15;
 	} else {
-	    mod->xxc[i].pan = (((i + 1) / 2) % 2) * 0xff;	/* ??? */
+	    mod->xxc[i].pan = DEFPAN((((i + 1) / 2) % 2) * 0xff); /* ??? */
 	}
     }
 
-    if (pattern_init(mod) < 0)
+    if (libxmp_init_pattern(mod) < 0)
 	return -1;
 
     /* Read and convert patterns */
@@ -239,7 +255,7 @@ static int ult_load(struct module_data *m, HIO_HANDLE *f, const int start)
 
     /* Events are stored by channel */
     for (i = 0; i < mod->pat; i++) {
-	if (pattern_tracks_alloc(mod, i, 64) < 0)
+	if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
 	    return -1;
     }
 
@@ -328,7 +344,7 @@ static int ult_load(struct module_data *m, HIO_HANDLE *f, const int start)
     for (i = 0; i < mod->ins; i++) {
 	if (!mod->xxs[i].len)
 	    continue;
-	if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
+	if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
 	    return -1;
     }
 
diff --git a/src/loaders/umx_load.c b/src/loaders/umx_load.c
index 30c2e0c..8df540c 100644
--- a/src/loaders/umx_load.c
+++ b/src/loaders/umx_load.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -15,15 +29,15 @@
 #define MAGIC_SCRM	MAGIC4('S','C','R','M')
 #define MAGIC_M_K_	MAGIC4('M','.','K','.')
 
-extern const struct format_loader xm_loader;
-extern const struct format_loader it_loader;
-extern const struct format_loader s3m_loader;
-extern const struct format_loader mod_loader;
+extern const struct format_loader libxmp_loader_xm;
+extern const struct format_loader libxmp_loader_it;
+extern const struct format_loader libxmp_loader_s3m;
+extern const struct format_loader libxmp_loader_mod;
 
 static int umx_test (HIO_HANDLE *, char *, const int);
 static int umx_load (struct module_data *, HIO_HANDLE *, const int);
 
-const struct format_loader umx_loader = {
+const struct format_loader libxmp_loader_umx = {
 	"Epic Games UMX",
 	umx_test,
 	umx_load
@@ -85,17 +99,35 @@ static int umx_load(struct module_data *m, HIO_HANDLE *f, const int start)
 	for (i = 0; i < TEST_SIZE; i++, b++) {
 		id = readmem32b(b);
 
-		if (!memcmp(b, "Extended Module:", 16))
-			return xm_loader.loader(m, f, i);
+		if (!memcmp(b, "Extended Module:", 16)) {
+			if (hio_seek(f, i, SEEK_SET) < 0) {
+				return -1;
+			}
+			return libxmp_loader_xm.loader(m, f, i);
+		}
 
-		if (id == MAGIC_IMPM)
-			return it_loader.loader(m, f, i);
+		if (id == MAGIC_IMPM) {
+			if (hio_seek(f, i, SEEK_SET) < 0) {
+				return -1;
+			}
+			return libxmp_loader_it.loader(m, f, i);
+		}
 
-		if (i > 44 && id == MAGIC_SCRM)
-			return s3m_loader.loader(m, f, i - 44);
+		if (i > 44 && id == MAGIC_SCRM) {
+			i -= 44;
+			if (hio_seek(f, i, SEEK_SET) < 0) {
+				return -1;
+			}
+			return libxmp_loader_s3m.loader(m, f, i);
+		}
 
-		if (i > 1080 && id == MAGIC_M_K_)
-			return mod_loader.loader(m, f, i - 1080);
+		if (i > 1080 && id == MAGIC_M_K_) {
+			i -= 1080;
+			if (hio_seek(f, i, SEEK_SET) < 0) {
+				return -1;
+			}
+			return libxmp_loader_mod.loader(m, f, i);
+		}
 	}
 	
 	return -1;
diff --git a/src/loaders/voltable.c b/src/loaders/voltable.c
index b92c897..7addfa0 100644
--- a/src/loaders/voltable.c
+++ b/src/loaders/voltable.c
@@ -1,9 +1,23 @@
 /* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
  */
 
 #include "loader.h"
@@ -30,7 +44,7 @@ version of the table is as follows:
  * so I'll perform linear interpolation to have all 256 values
  */
 
-int const arch_vol_table[] = {
+int const libxmp_arch_vol_table[] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
diff --git a/src/loaders/xm_load.c b/src/loaders/xm_load.c
index bb85fb9..e4091db 100644
--- a/src/loaders/xm_load.c
+++ b/src/loaders/xm_load.c
@@ -1,5 +1,5 @@
-/* Extended Module Player format loaders
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -36,180 +36,307 @@
 #include "loader.h"
 #include "xm.h"
 
-#define MAX_SAMP 1024
+static int xm_test(HIO_HANDLE *, char *, const int);
+static int xm_load(struct module_data *, HIO_HANDLE *, const int);
 
-static int xm_test (HIO_HANDLE *, char *, const int);
-static int xm_load (struct module_data *, HIO_HANDLE *, const int);
-
-const struct format_loader xm_loader = {
-    "Fast Tracker II",
-    xm_test,
-    xm_load
+const struct format_loader libxmp_loader_xm = {
+	"Fast Tracker II",
+	xm_test,
+	xm_load
 };
 
 static int xm_test(HIO_HANDLE *f, char *t, const int start)
 {
-    char buf[20];
+	char buf[20];
 
-    if (hio_read(buf, 1, 17, f) < 17)		/* ID text */
-	return -1;
+	if (hio_read(buf, 1, 17, f) < 17)	/* ID text */
+		return -1;
 
-    if (memcmp(buf, "Extended Module: ", 17))
-	return -1;
+	if (memcmp(buf, "Extended Module: ", 17))
+		return -1;
 
-    read_title(f, t, 20);
+	libxmp_read_title(f, t, 20);
 
-    return 0;
+	return 0;
 }
 
-static int load_patterns(struct module_data *m, int version, HIO_HANDLE *f)
+static int load_xm_pattern(struct module_data *m, int num, int version, HIO_HANDLE *f)
 {
-    struct xmp_module *mod = &m->mod;
-    struct xm_pattern_header xph;
-    struct xmp_event *event;
-    uint8 *patbuf, *pat, b;
-    int i, j, r;
-
-    mod->pat++;
-    if (pattern_init(mod) < 0)
-	return -1;
-
-    D_(D_INFO "Stored patterns: %d", mod->pat - 1);
-
-    /* Endianism fixed by Miodrag Vallat 
-     * Mon, 04 Jan 1999 11:17:20 +0100
-     */
-    for (i = 0; i < mod->pat - 1; i++) {
-    	const int headsize = version > 0x0102 ? 9 : 8;
+	const int headsize = version > 0x0102 ? 9 : 8;
+	struct xmp_module *mod = &m->mod;
+	struct xm_pattern_header xph;
+	struct xmp_event *event;
+	uint8 *patbuf, *pat, b;
+	int j, r;
+	int size;
 
 	xph.length = hio_read32l(f);
 	xph.packing = hio_read8(f);
 	xph.rows = version > 0x0102 ? hio_read16l(f) : hio_read8(f) + 1;
+
+	/* Sanity check */
+	if (xph.rows > 256) {
+		goto err;
+	}
+
 	xph.datasize = hio_read16l(f);
 	hio_seek(f, xph.length - headsize, SEEK_CUR);
+	if (hio_error(f)) {
+		goto err;
+	}
 
 	r = xph.rows;
-	if (r == 0)
-	    r = 0x100;
+	if (r == 0) {
+		r = 0x100;
+	}
 
-	if (pattern_tracks_alloc(mod, i, r) < 0)
-	    return -1;
+	if (libxmp_alloc_pattern_tracks(mod, num, r) < 0) {
+		goto err;
+	}
 
-	if (xph.datasize) {
-	    pat = patbuf = calloc(1, xph.datasize);
-	    if (patbuf == NULL)
-		return -1;
+	if (xph.datasize == 0) {
+		return 0;
+	}
+
+	size = xph.datasize;
+
+	pat = patbuf = calloc(1, size);
+	if (patbuf == NULL) {
+		goto err;
+	}
+
+	hio_read(patbuf, 1, size, f);
+	for (j = 0; j < (mod->chn * r); j++) {
+
+		/*if ((pat - patbuf) >= xph.datasize)
+		   break; */
+
+		event = &EVENT(num, j % mod->chn, j / mod->chn);
+
+		if (--size < 0) {
+			goto err2;
+		}
 
-	    hio_read(patbuf, 1, xph.datasize, f);
-	    for (j = 0; j < (mod->chn * r); j++) {
-		if ((pat - patbuf) >= xph.datasize)
-		    break;
-		event = &EVENT(i, j % mod->chn, j / mod->chn);
 		if ((b = *pat++) & XM_EVENT_PACKING) {
-		    if (b & XM_EVENT_NOTE_FOLLOWS)
-			event->note = *pat++;
-		    if (b & XM_EVENT_INSTRUMENT_FOLLOWS)
+			if (b & XM_EVENT_NOTE_FOLLOWS) {
+				if (--size < 0)
+					goto err2;
+				event->note = *pat++;
+			}
+			if (b & XM_EVENT_INSTRUMENT_FOLLOWS) {
+				if (--size < 0)
+					goto err2;
+				event->ins = *pat++;
+			}
+			if (b & XM_EVENT_VOLUME_FOLLOWS) {
+				if (--size < 0)
+					goto err2;
+				event->vol = *pat++;
+			}
+			if (b & XM_EVENT_FXTYPE_FOLLOWS) {
+				if (--size < 0)
+					goto err2;
+				event->fxt = *pat++;
+			}
+			if (b & XM_EVENT_FXPARM_FOLLOWS) {
+				if (--size < 0)
+					goto err2;
+				event->fxp = *pat++;
+			}
+		} else {
+			size -= 4;
+			if (size < 0)
+				goto err2;
+			event->note = b;
 			event->ins = *pat++;
-		    if (b & XM_EVENT_VOLUME_FOLLOWS)
 			event->vol = *pat++;
-		    if (b & XM_EVENT_FXTYPE_FOLLOWS) {
 			event->fxt = *pat++;
-#if 0
-			if (event->fxt == FX_GLOBALVOL)
-			    event->fxt = FX_TRK_VOL;
-			if (event->fxt == FX_G_VOLSLIDE)
-			    event->fxt = FX_TRK_VSLIDE;
-#endif
-		    }
-		    if (b & XM_EVENT_FXPARM_FOLLOWS)
 			event->fxp = *pat++;
-		} else {
-		    event->note = b;
-		    event->ins = *pat++;
-		    event->vol = *pat++;
-		    event->fxt = *pat++;
-		    event->fxp = *pat++;
 		}
 
-		if (event->note == 0x61)
-		    event->note = XMP_KEY_OFF;
-		else if (event->note > 0)
-		    event->note += 12;
+		/* Sanity check */
+		switch (event->fxt) {
+		case 18:
+		case 19:
+		case 22:
+		case 23:
+		case 24:
+		case 26:
+		case 28:
+		case 30:
+		case 31:
+		case 32:
+			event->fxt = 0;
+		}
+		if (event->fxt > 34) {
+			event->fxt = 0;
+		}
+
+		if (event->note == 0x61) {
+			/* See OpenMPT keyoff+instr.xm test case */
+			if (event->fxt == 0x0e && MSN(event->fxp) == 0x0d) {
+				event->note = XMP_KEY_OFF;
+			} else {
+				event->note =
+				    event->ins ? XMP_KEY_FADE : XMP_KEY_OFF;
+			}
+		} else if (event->note > 0) {
+			event->note += 12;
+		}
 
-		if (!event->vol)
-		    continue;
+		if (event->fxt == 0x0e) {
+			if (MSN(event->fxp) == EX_FINETUNE) {
+				unsigned char val = (LSN(event->fxp) - 8) & 0xf;
+				event->fxp = (EX_FINETUNE << 4) | val;
+			}
+			switch (event->fxp) {
+			case 0x43:
+			case 0x73:
+				event->fxp--;
+				break;
+			}
+		}
+
+		if (!event->vol) {
+			continue;
+		}
 
 		/* Volume set */
 		if ((event->vol >= 0x10) && (event->vol <= 0x50)) {
-		    event->vol -= 0x0f;
-		    continue;
+			event->vol -= 0x0f;
+			continue;
 		}
+
 		/* Volume column effects */
 		switch (event->vol >> 4) {
 		case 0x06:	/* Volume slide down */
-		    event->f2t = FX_VOLSLIDE_2;
-		    event->f2p = event->vol - 0x60;
-		    break;
+			event->f2t = FX_VOLSLIDE_2;
+			event->f2p = event->vol - 0x60;
+			break;
 		case 0x07:	/* Volume slide up */
-		    event->f2t = FX_VOLSLIDE_2;
-		    event->f2p = (event->vol - 0x70) << 4;
-		    break;
+			event->f2t = FX_VOLSLIDE_2;
+			event->f2p = (event->vol - 0x70) << 4;
+			break;
 		case 0x08:	/* Fine volume slide down */
-		    event->f2t = FX_EXTENDED;
-		    event->f2p = (EX_F_VSLIDE_DN << 4) | (event->vol - 0x80);
-		    break;
+			event->f2t = FX_EXTENDED;
+			event->f2p =
+			    (EX_F_VSLIDE_DN << 4) | (event->vol - 0x80);
+			break;
 		case 0x09:	/* Fine volume slide up */
-		    event->f2t = FX_EXTENDED;
-		    event->f2p = (EX_F_VSLIDE_UP << 4) | (event->vol - 0x90);
-		    break;
+			event->f2t = FX_EXTENDED;
+			event->f2p =
+			    (EX_F_VSLIDE_UP << 4) | (event->vol - 0x90);
+			break;
 		case 0x0a:	/* Set vibrato speed */
-		    event->f2t = FX_VIBRATO;
-		    event->f2p = (event->vol - 0xa0) << 4;
-		    break;
+			event->f2t = FX_VIBRATO;
+			event->f2p = (event->vol - 0xa0) << 4;
+			break;
 		case 0x0b:	/* Vibrato */
-		    event->f2t = FX_VIBRATO;
-		    event->f2p = event->vol - 0xb0;
-		    break;
+			event->f2t = FX_VIBRATO;
+			event->f2p = event->vol - 0xb0;
+			break;
 		case 0x0c:	/* Set panning */
-		    event->f2t = FX_SETPAN;
-		    event->f2p = (event->vol - 0xc0) << 4;
-		    break;
+			event->f2t = FX_SETPAN;
+			event->f2p = (event->vol - 0xc0) << 4;
+			break;
 		case 0x0d:	/* Pan slide left */
-		    event->f2t = FX_PANSLIDE;
-		    event->f2p = (event->vol - 0xd0) << 4;
-		    break;
+			event->f2t = FX_PANSL_NOMEM;
+			event->f2p = (event->vol - 0xd0) << 4;
+			break;
 		case 0x0e:	/* Pan slide right */
-		    event->f2t = FX_PANSLIDE;
-		    event->f2p = event->vol - 0xe0;
-		    break;
+			event->f2t = FX_PANSL_NOMEM;
+			event->f2p = event->vol - 0xe0;
+			break;
 		case 0x0f:	/* Tone portamento */
-		    event->f2t = FX_TONEPORTA;
-		    event->f2p = (event->vol - 0xf0) << 4;
-		    break;
+			event->f2t = FX_TONEPORTA;
+			event->f2p = (event->vol - 0xf0) << 4;
+
+			/* From OpenMPT TonePortamentoMemory.xm:
+			 * "Another nice bug (...) is the combination of both
+			 *  portamento commands (Mx and 3xx) in the same cell:
+			 *  The 3xx parameter is ignored completely, and the Mx
+			 *  parameter is doubled. (M2 3FF is the same as M4 000)
+			 */
+			if (event->fxt == FX_TONEPORTA
+			    || event->fxt == FX_TONE_VSLIDE) {
+				if (event->fxt == FX_TONEPORTA) {
+					event->fxt = 0;
+				} else {
+					event->fxt = FX_VOLSLIDE;
+				}
+				event->fxp = 0;
+
+				if (event->f2p < 0x80) {
+					event->f2p <<= 1;
+				} else {
+					event->f2p = 0xff;
+				}
+			}
+
+			/* From OpenMPT porta-offset.xm:
+			 * "If there is a portamento command next to an offset
+			 *  command, the offset command is ignored completely. In
+			 *  particular, the offset parameter is not memorized."
+			 */
+			if (event->fxt == FX_OFFSET
+			    && event->f2t == FX_TONEPORTA) {
+				event->fxt = event->fxp = 0;
+			}
+			break;
 		}
 		event->vol = 0;
-	    }
-	    free (patbuf);
 	}
-    }
+	free(patbuf);
 
-    /* Alloc one extra pattern */
-    {
-	int t = i * mod->chn;
+	return 0;
 
-	if (pattern_alloc(mod, i) < 0)
-	    return -1;
+err2:
+	free(patbuf);
+err:
+	return -1;
+}
 
-	mod->xxp[i]->rows = 64;
+static int load_patterns(struct module_data *m, int version, HIO_HANDLE *f)
+{
+	struct xmp_module *mod = &m->mod;
+	int i, j;
 
-	if (track_alloc(mod, t, 64) < 0)
-	    return -1;
+	mod->pat++;
+	if (libxmp_init_pattern(mod) < 0) {
+		return -1;
+	}
 
-	for (j = 0; j < mod->chn; j++)
-	    mod->xxp[i]->index[j] = t;
-    }
+	D_(D_INFO "Stored patterns: %d", mod->pat - 1);
 
-    return 0;
+	for (i = 0; i < mod->pat - 1; i++) {
+		if (load_xm_pattern(m, i, version, f) < 0) {
+			goto err;
+		}
+	}
+
+	/* Alloc one extra pattern */
+	{
+		int t = i * mod->chn;
+
+		if (libxmp_alloc_pattern(mod, i) < 0) {
+			goto err;
+		}
+
+		mod->xxp[i]->rows = 64;
+
+		if (libxmp_alloc_track(mod, t, 64) < 0) {
+			goto err;
+		}
+
+		for (j = 0; j < mod->chn; j++) {
+			mod->xxp[i]->index[j] = t;
+		}
+	}
+
+	return 0;
+
+err:
+	return -1;
 }
 
 /* Packed structures size */
@@ -228,9 +355,9 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE *f)
     D_(D_INFO "Instruments: %d", mod->ins);
 
     /* ESTIMATED value! We don't know the actual value at this point */
-    mod->smp = MAX_SAMP;
+    mod->smp = MAX_SAMPLES;
 
-    if (instrument_init(mod) < 0)
+    if (libxmp_init_instrument(m) < 0)
 	return -1;
 
     for (i = 0; i < mod->ins; i++) {
@@ -243,7 +370,6 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE *f)
 	 * will not work if file has trailing garbage.
 	 */
 	if (hio_eof(f)) {
-		mod->ins = i;
 		break;
 	}
 
@@ -254,11 +380,11 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE *f)
 
 	/* Sanity check */
 	if (xih.samples > 0x10 || (xih.samples > 0 && xih.sh_size > 0x100)) {
-		mod->ins = i;
-		break;
+		D_(D_CRIT "Sanity check: %d %d", xih.samples, xih.sh_size);
+		return -1;
 	}
 
-	instrument_name(mod, i, xih.name, 22);
+	libxmp_instrument_name(mod, i, xih.name, 22);
 
 	xxi->nsm = xih.samples;
 	if (xxi->nsm > 16)
@@ -267,7 +393,7 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE *f)
 	D_(D_INFO "[%2X] %-22.22s %2d", i, xxi->name, xxi->nsm);
 
 	if (xxi->nsm) {
-	    if (subinstrument_alloc(mod, i, xxi->nsm) < 0)
+	    if (libxmp_alloc_subinstrument(mod, i, xxi->nsm) < 0)
 		return -1;
 	    if (xih.size < XM_INST_HEADER_SIZE)
 		return -1;
@@ -317,12 +443,12 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE *f)
 		xxi->pei.lpe = xi.p_end;
 		xxi->pei.flg = xi.p_type;
 
-		if (xxi->aei.npt <= 0 || xxi->aei.npt > XMP_MAX_ENV_POINTS)
+		if (xxi->aei.npt <= 0 || xxi->aei.npt > 12 /*XMP_MAX_ENV_POINTS*/)
 		    xxi->aei.flg &= ~XMP_ENVELOPE_ON;
 		else
 		    memcpy(xxi->aei.data, xi.v_env, xxi->aei.npt * 4);
 
-		if (xxi->pei.npt <= 0 || xxi->pei.npt > XMP_MAX_ENV_POINTS)
+		if (xxi->pei.npt <= 0 || xxi->pei.npt > 12 /*XMP_MAX_ENV_POINTS*/)
 		    xxi->pei.flg &= ~XMP_ENVELOPE_ON;
 		else
 		    memcpy(xxi->pei.data, xi.p_env, xxi->pei.npt * 4);
@@ -339,13 +465,18 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE *f)
 		struct xmp_sample *xxs;
 
 		if (sample_num >= mod->smp) {
-		    mod->xxs = realloc_samples(mod->xxs, &mod->smp, mod->smp * 3 / 2);
+		    mod->xxs = libxmp_realloc_samples(mod->xxs, &mod->smp, mod->smp * 3 / 2);
 		    if (mod->xxs == NULL)
 			return -1;
 		}
 		xxs = &mod->xxs[sample_num];
 
 		xsh[j].length = hio_read32l(f);		/* Sample length */
+
+		/* Sanity check */
+		if (xsh[j].length > MAX_SAMPLE_SIZE)
+			return -1;
+
 		xsh[j].loop_start = hio_read32l(f);	/* Sample loop start */
 		xsh[j].loop_length = hio_read32l(f);	/* Sample loop length */
 		xsh[j].volume = hio_read8(f);		/* Volume */
@@ -361,12 +492,12 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE *f)
 		sub->xpo = xsh[j].relnote;
 		sub->fin = xsh[j].finetune;
 		sub->vwf = xi.y_wave;
-		sub->vde = xi.y_depth;
+		sub->vde = xi.y_depth << 2;
 		sub->vra = xi.y_rate;
 		sub->vsw = xi.y_sweep;
 		sub->sid = sample_num;
 
-		copy_adjust(xxs->name, xsh[j].name, 22);
+		libxmp_copy_adjust(xxs->name, xsh[j].name, 22);
 
 		xxs->len = xsh[j].length;
 		xxs->lps = xsh[j].loop_start;
@@ -407,7 +538,7 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE *f)
 #endif
 		
 		if (version > 0x0103) {
-		    if (load_sample(m, f, flags,
+		    if (libxmp_load_sample(m, f, flags,
 					&mod->xxs[sub->sid], NULL) < 0) {
 			return -1;
 		    }
@@ -434,132 +565,165 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE *f)
     }
 
     /* Final sample number adjustment */
-    mod->xxs = realloc_samples(mod->xxs, &mod->smp, sample_num);
+    mod->xxs = libxmp_realloc_samples(mod->xxs, &mod->smp, sample_num);
     if (mod->xxs == NULL)
 	return -1;
 
     return 0;
 }
 
-static int xm_load(struct module_data *m, HIO_HANDLE *f, const int start)
+static int xm_load(struct module_data *m, HIO_HANDLE * f, const int start)
 {
-    struct xmp_module *mod = &m->mod;
-    int i, j;
-    struct xm_file_header xfh;
-    char tracker_name[21];
-
-    LOAD_INIT();
-
-    hio_read(&xfh.id, 17, 1, f);	/* ID text */
-    hio_read(&xfh.name, 20, 1, f);	/* Module name */
-    hio_read8(f);			/* 0x1a */
-    hio_read(&xfh.tracker, 20, 1, f);	/* Tracker name */
-    xfh.version = hio_read16l(f);	/* Version number, minor-major */
-    xfh.headersz = hio_read32l(f);	/* Header size */
-    xfh.songlen = hio_read16l(f);	/* Song length */
-    xfh.restart = hio_read16l(f);	/* Restart position */
-    xfh.channels = hio_read16l(f);	/* Number of channels */
-    xfh.patterns = hio_read16l(f);	/* Number of patterns */
-    xfh.instruments = hio_read16l(f);	/* Number of instruments */
-    xfh.flags = hio_read16l(f);		/* 0=Amiga freq table, 1=Linear */
-    xfh.tempo = hio_read16l(f);		/* Default tempo */
-    xfh.bpm = hio_read16l(f);		/* Default BPM */
-
-    /* Honor header size -- needed by BoobieSqueezer XMs */
-    hio_read(&xfh.order, xfh.headersz - 0x14, 1, f); /* Pattern order table */
-
-    strncpy(mod->name, (char *)xfh.name, 20);
-
-    mod->len = xfh.songlen;
-    mod->rst = xfh.restart;
-    mod->chn = xfh.channels;
-    mod->pat = xfh.patterns;
-    mod->trk = mod->chn * mod->pat + 1;
-    mod->ins = xfh.instruments;
-    mod->spd = xfh.tempo;
-    mod->bpm = xfh.bpm;
-
-    m->quirk |= xfh.flags & XM_LINEAR_PERIOD_MODE ? QUIRK_LINEAR : 0;
-
-    memcpy(mod->xxo, xfh.order, mod->len);
-    tracker_name[20] = 0;
-    snprintf(tracker_name, 20, "%-20.20s", xfh.tracker);
-    for (i = 20; i >= 0; i--) {
-	if (tracker_name[i] == 0x20)
-	    tracker_name[i] = 0;
-	if (tracker_name[i])
-	    break;
-    }
+	struct xmp_module *mod = &m->mod;
+	int i, j;
+	struct xm_file_header xfh;
+	char tracker_name[21];
+	int len;
+
+	LOAD_INIT();
+
+	hio_read(&xfh.id, 17, 1, f);		/* ID text */
+	hio_read(&xfh.name, 20, 1, f);		/* Module name */
+	hio_read8(f);				/* 0x1a */
+	hio_read(&xfh.tracker, 20, 1, f);	/* Tracker name */
+	xfh.version = hio_read16l(f);		/* Version number, minor-major */
+	xfh.headersz = hio_read32l(f);		/* Header size */
+	xfh.songlen = hio_read16l(f);		/* Song length */
+	xfh.restart = hio_read16l(f);		/* Restart position */
+	xfh.channels = hio_read16l(f);		/* Number of channels */
+	xfh.patterns = hio_read16l(f);		/* Number of patterns */
+	xfh.instruments = hio_read16l(f);	/* Number of instruments */
+	xfh.flags = hio_read16l(f);		/* 0=Amiga freq table, 1=Linear */
+	xfh.tempo = hio_read16l(f);		/* Default tempo */
+	xfh.bpm = hio_read16l(f);		/* Default BPM */
+
+	/* Sanity checks */
+	if (xfh.songlen > 256 || xfh.patterns > 256 || xfh.instruments > 255) {
+		D_(D_CRIT "Sanity check: %d %d %d", xfh.songlen, xfh.patterns,
+		   xfh.instruments);
+		return -1;
+	}
 
+	if (xfh.restart > 255 || xfh.channels > XMP_MAX_CHANNELS) {
+		D_(D_CRIT "Sanity check: %d %d", xfh.restart, xfh.channels);
+		return -1;
+	}
+
+	if (xfh.tempo >= 32 || xfh.bpm < 32 || xfh.bpm > 255) {
+		if (memcmp("MED2XM", xfh.tracker, 6)) {
+			D_(D_CRIT "Sanity check: %d %d", xfh.tempo, xfh.bpm);
+			return -1;
+		}
+	}
+
+	len = xfh.headersz - 0x14;
+	if (len < 0 || len > 256) {
+		D_(D_CRIT "Sanity check: %d", len);
+		return -1;
+	}
+
+	/* Honor header size -- needed by BoobieSqueezer XMs */
+	hio_read(&xfh.order, len, 1, f);	/* Pattern order table */
+
+	strncpy(mod->name, (char *)xfh.name, 20);
+
+	mod->len = xfh.songlen;
+	mod->chn = xfh.channels;
+	mod->pat = xfh.patterns;
+	mod->ins = xfh.instruments;
+	mod->rst = xfh.restart;
+	mod->spd = xfh.tempo;
+	mod->bpm = xfh.bpm;
+	mod->trk = mod->chn * mod->pat + 1;
+
+	m->c4rate = C4_NTSC_RATE;
+	m->period_type = xfh.flags & XM_LINEAR_PERIOD_MODE ?
+				PERIOD_LINEAR : PERIOD_AMIGA;
+
+	memcpy(mod->xxo, xfh.order, mod->len);
+	tracker_name[20] = 0;
+	snprintf(tracker_name, 20, "%-20.20s", xfh.tracker);
+	for (i = 20; i >= 0; i--) {
+		if (tracker_name[i] == 0x20)
+			tracker_name[i] = 0;
+		if (tracker_name[i])
+			break;
+	}
+
+	/* OpenMPT accurately emulates weird FT2 bugs */
+	if (!strncmp(tracker_name, "FastTracker v2.00", 17) ||
+	    !strncmp(tracker_name, "OpenMPT ", 8)) {
+		m->quirk |= QUIRK_FT2BUGS;
+	}
 #ifndef LIBXMP_CORE_PLAYER
-    if (xfh.headersz == 0x0113) {
-	strcpy(tracker_name, "unknown tracker");
-    } else if (*tracker_name == 0) {
-	strcpy(tracker_name, "Digitrakker");	/* best guess */
-    }
+	if (xfh.headersz == 0x0113) {
+		strcpy(tracker_name, "unknown tracker");
+		m->quirk &= ~QUIRK_FT2BUGS;
+	} else if (*tracker_name == 0) {
+		strcpy(tracker_name, "Digitrakker");	/* best guess */
+		m->quirk &= ~QUIRK_FT2BUGS;
+	}
 
-    /* See MMD1 loader for explanation */
-    if (!strncmp(tracker_name, "MED2XM by J.Pynnone", 19)) {
-	if (mod->bpm <= 10)
-	    mod->bpm = 125 * (0x35 - mod->bpm * 2) / 33;
-    }
+	/* See MMD1 loader for explanation */
+	if (!strncmp(tracker_name, "MED2XM by J.Pynnone", 19)) {
+		if (mod->bpm <= 10)
+			mod->bpm = 125 * (0x35 - mod->bpm * 2) / 33;
+		m->quirk &= ~QUIRK_FT2BUGS;
+	}
 
-    if (!strncmp(tracker_name, "FastTracker v 2.00", 18)) {
-	strcpy(tracker_name, "old ModPlug Tracker");
-    }
+	if (!strncmp(tracker_name, "FastTracker v 2.00", 18)) {
+		strcpy(tracker_name, "old ModPlug Tracker");
+		m->quirk &= ~QUIRK_FT2BUGS;
+	}
 
-    if (!strncmp(tracker_name, "MilkyTracker", 12)) {
-	m->quirk |= QUIRK_MLKDLY;
-    }
-	
-    set_type(m, "%s XM %d.%02d", tracker_name,
-				xfh.version >> 8, xfh.version & 0xff);
+	libxmp_set_type(m, "%s XM %d.%02d", tracker_name,
+		 xfh.version >> 8, xfh.version & 0xff);
 #else
-    set_type(m, tracker_name);
+	libxmp_set_type(m, tracker_name);
 #endif
 
-    MODULE_INFO();
+	MODULE_INFO();
 
-    /* Honor header size */
+	/* Honor header size */
 
-    hio_seek(f, start + xfh.headersz + 60, SEEK_SET);
+	hio_seek(f, start + xfh.headersz + 60, SEEK_SET);
 
-    /* XM 1.02/1.03 has a different patterns and instruments order */
+	/* XM 1.02/1.03 has a different patterns and instruments order */
 
-    if (xfh.version <= 0x0103) {
-	if (load_instruments(m, xfh.version, f) < 0)
-	    return -1;
-	if (load_patterns(m, xfh.version, f) < 0)
-	    return -1;
-    } else {
-	if (load_patterns(m, xfh.version, f) < 0)
-	    return -1;
-	if (load_instruments(m, xfh.version, f) < 0)
-	    return -1;
-    }
+	if (xfh.version <= 0x0103) {
+		if (load_instruments(m, xfh.version, f) < 0)
+			return -1;
+		if (load_patterns(m, xfh.version, f) < 0)
+			return -1;
+	} else {
+		if (load_patterns(m, xfh.version, f) < 0)
+			return -1;
+		if (load_instruments(m, xfh.version, f) < 0)
+			return -1;
+	}
 
-    D_(D_INFO "Stored samples: %d", mod->smp);
+	D_(D_INFO "Stored samples: %d", mod->smp);
 
-    /* XM 1.02 stores all samples after the patterns */
+	/* XM 1.02 stores all samples after the patterns */
 
-    if (xfh.version <= 0x0103) {
-	for (i = 0; i < mod->ins; i++) {
-	    for (j = 0; j < mod->xxi[i].nsm; j++) {
-		int sid = mod->xxi[i].sub[j].sid;
-		if (load_sample(m, f, SAMPLE_FLAG_DIFF,
-				&mod->xxs[sid], NULL) < 0) {
-		    return -1;
+	if (xfh.version <= 0x0103) {
+		for (i = 0; i < mod->ins; i++) {
+			for (j = 0; j < mod->xxi[i].nsm; j++) {
+				int sid = mod->xxi[i].sub[j].sid;
+				if (libxmp_load_sample(m, f, SAMPLE_FLAG_DIFF,
+						&mod->xxs[sid], NULL) < 0) {
+					return -1;
+				}
+			}
 		}
-	    }
 	}
-    }
 
-    for (i = 0; i < mod->chn; i++) {
-        mod->xxc[i].pan = 0x80;
-    }
+	for (i = 0; i < mod->chn; i++) {
+		mod->xxc[i].pan = 0x80;
+	}
 
-    m->quirk |= QUIRKS_FT2;
-    m->read_event_type = READ_EVENT_FT2;
+	m->quirk |= QUIRKS_FT2;
+	m->read_event_type = READ_EVENT_FT2;
 
-    return 0;
+	return 0;
 }
diff --git a/src/lutgen.c b/src/lutgen.c
new file mode 100644
index 0000000..d98cd8b
--- /dev/null
+++ b/src/lutgen.c
@@ -0,0 +1,299 @@
+#define compile \
+        exec gcc -Wall -pedantic -std=gnu99 -lm lutgen.c -o lutgen || exit 255
+
+#include 
+#include 
+#include 
+#include 
+
+/* Lifted from Schism Tracker, array interleaving changed */
+
+/*
+ *  cubic spline interpolation doc,
+ *    (derived from "digital image warping", g. wolberg)
+ *
+ *    interpolation polynomial: f(x) = A3*(x-floor(x))**3 + A2*(x-floor(x))**2 + A1*(x-floor(x)) + A0
+ *
+ *    with Y = equispaced data points (dist=1), YD = first derivates of data points and IP = floor(x)
+ *    the A[0..3] can be found by solving
+ *      A0  = Y[IP]
+ *      A1  = YD[IP]
+ *      A2  = 3*(Y[IP+1]-Y[IP])-2.0*YD[IP]-YD[IP+1]
+ *      A3  = -2.0 * (Y[IP+1]-Y[IP]) + YD[IP] - YD[IP+1]
+ *
+ *    with the first derivates as
+ *      YD[IP]    = 0.5 * (Y[IP+1] - Y[IP-1]);
+ *      YD[IP+1]  = 0.5 * (Y[IP+2] - Y[IP])
+ *
+ *    the coefs becomes
+ *      A0  = Y[IP]
+ *      A1  = YD[IP]
+ *          =  0.5 * (Y[IP+1] - Y[IP-1]);
+ *      A2  =  3.0 * (Y[IP+1]-Y[IP])-2.0*YD[IP]-YD[IP+1]
+ *          =  3.0 * (Y[IP+1] - Y[IP]) - 0.5 * 2.0 * (Y[IP+1] - Y[IP-1]) - 0.5 * (Y[IP+2] - Y[IP])
+ *          =  3.0 * Y[IP+1] - 3.0 * Y[IP] - Y[IP+1] + Y[IP-1] - 0.5 * Y[IP+2] + 0.5 * Y[IP]
+ *          = -0.5 * Y[IP+2] + 2.0 * Y[IP+1] - 2.5 * Y[IP] + Y[IP-1]
+ *          = Y[IP-1] + 2 * Y[IP+1] - 0.5 * (5.0 * Y[IP] + Y[IP+2])
+ *      A3  = -2.0 * (Y[IP+1]-Y[IP]) + YD[IP] + YD[IP+1]
+ *          = -2.0 * Y[IP+1] + 2.0 * Y[IP] + 0.5 * (Y[IP+1] - Y[IP-1]) + 0.5 * (Y[IP+2] - Y[IP])
+ *          = -2.0 * Y[IP+1] + 2.0 * Y[IP] + 0.5 * Y[IP+1] - 0.5 * Y[IP-1] + 0.5 * Y[IP+2] - 0.5 * Y[IP]
+ *          =  0.5 * Y[IP+2] - 1.5 * Y[IP+1] + 1.5 * Y[IP] - 0.5 * Y[IP-1]
+ *          =  0.5 * (3.0 * (Y[IP] - Y[IP+1]) - Y[IP-1] + YP[IP+2])
+ *
+ *    then interpolated data value is (horner rule)
+ *      out = (((A3*x)+A2)*x+A1)*x+A0
+ *
+ *    this gives parts of data points Y[IP-1] to Y[IP+2] of
+ *      part       x**3    x**2    x**1    x**0
+ *      Y[IP-1]    -0.5     1      -0.5    0
+ *      Y[IP]       1.5    -2.5     0      1
+ *      Y[IP+1]    -1.5     2       0.5    0
+ *      Y[IP+2]     0.5    -0.5     0      0
+ */
+
+// number of bits used to scale spline coefs
+#define SPLINE_QUANTBITS    14
+#define SPLINE_QUANTSCALE   (1L << SPLINE_QUANTBITS)
+#define SPLINE_8SHIFT       (SPLINE_QUANTBITS - 8)
+#define SPLINE_16SHIFT      (SPLINE_QUANTBITS)
+
+// forces coefsset to unity gain
+#define SPLINE_CLAMPFORUNITY
+
+// log2(number) of precalculated splines (range is [4..14])
+#define SPLINE_FRACBITS 10
+#define SPLINE_LUTLEN (1L << SPLINE_FRACBITS)
+
+
+int16_t cubic_spline_lut[4 * SPLINE_LUTLEN];
+
+
+void cubic_spline_init(void)
+{
+    int i;
+    int len = SPLINE_LUTLEN;
+    float flen = 1.0f / (float) SPLINE_LUTLEN;
+    float scale = (float) SPLINE_QUANTSCALE;
+
+    for (i = 0; i < len; i++) {
+        float LCm1, LC0, LC1, LC2;
+        float LX = ((float) i) * flen;
+        int indx = i << 2;
+#ifdef SPLINE_CLAMPFORUNITY
+        int sum;
+#endif
+
+        LCm1 = (float) floor(0.5 + scale * (-0.5 * LX * LX * LX + 1.0 * LX * LX - 0.5 * LX       ));
+        LC0  = (float) floor(0.5 + scale * ( 1.5 * LX * LX * LX - 2.5 * LX * LX             + 1.0));
+        LC1  = (float) floor(0.5 + scale * (-1.5 * LX * LX * LX + 2.0 * LX * LX + 0.5 * LX       ));
+        LC2  = (float) floor(0.5 + scale * ( 0.5 * LX * LX * LX - 0.5 * LX * LX                  ));
+
+        cubic_spline_lut[indx + 0] = (int16_t) ((LCm1 < -scale) ? -scale : ((LCm1 > scale) ? scale : LCm1));
+        cubic_spline_lut[indx + 1] = (int16_t) ((LC0  < -scale) ? -scale : ((LC0  > scale) ? scale : LC0 ));
+        cubic_spline_lut[indx + 2] = (int16_t) ((LC1  < -scale) ? -scale : ((LC1  > scale) ? scale : LC1 ));
+        cubic_spline_lut[indx + 3] = (int16_t) ((LC2  < -scale) ? -scale : ((LC2  > scale) ? scale : LC2 ));
+
+#ifdef SPLINE_CLAMPFORUNITY
+        sum = cubic_spline_lut[indx + 0] +
+              cubic_spline_lut[indx + 1] +
+              cubic_spline_lut[indx + 2] +
+              cubic_spline_lut[indx + 3];
+
+        if (sum != SPLINE_QUANTSCALE) {
+            int max = indx;
+
+            if (cubic_spline_lut[indx + 1] > cubic_spline_lut[max]) max = indx + 1;
+            if (cubic_spline_lut[indx + 2] > cubic_spline_lut[max]) max = indx + 2;
+            if (cubic_spline_lut[indx + 3] > cubic_spline_lut[max]) max = indx + 3;
+
+            cubic_spline_lut[max] += (SPLINE_QUANTSCALE - sum);
+        }
+#endif
+    }
+}
+
+
+/* fir interpolation doc,
+ *  (derived from "an engineer's guide to fir digital filters", n.j. loy)
+ *
+ *  calculate coefficients for ideal lowpass filter (with cutoff = fc in 0..1 (mapped to 0..nyquist))
+ *    c[-N..N] = (i==0) ? fc : sin(fc*pi*i)/(pi*i)
+ *
+ *  then apply selected window to coefficients
+ *    c[-N..N] *= w(0..N)
+ *  with n in 2*N and w(n) being a window function (see loy)
+ *
+ *  then calculate gain and scale filter coefs to have unity gain.
+ */
+
+// quantizer scale of window coefs
+#define WFIR_QUANTBITS      15
+#define WFIR_QUANTSCALE     (1L << WFIR_QUANTBITS)
+#define WFIR_8SHIFT         (WFIR_QUANTBITS - 8)
+#define WFIR_16BITSHIFT     (WFIR_QUANTBITS)
+
+// log2(number)-1 of precalculated taps range is [4..12]
+#define WFIR_FRACBITS       10
+#define WFIR_LUTLEN         ((1L << (WFIR_FRACBITS + 1)) + 1)
+
+// number of samples in window
+#define WFIR_LOG2WIDTH      3
+#define WFIR_WIDTH          (1L << WFIR_LOG2WIDTH)
+#define WFIR_SMPSPERWING    ((WFIR_WIDTH - 1) >> 1)
+
+// cutoff (1.0 == pi/2)
+#define WFIR_CUTOFF         0.90f
+
+// wfir type
+#define WFIR_HANN           0
+#define WFIR_HAMMING        1
+#define WFIR_BLACKMANEXACT  2
+#define WFIR_BLACKMAN3T61   3
+#define WFIR_BLACKMAN3T67   4
+#define WFIR_BLACKMAN4T92   5
+#define WFIR_BLACKMAN4T74   6
+#define WFIR_KAISER4T       7
+#define WFIR_TYPE           WFIR_BLACKMANEXACT
+
+// wfir help
+#ifndef M_zPI
+#define M_zPI               3.1415926535897932384626433832795
+#endif
+#define M_zEPS              1e-8
+#define M_zBESSELEPS        1e-21
+
+
+float coef(int pc_nr, float p_ofs, float p_cut, int p_width, int p_type)
+{
+    double width_m1      = p_width - 1;
+    double width_m1_half = 0.5 * width_m1;
+    double pos_u         = (double) pc_nr - p_ofs;
+    double pos           = pos_u - width_m1_half;
+    double idl           = 2.0 * M_zPI / width_m1;
+    double wc, si;
+
+    if (fabs(pos) < M_zEPS) {
+        wc    = 1.0;
+        si    = p_cut;
+        return p_cut;
+    }
+
+    switch (p_type) {
+    case WFIR_HANN:
+            wc = 0.50 - 0.50 * cos(idl * pos_u);
+            break;
+
+    case WFIR_HAMMING:
+            wc = 0.54 - 0.46 * cos(idl * pos_u);
+            break;
+
+    case WFIR_BLACKMANEXACT:
+            wc = 0.42 - 0.50 * cos(idl * pos_u) + 0.08 * cos(2.0 * idl * pos_u);
+            break;
+
+    case WFIR_BLACKMAN3T61:
+            wc = 0.44959 - 0.49364 * cos(idl * pos_u) + 0.05677 * cos(2.0 * idl * pos_u);
+            break;
+
+    case WFIR_BLACKMAN3T67:
+            wc = 0.42323 - 0.49755 * cos(idl * pos_u) + 0.07922 * cos(2.0 * idl * pos_u);
+            break;
+
+    case WFIR_BLACKMAN4T92:
+            wc = 0.35875 - 0.48829 * cos(idl * pos_u) + 0.14128 * cos(2.0 * idl * pos_u) -
+                    0.01168 * cos(3.0 * idl * pos_u);
+            break;
+
+    case WFIR_BLACKMAN4T74:
+            wc = 0.40217 - 0.49703 * cos(idl * pos_u) + 0.09392 * cos(2.0 * idl * pos_u) -
+                0.00183 * cos(3.0*idl*pos_u);
+            break;
+
+    case WFIR_KAISER4T:
+            wc = 0.40243 - 0.49804 * cos(idl * pos_u) + 0.09831 * cos(2.0 * idl * pos_u) -
+                0.00122 * cos(3.0 * idl * pos_u);
+            break;
+
+    default:
+            wc = 1.0;
+            break;
+    }
+
+    pos *= M_zPI;
+    si   = sin(p_cut * pos) / pos;
+
+    return (float)(wc * si);
+}
+
+
+
+int16_t windowed_fir_lut[WFIR_LUTLEN*WFIR_WIDTH];
+
+void windowed_fir_init(void)
+{
+    int pcl;
+    // number of precalculated lines for 0..1 (-1..0)
+    float pcllen = (float)(1L << WFIR_FRACBITS);
+    float norm  = 1.0f / (float)(2.0f * pcllen);
+    float cut   = WFIR_CUTOFF;
+    float scale = (float) WFIR_QUANTSCALE;
+
+    for (pcl = 0; pcl < WFIR_LUTLEN; pcl++) {
+        float gain,coefs[WFIR_WIDTH];
+        float ofs = ((float) pcl - pcllen) * norm;
+        int cc, indx = pcl << WFIR_LOG2WIDTH;
+
+        for (cc = 0, gain = 0.0f; cc < WFIR_WIDTH; cc++) {
+            coefs[cc] = coef(cc, ofs, cut, WFIR_WIDTH, WFIR_TYPE);
+            gain += coefs[cc];
+        }
+
+        gain = 1.0f / gain;
+
+        for (cc = 0; cc < WFIR_WIDTH; cc++) {
+            float coef = (float)floor( 0.5 + scale * coefs[cc] * gain);
+            windowed_fir_lut[indx + cc] = (signed short)((coef < -scale) ? - scale :
+                ((coef > scale) ? scale : coef));
+        }
+    }
+}
+
+
+#define LOOP(x, y) \
+    printf("static signed short %s[%lu] = {\n", #x, y); \
+    \
+    for (int i = 0; i < y; i++) { \
+        if (i && !(i % 64)) { \
+            printf("\n"); \
+        } \
+        printf(" %d,", x[i]); \
+    } \
+    \
+    printf("\n};\n\n");
+
+#define LOOP2(x, y) \
+for(int j = 0; j < 4; j++) { \
+    printf("static int16 %s%d[%lu] = {\n\t", #x, j, y); \
+    \
+    for (int i = 0; i < y; i++) { \
+        if (i && !(i % 8)) { \
+            printf("\n\t"); \
+        } \
+        printf(" %d,", x[i * 4 + j]); \
+    } \
+    \
+    printf("\n};\n\n"); \
+}
+
+
+int main(int argc, char **argv)
+{
+    cubic_spline_init();
+    windowed_fir_init();
+
+    LOOP2(cubic_spline_lut, SPLINE_LUTLEN);
+    //LOOP(windowed_fir_lut, (WFIR_LUTLEN * WFIR_WIDTH));
+
+    return 0;
+}
+
diff --git a/src/mdataio.h b/src/mdataio.h
index dc46b9f..4fa8dc8 100644
--- a/src/mdataio.h
+++ b/src/mdataio.h
@@ -12,14 +12,16 @@ static inline ptrdiff_t CAN_READ(MFILE *m)
 	return INT_MAX;
 }
 
-static inline int8 mread8s(MFILE *m)
+static inline uint8 mread8(MFILE *m)
 {
-	return (int8)mgetc(m);
+	uint8 x = 0xff;
+	mread(&x, 1, 1, m);
+	return x;
 }
 
-static inline uint8 mread8(MFILE *m)
+static inline int8 mread8s(MFILE *m)
 {
-	return (uint8)mgetc(m);
+	return (int8)mgetc(m);
 }
 
 static inline uint16 mread16l(MFILE *m)
diff --git a/src/med_extras.c b/src/med_extras.c
index 05a7a62..9f905c0 100644
--- a/src/med_extras.c
+++ b/src/med_extras.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -66,7 +66,7 @@ static const int sine[32] = {
 	-255,-250,-235,-212,-180,-141, -97, -49
 };
 
-int med_change_period(struct context_data *ctx, struct channel_data *xc)
+int libxmp_med_change_period(struct context_data *ctx, struct channel_data *xc)
 {
 	struct med_channel_extras *ce = xc->extra;
 	int vib;
@@ -91,7 +91,7 @@ int med_change_period(struct context_data *ctx, struct channel_data *xc)
 }
 
 
-int med_linear_bend(struct context_data *ctx, struct channel_data *xc)
+int libxmp_med_linear_bend(struct context_data *ctx, struct channel_data *xc)
 {
 	struct module_data *m = &ctx->m;
 	struct med_module_extras *me = m->extra;
@@ -116,11 +116,11 @@ int med_linear_bend(struct context_data *ctx, struct channel_data *xc)
 }
 
 
-void med_play_extras(struct context_data *ctx, struct channel_data *xc,
-			int chn, int t)
+void libxmp_med_play_extras(struct context_data *ctx, struct channel_data *xc, int chn)
 {
 	struct module_data *m = &ctx->m;
 	struct player_data *p = &ctx->p;
+	struct xmp_module *mod = &m->mod;
 	struct med_module_extras *me;
 	struct med_channel_extras *ce;
 	struct med_instrument_extras *ie;
@@ -167,17 +167,20 @@ void med_play_extras(struct context_data *ctx, struct channel_data *xc,
 		return;
 	}
 
-	if (t == 0 && TEST(NEW_NOTE)) {
-		ce->arp = ce->aidx = 0;
+	if (p->frame == 0 && TEST(NEW_NOTE)) {
 		ce->period = xc->period;
 		if (TEST(NEW_INS)) {
+			ce->arp = ce->aidx = 0;
 			ce->vp = ce->vc = ce->vw = 0;
 			ce->wp = ce->wc = ce->ww = 0;
+			ce->env_wav = -1;
+			ce->env_idx = 0;
+			ce->flags &= ~MED_SYNTH_ENV_LOOP;
+			ce->vv = 0;
+			ce->wv = 0;
+			ce->vs = ie->vts;
+			ce->ws = ie->wts;
 		}
-		ce->vv = 0;
-		ce->wv = 0;
-		ce->vs = ie->vts;
-		ce->ws = ie->wts;
 	}
 
 	if (ce->vs > 0 && ce->vc-- == 0) {
@@ -190,6 +193,8 @@ void med_play_extras(struct context_data *ctx, struct channel_data *xc,
 
 		loop = jws = 0;
 
+		/* Volume commands */
+
 	    next_vt:
 		switch (b = VT) {
 		case 0xff:	/* END */
@@ -208,8 +213,11 @@ void med_play_extras(struct context_data *ctx, struct channel_data *xc,
 			jws = VT;
 			break;
 		case 0xf5:	/* EN2 */
+			ce->env_wav = VT;
+			ce->flags |= MED_SYNTH_ENV_LOOP;
+			break;
 		case 0xf4:	/* EN1 */
-			VT_SKIP;	/* Not implemented */
+			ce->env_wav = VT;
 			break;
 		case 0xf3:	/* CHU */
 			ce->vv = VT;
@@ -228,11 +236,28 @@ void med_play_extras(struct context_data *ctx, struct channel_data *xc,
 				ce->volume = b;
 		}
 
+	    skip_vol:
+
+		/* volume envelope */
+		if (ce->env_wav >= 0) {
+			int sid = mod->xxi[xc->ins].sub[ce->env_wav].sid;
+			struct xmp_sample *xxs = &mod->xxs[sid];
+			if (xxs->len == 0x80) {		/* sanity check */
+				ce->volume = ((int8)xxs->data[ce->env_idx] + 0x80) >> 2;
+				ce->env_idx++;
+
+				if (ce->env_idx >= 0x80) {
+					if (~ce->flags & MED_SYNTH_ENV_LOOP) {
+						ce->env_wav = -1;
+					}
+					ce->env_idx = 0;
+				}
+			}
+		}
+
 		ce->volume += ce->vv;
 		CLAMP(ce->volume, 0, 64);
 
-	    skip_vol:
-
 		if (ce->ww > 0) {
 			ce->ww--;
 			goto skip_wav;
@@ -240,6 +265,8 @@ void med_play_extras(struct context_data *ctx, struct channel_data *xc,
 
 		loop = jvs = 0;
 
+		/* Waveform commands */
+
 	    next_wt:
 		switch (b = WT) {
 			struct xmp_instrument *xxi;
@@ -266,7 +293,7 @@ void med_play_extras(struct context_data *ctx, struct channel_data *xc,
 			while (WT != 0xfd) ;
 			break;
 		case 0xfa:	/* JVS */
-			jws = WT;
+			jvs = WT;
 			break;
 		case 0xf7:	/* VWF */
 			ce->vwf = WT;
@@ -296,14 +323,13 @@ void med_play_extras(struct context_data *ctx, struct channel_data *xc,
 			xxi = &m->mod.xxi[xc->ins];
 			if (b < xxi->nsm && xxi->sub[b].sid != xc->smp) {
 				xc->smp = xxi->sub[b].sid;
-				virt_setsmp(ctx, chn, xc->smp);
+				libxmp_virt_setsmp(ctx, chn, xc->smp);
 			}
 		}
-		xc->period += ce->wv;
 
 	    skip_wav:
-		;
-		/* xc->period += ce->wv; */
+
+		xc->period += ce->wv;
 	}
 
 	if (jws) {
@@ -317,7 +343,7 @@ void med_play_extras(struct context_data *ctx, struct channel_data *xc,
 	}
 }
 
-int med_new_instrument_extras(struct xmp_instrument *xxi)
+int libxmp_med_new_instrument_extras(struct xmp_instrument *xxi)
 {
 	xxi->extra = calloc(1, sizeof(struct med_instrument_extras));
 	if (xxi->extra == NULL)
@@ -327,7 +353,7 @@ int med_new_instrument_extras(struct xmp_instrument *xxi)
 	return 0;
 }
 
-int med_new_channel_extras(struct channel_data *xc)
+int libxmp_med_new_channel_extras(struct channel_data *xc)
 {
 	xc->extra = calloc(1, sizeof(struct med_channel_extras));
 	if (xc->extra == NULL)
@@ -337,17 +363,17 @@ int med_new_channel_extras(struct channel_data *xc)
 	return 0;
 }
 
-void med_reset_channel_extras(struct channel_data *xc)
+void libxmp_med_reset_channel_extras(struct channel_data *xc)
 {
 	memset((char *)xc->extra + 4, 0, sizeof(struct med_channel_extras) - 4);
 }
 
-void med_release_channel_extras(struct channel_data *xc)
+void libxmp_med_release_channel_extras(struct channel_data *xc)
 {
 	free(xc->extra);
 }
 
-int med_new_module_extras(struct module_data *m)
+int libxmp_med_new_module_extras(struct module_data *m)
 {
 	struct med_module_extras *me;
 	struct xmp_module *mod = &m->mod;
@@ -369,7 +395,7 @@ int med_new_module_extras(struct module_data *m)
 	return 0;
 }
 
-void med_release_module_extras(struct module_data *m)
+void libxmp_med_release_module_extras(struct module_data *m)
 {
 	struct med_module_extras *me;
 	struct xmp_module *mod = &m->mod;
@@ -392,7 +418,7 @@ void med_release_module_extras(struct module_data *m)
 	free(m->extra);
 }
 
-void med_extras_process_fx(struct context_data *ctx, struct channel_data *xc,
+void libxmp_med_extras_process_fx(struct context_data *ctx, struct channel_data *xc,
 			int chn, uint8 note, uint8 fxt, uint8 fxp, int fnum)
 {
 	switch (fxt) {
@@ -403,7 +429,7 @@ void med_extras_process_fx(struct context_data *ctx, struct channel_data *xc,
 	}
 }
 
-void med_hold_hack(struct context_data *ctx, int pat, int chn, int row)
+void libxmp_med_hold_hack(struct context_data *ctx, int pat, int chn, int row)
 {
 	struct module_data *m = &ctx->m;
 	struct xmp_module *mod = &m->mod;
diff --git a/src/med_extras.h b/src/med_extras.h
index b02e172..6458327 100644
--- a/src/med_extras.h
+++ b/src/med_extras.h
@@ -33,6 +33,10 @@ struct med_channel_extras {
 	int volume;		/* MED synth note volume */
 	int hold;		/* MED note on hold flag */
 	int hold_count;		/* MED note on hold frame counter */
+	int env_wav;		/* MED synth volume envelope waveform */
+	int env_idx;		/* MED synth volume envelope index */
+#define MED_SYNTH_ENV_LOOP (1 << 0)
+	int flags;		/* flags */
 };
 
 struct med_module_extras {
@@ -56,16 +60,16 @@ struct med_module_extras {
 	(MED_MODULE_EXTRAS(x) != NULL && \
 	 MED_MODULE_EXTRAS(x)->magic == MED_EXTRAS_MAGIC)
 
-int med_change_period(struct context_data *, struct channel_data *);
-int med_linear_bend(struct context_data *, struct channel_data *);
-int med_get_vibrato(struct channel_data *);
-void med_play_extras(struct context_data *, struct channel_data *, int, int);
-int med_new_instrument_extras(struct xmp_instrument *);
-int med_new_channel_extras(struct channel_data *);
-void med_reset_channel_extras(struct channel_data *);
-void med_release_channel_extras(struct channel_data *);
-int med_new_module_extras(struct module_data *);
-void med_release_module_extras(struct module_data *);
-void med_extras_process_fx(struct context_data *, struct channel_data *, int, uint8, uint8, uint8, int);
+int  libxmp_med_change_period(struct context_data *, struct channel_data *);
+int  libxmp_med_linear_bend(struct context_data *, struct channel_data *);
+int  libxmp_med_get_vibrato(struct channel_data *);
+void libxmp_med_play_extras(struct context_data *, struct channel_data *, int);
+int  libxmp_med_new_instrument_extras(struct xmp_instrument *);
+int  libxmp_med_new_channel_extras(struct channel_data *);
+void libxmp_med_reset_channel_extras(struct channel_data *);
+void libxmp_med_release_channel_extras(struct channel_data *);
+int  libxmp_med_new_module_extras(struct module_data *);
+void libxmp_med_release_module_extras(struct module_data *);
+void libxmp_med_extras_process_fx(struct context_data *, struct channel_data *, int, uint8, uint8, uint8, int);
 
 #endif
diff --git a/src/memio.c b/src/memio.c
index 637e0d6..ad49a24 100644
--- a/src/memio.c
+++ b/src/memio.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -52,8 +52,9 @@ size_t mread(void *buf, size_t size, size_t num, MFILE *m)
  	size_t should_read = size * num;
  	ptrdiff_t can_read = CAN_READ(m);
 
- 	if (can_read <= 0)
+ 	if (size <= 0 || num <= 0 || can_read <= 0) {
  		return 0;
+	}
 
 	if (should_read > can_read) {
  		should_read = can_read;
diff --git a/src/memio.h b/src/memio.h
index e2c9d0b..f347bbd 100644
--- a/src/memio.h
+++ b/src/memio.h
@@ -20,7 +20,9 @@ int     mseek(MFILE *, long, int);
 long    mtell(MFILE *);
 int     mclose(MFILE *);
 int	meof(MFILE *);
+#ifndef LIBXMP_CORE_PLAYER
 int	mstat(MFILE *, struct stat *);
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/src/mix_all.c b/src/mix_all.c
index 84cc890..6784abe 100644
--- a/src/mix_all.c
+++ b/src/mix_all.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -25,10 +25,6 @@
 #include "mixer.h"
 #include "precomp_lut.h"
 
-#ifndef LIBXMP_CORE_PLAYER
-#include "synth.h"
-#endif
-
 /* Mixers
  *
  * To increase performance eight mixers are defined, one for each
@@ -36,16 +32,25 @@
  * and number of channels.
  */
 #define NEAREST_NEIGHBOR() do { \
+    smp_in = ((int16)sptr[pos] << 8); \
+} while (0)
+
+#define NEAREST_NEIGHBOR_16BIT() do { \
     smp_in = sptr[pos]; \
 } while (0)
 
 #define LINEAR_INTERP() do { \
+    smp_l1 = ((int16)sptr[pos] << 8); \
+    smp_dt = ((int16)sptr[pos + 1] << 8) - smp_l1; \
+    smp_in = smp_l1 + (((frac >> 1) * smp_dt) >> (SMIX_SHIFT - 1)); \
+} while (0)
+
+#define LINEAR_INTERP_16BIT() do { \
     smp_l1 = sptr[pos]; \
     smp_dt = sptr[pos + 1] - smp_l1; \
-    smp_in = smp_l1 + ((frac * smp_dt) >> SMIX_SHIFT); \
+    smp_in = smp_l1 + (((frac >> 1) * smp_dt) >> (SMIX_SHIFT - 1)); \
 } while (0)
 
-
 /* The following lut settings are PRECOMPUTED. If you plan on changing these
  * settings, you MUST also regenerate the arrays.
  */
@@ -61,6 +66,14 @@
 #define SPLINE_FRACMASK  (((1L << (16 - SPLINE_FRACSHIFT)) - 1) & ~3)
 
 #define SPLINE_INTERP() do { \
+    int f = frac >> 6; \
+    smp_in = (cubic_spline_lut0[f] * sptr[(int)pos - 1] + \
+              cubic_spline_lut1[f] * sptr[pos    ] + \
+              cubic_spline_lut3[f] * sptr[pos + 2] + \
+              cubic_spline_lut2[f] * sptr[pos + 1]) >> (SPLINE_SHIFT - 8); \
+} while (0)
+
+#define SPLINE_INTERP_16BIT() do { \
     int f = frac >> 6; \
     smp_in = (cubic_spline_lut0[f] * sptr[(int)pos - 1] + \
               cubic_spline_lut1[f] * sptr[pos    ] + \
@@ -68,82 +81,94 @@
               cubic_spline_lut2[f] * sptr[pos + 1]) >> SPLINE_SHIFT; \
 } while (0)
 
+#define LOOP_AC for (; count > ramp; count--)
+
+#define LOOP for (; count; count--)
+
 #define UPDATE_POS() do { \
     frac += step; \
     pos += frac >> SMIX_SHIFT; \
     frac &= SMIX_MASK; \
 } while (0)
 
-#define MIX_STEREO() do { \
-    *(buffer++) += smp_in * vr; \
+#define MIX_MONO() do { \
     *(buffer++) += smp_in * vl; \
 } while (0)
 
-#define MIX_MONO() do { \
+#define MIX_MONO_AC() do { \
+    *(buffer++) += smp_in * (old_vl >> 8); old_vl += delta_l; \
+} while (0)
+
+#define MIX_MONO_FILTER() do { \
+    sl = (a0 * smp_in * vl + b0 * fl1 + b1 * fl2) >> FILTER_SHIFT; \
+    fl2 = fl1; fl1 = sl; \
+    *(buffer++) += sl; \
+} while (0)
+
+#define MIX_MONO_FILTER_AC() do { \
+    int vl = old_vl >> 8; \
+    MIX_MONO_FILTER(); \
+    old_vl += delta_l; \
+} while (0)
+
+#define MIX_STEREO() do { \
+    *(buffer++) += smp_in * vr; \
     *(buffer++) += smp_in * vl; \
 } while (0)
 
 #define MIX_STEREO_AC() do { \
-    if (vi->attack) { \
-	int a = SLOW_ATTACK - vi->attack; \
-	*(buffer++) += (smp_in * vr * a) >> SLOW_ATTACK_SHIFT; \
-	*(buffer++) += (smp_in * vl * a) >> SLOW_ATTACK_SHIFT; \
-	vi->attack--; \
-    } else { \
-	*(buffer++) += smp_in * vr; \
-	*(buffer++) += smp_in * vl; \
-    } \
+    *(buffer++) += smp_in * (old_vr >> 8); old_vr += delta_r; \
+    *(buffer++) += smp_in * (old_vl >> 8); old_vl += delta_l; \
 } while (0)
 
-#define MIX_STEREO_AC_FILTER() do { \
+#define MIX_STEREO_FILTER() do { \
     sr = (a0 * smp_in * vr + b0 * fr1 + b1 * fr2) >> FILTER_SHIFT; \
     fr2 = fr1; fr1 = sr; \
     sl = (a0 * smp_in * vl + b0 * fl1 + b1 * fl2) >> FILTER_SHIFT; \
     fl2 = fl1; fl1 = sl; \
-    if (vi->attack) { \
-	int a = SLOW_ATTACK - vi->attack; \
-	*(buffer++) += (sr * a) >> SLOW_ATTACK_SHIFT; \
-	*(buffer++) += (sl * a) >> SLOW_ATTACK_SHIFT; \
-	vi->attack--; \
-    } else { \
-	*(buffer++) += sr; \
-	*(buffer++) += sl; \
-    } \
+    *(buffer++) += sr; \
+    *(buffer++) += sl; \
 } while (0)
 
-#define MIX_MONO_AC() do { \
-    if (vi->attack) { \
-	*(buffer++) += (smp_in * vl * (SLOW_ATTACK - vi->attack)) >> SLOW_ATTACK_SHIFT; \
-	vi->attack--; \
-    } else { \
-	*(buffer++) += smp_in * vl; \
-    } \
+#define MIX_STEREO_FILTER_AC() do { \
+    int vr = old_vr >> 8; \
+    int vl = old_vl >> 8; \
+    MIX_STEREO_FILTER(); \
+    old_vr += delta_r; \
+    old_vl += delta_l; \
 } while (0)
 
-#define MIX_MONO_AC_FILTER() do { \
-    sl = (a0 * smp_in * vl + b0 * fl1 + b1 * fl2) >> FILTER_SHIFT; \
-    fl2 = fl1; fl1 = sl; \
-    if (vi->attack) { \
-	*(buffer++) += (sl * (SLOW_ATTACK - vi->attack)) >> SLOW_ATTACK_SHIFT; \
-	vi->attack--; \
-    } else { \
-	*(buffer++) += sl; \
-    } \
+#define MIX_STEREO_FILTER_AC() do { \
+    int vr = old_vr >> 8; \
+    int vl = old_vl >> 8; \
+    MIX_STEREO_FILTER(); \
+    old_vr += delta_r; \
+    old_vl += delta_l; \
 } while (0)
 
 #define VAR_NORM(x) \
     register int smp_in; \
     x *sptr = vi->sptr; \
     unsigned int pos = vi->pos; \
-    int frac = vi->frac
+    int frac = (1 << SMIX_SHIFT) * (vi->pos - (int)vi->pos)
 
-#define VAR_LINEAR(x) \
+#define VAR_LINEAR_MONO(x) \
     VAR_NORM(x); \
+    int old_vl = vi->old_vl; \
     int smp_l1, smp_dt
 
-#define VAR_SPLINE(x) \
+#define VAR_LINEAR_STEREO(x) \
+    VAR_LINEAR_MONO(x); \
+    int old_vr = vi->old_vr
+
+#define VAR_SPLINE_MONO(x) \
+    int old_vl = vi->old_vl; \
     VAR_NORM(x)
 
+#define VAR_SPLINE_STEREO(x); \
+    VAR_SPLINE_MONO(x); \
+    int old_vr = vi->old_vr; \
+
 #ifndef LIBXMP_CORE_DISABLE_IT
 
 #define VAR_FILTER_MONO \
@@ -169,53 +194,46 @@
 
 #endif
 
-#define SMIX_MIXER(f) void f(struct mixer_voice *vi, int *buffer, \
-    int count, int vl, int vr, int step)
-
 
 /*
  * Nearest neighbor mixers
  */
 
-/* Handler for 8 bit samples, linear interpolated stereo output
+/* Handler for 8 bit samples, nearest neighbor mono output
  */
-SMIX_MIXER(smix_stereo_8bit_linear)
+MIXER(mono_8bit_nearest)
 {
-    VAR_LINEAR(int8);
-    while (count--) { LINEAR_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
+    VAR_NORM(int8);
+
+    LOOP { NEAREST_NEIGHBOR(); MIX_MONO(); UPDATE_POS(); }
 }
 
 
-/* Handler for 16 bit samples, linear interpolated stereo output
+/* Handler for 16 bit samples, nearest neighbor mono output
  */
-SMIX_MIXER(smix_stereo_16bit_linear)
+MIXER(mono_16bit_nearest)
 {
-    VAR_LINEAR(int16);
+    VAR_NORM(int16);
 
-    vl >>= 8;
-    vr >>= 8;
-    while (count--) { LINEAR_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
+    LOOP { NEAREST_NEIGHBOR_16BIT(); MIX_MONO(); UPDATE_POS(); }
 }
 
-
 /* Handler for 8 bit samples, nearest neighbor stereo output
  */
-SMIX_MIXER(smix_stereo_8bit_nearest)
+MIXER(stereo_8bit_nearest)
 {
     VAR_NORM(int8);
-    while (count--) { NEAREST_NEIGHBOR(); MIX_STEREO(); UPDATE_POS(); }
-}
 
+    LOOP { NEAREST_NEIGHBOR(); MIX_STEREO(); UPDATE_POS(); }
+}
 
 /* Handler for 16 bit samples, nearest neighbor stereo output
  */
-SMIX_MIXER(smix_stereo_16bit_nearest)
+MIXER(stereo_16bit_nearest)
 {
     VAR_NORM(int16);
 
-    vl >>= 8;
-    vr >>= 8;
-    while (count--) { NEAREST_NEIGHBOR(); MIX_STEREO(); UPDATE_POS(); }
+    LOOP { NEAREST_NEIGHBOR_16BIT(); MIX_STEREO(); UPDATE_POS(); }
 }
 
 
@@ -225,92 +243,97 @@ SMIX_MIXER(smix_stereo_16bit_nearest)
 
 /* Handler for 8 bit samples, linear interpolated mono output
  */
-SMIX_MIXER(smix_mono_8bit_linear)
+MIXER(mono_8bit_linear)
 {
-    VAR_LINEAR(int8);
+    VAR_LINEAR_MONO(int8);
 
-    while (count--) { LINEAR_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
+    LOOP_AC { LINEAR_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
+    LOOP    { LINEAR_INTERP(); MIX_MONO(); UPDATE_POS(); }
 }
 
-
 /* Handler for 16 bit samples, linear interpolated mono output
  */
-SMIX_MIXER(smix_mono_16bit_linear)
+MIXER(mono_16bit_linear)
 {
-    VAR_LINEAR(int16);
+    VAR_LINEAR_MONO(int16);
 
-    vl >>= 8;
-    while (count--) { LINEAR_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
+    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_MONO_AC(); UPDATE_POS(); }
+    LOOP    { LINEAR_INTERP_16BIT(); MIX_MONO(); UPDATE_POS(); }
 }
 
-
-/* Handler for 8 bit samples, nearest neighbor mono output
+/* Handler for 8 bit samples, linear interpolated stereo output
  */
-SMIX_MIXER(smix_mono_8bit_nearest)
+MIXER(stereo_8bit_linear)
 {
-    VAR_NORM(int8);
+   VAR_LINEAR_STEREO(int8);
 
-    while (count--) { NEAREST_NEIGHBOR(); MIX_MONO(); UPDATE_POS(); }
+    LOOP_AC { LINEAR_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
+    LOOP    { LINEAR_INTERP(); MIX_STEREO(); UPDATE_POS(); }
 }
 
-
-/* Handler for 16 bit samples, nearest neighbor mono output
+/* Handler for 16 bit samples, linear interpolated stereo output
  */
-SMIX_MIXER(smix_mono_16bit_nearest)
+MIXER(stereo_16bit_linear)
 {
-    VAR_NORM(int16);
+    VAR_LINEAR_STEREO(int16);
 
-    vl >>= 8;
-    while (count--) { NEAREST_NEIGHBOR(); MIX_MONO(); UPDATE_POS(); }
+    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_STEREO_AC(); UPDATE_POS(); }
+    LOOP    { LINEAR_INTERP_16BIT(); MIX_STEREO(); UPDATE_POS(); }
 }
 
+
 #ifndef LIBXMP_CORE_DISABLE_IT
 
-/* Handler for 8 bit samples, linear interpolated stereo output
+/* Handler for 8 bit samples, filtered linear interpolated mono output
  */
-SMIX_MIXER(smix_stereo_8bit_linear_filter)
+MIXER(mono_8bit_linear_filter)
 {
-    VAR_LINEAR(int8);
-    VAR_FILTER_STEREO;
+    VAR_LINEAR_MONO(int8);
+    VAR_FILTER_MONO;
 
-    while (count--) { LINEAR_INTERP(); MIX_STEREO_AC_FILTER(); UPDATE_POS(); }
-    SAVE_FILTER_STEREO();
+    LOOP_AC { LINEAR_INTERP(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
+    LOOP    { LINEAR_INTERP(); MIX_MONO_FILTER(); UPDATE_POS(); }
+
+    SAVE_FILTER_MONO();
 }
 
-/* Handler for 16 bit samples, linear interpolated stereo output
+/* Handler for 16 bit samples, filtered linear interpolated mono output
  */
-SMIX_MIXER(smix_stereo_16bit_linear_filter)
+MIXER(mono_16bit_linear_filter)
 {
-    VAR_LINEAR(int16);
-    VAR_FILTER_STEREO;
+    VAR_LINEAR_MONO(int16);
+    VAR_FILTER_MONO;
 
-    vl >>= 8;
-    vr >>= 8;
-    while (count--) { LINEAR_INTERP(); MIX_STEREO_AC_FILTER(); UPDATE_POS(); }
-    SAVE_FILTER_STEREO();
+    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
+    LOOP    { LINEAR_INTERP_16BIT(); MIX_MONO_FILTER(); UPDATE_POS(); }
+
+    SAVE_FILTER_MONO();
 }
 
-/* Handler for 8 bit samples, linear interpolated mono output
+/* Handler for 8 bit samples, filtered linear interpolated stereo output
  */
-SMIX_MIXER(smix_mono_8bit_linear_filter)
+MIXER(stereo_8bit_linear_filter)
 {
-    VAR_LINEAR(int8);
-    VAR_FILTER_MONO;
+    VAR_LINEAR_STEREO(int8);
+    VAR_FILTER_STEREO;
 
-    while (count--) { LINEAR_INTERP(); MIX_MONO_AC_FILTER(); UPDATE_POS(); }
-    SAVE_FILTER_MONO();
+    LOOP_AC { LINEAR_INTERP(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
+    LOOP    { LINEAR_INTERP(); MIX_STEREO_FILTER(); UPDATE_POS(); }
+
+    SAVE_FILTER_STEREO();
 }
 
-/* Handler for 16 bit samples, linear interpolated mono output
+/* Handler for 16 bit samples, filtered linear interpolated stereo output
  */
-SMIX_MIXER(smix_mono_16bit_linear_filter)
+MIXER(stereo_16bit_linear_filter)
 {
-    VAR_LINEAR(int16);
-    VAR_FILTER_MONO;
+    VAR_LINEAR_STEREO(int16);
+    VAR_FILTER_STEREO;
 
-    vl >>= 8;
-    while (count--) { LINEAR_INTERP(); MIX_MONO_AC_FILTER(); UPDATE_POS(); }
-    SAVE_FILTER_MONO();
+    LOOP_AC { LINEAR_INTERP_16BIT(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
+    LOOP    { LINEAR_INTERP_16BIT(); MIX_STEREO_FILTER(); UPDATE_POS(); }
+
+    SAVE_FILTER_STEREO();
 }
 
 #endif
@@ -319,98 +342,98 @@ SMIX_MIXER(smix_mono_16bit_linear_filter)
  * Spline mixers
  */
 
-/* Handler for 8 bit samples, spline interpolated stereo output
+/* Handler for 8 bit samples, spline interpolated mono output
  */
-SMIX_MIXER(smix_stereo_8bit_spline)
+MIXER(mono_8bit_spline)
 {
-    VAR_SPLINE(int8);
+    VAR_SPLINE_MONO(int8);
 
-    while (count--) { SPLINE_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
+    LOOP_AC { SPLINE_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
+    LOOP    { SPLINE_INTERP(); MIX_MONO(); UPDATE_POS(); }
 }
 
-
-/* Handler for 16 bit samples, spline interpolated stereo output
+/* Handler for 16 bit samples, spline interpolated mono output
  */
-SMIX_MIXER(smix_stereo_16bit_spline)
+MIXER(mono_16bit_spline)
 {
-    VAR_SPLINE(int16);
+    VAR_SPLINE_MONO(int16);
 
-    vl >>= 8;
-    vr >>= 8;
-    while (count--) { SPLINE_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
+    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_MONO_AC(); UPDATE_POS(); }
+    LOOP    { SPLINE_INTERP_16BIT(); MIX_MONO(); UPDATE_POS(); }
 }
 
-
-/* Handler for 8 bit samples, spline interpolated mono output
+/* Handler for 8 bit samples, spline interpolated stereo output
  */
-SMIX_MIXER(smix_mono_8bit_spline)
+MIXER(stereo_8bit_spline)
 {
-    VAR_SPLINE(int8);
+    VAR_SPLINE_STEREO(int8);
 
-    while (count--) { SPLINE_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
+    LOOP_AC { SPLINE_INTERP(); MIX_STEREO_AC(); UPDATE_POS(); }
+    LOOP    { SPLINE_INTERP(); MIX_STEREO(); UPDATE_POS(); }
 }
 
-
-/* Handler for 16 bit samples, spline interpolated mono output
+/* Handler for 16 bit samples, spline interpolated stereo output
  */
-SMIX_MIXER(smix_mono_16bit_spline)
+MIXER(stereo_16bit_spline)
 {
-    VAR_SPLINE(int16);
+    VAR_SPLINE_STEREO(int16);
 
-    vl >>= 8;
-    while (count--) { SPLINE_INTERP(); MIX_MONO_AC(); UPDATE_POS(); }
+    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_STEREO_AC(); UPDATE_POS(); }
+    LOOP    { SPLINE_INTERP_16BIT(); MIX_STEREO(); UPDATE_POS(); }
 }
 
 #ifndef LIBXMP_CORE_DISABLE_IT
 
-/* Handler for 8 bit samples, spline interpolated stereo output
+/* Handler for 8 bit samples, filtered spline interpolated mono output
  */
-SMIX_MIXER(smix_stereo_8bit_spline_filter)
+MIXER(mono_8bit_spline_filter)
 {
-    VAR_SPLINE(int8);
-    VAR_FILTER_STEREO;
+    VAR_SPLINE_MONO(int8);
+    VAR_FILTER_MONO;
 
-    while (count--) { SPLINE_INTERP(); MIX_STEREO_AC_FILTER(); UPDATE_POS(); }
-    SAVE_FILTER_STEREO();
-}
+    LOOP_AC { SPLINE_INTERP(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
+    LOOP    { SPLINE_INTERP(); MIX_MONO_FILTER(); UPDATE_POS(); }
 
+    SAVE_FILTER_MONO();
+}
 
-/* Handler for 16 bit samples, spline interpolated stereo output
+/* Handler for 16 bit samples, filtered spline interpolated mono output
  */
-SMIX_MIXER(smix_stereo_16bit_spline_filter)
+MIXER(mono_16bit_spline_filter)
 {
-    VAR_SPLINE(int16);
-    VAR_FILTER_STEREO;
+    VAR_SPLINE_MONO(int16);
+    VAR_FILTER_MONO;
 
-    vl >>= 8;
-    vr >>= 8;
-    while (count--) { SPLINE_INTERP(); MIX_STEREO_AC_FILTER(); UPDATE_POS(); }
-    SAVE_FILTER_STEREO();
-}
+    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_MONO_FILTER_AC(); UPDATE_POS(); }
+    LOOP    { SPLINE_INTERP_16BIT(); MIX_MONO_FILTER(); UPDATE_POS(); }
 
+    SAVE_FILTER_MONO();
+}
 
-/* Handler for 8 bit samples, spline interpolated mono output
+/* Handler for 8 bit samples, filtered spline interpolated stereo output
  */
-SMIX_MIXER(smix_mono_8bit_spline_filter)
+MIXER(stereo_8bit_spline_filter)
 {
-    VAR_SPLINE(int8);
-    VAR_FILTER_MONO;
+    VAR_SPLINE_STEREO(int8);
+    VAR_FILTER_STEREO;
 
-    while (count--) { SPLINE_INTERP(); MIX_MONO_AC_FILTER(); UPDATE_POS(); }
-    SAVE_FILTER_MONO();
-}
+    LOOP_AC { SPLINE_INTERP(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
+    LOOP    { SPLINE_INTERP(); MIX_STEREO_FILTER(); UPDATE_POS(); }
 
+    SAVE_FILTER_STEREO();
+}
 
-/* Handler for 16 bit samples, spline interpolated mono output
+/* Handler for 16 bit samples, filtered spline interpolated stereo output
  */
-SMIX_MIXER(smix_mono_16bit_spline_filter)
+MIXER(stereo_16bit_spline_filter)
 {
-    VAR_SPLINE(int16);
-    VAR_FILTER_MONO;
+    VAR_SPLINE_STEREO(int16);
+    VAR_FILTER_STEREO;
 
-    vl >>= 8;
-    while (count--) { SPLINE_INTERP(); MIX_MONO_AC_FILTER(); UPDATE_POS(); }
-    SAVE_FILTER_MONO();
+    LOOP_AC { SPLINE_INTERP_16BIT(); MIX_STEREO_FILTER_AC(); UPDATE_POS(); }
+    LOOP    { SPLINE_INTERP_16BIT(); MIX_STEREO_FILTER(); UPDATE_POS(); }
+
+    SAVE_FILTER_STEREO();
 }
 
 #endif
diff --git a/src/mix_paula.c b/src/mix_paula.c
new file mode 100644
index 0000000..5b0589a
--- /dev/null
+++ b/src/mix_paula.c
@@ -0,0 +1,162 @@
+#include "common.h"
+
+#ifdef LIBXMP_PAULA_SIMULATOR
+/*
+ * Based on Antti S. Lankila's reference code, modified for libxmp
+ * by Claudio Matsuoka.
+ */
+#include "virtual.h"
+#include "mixer.h"
+#include "paula.h"
+#include "precomp_blep.h"
+
+void libxmp_paula_init(struct context_data *ctx, struct paula_state *paula)
+{
+	struct mixer_data *s = &ctx->s;
+
+	paula->global_output_level = 0;
+	paula->active_bleps = 0;
+	paula->fdiv = (double)PAULA_HZ / s->freq;
+	paula->remainder = paula->fdiv;
+}
+
+/* return output simulated as series of bleps */
+static int16 output_sample(struct paula_state *paula, int tabnum)
+{
+	int i;
+	int32 output;
+
+	output = paula->global_output_level << BLEP_SCALE;
+	for (i = 0; i < paula->active_bleps; i++) {
+		int age = paula->blepstate[i].age;
+		int level = paula->blepstate[i].level;
+		output -= winsinc_integral[tabnum][age] * level;
+	}
+	output >>= BLEP_SCALE;
+
+	if (output < -32768)
+		output = -32768;
+	else if (output > 32767)
+		output = 32767;
+
+	return output;
+}
+
+static void input_sample(struct paula_state *paula, int16 sample)
+{
+	if (sample != paula->global_output_level) {
+		/* Start a new blep: level is the difference, age (or phase) is 0 clocks. */
+		if (paula->active_bleps > MAX_BLEPS - 1) {
+			fprintf(stderr, "warning: active blep list truncated!\n");
+			paula->active_bleps = MAX_BLEPS - 1;
+		}
+
+		/* Make room for new blep */
+		memmove(&paula->blepstate[1], &paula->blepstate[0],
+			sizeof(struct blep_state) * paula->active_bleps);
+
+		/* Update state to account for the new blep */
+		paula->active_bleps++;
+		paula->blepstate[0].age = 0;
+		paula->blepstate[0].level = sample - paula->global_output_level;
+		paula->global_output_level = sample;
+	}
+}
+
+static void do_clock(struct paula_state *paula, unsigned int cycles)
+{
+	int i;
+
+	if (cycles <= 0) {
+		return;
+	}
+
+	for (i = 0; i < paula->active_bleps; i++) {
+		paula->blepstate[i].age += cycles;
+		if (paula->blepstate[i].age >= BLEP_SIZE) {
+			paula->active_bleps = i;
+			break;
+		}
+	}
+}
+
+#define LOOP for (; count; count--)
+
+#define UPDATE_POS(x) do { \
+	frac += (x); \
+	pos += frac >> SMIX_SHIFT; \
+	frac &= SMIX_MASK; \
+} while (0)
+
+#define PAULA_SIMULATION(x) do { \
+	int num_in = vi->paula->remainder / MINIMUM_INTERVAL; \
+	int ministep = step / num_in; \
+	int i; \
+	\
+	/* input is always sampled at a higher rate than output */ \
+	for (i = 0; i < num_in - 1; i++) { \
+		input_sample(vi->paula, sptr[pos]); \
+		do_clock(vi->paula, MINIMUM_INTERVAL); \
+		UPDATE_POS(ministep); \
+	} \
+	input_sample(vi->paula, sptr[pos]); \
+	vi->paula->remainder -= num_in * MINIMUM_INTERVAL; \
+	\
+	do_clock(vi->paula, (int)vi->paula->remainder); \
+	smp_in = output_sample(vi->paula, (x)); \
+	do_clock(vi->paula, MINIMUM_INTERVAL - (int)vi->paula->remainder); \
+	UPDATE_POS(step - (num_in - 1) * ministep); \
+	\
+	vi->paula->remainder += vi->paula->fdiv; \
+} while (0)
+
+#define MIX_MONO() do { \
+	*(buffer++) += smp_in * vl; \
+} while (0)
+
+#define MIX_STEREO() do { \
+	*(buffer++) += smp_in * vr; \
+	*(buffer++) += smp_in * vl; \
+} while (0)
+
+#define VAR_NORM(x) \
+    int smp_in; \
+    x *sptr = vi->sptr; \
+    unsigned int pos = vi->pos; \
+    int frac = (1 << SMIX_SHIFT) * (vi->pos - (int)vi->pos)
+
+#define VAR_PAULA(x) \
+    VAR_NORM(x); \
+    vl <<= 8; \
+    vr <<= 8
+
+
+MIXER(mono_a500)
+{
+	VAR_PAULA(int8);
+
+	LOOP { PAULA_SIMULATION(0); MIX_MONO(); }
+} 
+
+MIXER(mono_a500_filter)
+{
+	VAR_PAULA(int8);
+
+	LOOP { PAULA_SIMULATION(1); MIX_MONO(); }
+} 
+
+MIXER(stereo_a500)
+{
+	VAR_PAULA(int8);
+
+	LOOP { PAULA_SIMULATION(0); MIX_STEREO(); }
+} 
+
+MIXER(stereo_a500_filter)
+{
+	VAR_PAULA(int8);
+
+	LOOP { PAULA_SIMULATION(1); MIX_STEREO(); }
+} 
+
+#endif /* LIBXMP_PAULA_SIMULATOR */
diff --git a/src/mixer.c b/src/mixer.c
index 063db8d..49a2a68 100644
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -22,14 +22,15 @@
 
 #include 
 #include 
-
+#include 
 #include "common.h"
 #include "virtual.h"
 #include "mixer.h"
 #include "period.h"
+#include "player.h"	/* for set_sample_end() */
 
-#ifndef LIBXMP_CORE_PLAYER
-#include "synth.h"
+#ifdef LIBXMP_PAULA_SIMULATOR
+#include "paula.h"
 #endif
 
 
@@ -37,7 +38,7 @@
 #define FLAG_STEREO	0x02
 #define FLAG_FILTER	0x04
 #define FLAG_ACTIVE	0x10
-#define FLAG_SYNTH	0x20
+/* #define FLAG_SYNTH	0x20 */
 #define FIDX_FLAGMASK	(FLAG_16_BITS | FLAG_STEREO | FLAG_FILTER)
 
 #define DOWNMIX_SHIFT	 12
@@ -46,32 +47,38 @@
 #define LIM16_HI	 32767
 #define LIM16_LO	-32768
 
-#define MIX_FN(x) void x (struct mixer_voice *, int *, int, int, int, int)
-
-MIX_FN(smix_mono_8bit_nearest);
-MIX_FN(smix_mono_8bit_linear);
-MIX_FN(smix_mono_16bit_nearest);
-MIX_FN(smix_mono_16bit_linear);
-MIX_FN(smix_stereo_8bit_nearest);
-MIX_FN(smix_stereo_8bit_linear);
-MIX_FN(smix_stereo_16bit_nearest);
-MIX_FN(smix_stereo_16bit_linear);
-MIX_FN(smix_mono_8bit_spline);
-MIX_FN(smix_mono_16bit_spline);
-MIX_FN(smix_stereo_8bit_spline);
-MIX_FN(smix_stereo_16bit_spline);
+#define MIX_FN(x) void libxmp_mix_##x(struct mixer_voice *, int *, int, int, int, int, int, int, int)
+
+MIX_FN(mono_8bit_nearest);
+MIX_FN(mono_8bit_linear);
+MIX_FN(mono_16bit_nearest);
+MIX_FN(mono_16bit_linear);
+MIX_FN(stereo_8bit_nearest);
+MIX_FN(stereo_8bit_linear);
+MIX_FN(stereo_16bit_nearest);
+MIX_FN(stereo_16bit_linear);
+MIX_FN(mono_8bit_spline);
+MIX_FN(mono_16bit_spline);
+MIX_FN(stereo_8bit_spline);
+MIX_FN(stereo_16bit_spline);
 
 #ifndef LIBXMP_CORE_DISABLE_IT
-MIX_FN(smix_mono_8bit_linear_filter);
-MIX_FN(smix_mono_16bit_linear_filter);
-MIX_FN(smix_stereo_8bit_linear_filter);
-MIX_FN(smix_stereo_16bit_linear_filter);
-MIX_FN(smix_mono_8bit_spline_filter);
-MIX_FN(smix_mono_16bit_spline_filter);
-MIX_FN(smix_stereo_8bit_spline_filter);
-MIX_FN(smix_stereo_16bit_spline_filter);
+MIX_FN(mono_8bit_linear_filter);
+MIX_FN(mono_16bit_linear_filter);
+MIX_FN(stereo_8bit_linear_filter);
+MIX_FN(stereo_16bit_linear_filter);
+MIX_FN(mono_8bit_spline_filter);
+MIX_FN(mono_16bit_spline_filter);
+MIX_FN(stereo_8bit_spline_filter);
+MIX_FN(stereo_16bit_spline_filter);
 #endif
 
+#ifdef LIBXMP_PAULA_SIMULATOR
+MIX_FN(mono_a500);
+MIX_FN(mono_a500_filter);
+MIX_FN(stereo_a500);
+MIX_FN(stereo_a500_filter);
+#endif
 
 /* Mixers array index:
  *
@@ -80,51 +87,76 @@ MIX_FN(smix_stereo_16bit_spline_filter);
  * bit 2: 0=unfiltered, 1=filtered
  */
 
-// typedef void (*mixer_set[])();
-typedef void (*mixer_set[])(struct mixer_voice *, int *, int, int, int, int);
+typedef void (*mixer_set[])(struct mixer_voice *, int *, int, int, int, int, int, int, int);
 
 static mixer_set nearest_mixers = {
-	smix_mono_8bit_nearest,
-	smix_mono_16bit_nearest,
-	smix_stereo_8bit_nearest,
-	smix_stereo_16bit_nearest,
+	libxmp_mix_mono_8bit_nearest,
+	libxmp_mix_mono_16bit_nearest,
+	libxmp_mix_stereo_8bit_nearest,
+	libxmp_mix_stereo_16bit_nearest,
 
 #ifndef LIBXMP_CORE_DISABLE_IT
-	smix_mono_8bit_nearest,
-	smix_mono_16bit_nearest,
-	smix_stereo_8bit_nearest,
-	smix_stereo_16bit_nearest,
+	libxmp_mix_mono_8bit_nearest,
+	libxmp_mix_mono_16bit_nearest,
+	libxmp_mix_stereo_8bit_nearest,
+	libxmp_mix_stereo_16bit_nearest,
 #endif
 };
 
 static mixer_set linear_mixers = {
-	smix_mono_8bit_linear,
-	smix_mono_16bit_linear,
-	smix_stereo_8bit_linear,
-	smix_stereo_16bit_linear,
+	libxmp_mix_mono_8bit_linear,
+	libxmp_mix_mono_16bit_linear,
+	libxmp_mix_stereo_8bit_linear,
+	libxmp_mix_stereo_16bit_linear,
 
 #ifndef LIBXMP_CORE_DISABLE_IT
-	smix_mono_8bit_linear_filter,
-	smix_mono_16bit_linear_filter,
-	smix_stereo_8bit_linear_filter,
-	smix_stereo_16bit_linear_filter
+	libxmp_mix_mono_8bit_linear_filter,
+	libxmp_mix_mono_16bit_linear_filter,
+	libxmp_mix_stereo_8bit_linear_filter,
+	libxmp_mix_stereo_16bit_linear_filter
 #endif
 };
 
 static mixer_set spline_mixers = {
-	smix_mono_8bit_spline,
-	smix_mono_16bit_spline,
-	smix_stereo_8bit_spline,
-	smix_stereo_16bit_spline,
+	libxmp_mix_mono_8bit_spline,
+	libxmp_mix_mono_16bit_spline,
+	libxmp_mix_stereo_8bit_spline,
+	libxmp_mix_stereo_16bit_spline,
 
 #ifndef LIBXMP_CORE_DISABLE_IT
-	smix_mono_8bit_spline_filter,
-	smix_mono_16bit_spline_filter,
-	smix_stereo_8bit_spline_filter,
-	smix_stereo_16bit_spline_filter
+	libxmp_mix_mono_8bit_spline_filter,
+	libxmp_mix_mono_16bit_spline_filter,
+	libxmp_mix_stereo_8bit_spline_filter,
+	libxmp_mix_stereo_16bit_spline_filter
 #endif
 };
 
+#ifdef LIBXMP_PAULA_SIMULATOR
+static mixer_set a500_mixers = {
+	libxmp_mix_mono_a500,
+	NULL,
+	libxmp_mix_stereo_a500,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
+static mixer_set a500led_mixers = {
+	libxmp_mix_mono_a500_filter,
+	NULL,
+	libxmp_mix_stereo_a500_filter,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+#endif
+
+
 /* Downmix 32bit samples to 8bit, signed or unsigned, mono or stereo output */
 static void downmix_int_8bit(char *dest, int32 *src, int num, int amp, int offs)
 {
@@ -166,43 +198,25 @@ static void downmix_int_16bit(int16 *dest, int32 *src, int num, int amp, int off
 	}
 }
 
-
-/* Prepare the mixer for the next tick */
-void mixer_prepare(struct context_data *ctx)
+static void anticlick(struct mixer_voice *vi)
 {
-	struct player_data *p = &ctx->p;
-	struct module_data *m = &ctx->m;
-	struct mixer_data *s = &ctx->s;
-	int bytelen;
-
-	s->ticksize = s->freq * m->time_factor * m->rrate / p->bpm / 1000;
-
-	bytelen = s->ticksize * sizeof(int);
-	if (~s->format & XMP_FORMAT_MONO) {
-		bytelen *= 2;
-	}
-	memset(s->buf32, 0, bytelen);
+	vi->flags |= ANTICLICK;
+	vi->old_vl = 0;
+	vi->old_vr = 0;
 }
 
-
-/* Hipolito's rampdown anticlick */
-static void rampdown(struct context_data *ctx, int voc, int32 *buf, int count)
+/* Ok, it's messy, but it works :-) Hipolito */
+static void do_anticlick(struct context_data *ctx, int voc, int32 *buf, int count)
 {
 	struct player_data *p = &ctx->p;
 	struct mixer_data *s = &ctx->s;
-	int smp_l, smp_r;
-	int dec_l, dec_r;
+	struct mixer_voice *vi = &p->virt.voice_array[voc];
+	int smp_l, smp_r, max_x2;
+	int discharge = s->ticksize >> ANTICLICK_SHIFT;
 
-	if (voc < 0) {
-		/* initialize */
-		smp_r = s->dtright;
-		smp_l = s->dtleft;
-	} else {
-		struct mixer_voice *vi = &p->virt.voice_array[voc];
-		smp_r = vi->sright;
-		smp_l = vi->sleft;
-		vi->sright = vi->sleft = 0;
-	}
+	smp_r = vi->sright;
+	smp_l = vi->sleft;
+	vi->sright = vi->sleft = 0;
 
 	if (smp_l == 0 && smp_r == 0) {
 		return;
@@ -210,102 +224,110 @@ static void rampdown(struct context_data *ctx, int voc, int32 *buf, int count)
 
 	if (buf == NULL) {
 		buf = s->buf32;
-		count = SLOW_RELEASE;
+		count = discharge;
+	} else if (count > discharge) {
+		count = discharge;
 	}
 
 	if (count <= 0) {
 		return;
 	}
 
-	dec_r = smp_r / count;
-	dec_l = smp_l / count;
+	max_x2 = count * count;
 
-	while ((smp_r || smp_l) && count--) {
+	while (count--) {
 		if (~s->format & XMP_FORMAT_MONO) {
-			if (dec_r > 0) {
-				if (smp_r > dec_r) {
-					smp_r -= dec_r;
-					*buf += smp_r;
-				} else {
-					smp_r = 0;
-				}
-			} else {
-				if (smp_r < dec_r) {
-					smp_r -= dec_r;
-					*buf += smp_r;
-				} else {
-					smp_r = 0;
-				}
-			}
-			buf++;
+			*buf++ += (count * (smp_r >> 10) / max_x2 * count) << 10;
 		}
 
-		if (dec_l > 0) {
-			if (smp_l > dec_l) {
-				smp_l -= dec_l;
-				*buf += smp_l;
-			} else {
-				smp_l = 0;
-			}
-		} else {
-			if (smp_l < dec_l) {
-				smp_l -= dec_l;
-				*buf += smp_l;
-			} else {
-				smp_l = 0;
-			}
-		}
-		buf++;
+		*buf++ += (count * (smp_l >> 10) / max_x2 * count) << 10;
 	}
 }
 
-
-/* Ok, it's messy, but it works :-) Hipolito */
-static void anticlick(struct context_data *ctx, int voc, int vol, int pan,
-		      int32 *buf, int count)
+static void set_sample_end(struct context_data *ctx, int voc, int end)
 {
-	int oldvol, newvol, pan0;
 	struct player_data *p = &ctx->p;
-	struct mixer_data *s = &ctx->s;
+	struct module_data *m = &ctx->m;
 	struct mixer_voice *vi = &p->virt.voice_array[voc];
+	struct channel_data *xc;
 
-	/* From: Mirko Buffoni 
-	 * To: Claudio Matsuoka 
-	 * Date: Nov 29, 2007 6:45 AM
-	 *  
-	 * Put PAN SEPARATION to 100. Then it crashes. Other modules crash when
-	 * PAN SEPARATION = 100, (...) moving separation one step behind, stop
-	 * crashes.
-	 */
-	pan0 = vi->pan;
-	if (pan0 < -127) {
-		pan0 = -127;
-	}
+	if ((uint32)voc >= p->virt.maxvoc)
+		return;
 
-	if (vi->vol) {
-		oldvol = vi->vol * (0x80 - pan0);
-		newvol = vol * (0x80 - pan);
-		vi->sright -= (int64)vi->sright * newvol / oldvol;
+	xc = &p->xc_data[vi->chn];
 
-		oldvol = vi->vol * (0x80 + pan0);
-		newvol = vol * (0x80 + pan);
-		vi->sleft -= (int64)vi->sleft * newvol / oldvol;
+	if (end) {
+		SET_NOTE(NOTE_SAMPLE_END);
+		if (HAS_QUIRK(QUIRK_RSTCHN)) {
+			libxmp_virt_resetvoice(ctx, voc, 0);
+		}
+	} else {
+		RESET_NOTE(NOTE_SAMPLE_END);
 	}
+}
 
-	if (!buf) {
-		s->dtright += vi->sright;
-		s->dtleft += vi->sleft;
-		vi->sright = vi->sleft = 0;
+static void adjust_voice_end(struct mixer_voice *vi, struct xmp_sample *xxs)
+{
+	if (xxs->flg & XMP_SAMPLE_LOOP) {
+		if ((xxs->flg & XMP_SAMPLE_LOOP_FULL) && (~vi->flags & SAMPLE_LOOP)) {
+			vi->end = xxs->len;
+		} else {
+			vi->end = xxs->lpe;
+		}
 	} else {
-		rampdown(ctx, voc, buf, count);
+		vi->end = xxs->len;
+	}
+}
+
+static void loop_reposition(struct context_data *ctx, struct mixer_voice *vi, struct xmp_sample *xxs)
+{
+#ifndef LIBXMP_CORE_DISABLE_IT
+	struct module_data *m = &ctx->m;
+#endif
+	int loop_size = xxs->lpe - xxs->lps;
+
+	/* Reposition for next loop */
+	vi->pos -= loop_size;		/* forward loop */
+	vi->end = xxs->lpe;
+	vi->flags |= SAMPLE_LOOP;
+
+	if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
+		vi->end += loop_size;	/* unrolled loop */
+		vi->pos -= loop_size;	/* forward loop */
+
+#ifndef LIBXMP_CORE_DISABLE_IT
+		/* OpenMPT Bidi-Loops.it: "In Impulse Tracker’s software mixer,
+		 * ping-pong loops are shortened by one sample. 
+		 */
+		if (IS_PLAYER_MODE_IT()) {
+			vi->end--;
+			vi->pos++;
+		}
+#endif
 	}
 }
 
 
+/* Prepare the mixer for the next tick */
+void libxmp_mixer_prepare(struct context_data *ctx)
+{
+	struct player_data *p = &ctx->p;
+	struct module_data *m = &ctx->m;
+	struct mixer_data *s = &ctx->s;
+	int bytelen;
+
+	s->ticksize = s->freq * m->time_factor * m->rrate / p->bpm / 1000;
+
+	bytelen = s->ticksize * sizeof(int);
+	if (~s->format & XMP_FORMAT_MONO) {
+		bytelen *= 2;
+	}
+	memset(s->buf32, 0, bytelen);
+}
 /* Fill the output buffer calling one of the handlers. The buffer contains
  * sound for one tick (a PAL frame or 1/50s for standard vblank-timed mods)
  */
-void mixer_softmixer(struct context_data *ctx)
+void libxmp_mixer_softmixer(struct context_data *ctx)
 {
 	struct player_data *p = &ctx->p;
 	struct mixer_data *s = &ctx->s;
@@ -313,15 +335,13 @@ void mixer_softmixer(struct context_data *ctx)
 	struct xmp_module *mod = &m->mod;
 	struct xmp_sample *xxs;
 	struct mixer_voice *vi;
+	double step;
 	int samples, size;
-	int vol_l, vol_r, step, voc;
-	int prev_l, prev_r;
+	int vol_l, vol_r, voc, usmp;
+	int prev_l, prev_r = 0;
 	int lps, lpe;
-#ifndef LIBXMP_CORE_PLAYER
-	int synth = 1;
-#endif
 	int32 *buf_pos;
-	void (*mix_fn)(struct mixer_voice *, int *, int, int, int, int);
+	void (*mix_fn)(struct mixer_voice *, int *, int, int, int, int, int, int, int);
 	mixer_set *mixers;
 
 	switch (s->interp) {
@@ -338,49 +358,77 @@ void mixer_softmixer(struct context_data *ctx)
 		mixers = &linear_mixers;
 	}
 
-	mixer_prepare(ctx);
+#ifdef LIBXMP_PAULA_SIMULATOR
+	if (p->flags & XMP_FLAGS_A500) {
+		if (IS_AMIGA_MOD()) {
+			if (p->filter) {
+				mixers = &a500led_mixers;
+			} else {
+				mixers = &a500_mixers;
+			}
+		}
+	}
+#endif
 
-	rampdown(ctx, -1, NULL, 0);	/* Anti-click */
+	libxmp_mixer_prepare(ctx);
 
 	for (voc = 0; voc < p->virt.maxvoc; voc++) {
+		int c5spd;
+
 		vi = &p->virt.voice_array[voc];
 
-		if (vi->chn < 0)
+		if (vi->flags & ANTICLICK) {
+			if (s->interp > XMP_INTERP_NEAREST) {
+				do_anticlick(ctx, voc, NULL, 0);
+			}
+			vi->flags &= ~ANTICLICK;
+		}
+
+		if (vi->chn < 0) {
 			continue;
+		}
 
 		if (vi->period < 1) {
-			virt_resetvoice(ctx, voc, 1);
+			libxmp_virt_resetvoice(ctx, voc, 1);
 			continue;
 		}
 
 		vi->pos0 = vi->pos;
 
 		buf_pos = s->buf32;
-		vol_r = vi->vol * (0x80 - vi->pan);
-		vol_l = vi->vol * (0x80 + vi->pan);
-
-#ifndef LIBXMP_CORE_PLAYER
-		if (vi->fidx & FLAG_SYNTH) {
-			if (synth) {
-				m->synth->mixer(ctx, buf_pos, s->ticksize,
-						vol_l >> 7, vol_r >> 7,
-						vi->fidx & FLAG_STEREO);
-				synth = 0;
-			}
-			continue;
+		if (vi->pan == PAN_SURROUND) {
+			vol_r = vi->vol * 0x80;
+			vol_l = -vi->vol * 0x80;
+		} else {
+			vol_r = vi->vol * (0x80 - vi->pan);
+			vol_l = vi->vol * (0x80 + vi->pan);
 		}
-#endif
 
-		step = ((int64)s->pbase << 24) / vi->period;
+		if (vi->smp < mod->smp) {
+			xxs = &mod->xxs[vi->smp];
+			c5spd = m->xtra[vi->smp].c5spd;
+		} else {
+			xxs = &ctx->smix.xxs[vi->smp - mod->smp];
+			c5spd = m->c4rate;
+		}
+
+		step = C4_PERIOD * c5spd / s->freq / vi->period;
 
-		if (step == 0) {	/* otherwise m5v-nwlf.it crashes */
+		if (step < 0.001) {	/* otherwise m5v-nwlf.it crashes */
 			continue;
 		}
 
-		if (vi->smp < mod->smp)
-			xxs = &mod->xxs[vi->smp];
-		else
-			xxs = &ctx->smix.xxs[vi->smp - mod->smp];
+#ifndef LIBXMP_CORE_DISABLE_IT
+		if (xxs->flg & XMP_SAMPLE_SLOOP && vi->smp < mod->smp) {
+			if (~vi->flags & VOICE_RELEASE) {
+				if (vi->pos < m->xsmp[vi->smp].lpe) {
+					xxs = &m->xsmp[vi->smp];
+				}
+			}
+		}
+
+		adjust_voice_end(vi, xxs);
+#endif
 
 		lps = xxs->lps;
 		lpe = xxs->lpe;
@@ -389,23 +437,47 @@ void mixer_softmixer(struct context_data *ctx)
 			lps >>= 1;
 		}
 
+		if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
+			vi->end += lpe - lps;
+
+#ifndef LIBXMP_CORE_DISABLE_IT
+			if (IS_PLAYER_MODE_IT()) {
+				vi->end--;
+			}
+#endif
+		}
+
+		int rampsize = s->ticksize >> ANTICLICK_SHIFT;
+		int delta_l = (vol_l - vi->old_vl) / rampsize;
+		int delta_r = (vol_r - vi->old_vr) / rampsize;
+
+		usmp = 0;
 		for (size = s->ticksize; size > 0; ) {
+			int split_noloop = 0;
+
+			if (p->xc_data[vi->chn].split) {
+				split_noloop = 1;
+			}
+
 			/* How many samples we can write before the loop break
 			 * or sample end... */
 			if (vi->pos >= vi->end) {
 				samples = 0;
+				usmp = 1;
 			} else {
-				samples = 1 + (((int64)(vi->end - vi->pos) <<
-					SMIX_SHIFT) - vi->frac) / step;
-			}
+				int s = ceil(((double)vi->end - vi->pos) / step);
+				/* ...inside the tick boundaries */
+				if (s > size) {
+					s = size;
+				}
 
-			/* ...inside the tick boundaries */
-			if (samples > size) {
-				samples = size;
+				samples = s;
+				if (samples > 0) {
+					usmp = 0;
+				}
 			}
 
 			if (vi->vol) {
-				int idx;
 				int mix_size = samples;
 				int mixer = vi->fidx & FIDX_FLAGMASK;
 
@@ -414,64 +486,86 @@ void mixer_softmixer(struct context_data *ctx)
 				}
 
 				/* For Hipolito's anticlick routine */
-				idx = mix_size;
-				if (mix_size >= 2) {
-					prev_r = buf_pos[idx - 2];
-					prev_l = buf_pos[idx - 1];
+				if (samples > 0) {
+					if (~s->format & XMP_FORMAT_MONO) {
+						prev_r = buf_pos[mix_size - 2];
+					}
+					prev_l = buf_pos[mix_size - 1];
 				} else {
 					prev_r = prev_l = 0;
 				}
 
 #ifndef LIBXMP_CORE_DISABLE_IT
-				/* "Beautiful Ones" apparently uses 0xfe as
-				 * 'no filter' :\ */
-				if (vi->filter.cutoff >= 0xfe)
+				/* See OpenMPT env-flt-max.it */
+				if (vi->filter.cutoff >= 0xfe &&
+                                    vi->filter.resonance == 0) {
 					mixer &= ~FLAG_FILTER;
+				}
 #endif
 
 				mix_fn = (*mixers)[mixer];
 
 				/* Call the output handler */
-				if (samples >= 0) {
-					mix_fn(vi, buf_pos, samples, vol_l,
-								vol_r, step);
+				if (samples > 0 && vi->sptr != NULL) {
+					int rsize = 0;
+
+					if (rampsize > samples) {
+						rampsize -= samples;
+					} else {
+						rsize = samples - rampsize;
+						rampsize = 0;
+					}
+
+					if (delta_l == 0 && delta_r == 0) {
+						/* no need to ramp */
+						rsize = samples;
+					}
+
+					if (mix_fn != NULL) {
+						mix_fn(vi, buf_pos, samples,
+							vol_l >> 8, vol_r >> 8, step * (1 << SMIX_SHIFT), rsize, delta_l, delta_r);
+					}
+
 					buf_pos += mix_size;
-				}
+					vi->old_vl += samples * delta_l;
+					vi->old_vr += samples * delta_r;
 
-				/* For Hipolito's anticlick routine */
-				idx = 0;
-				if (mix_size >= 2) {
-					vi->sright = buf_pos[idx - 2] - prev_r;
-					vi->sleft = buf_pos[idx - 1] - prev_l;
+
+					/* For Hipolito's anticlick routine */
+					if (~s->format & XMP_FORMAT_MONO) {
+						vi->sright = buf_pos[-2] - prev_r;
+					}
+					vi->sleft = buf_pos[-1] - prev_l;
 				}
 			}
 
-			vi->frac += step * samples;
-			vi->pos += vi->frac >> SMIX_SHIFT;
-			vi->frac &= SMIX_MASK;
+			vi->pos += step * samples;
 
 			/* No more samples in this tick */
-			size -= samples;
-			if (size <= 0)
+			size -= samples + usmp;
+			if (size <= 0) {
+				if (xxs->flg & XMP_SAMPLE_LOOP) {
+					if (vi->pos + step > vi->end) {
+						vi->pos += step;
+						loop_reposition(ctx, vi, xxs);
+					}
+				}
 				continue;
+			}
 
 			/* First sample loop run */
-			if (~xxs->flg & XMP_SAMPLE_LOOP) {
-				anticlick(ctx, voc, 0, 0, buf_pos, size);
-				virt_resetvoice(ctx, voc, 0);
+			if ((~xxs->flg & XMP_SAMPLE_LOOP) || split_noloop) {
+				do_anticlick(ctx, voc, buf_pos, size);
+				set_sample_end(ctx, voc, 1);
 				size = 0;
 				continue;
 			}
 
-			vi->pos -= lpe - lps;	/* forward loop */
-			vi->end = lpe;
-			vi->sample_loop = 1;
-
-			if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
-				vi->end += lpe - lps;
-				vi->pos -= lpe - lps;	/* forward loop */
-			}
+			loop_reposition(ctx, vi, xxs);
 		}
+
+		vi->old_vl = vol_l;
+		vi->old_vr = vol_r;
 	}
 
 	/* Render final frame */
@@ -496,7 +590,7 @@ void mixer_softmixer(struct context_data *ctx)
 	s->dtright = s->dtleft = 0;
 }
 
-void mixer_voicepos(struct context_data *ctx, int voc, int pos, int frac)
+void libxmp_mixer_voicepos(struct context_data *ctx, int voc, double pos, int ac)
 {
 	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
@@ -514,23 +608,18 @@ void mixer_voicepos(struct context_data *ctx, int voc, int pos, int frac)
 		return;
 	}
 
-	if (xxs->flg & XMP_SAMPLE_LOOP) {
-		if ((xxs->flg & XMP_SAMPLE_LOOP_FULL) && vi->sample_loop == 0) {
-			vi->end = xxs->len;
+	vi->pos = pos;
+
+	adjust_voice_end(vi, xxs);
+
+	if (vi->pos >= vi->end) {
+		if (xxs->flg & XMP_SAMPLE_LOOP) {
+			vi->pos = xxs->lps;
 		} else {
-			vi->end = xxs->lpe;
+			vi->pos = xxs->len;
 		}
-	} else {
-		vi->end = xxs->len;
 	}
 
-	if (pos >= vi->end) {		/* Happens often in MED synth */
-		pos = 0;
-	}
-
-	vi->pos = pos;
-	vi->frac = frac;
-
 	lps = xxs->lps;
 	if (p->flags & XMP_FLAGS_FIXLOOP) {
 		lps >>= 1;
@@ -538,18 +627,26 @@ void mixer_voicepos(struct context_data *ctx, int voc, int pos, int frac)
 
 	if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
 		vi->end += (xxs->lpe - lps);
+
+#ifndef LIBXMP_CORE_DISABLE_IT
+		if (IS_PLAYER_MODE_IT()) {
+			vi->end--;
+		}
+#endif
 	}
 
-	vi->attack = SLOW_ATTACK;
+	if (ac) {
+		anticlick(vi);
+	}
 }
 
-int mixer_getvoicepos(struct context_data *ctx, int voc)
+double libxmp_mixer_getvoicepos(struct context_data *ctx, int voc)
 {
 	struct player_data *p = &ctx->p;
 	struct mixer_voice *vi = &p->virt.voice_array[voc];
 	struct xmp_sample *xxs;
 
-	xxs = get_sample(ctx, vi->smp);
+	xxs = libxmp_get_sample(ctx, vi->smp);
 
 	if (xxs->flg & XMP_SAMPLE_SYNTH) {
 		return 0;
@@ -564,7 +661,7 @@ int mixer_getvoicepos(struct context_data *ctx, int voc)
 	return vi->pos;
 }
 
-void mixer_setpatch(struct context_data *ctx, int voc, int smp)
+void libxmp_mixer_setpatch(struct context_data *ctx, int voc, int smp, int ac)
 {
 	struct player_data *p = &ctx->p;
 #ifndef LIBXMP_CORE_DISABLE_IT
@@ -574,12 +671,12 @@ void mixer_setpatch(struct context_data *ctx, int voc, int smp)
 	struct mixer_voice *vi = &p->virt.voice_array[voc];
 	struct xmp_sample *xxs;
 
-	xxs = get_sample(ctx, smp);
+	xxs = libxmp_get_sample(ctx, smp);
 
 	vi->smp = smp;
 	vi->vol = 0;
 	vi->pan = 0;
-	vi->sample_loop = 0;
+	vi->flags &= ~SAMPLE_LOOP;
 
 	vi->fidx = 0;
 
@@ -587,15 +684,9 @@ void mixer_setpatch(struct context_data *ctx, int voc, int smp)
 		vi->fidx |= FLAG_STEREO;
 	}
 
-#ifndef LIBXMP_CORE_PLAYER
-	if (xxs->flg & XMP_SAMPLE_SYNTH) {
-		vi->fidx |= FLAG_SYNTH;
-		m->synth->setpatch(ctx, voc, xxs->data);
-		return;
-	}
-#endif
+	set_sample_end(ctx, voc, 0);
 
-	mixer_setvol(ctx, voc, 0);
+	/*mixer_setvol(ctx, voc, 0);*/
 
 	vi->sptr = xxs->data;
 	vi->fidx |= FLAG_ACTIVE;
@@ -610,58 +701,60 @@ void mixer_setpatch(struct context_data *ctx, int voc, int smp)
 		vi->fidx |= FLAG_16_BITS;
 	}
 
-	mixer_voicepos(ctx, voc, 0, 0);
+	libxmp_mixer_voicepos(ctx, voc, 0, ac);
 }
 
-void mixer_setnote(struct context_data *ctx, int voc, int note)
+void libxmp_mixer_setnote(struct context_data *ctx, int voc, int note)
 {
 	struct player_data *p = &ctx->p;
 	struct mixer_voice *vi = &p->virt.voice_array[voc];
 
+	/* FIXME: Workaround for crash on notes that are too high
+	 *        see 6nations.it (+114 transposition on instrument 16)
+	 */
+	if (note > 149) {
+		note = 149;
+	}
+
 	vi->note = note;
-	vi->period = note_to_period_mix(note, 0);
-	vi->attack = SLOW_ATTACK;
+	vi->period = libxmp_note_to_period_mix(note, 0);
+
+	anticlick(vi);
 }
 
-void mixer_setbend(struct context_data *ctx, int voc, int bend)
+void libxmp_mixer_setperiod(struct context_data *ctx, int voc, double period)
 {
 	struct player_data *p = &ctx->p;
 	struct mixer_voice *vi = &p->virt.voice_array[voc];
-#ifndef LIBXMP_CORE_PLAYER
-	struct module_data *m = &ctx->m;
-#endif
-
-	vi->period = note_to_period_mix(vi->note, bend);
 
-#ifndef LIBXMP_CORE_PLAYER
-	if (vi->fidx & FLAG_SYNTH) {
-		m->synth->setnote(ctx, voc, vi->note, bend >> 7);
-	}
-#endif
+	vi->period = period;
 }
 
-void mixer_setvol(struct context_data *ctx, int voc, int vol)
+void libxmp_mixer_setvol(struct context_data *ctx, int voc, int vol)
 {
 	struct player_data *p = &ctx->p;
-	struct mixer_data *s = &ctx->s;
 	struct mixer_voice *vi = &p->virt.voice_array[voc];
-#ifndef LIBXMP_CORE_PLAYER
-	struct module_data *m = &ctx->m;
-#endif
 
-	if (s->interp > XMP_INTERP_NEAREST)
-		anticlick(ctx, voc, vol, vi->pan, NULL, 0);
+	if (vol == 0) {
+		anticlick(vi);
+	}
 
 	vi->vol = vol;
+}
 
-#ifndef LIBXMP_CORE_PLAYER
-	if (vi->fidx & FLAG_SYNTH) {
-		m->synth->setvol(ctx, voc, vol >> 4);
+void libxmp_mixer_release(struct context_data *ctx, int voc, int rel)
+{
+	struct player_data *p = &ctx->p;
+	struct mixer_voice *vi = &p->virt.voice_array[voc];
+
+	if (rel) {
+		vi->flags |= VOICE_RELEASE;
+	} else {
+		vi->flags &= ~VOICE_RELEASE;
 	}
-#endif
 }
 
-void mixer_seteffect(struct context_data *ctx, int voc, int type, int val)
+void libxmp_mixer_seteffect(struct context_data *ctx, int voc, int type, int val)
 {
 #ifndef LIBXMP_CORE_DISABLE_IT
 	struct player_data *p = &ctx->p;
@@ -687,7 +780,7 @@ void mixer_seteffect(struct context_data *ctx, int voc, int type, int val)
 #endif
 }
 
-void mixer_setpan(struct context_data *ctx, int voc, int pan)
+void libxmp_mixer_setpan(struct context_data *ctx, int voc, int pan)
 {
 	struct player_data *p = &ctx->p;
 	struct mixer_voice *vi = &p->virt.voice_array[voc];
@@ -695,7 +788,7 @@ void mixer_setpan(struct context_data *ctx, int voc, int pan)
 	vi->pan = pan;
 }
 
-int mixer_numvoices(struct context_data *ctx, int num)
+int libxmp_mixer_numvoices(struct context_data *ctx, int num)
 {
 	struct mixer_data *s = &ctx->s;
 
@@ -706,7 +799,7 @@ int mixer_numvoices(struct context_data *ctx, int num)
 	}
 }
 
-int mixer_on(struct context_data *ctx, int rate, int format, int c4rate)
+int libxmp_mixer_on(struct context_data *ctx, int rate, int format, int c4rate)
 {
 	struct mixer_data *s = &ctx->s;
 
@@ -722,10 +815,10 @@ int mixer_on(struct context_data *ctx, int rate, int format, int c4rate)
 	s->format = format;
 	s->amplify = DEFAULT_AMPLIFY;
 	s->mix = DEFAULT_MIX;
-	s->pbase = SMIX_C4NOTE * c4rate / s->freq;
+	/* s->pbase = C4_PERIOD * c4rate / s->freq; */
 	s->interp = XMP_INTERP_LINEAR;	/* default interpolation type */
 	s->dsp = XMP_DSP_LOWPASS;	/* enable filters by default */
-	s->numvoc = SMIX_NUMVOC;
+	/* s->numvoc = SMIX_NUMVOC; */
 	s->dtright = s->dtleft = 0;
 
 	return 0;
@@ -736,7 +829,7 @@ int mixer_on(struct context_data *ctx, int rate, int format, int c4rate)
 	return -1;
 }
 
-void mixer_off(struct context_data *ctx)
+void libxmp_mixer_off(struct context_data *ctx)
 {
 	struct mixer_data *s = &ctx->s;
 
diff --git a/src/mixer.h b/src/mixer.h
index 8cfa3bf..5ed3b97 100644
--- a/src/mixer.h
+++ b/src/mixer.h
@@ -1,40 +1,51 @@
 #ifndef LIBXMP_MIXER_H
 #define LIBXMP_MIXER_H
 
-#define SMIX_C4NOTE	6864
+#define C4_PERIOD	428.0
 
 #define SMIX_NUMVOC	128	/* default number of softmixer voices */
 #define SMIX_SHIFT	16
 #define SMIX_MASK	0xffff
 
 #define FILTER_SHIFT	16
+#define ANTICLICK_SHIFT	3
 
-/* Anticlick ramps */
-#define SLOW_ATTACK_SHIFT 4
-#define SLOW_ATTACK	(1 << SLOW_ATTACK_SHIFT)
-#define SLOW_RELEASE	16
+#ifdef LIBXMP_PAULA_SIMULATOR
+#include "paula.h"
+#endif
 
+#define MIXER(f) void libxmp_mix_##f(struct mixer_voice *vi, int *buffer, \
+	int count, int vl, int vr, int step, int ramp, int delta_l, int delta_r)
 
 struct mixer_voice {
 	int chn;		/* channel number */
 	int root;		/* */
-	unsigned int age;	/* */
 	int note;		/* */
+#define PAN_SURROUND 0x8000
 	int pan;		/* */
 	int vol;		/* */
-	int period;		/* current period */
-	unsigned int pos;	/* position in sample */
+	double period;		/* current period */
+	double pos;		/* position in sample */
 	int pos0;		/* position in sample before mixing */
-	int frac;		/* interpolation */
-	int fidx;		/* function index */
+	int fidx;		/* mixer function index */
 	int ins;		/* instrument number */
 	int smp;		/* sample number */
 	int end;		/* loop end */
 	int act;		/* nna info & status of voice */
+	int old_vl;		/* previous volume, left channel */
+	int old_vr;		/* previous volume, right channel */
 	int sleft;		/* last left sample output, in 32bit */
 	int sright;		/* last right sample output, in 32bit */
+#define VOICE_RELEASE	(1 << 0)
+#define ANTICLICK	(1 << 1)	
+#define SAMPLE_LOOP	(1 << 2)
+	int flags;		/* flags */
 	void *sptr;		/* sample pointer */
+#ifdef LIBXMP_PAULA_SIMULATOR
+	struct paula_state *paula; /* paula simulation state */
+#endif
 
+#ifndef LIBXMP_CORE_DISABLE_IT
 	struct {
 		int r1;		/* filter variables */
 		int r2;
@@ -46,23 +57,22 @@ struct mixer_voice {
 		int cutoff;
 		int resonance;
 	} filter;
-
-	int attack;		/* ramp up anticlick */
-	int sample_loop;	/* set if sample has looped */
+#endif
 };
 
-int	mixer_on		(struct context_data *, int, int, int);
-void	mixer_off		(struct context_data *);
-void    mixer_setvol		(struct context_data *, int, int);
-void    mixer_seteffect		(struct context_data *, int, int, int);
-void    mixer_setpan		(struct context_data *, int, int);
-int	mixer_numvoices		(struct context_data *, int);
-void	mixer_softmixer		(struct context_data *);
-void	mixer_reset		(struct context_data *);
-void	mixer_setpatch		(struct context_data *, int, int);
-void	mixer_voicepos		(struct context_data *, int, int, int);
-int	mixer_getvoicepos	(struct context_data *, int);
-void	mixer_setnote		(struct context_data *, int, int);
-void	mixer_setbend		(struct context_data *, int, int);
+int	libxmp_mixer_on		(struct context_data *, int, int, int);
+void	libxmp_mixer_off	(struct context_data *);
+void    libxmp_mixer_setvol	(struct context_data *, int, int);
+void    libxmp_mixer_seteffect	(struct context_data *, int, int, int);
+void    libxmp_mixer_setpan	(struct context_data *, int, int);
+int	libxmp_mixer_numvoices	(struct context_data *, int);
+void	libxmp_mixer_softmixer	(struct context_data *);
+void	libxmp_mixer_reset	(struct context_data *);
+void	libxmp_mixer_setpatch	(struct context_data *, int, int, int);
+void	libxmp_mixer_voicepos	(struct context_data *, int, double, int);
+double	libxmp_mixer_getvoicepos(struct context_data *, int);
+void	libxmp_mixer_setnote	(struct context_data *, int, int);
+void	libxmp_mixer_setperiod	(struct context_data *, int, double);
+void	libxmp_mixer_release	(struct context_data *, int, int);
 
 #endif /* LIBXMP_MIXER_H */
diff --git a/src/mkstemp.c b/src/mkstemp.c
index 0e0816d..730074e 100644
--- a/src/mkstemp.c
+++ b/src/mkstemp.c
@@ -4,129 +4,87 @@
 
 #ifndef HAVE_MKSTEMP
 
-/* Copyright (C) 1991, 1992, 1996, 1998, 2001 Free Software Foundation, Inc.
-   This file is derived from mkstemps.c from the GNU Libiberty Library
-   which in turn is derived from the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA. 
-
-*/
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Hgskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
-#include 
 #include 
-#include 
-#include 
-#include 
 #include 
-#include 
+#include 
+#include 
 
 #ifdef _MSC_VER
 #include 
 #define getpid _getpid
+#define open _open
+typedef int pid_t;
 #endif
 
 #ifndef O_BINARY
 #define O_BINARY 0
 #endif
 
-#ifdef _MSC_VER
-#define open _open
-#endif
-
-/* We need to provide a type for gcc_uint64_t.  */
-#ifdef __GNUC__
-typedef unsigned long long gcc_uint64_t;
-#else
-typedef unsigned long gcc_uint64_t;
-#endif
-
-#ifndef TMP_MAX
-#define TMP_MAX 16384
-#endif
-
-/* Generate a unique temporary file name from TEMPLATE.
- *
- * TEMPLATE has the form:
- *
- * /ccXXXXXX
- *
- * The last six characters of TEMPLATE must be "XXXXXX"; they are
- * replaced with a string that makes the filename unique.
- *
- * Returns a file descriptor open on the file for reading and writing.
- */
 int mkstemp(char *template)
 {
-	static const char letters[]
-	    = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-	static gcc_uint64_t value;
-#ifdef HAVE_GETTIMEOFDAY
-	struct timeval tv;
-#endif
-	char *XXXXXX;
-	size_t len;
-	int count;
+	int start, i;
+	pid_t val;
 
-	len = strlen(template);
+	val = getpid();
+	start = strlen(template) - 1;
 
-	if ((int)len < 6 || strncmp(&template[len - 6], "XXXXXX", 6)) {
-		return -1;
+	while (template[start] == 'X') {
+		template[start] = '0' + val % 10;
+		val /= 10;
+		start--;
 	}
 
-	XXXXXX = &template[len - 6];
-
-#ifdef HAVE_GETTIMEOFDAY
-	/* Get some more or less random data.  */
-	gettimeofday(&tv, NULL);
-	value += ((gcc_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid();
-#else
-	value += getpid();
-#endif
-
-	for (count = 0; count < TMP_MAX; ++count) {
-		gcc_uint64_t v = value;
+	do {
 		int fd;
-
-		/* Fill in the random bits.  */
-		XXXXXX[0] = letters[v % 62];
-		v /= 62;
-		XXXXXX[1] = letters[v % 62];
-		v /= 62;
-		XXXXXX[2] = letters[v % 62];
-		v /= 62;
-		XXXXXX[3] = letters[v % 62];
-		v /= 62;
-		XXXXXX[4] = letters[v % 62];
-		v /= 62;
-		XXXXXX[5] = letters[v % 62];
-
 		fd = open(template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
-		if (fd >= 0)
-			/* The file does not exist.  */
+		if (fd >= 0 || errno != EEXIST)
 			return fd;
-
-		/* This is a random value.  It is only necessary that the next
-		   TMP_MAX values generated by adding 7777 to VALUE are different
-		   with (module 2^32).  */
-		value += 7777;
-	}
-
-	/* We return the null string if we can't find a unique file name.  */
-	template[0] = '\0';
-	return -1;
+		i = start + 1;
+		do {
+			if (template[i] == 0)
+				return -1;
+			template[i]++;
+			if (template[i] == '9' + 1)
+				template[i] = 'a';
+			if (template[i] <= 'z')
+				break;
+			template[i] = 'a';
+			i++;
+		} while (1);
+	} while (1);
 }
 
-#endif /* HAVE_MKSTEMP */
+#endif
diff --git a/src/paula.h b/src/paula.h
new file mode 100644
index 0000000..8f3f381
--- /dev/null
+++ b/src/paula.h
@@ -0,0 +1,37 @@
+#ifndef LIBXMP_PAULA_H
+#define LIBXMP_PAULA_H
+
+/* 131072 to 0, 2048 entries */
+#define PAULA_HZ 3546895
+#define MINIMUM_INTERVAL 16
+#define BLEP_SCALE 17
+#define BLEP_SIZE 2048
+#define MAX_BLEPS (BLEP_SIZE / MINIMUM_INTERVAL)
+
+/* the structure that holds data of bleps */
+struct blep_state {
+	int16 level;
+	int16 age;
+};
+
+struct paula_state {
+	/* the instantenous value of Paula output */
+	int16 global_output_level;
+
+	/* count of simultaneous bleps to keep track of */
+	unsigned int active_bleps;
+
+	/* place to keep our bleps in. MAX_BLEPS should be
+	 * defined as a BLEP_SIZE / MINIMUM_EVENT_INTERVAL.
+	 * For Paula, minimum event interval could be even 1, but it makes
+	 * sense to limit it to some higher value such as 16. */
+	struct blep_state blepstate[MAX_BLEPS];
+
+	double remainder;
+	double fdiv;
+};
+
+
+void	libxmp_paula_init	(struct context_data *, struct paula_state *);
+
+#endif /* !LIBXMP_PAULA_H */
diff --git a/src/period.c b/src/period.c
index 0080934..a1cbdb4 100644
--- a/src/period.c
+++ b/src/period.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -27,111 +27,234 @@
 
 #include 
 
-/* Amiga periods */
-static const int period_amiga[] = {
-   /*  0       1       2       3       4       5       6       7   */
-    0x1c56, 0x1c22, 0x1bee, 0x1bbb, 0x1b87, 0x1b55, 0x1b22, 0x1af0,  /* B  */
-    0x1abf, 0x1a8e, 0x1a5d, 0x1a2c, 0x19fc, 0x19cc, 0x199c, 0x196d,  /* C  */
-    0x193e, 0x1910, 0x18e2, 0x18b4, 0x1886, 0x1859, 0x182c, 0x1800,  /* C# */
-    0x17d4, 0x17a8, 0x177c, 0x1751, 0x1726, 0x16fb, 0x16d1, 0x16a7,  /* D  */
-    0x167d, 0x1654, 0x162b, 0x1602, 0x15d9, 0x15b1, 0x1589, 0x1562,  /* D# */
-    0x153a, 0x1513, 0x14ec, 0x14c6, 0x149f, 0x1479, 0x1454, 0x142e,  /* E  */
-    0x1409, 0x13e4, 0x13c0, 0x139b, 0x1377, 0x1353, 0x1330, 0x130c,  /* F  */
-    0x12e9, 0x12c6, 0x12a4, 0x1282, 0x125f, 0x123e, 0x121c, 0x11fb,  /* F# */
-    0x11da, 0x11b9, 0x1198, 0x1178, 0x1157, 0x1137, 0x1118, 0x10f8,  /* G  */
-    0x10d9, 0x10ba, 0x109b, 0x107d, 0x105e, 0x1040, 0x1022, 0x1004,  /* G# */
-    0x0fe7, 0x0fca, 0x0fad, 0x0f90, 0x0f73, 0x0f57, 0x0f3a, 0x0f1e,  /* A  */
-    0x0f02, 0x0ee7, 0x0ecb, 0x0eb0, 0x0e95, 0x0e7a, 0x0e5f, 0x0e45,  /* A# */
-    0x0e2b, 0x0e11, 0x0df7, 0x0ddd, 0x0dc3, 0x0daa, 0x0d91, 0x0d78,  /* B  */
+#ifdef LIBXMP_PAULA_SIMULATOR
+/*
+ * Period table from the Protracker V2.1A play routine
+ */
+static uint16 pt_period_table[16][36] = {
+	/* Tuning 0, Normal */
+	{
+		856,808,762,720,678,640,604,570,538,508,480,453,
+		428,404,381,360,339,320,302,285,269,254,240,226,
+		214,202,190,180,170,160,151,143,135,127,120,113
+	},
+	/* Tuning 1 */
+	{
+		850,802,757,715,674,637,601,567,535,505,477,450,
+		425,401,379,357,337,318,300,284,268,253,239,225,
+		213,201,189,179,169,159,150,142,134,126,119,113
+	},
+	/* Tuning 2 */
+	{
+		844,796,752,709,670,632,597,563,532,502,474,447,
+		422,398,376,355,335,316,298,282,266,251,237,224,
+		211,199,188,177,167,158,149,141,133,125,118,112
+	},
+	/* Tuning 3 */
+	{
+		838,791,746,704,665,628,592,559,528,498,470,444,
+		419,395,373,352,332,314,296,280,264,249,235,222,
+		209,198,187,176,166,157,148,140,132,125,118,111
+	},
+	/* Tuning 4 */
+	{
+		832,785,741,699,660,623,588,555,524,495,467,441,
+		416,392,370,350,330,312,294,278,262,247,233,220,
+		208,196,185,175,165,156,147,139,131,124,117,110
+	},
+	/* Tuning 5 */
+	{
+		826,779,736,694,655,619,584,551,520,491,463,437,
+		413,390,368,347,328,309,292,276,260,245,232,219,
+		206,195,184,174,164,155,146,138,130,123,116,109
+	},
+	/* Tuning 6 */
+	{
+		820,774,730,689,651,614,580,547,516,487,460,434,
+		410,387,365,345,325,307,290,274,258,244,230,217,
+		205,193,183,172,163,154,145,137,129,122,115,109
+	},
+	/* Tuning 7 */
+	{
+		814,768,725,684,646,610,575,543,513,484,457,431,
+		407,384,363,342,323,305,288,272,256,242,228,216,
+		204,192,181,171,161,152,144,136,128,121,114,108
+	},
+	/* Tuning -8 */
+	{
+		907,856,808,762,720,678,640,604,570,538,508,480,
+		453,428,404,381,360,339,320,302,285,269,254,240,
+		226,214,202,190,180,170,160,151,143,135,127,120
+	},
+	/* Tuning -7 */
+	{
+		900,850,802,757,715,675,636,601,567,535,505,477,
+		450,425,401,379,357,337,318,300,284,268,253,238,
+		225,212,200,189,179,169,159,150,142,134,126,119
+	},
+	/* Tuning -6 */
+	{
+		894,844,796,752,709,670,632,597,563,532,502,474,
+		447,422,398,376,355,335,316,298,282,266,251,237,
+		223,211,199,188,177,167,158,149,141,133,125,118
+	},
+	/* Tuning -5 */
+	{
+		887,838,791,746,704,665,628,592,559,528,498,470,
+		444,419,395,373,352,332,314,296,280,264,249,235,
+		222,209,198,187,176,166,157,148,140,132,125,118
+	},
+	/* Tuning -4 */
+	{
+		881,832,785,741,699,660,623,588,555,524,494,467,
+		441,416,392,370,350,330,312,294,278,262,247,233,
+		220,208,196,185,175,165,156,147,139,131,123,117
+	},
+	/* Tuning -3 */
+	{
+		875,826,779,736,694,655,619,584,551,520,491,463,
+		437,413,390,368,347,328,309,292,276,260,245,232,
+		219,206,195,184,174,164,155,146,138,130,123,116
+	},
+	/* Tuning -2 */
+	{
+		868,820,774,730,689,651,614,580,547,516,487,460,
+		434,410,387,365,345,325,307,290,274,258,244,230,
+		217,205,193,183,172,163,154,145,137,129,122,115
+	},
+	/* Tuning -1 */
+	{
+		862,814,768,725,684,646,610,575,543,513,484,457,
+		431,407,384,363,342,323,305,288,272,256,242,228,
+		216,203,192,181,171,161,152,144,136,128,121,114
+	}
 };
+#endif
 
 #ifdef _MSC_VER
 static inline double round(double val)
-{    
+{
 	return floor(val + 0.5);
 }
 #endif
 
+#ifdef LIBXMP_PAULA_SIMULATOR
+/* Get period from note using Protracker tuning */
+static inline int libxmp_note_to_period_pt(int n, int f)
+{
+	if (n < MIN_NOTE_MOD || n > MAX_NOTE_MOD) {
+		return -1;
+	}
+
+	n -= 48;
+	f >>= 4;
+	if (f < -8 || f > 7) {
+		return 0;
+	}
+
+	if (f < 0) {
+		f += 16;
+	}
+
+	return (int)pt_period_table[f][n];
+}
+#endif
+
 /* Get period from note */
-inline double note_to_period(int n, int f, int type, double adj)
+double libxmp_note_to_period(struct context_data *ctx, int n, int f, double adj)
 {
-    double d = (double)n + (double)f / 128;
-    double per;
+	double d, per;
+	struct module_data *m = &ctx->m;
+#ifdef LIBXMP_PAULA_SIMULATOR
+	struct player_data *p = &ctx->p;
 
-    per = type ?
-	(240.0 - d) * 16 :			/* Linear */
-        13694.0 / pow(2, d / 12);		/* Amiga */
+	/* If mod replayer, modrng and Amiga mixing are active */
+	if (p->flags & XMP_FLAGS_A500) {
+		if (IS_AMIGA_MOD()) {
+			return libxmp_note_to_period_pt(n, f);
+		}
+	}
+#endif
+
+	d = (double)n + (double)f / 128;
+
+	switch (m->period_type) {
+	case PERIOD_LINEAR:
+		per = (240.0 - d) * 16;			/* Linear */
+		break;
+	case PERIOD_CSPD:
+		per = 8363.0 * pow(2, n / 12) / 32 + f;	/* Hz */
+		break;
+	default:
+		per = PERIOD_BASE / pow(2, d / 12);	/* Amiga */
+	}
 
 #ifndef LIBXMP_CORE_PLAYER
-    if (adj > 0.1)
-	per *= adj;
+	if (adj > 0.1) {
+		per *= adj;
+	}
 #endif
 
-    return per;
+	return per;
 }
 
-
 /* For the software mixer */
-int note_to_period_mix(int n, int b)
+double libxmp_note_to_period_mix(int n, int b)
 {
-    double d = (double)n + (double)b / 12800;
-    return (int)(8192.0 * XMP_PERIOD_BASE / pow(2, d / 12));
+	double d = (double)n + (double)b / 12800;
+	return PERIOD_BASE / pow(2, d / 12);
 }
 
-
-/* Get note from period using the Amiga frequency table */
+/* Get note from period */
 /* This function is used only by the MOD loader */
-int period_to_note(int p)
+int libxmp_period_to_note(int p)
 {
-    int n, f;
-    const int *t = period_amiga + MAX_NOTE;
-
-    if (!p)
-	return 0;
-    for (n = 12 + NOTE_Bb0; p <= (MAX_PERIOD / 2); n += 12, p <<= 1);
-    for (; p > *t; t -= 8, n--);
-    for (f = 7; f && (*t > p); t++, f--);
-    return n - (f >> 2);
-}
+	if (p <= 0) {
+		return 0;
+	}
 
+	return round(12.0 * log(PERIOD_BASE / p) / M_LN2) + 1;
+}
 
 /* Get pitchbend from base note and amiga period */
-int period_to_bend(double p, int n, int gliss, int type, double adj)
+int libxmp_period_to_bend(struct context_data *ctx, double p, int n, double adj)
 {
-    int b;
-    double d;
-
-    if (n == 0)
-	return 0;
+	struct module_data *m = &ctx->m;
+	double d;
 
-    if (type) {
-    	b = 100 * (8 * (((240 - n) << 4) - p));	/* Linear */
-    	return gliss ? b / 12800 * 12800 : b;
-    }
+	if (n == 0) {
+		return 0;
+	}
 
-    d = note_to_period(n, 0, 0, adj);
-    b = round(100.0 * ((1536.0 * log(d / p) / M_LN2)));
-
-    return gliss ? b / 12800 * 12800 : b;	/* Amiga */
+	switch (m->period_type) {
+	case PERIOD_LINEAR:
+		return 100 * (8 * (((240 - n) << 4) - p));
+	case PERIOD_CSPD:
+		d = libxmp_note_to_period(ctx, n, 0, adj);
+		return round(100.0 * (1536.0 / M_LN2) * log(p / d));
+	default:
+		/* Amiga */
+		d = libxmp_note_to_period(ctx, n, 0, adj);
+		return round(100.0 * (1536.0 / M_LN2) * log(d / p));
+	}
 }
 
-
 /* Convert finetune = 1200 * log2(C2SPD/8363))
  *
  *      c = (1200.0 * log(c2spd) - 1200.0 * log(c4_rate)) / M_LN2;
  *      xpo = c/100;
  *      fin = 128 * (c%100) / 100;
  */
-void c2spd_to_note(int c2spd, int *n, int *f)
+void libxmp_c2spd_to_note(int c2spd, int *n, int *f)
 {
-    int c;
+	int c;
 
-    if (c2spd == 0) {
-	*n = *f = 0;
-	return;
-    }
+	if (c2spd == 0) {
+		*n = *f = 0;
+		return;
+	}
 
-    c = (int)(1536.0 * log((double)c2spd / 8363) / M_LN2);
-    *n = c / 128;
-    *f = c % 128;
+	c = (int)(1536.0 * log((double)c2spd / 8363) / M_LN2);
+	*n = c / 128;
+	*f = c % 128;
 }
diff --git a/src/period.h b/src/period.h
index 11f0ef1..10a8c67 100644
--- a/src/period.h
+++ b/src/period.h
@@ -1,6 +1,8 @@
 #ifndef LIBXMP_PERIOD_H
 #define LIBXMP_PERIOD_H
 
+#define PERIOD_BASE	13696.0		/* C0 period */
+
 /* Macros for period conversion */
 #define NOTE_B0		11
 #define NOTE_Bb0	(NOTE_B0 + 1)
@@ -10,11 +12,13 @@
 #define MAX_PERIOD_A	0x0358
 #define MIN_PERIOD_L	0x0000
 #define MAX_PERIOD_L	0x1e00
+#define MIN_NOTE_MOD	48
+#define MAX_NOTE_MOD	83
 
-double	note_to_period		(int, int, int, double);
-int	note_to_period_mix	(int, int);
-int	period_to_note		(int);
-int	period_to_bend		(double, int, int, int, double);
-void	c2spd_to_note		(int, int *, int *);
+double	libxmp_note_to_period	(struct context_data *, int, int, double);
+double	libxmp_note_to_period_mix (int, int);
+int	libxmp_period_to_note	(int);
+int	libxmp_period_to_bend	(struct context_data *, double, int, double);
+void	libxmp_c2spd_to_note	(int, int *, int *);
 
 #endif /* LIBXMP_PERIOD_H */
diff --git a/src/player.c b/src/player.c
index e3f1755..e2e7f81 100644
--- a/src/player.c
+++ b/src/player.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -45,7 +45,6 @@
 #include "player.h"
 #include "mixer.h"
 #ifndef LIBXMP_CORE_PLAYER
-#include "synth.h"
 #include "extras.h"
 #endif
 
@@ -59,7 +58,6 @@ static const struct retrig_control rval[] = {
 	
 };
 
-static const struct xmp_event empty_event = { 0, 0, 0, 0, 0, 0, 0 };
 
 /*
  * "Anyway I think this is the most brilliant piece of crap we
@@ -68,6 +66,193 @@ static const struct xmp_event empty_event = { 0, 0, 0, 0, 0, 0, 0 };
  */
 
 
+/* Envelope */
+
+static int check_envelope_end(struct xmp_envelope *env, int x)
+{
+	int16 *data = env->data;
+	int index;
+
+	if (~env->flg & XMP_ENVELOPE_ON || env->npt <= 0)
+		return 0;
+
+	index = (env->npt - 1) * 2;
+
+	/* last node */
+	if (x >= data[index] || index == 0) { 
+		if (~env->flg & XMP_ENVELOPE_LOOP) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int get_envelope(struct xmp_envelope *env, int x, int def)
+{
+	int x1, x2, y1, y2;
+	int16 *data = env->data;
+	int index;
+
+	if (x < 0 || ~env->flg & XMP_ENVELOPE_ON || env->npt <= 0)
+		return def;
+
+	index = (env->npt - 1) * 2;
+
+	x1 = data[index];		/* last node */
+	if (x >= x1 || index == 0) { 
+		return data[index + 1];
+	}
+
+	do {
+		index -= 2;
+		x1 = data[index];
+	} while (index > 0 && x1 > x);
+
+	/* interpolate */
+	y1 = data[index + 1];
+	x2 = data[index + 2];
+	y2 = data[index + 3];
+
+	return x2 == x1 ? y2 : ((y2 - y1) * (x - x1) / (x2 - x1)) + y1;
+}
+
+static int update_envelope_xm(struct xmp_envelope *env, int x, int release)
+{
+	int16 *data = env->data;
+	int has_loop, has_sus;
+	int lpe, lps, sus;
+
+	has_loop = env->flg & XMP_ENVELOPE_LOOP;
+	has_sus = env->flg & XMP_ENVELOPE_SUS;
+
+	lps = env->lps << 1;
+	lpe = env->lpe << 1;
+	sus = env->sus << 1;
+
+	/* FT2 and IT envelopes behave in a different way regarding loops,
+	 * sustain and release. When the sustain point is at the end of the
+	 * envelope loop end and the key is released, FT2 escapes the loop
+	 * while IT runs another iteration. (See EnvLoops.xm in the OpenMPT
+	 * test cases.)
+	 */
+	if (has_loop && has_sus && sus == lpe) {
+		if (!release)
+			has_sus = 0;
+	}
+
+	/* If the envelope point is set to somewhere after the sustain point
+	 * or sustain loop, enable release to prevent the envelope point to
+	 * return to the sustain point or loop start. (See Filip Skutela's
+	 * farewell_tear.xm.)
+	 */
+	if (has_loop && x > data[lpe] + 1) {
+		release = 1;
+	} else if (has_sus && x > data[sus] + 1) {
+		release = 1;
+	}
+
+	/* If enabled, stay at the sustain point */
+	if (has_sus && !release) {
+		if (x >= data[sus]) {
+			x = data[sus];
+		}
+	}
+
+	/* Envelope loops */
+	if (has_loop && x >= data[lpe]) {
+		if (!(release && has_sus && sus == lpe))
+			x = data[lps];
+	}
+
+	return x;
+}
+
+#ifndef LIBXMP_CORE_DISABLE_IT
+
+static int update_envelope_it(struct xmp_envelope *env, int x, int release, int key_off)
+{
+	int16 *data = env->data;
+	int has_loop, has_sus;
+	int lpe, lps, sus, sue;
+
+	has_loop = env->flg & XMP_ENVELOPE_LOOP;
+	has_sus = env->flg & XMP_ENVELOPE_SUS;
+
+	lps = env->lps << 1;
+	lpe = env->lpe << 1;
+	sus = env->sus << 1;
+	sue = env->sue << 1;
+
+	/* Release at the end of a sustain loop, run another loop */
+	if (has_sus && key_off && x == data[sue] + 1) {
+		x = data[sus];
+	} else
+	/* If enabled, stay in the sustain loop */
+	if (has_sus && !release) {
+		if (x == data[sue] + 1) {
+			x = data[sus];
+		}
+	} else
+	/* Finally, execute the envelope loop */
+	if (has_loop) {
+		if (x > data[lpe]) {
+			x = data[lps];
+		}
+	}
+
+	return x;
+}
+
+#endif
+
+static int update_envelope(struct xmp_envelope *env, int x, int release, int key_off, int it_env)
+{
+	if (x < 0xffff)	{	/* increment tick */
+		x++;
+	}
+
+	if (x < 0) {
+		return -1;
+	}
+
+	if (~env->flg & XMP_ENVELOPE_ON || env->npt <= 0) {
+		return x;
+	}
+
+#ifndef LIBXMP_CORE_DISABLE_IT
+	return it_env ?
+		update_envelope_it(env, x, release, key_off) :
+		update_envelope_xm(env, x, release);
+#else
+	return update_envelope_xm(env, x, release);
+#endif
+}
+
+
+/* Returns: 0 if do nothing, <0 to reset channel, >0 if has fade */
+static int check_envelope_fade(struct xmp_envelope *env, int x)
+{
+	int16 *data = env->data;
+	int index;
+
+	if (~env->flg & XMP_ENVELOPE_ON)
+		return 0;
+
+	index = (env->npt - 1) * 2;		/* last node */
+	if (x > data[index]) {
+		if (data[index + 1] == 0)
+			return -1;
+		else
+			return 1;
+	}
+
+	return 0;
+}
+
+
+#ifndef LIBXMP_CORE_PLAYER
+
 /* From http://www.un4seen.com/forum/?topic=7554.0
  *
  * "Invert loop" effect replaces (!) sample data bytes within loop with their
@@ -96,31 +281,88 @@ static void update_invloop(struct module_data *m, struct channel_data *xc)
 		xc->invloop.count = 0;
 		len = xxs->lpe - xxs->lps;	
 
-		if (HAS_QUIRK(QUIRK_FUNKIT)) {
-			/* FIXME: not implemented */
-		} else {
-			if (++xc->invloop.pos > len) {
-				xc->invloop.pos = 0;
-			}
+		if (++xc->invloop.pos > len) {
+			xc->invloop.pos = 0;
+		}
 
-			if (~xxs->flg & XMP_SAMPLE_16BIT) {
-				xxs->data[xxs->lps + xc->invloop.pos] ^= 0xff;
-			}
+		if (~xxs->flg & XMP_SAMPLE_16BIT) {
+			xxs->data[xxs->lps + xc->invloop.pos] ^= 0xff;
 		}
 	}
 }
 
+#endif
+
+/*
+ * From OpenMPT Arpeggio.xm test:
+ *
+ * "[FT2] Arpeggio behavior is very weird with more than 16 ticks per row. This
+ *  comes from the fact that Fasttracker 2 uses a LUT for computing the arpeggio
+ *  note (instead of doing something like tick%3 or similar). The LUT only has
+ *  16 entries, so when there are more than 16 ticks, it reads beyond array
+ *  boundaries. The vibrato table happens to be stored right after arpeggio
+ *  table. The tables look like this in memory:
+ *
+ *    ArpTab: 0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0
+ *    VibTab: 0,24,49,74,97,120,141,161,180,197,...
+ *
+ *  All values except for the first in the vibrato table are greater than 1, so
+ *  they trigger the third arpeggio note. Keep in mind that Fasttracker 2 counts
+ *  downwards, so the table has to be read from back to front, i.e. at 16 ticks
+ *  per row, the 16th entry in the LUT is the first to be read. This is also the
+ *  reason why Arpeggio is played 'backwards' in Fasttracker 2."
+ */
+static int ft2_arpeggio(struct context_data *ctx, struct channel_data *xc)
+{
+	struct player_data *p = &ctx->p;
+	int i;
+
+	if (xc->arpeggio.val[1] == 0 && xc->arpeggio.val[2] == 0) {
+		return 0;
+	}
+
+	if (p->frame == 0) {
+		return 0;
+	}
+
+	i = p->speed - (p->frame % p->speed);
+
+	if (i == 16) {
+		return 0;
+	} else if (i > 16) {
+		return xc->arpeggio.val[2];
+	}
+
+	return xc->arpeggio.val[i % 3];
+}
+
+static int is_first_frame(struct context_data *ctx)
+{
+	struct player_data *p = &ctx->p;
+	struct module_data *m = &ctx->m;
+
+	switch (m->read_event_type) {
+#ifndef LIBXMP_CORE_DISABLE_IT
+	case READ_EVENT_IT:
+		/* fall through */
+#endif
+	case READ_EVENT_ST3:
+		return p->frame % p->speed == 0;
+	default:
+		return p->frame == 0;
+	}
+}
+
 static void reset_channels(struct context_data *ctx)
 {
 	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
 	struct xmp_module *mod = &m->mod;
+	struct smix_data *smix = &ctx->smix;
 	struct channel_data *xc;
 	int i;
 
 #ifndef LIBXMP_CORE_PLAYER
-	m->synth->reset(ctx);
-
 	for (i = 0; i < p->virt.virt_channels; i++) {
 		void *extra;
 
@@ -128,22 +370,60 @@ static void reset_channels(struct context_data *ctx)
 		extra = xc->extra;
 		memset(xc, 0, sizeof (struct channel_data));
 		xc->extra = extra;
-		reset_channel_extras(ctx, xc);
-		xc->ins = xc->key = -1;
+		libxmp_reset_channel_extras(ctx, xc);
+		xc->ins = -1;
+		xc->old_ins = 1;	/* raw value */
+		xc->key = -1;
+		xc->volume = m->volbase;
 	}
 #else
 	for (i = 0; i < p->virt.virt_channels; i++) {
 		xc = &p->xc_data[i];
 		memset(xc, 0, sizeof (struct channel_data));
-		xc->ins = xc->key = -1;
+		xc->ins = -1;
+		xc->old_ins = 1;	/* raw value */
+		xc->key = -1;
+		xc->volume = m->volbase;
 	}
 #endif
 
 	for (i = 0; i < p->virt.num_tracks; i++) {
 		xc = &p->xc_data[i];
-		xc->pan.val = mod->xxc[i].pan;
-		xc->mastervol = mod->xxc[i].vol;
+
+		if (i >= mod->chn && i < mod->chn + smix->chn) {
+			xc->mastervol = 0x40;
+			xc->pan.val = 0x80;
+		} else {
+			xc->mastervol = mod->xxc[i].vol;
+			xc->pan.val = mod->xxc[i].pan;
+		}
+		
+#ifndef LIBXMP_CORE_DISABLE_IT
 		xc->filter.cutoff = 0xff;
+
+		/* Amiga split channel */
+		if (mod->xxc[i].flg & XMP_CHANNEL_SPLIT) {
+			int j;
+
+			xc->split = ((mod->xxc[i].flg & 0x30) >> 4) + 1;
+			/* Connect split channel pairs */
+			for (j = 0; j < i; j++) {
+				if (mod->xxc[j].flg & XMP_CHANNEL_SPLIT) {
+					if (p->xc_data[j].split == xc->split) {
+						p->xc_data[j].pair = i;
+						xc->pair = j;
+					}
+				}
+			}
+		} else {
+			xc->split = 0;
+		}
+#endif
+
+		/* Surround channel */
+		if (mod->xxc[i].flg & XMP_CHANNEL_SURROUND) {
+			xc->pan.surround = 1;
+		}
 	}
 }
 
@@ -185,9 +465,11 @@ static int check_delay(struct context_data *ctx, struct xmp_event *e, int chn)
 	}
 
 	if (HAS_QUIRK(QUIRK_RTDELAY)) {
+		if (e->vol == 0 && e->f2t == 0 && e->ins == 0 && e->note != XMP_KEY_OFF)
+			xc->delayed_event.vol = xc->volume + 1;
 		if (e->note == 0)
 			xc->delayed_event.note = xc->key + 1;
-		if (e->ins == 0 && !HAS_QUIRK(QUIRK_MLKDLY))
+		if (e->ins == 0)
 			xc->delayed_event.ins = xc->old_ins;
 	}
 
@@ -201,29 +483,47 @@ static inline void read_row(struct context_data *ctx, int pat, int row)
 	struct xmp_module *mod = &m->mod;
 	struct player_data *p = &ctx->p;
 	struct flow_control *f = &p->flow;
-	struct xmp_event *event;
-
-	/* FIXME: workaround for pattern delay + break) */
-	if (f->skip_fetch) {
-		f->skip_fetch = 0;
-		return;
-	}
+	struct xmp_event ev;
 
 	for (chn = 0; chn < mod->chn; chn++) {
 		const int num_rows = mod->xxt[TRACK_NUM(pat, chn)]->rows;
 		if (row < num_rows) {
-			event = &EVENT(pat, chn, row);
+			memcpy(&ev, &EVENT(pat, chn, row), sizeof(ev));
 		} else {
-			event = (struct xmp_event *)&empty_event;
+			memset(&ev, 0, sizeof(ev));
+		}
+
+		if (ev.note == XMP_KEY_OFF) {
+			int env_on = 0;
+			int ins = ev.ins - 1;
+
+			if (IS_VALID_INSTRUMENT(ins) &&
+			    (mod->xxi[ins].aei.flg & XMP_ENVELOPE_ON)) {
+				env_on = 1;
+			}
+
+			if (ev.fxt == FX_EXTENDED && MSN(ev.fxp) == EX_DELAY) {
+				if (ev.ins && (LSN(ev.fxp) || env_on)) {
+					if (LSN(ev.fxp)) {
+						ev.note = 0;
+					}
+					ev.fxp = ev.fxt = 0;
+				}
+			}
 		}
 
-		if (check_delay(ctx, event, chn) == 0) {
+		if (check_delay(ctx, &ev, chn) == 0) {
 			if (!f->rowdelay_set || f->rowdelay > 0) {
-				read_event(ctx, event, chn);
+				libxmp_read_event(ctx, &ev, chn);
 #ifndef LIBXMP_CORE_PLAYER
-				med_hold_hack(ctx, pat, chn, row);
+				libxmp_med_hold_hack(ctx, pat, chn, row);
 #endif
 			}
+		} else {
+			if (IS_PLAYER_MODE_IT()) {
+				/* Reset flags. See SlideDelay.it */
+				p->xc_data[chn].flags = 0;
+			}
 		}
 	}
 }
@@ -242,13 +542,63 @@ static inline int get_channel_vol(struct context_data *ctx, int chn)
 		return 0;
 
 	/* root is invalid */
-	root = virt_getroot(ctx, chn);
+	root = libxmp_virt_getroot(ctx, chn);
 	if (root < 0)
 		return 0;
 
 	return p->channel_vol[root];
 }
 
+static int tremor_ft2(struct context_data *ctx, int chn, int finalvol)
+{
+	struct player_data *p = &ctx->p;
+	struct channel_data *xc = &p->xc_data[chn];
+
+	if (xc->tremor.count & 0x80) {
+		if (TEST(TREMOR) && p->frame != 0) {
+			xc->tremor.count &= ~0x20;
+			if (xc->tremor.count == 0x80) {
+				/* end of down cycle, set up counter for up  */
+				xc->tremor.count = xc->tremor.up | 0xc0;
+			} else if (xc->tremor.count == 0xc0) {
+				/* end of up cycle, set up counter for down */
+				xc->tremor.count = xc->tremor.down | 0x80;
+			} else {
+				xc->tremor.count--;
+			}
+		}
+
+		if ((xc->tremor.count & 0xe0) == 0x80) {
+			finalvol = 0;
+		}
+	}
+
+	return finalvol;
+}
+
+static int tremor_s3m(struct context_data *ctx, int chn, int finalvol)
+{
+	struct player_data *p = &ctx->p;
+	struct channel_data *xc = &p->xc_data[chn];
+
+	if (TEST(TREMOR)) {
+		if (xc->tremor.count == 0) {
+			/* end of down cycle, set up counter for up  */
+			xc->tremor.count = xc->tremor.up | 0x80;
+		} else if (xc->tremor.count == 0x80) {
+			/* end of up cycle, set up counter for down */
+			xc->tremor.count = xc->tremor.down;
+		}
+
+		xc->tremor.count--;
+
+		if (~xc->tremor.count & 0x80) {
+			finalvol = 0;
+		}
+	}
+
+	return finalvol;
+}
 
 /*
  * Update channel data
@@ -256,7 +606,7 @@ static inline int get_channel_vol(struct context_data *ctx, int chn)
 
 #define DOENV_RELEASE ((TEST_NOTE(NOTE_RELEASE) || act == VIRT_ACTION_OFF))
 
-static void process_volume(struct context_data *ctx, int chn, int t, int act)
+static void process_volume(struct context_data *ctx, int chn, int act)
 {
 	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
@@ -264,9 +614,9 @@ static void process_volume(struct context_data *ctx, int chn, int t, int act)
 	struct xmp_instrument *instrument;
 	int finalvol;
 	uint16 vol_envelope;
-	int gvol, end;
+	int fade = 0;
 
-	instrument = get_instrument(ctx, xc->ins);
+	instrument = libxmp_get_instrument(ctx, xc->ins);
 
 	/* Keyoff and fadeout */
 
@@ -274,15 +624,35 @@ static void process_volume(struct context_data *ctx, int chn, int t, int act)
 	 * In XM it depends on envelope (see graff-strange_land.xm vs
 	 * Decibelter - Cosmic 'Wegian Mamas.xm)
 	 */
-	if (!HAS_QUIRK(QUIRK_KEYOFF)) {
-		if (TEST_NOTE(NOTE_RELEASE) && !(instrument->aei.flg & XMP_ENVELOPE_ON))
-			xc->fadeout = 0;
+	if (HAS_QUIRK(QUIRK_KEYOFF)) {
+		/* If IT, only apply fadeout on note release if we don't
+		 * have envelope, or if we have envelope loop
+		 */
+		if (TEST_NOTE(NOTE_RELEASE) || act == VIRT_ACTION_OFF) {
+			if ((~instrument->aei.flg & XMP_ENVELOPE_ON) ||
+			    (instrument->aei.flg & XMP_ENVELOPE_LOOP)) {
+				fade = 1;
+			}
+		}
+	} else {
+		if (~instrument->aei.flg & XMP_ENVELOPE_ON) {
+			if (TEST_NOTE(NOTE_RELEASE)) {
+				xc->fadeout = 0;
+			}
+		}
+
+		if (TEST_NOTE(NOTE_RELEASE) || act == VIRT_ACTION_OFF) {
+			fade = 1;
+		}
 	}
 
-	if (TEST_NOTE(NOTE_FADEOUT | NOTE_RELEASE) || act == VIRT_ACTION_FADE
-	    || act == VIRT_ACTION_OFF) {
-		if (xc->fadeout > instrument->rls) {
-			xc->fadeout -= instrument->rls;
+	if (TEST_NOTE(NOTE_FADEOUT) || act == VIRT_ACTION_FADE) {
+		fade = 1;
+	}
+
+	if (fade) {
+		if (xc->fadeout > xc->ins_fade) {
+			xc->fadeout -= xc->ins_fade;
 		} else {
 			xc->fadeout = 0;
 			SET_NOTE(NOTE_END);
@@ -304,44 +674,52 @@ static void process_volume(struct context_data *ctx, int chn, int t, int act)
 		}
 	}
 
-	vol_envelope = get_envelope(&instrument->aei, xc->v_idx, 64, &end);
-	xc->v_idx = update_envelope(&instrument->aei, xc->v_idx, DOENV_RELEASE,
-						HAS_QUIRK(QUIRK_ENVSUS));
-	if (end) {
-		if (vol_envelope == 0)
+	if (!TEST_PER(VENV_PAUSE)) {
+		xc->v_idx = update_envelope(&instrument->aei, xc->v_idx,
+			DOENV_RELEASE, TEST(KEY_OFF), IS_PLAYER_MODE_IT());
+	}
+
+	vol_envelope = get_envelope(&instrument->aei, xc->v_idx, 64);
+	if (check_envelope_end(&instrument->aei, xc->v_idx)) {
+		if (vol_envelope == 0) {
 			SET_NOTE(NOTE_END);
+		}
 		SET_NOTE(NOTE_ENV_END);
 	}
 
 	/* If note ended in background channel, we can safely reset it */
 	if (TEST_NOTE(NOTE_END) && chn >= p->virt.num_tracks) {
-		virt_resetchannel(ctx, chn);
+		libxmp_virt_resetchannel(ctx, chn);
 		return;
 	}
 
 #ifndef LIBXMP_CORE_PLAYER
-	finalvol = extras_get_volume(ctx, xc);
+	finalvol = libxmp_extras_get_volume(ctx, xc);
 #else
 	finalvol = xc->volume;
 #endif
 
+	if (IS_PLAYER_MODE_IT()) {
+		finalvol = xc->volume * (100 - xc->rvv) / 100;
+	}
+
 	if (TEST(TREMOLO)) {
-		finalvol += get_lfo(&xc->tremolo.lfo, 1 << 6);
-		update_lfo(&xc->tremolo.lfo);
+		/* OpenMPT VibratoReset.mod */
+		if (!is_first_frame(ctx) || !HAS_QUIRK(QUIRK_PROTRACK)) {
+			finalvol += libxmp_lfo_get(ctx, &xc->tremolo.lfo, 0) / (1 << 6);
+		}
+
+		if (!is_first_frame(ctx) || HAS_QUIRK(QUIRK_VIBALL)) {
+			libxmp_lfo_update(&xc->tremolo.lfo);
+		}
 	}
 
 	CLAMP(finalvol, 0, m->volbase);
 
 	finalvol = (finalvol * xc->fadeout) >> 6;	/* 16 bit output */
 
-	if (HAS_QUIRK(QUIRK_ST3GVOL)) {
-		gvol = 0x40;
-	} else {
-		gvol = p->gvol;
-	}
-
-	finalvol = (uint32)(vol_envelope * gvol * xc->mastervol / m->gvolbase *
-				((int)finalvol * 0x40 / m->volbase)) >> 18;
+	finalvol = (uint32)(vol_envelope * p->gvol * xc->mastervol /
+		m->gvolbase * ((int)finalvol * 0x40 / m->volbase)) >> 18;
 
 	/* Apply channel volume */
 	finalvol = finalvol * get_channel_vol(ctx, chn) / 100;
@@ -359,33 +737,29 @@ static void process_volume(struct context_data *ctx, int chn, int t, int act)
 		finalvol = (finalvol * instrument->vol * xc->gvl) >> 12;
 	}
 
-	if (xc->tremor.val) {
-		if (xc->tremor.count == 0) {
-			/* end of down cycle, set up counter for up  */
-			xc->tremor.count = MSN(xc->tremor.val) | 0x80;
-		} else if (xc->tremor.count == 0x80) {
-			/* end of up cycle, set up counter for down */
-			xc->tremor.count = LSN(xc->tremor.val);
-		}
-
-		xc->tremor.count--;
-
-		if (~xc->tremor.count & 0x80) {
-			finalvol = 0;
-		}
+	if (IS_PLAYER_MODE_FT2()) {
+		finalvol = tremor_ft2(ctx, chn, finalvol);
+	} else {
+		finalvol = tremor_s3m(ctx, chn, finalvol);
 	}
 
-	if (chn < m->mod.chn)
+	if (chn < m->mod.chn) {
 		finalvol = finalvol * p->master_vol / 100;
-	else
+	} else {
 		finalvol = finalvol * p->smix_vol / 100;
+	}
+
+	xc->info_finalvol = TEST_NOTE(NOTE_SAMPLE_END) ? 0 : finalvol;
 
-	xc->info_finalvol = finalvol;
+	libxmp_virt_setvol(ctx, chn, finalvol);
 
-	virt_setvol(ctx, chn, finalvol);
+	/* Check Amiga split channel */
+	if (xc->split) {
+		libxmp_virt_setvol(ctx, xc->pair, finalvol);
+	}
 }
 
-static void process_frequency(struct context_data *ctx, int chn, int t, int act)
+static void process_frequency(struct context_data *ctx, int chn, int act)
 {
 #ifndef LIBXMP_CORE_DISABLE_IT
 	struct mixer_data *s = &ctx->s;
@@ -394,20 +768,21 @@ static void process_frequency(struct context_data *ctx, int chn, int t, int act)
 	struct module_data *m = &ctx->m;
 	struct channel_data *xc = &p->xc_data[chn];
 	struct xmp_instrument *instrument;
-	double period;
+	double period, vibrato;
 	int linear_bend;
 	int frq_envelope;
-	int arp, vibrato;
+	int arp;
 #ifndef LIBXMP_CORE_DISABLE_IT
 	int cutoff, resonance;
 #endif
-	int end;
 
-	instrument = get_instrument(ctx, xc->ins);
+	instrument = libxmp_get_instrument(ctx, xc->ins);
 
-	frq_envelope = get_envelope(&instrument->fei, xc->f_idx, 0, &end);
-	xc->f_idx = update_envelope(&instrument->fei, xc->f_idx, DOENV_RELEASE,
-						HAS_QUIRK(QUIRK_ENVSUS));
+	if (!TEST_PER(FENV_PAUSE)) {
+		xc->f_idx = update_envelope(&instrument->fei, xc->f_idx,
+			DOENV_RELEASE, TEST(KEY_OFF), IS_PLAYER_MODE_IT());
+	}
+	frq_envelope = get_envelope(&instrument->fei, xc->f_idx, 0);
 
 #ifndef LIBXMP_CORE_PLAYER
 	/* Do note slide */
@@ -415,17 +790,20 @@ static void process_frequency(struct context_data *ctx, int chn, int t, int act)
 	if (TEST(NOTE_SLIDE)) {
 		if (xc->noteslide.count == 0) {
 			xc->note += xc->noteslide.slide;
-			xc->period = note_to_period(xc->note, xc->finetune,
-					HAS_QUIRK(QUIRK_LINEAR), xc->per_adj);
+			xc->period = libxmp_note_to_period(ctx, xc->note,
+					xc->finetune, xc->per_adj);
 			xc->noteslide.count = xc->noteslide.speed;
 		}
 		xc->noteslide.count--;
+
+		libxmp_virt_setnote(ctx, chn, xc->note);
 	}
 #endif
 
 	/* Instrument vibrato */
-	vibrato = get_lfo(&xc->insvib.lfo, (1024 * (1 + xc->insvib.sweep)));
-	update_lfo(&xc->insvib.lfo);
+	vibrato = 1.0 * libxmp_lfo_get(ctx, &xc->insvib.lfo, 1) /
+				(4096 * (1 + xc->insvib.sweep));
+	libxmp_lfo_update(&xc->insvib.lfo);
 	if (xc->insvib.sweep > 1) {
 		xc->insvib.sweep -= 2;
 	} else {
@@ -434,31 +812,88 @@ static void process_frequency(struct context_data *ctx, int chn, int t, int act)
 
 	/* Vibrato */
 	if (TEST(VIBRATO) || TEST_PER(VIBRATO)) {
-		int shift = HAS_QUIRK(QUIRK_VIBHALF) ? 10 : 9;
-		int vib = get_lfo(&xc->vibrato.lfo, 1 << shift);
+		/* OpenMPT VibratoReset.mod */
+		if (!is_first_frame(ctx) || !HAS_QUIRK(QUIRK_PROTRACK)) {
+			int shift = HAS_QUIRK(QUIRK_VIBHALF) ? 10 : 9;
+			int vib = libxmp_lfo_get(ctx, &xc->vibrato.lfo, 1) / (1 << shift);
 
-		if (HAS_QUIRK(QUIRK_VIBINV)) {
-			vibrato -= vib;
-		} else {
-			vibrato += vib;
+			if (HAS_QUIRK(QUIRK_VIBINV)) {
+				vibrato -= vib;
+			} else {
+				vibrato += vib;
+			}
 		}
 
-		if (t % p->speed != 0 || HAS_QUIRK(QUIRK_VIBALL)) {
-			update_lfo(&xc->vibrato.lfo);
+		if (!is_first_frame(ctx) || HAS_QUIRK(QUIRK_VIBALL)) {
+			libxmp_lfo_update(&xc->vibrato.lfo);
 		}
 	}
 
 	period = xc->period;
 #ifndef LIBXMP_CORE_PLAYER
-	period += extras_get_period(ctx, xc);
+	period += libxmp_extras_get_period(ctx, xc);
 #endif
 
-	linear_bend = period_to_bend(period + vibrato, xc->note, xc->gliss,
-				HAS_QUIRK(QUIRK_LINEAR), xc->per_adj);
+	/* Sanity check */
+	if (period < 0.1) {
+		period = 0.1;
+	} 
+
+	/* Arpeggio */
+
+	if (HAS_QUIRK(QUIRK_FT2BUGS)) {
+		arp = ft2_arpeggio(ctx, xc);
+	} else {
+		arp = xc->arpeggio.val[xc->arpeggio.count];
+	}
+
+	/* Pitch bend */
+
+ 	/* From OpenMPT PeriodLimit.s3m:
+	 * "ScreamTracker 3 limits the final output period to be at least 64,
+	 *  i.e. when playing a note that is too high or when sliding the
+	 *  period lower than 64, the output period will simply be clamped to
+	 *  64. However, when reaching a period of 0 through slides, the
+	 *  output on the channel should be stopped."
+	 */
+	/* ST3 uses periods*4, so the limit is 16. Adjusted to the exact
+	 * A6 value because we compute periods in floating point.
+	 */
+	if (HAS_QUIRK(QUIRK_ST3BUGS)) {
+		if (period < 16.239270) {	/* A6 */
+			period = 16.239270;
+		}
+	}
+
+	linear_bend = libxmp_period_to_bend(ctx, period + vibrato, xc->note,
+							xc->per_adj);
+
+	if (TEST_NOTE(NOTE_GLISSANDO) && TEST(TONEPORTA)) {
+		if (linear_bend > 0) {
+			linear_bend = (linear_bend + 6400) / 12800 * 12800;
+		} else if (linear_bend < 0) {
+			linear_bend = (linear_bend - 6400) / 12800 * 12800;
+		}
+	}
+
+	if (HAS_QUIRK(QUIRK_FT2BUGS)) {
+		if  (arp) {
+			/* OpenMPT ArpSlide.xm */
+			linear_bend = linear_bend / 12800 * 12800 +
+							xc->finetune * 100;
 
+			/* OpenMPT ArpeggioClamp.xm */
+			if (xc->note + arp > 107) {
+				if (p->speed - (p->frame % p->speed) > 0) {
+					arp = 108 - xc->note;
+				}
+			}
+		}
+	}
+	
 	/* Envelope */
 
-	if (~instrument->fei.flg & XMP_ENVELOPE_FLT) {
+	if (xc->f_idx >= 0 && (~instrument->fei.flg & XMP_ENVELOPE_FLT)) {
 		/* IT pitch envelopes are always linear, even in Amiga period
 		 * mode. Each unit in the envelope scale is 1/25 semitone.
 		 */
@@ -467,28 +902,39 @@ static void process_frequency(struct context_data *ctx, int chn, int t, int act)
 
 	/* Arpeggio */
 
-	arp = xc->arpeggio.val[xc->arpeggio.count];
 	if (arp != 0) {
 		linear_bend += (100 << 7) * arp;
+
+		/* OpenMPT ArpWrapAround.mod */
+		if (HAS_QUIRK(QUIRK_PROTRACK)) {
+			if (xc->note + arp > MAX_NOTE_MOD + 1) {
+				linear_bend -= 12800 * (3 * 12);
+			} else if (xc->note + arp > MAX_NOTE_MOD) {
+				libxmp_virt_setvol(ctx, chn, 0);
+			}
+		}
 	}
 
+
 #ifndef LIBXMP_CORE_PLAYER
-	linear_bend += extras_get_linear_bend(ctx, xc);
+	linear_bend += libxmp_extras_get_linear_bend(ctx, xc);
 #endif
 
+	period = libxmp_note_to_period_mix(xc->note, linear_bend);
+	libxmp_virt_setperiod(ctx, chn, period);
+
 	/* For xmp_get_frame_info() */
 	xc->info_pitchbend = linear_bend >> 7;
-	xc->info_period = note_to_period_mix(xc->note, linear_bend);
+	xc->info_period = period * 4096;
 
-	if (HAS_QUIRK(QUIRK_MODRNG)) {
+	if (IS_PERIOD_MODRNG()) {
 		CLAMP(xc->info_period,
-			note_to_period(83, xc->finetune, 0, 0) * 4096,
-			note_to_period(48, xc->finetune, 0, 0) * 4096);
-	} else if (xc->info_period <  (1 << 12)) {
+			libxmp_note_to_period(ctx, MAX_NOTE_MOD, xc->finetune, 0) * 4096,
+			libxmp_note_to_period(ctx, MIN_NOTE_MOD, xc->finetune, 0) * 4096);
+	} else if (xc->info_period < (1 << 12)) {
 		xc->info_period = (1 << 12);
 	}
 
-	virt_setbend(ctx, chn, linear_bend);
 
 #ifndef LIBXMP_CORE_DISABLE_IT
 
@@ -498,8 +944,11 @@ static void process_frequency(struct context_data *ctx, int chn, int t, int act)
 		return;
 	}
 
-	if (instrument->fei.flg & XMP_ENVELOPE_FLT) {
-		cutoff = xc->filter.cutoff * frq_envelope >> 8;
+	if (xc->f_idx >= 0 && (instrument->fei.flg & XMP_ENVELOPE_FLT)) {
+		if (frq_envelope < 0xfe) {
+			xc->filter.envelope = frq_envelope;
+		}
+		cutoff = xc->filter.cutoff * xc->filter.envelope >> 8;
 	} else {
 		cutoff = xc->filter.cutoff;
 	}
@@ -509,20 +958,20 @@ static void process_frequency(struct context_data *ctx, int chn, int t, int act)
 		cutoff = 0xff;
 	} else if (cutoff < 0xff) {
 		int a0, b0, b1;
-		filter_setup(s->freq, cutoff, resonance, &a0, &b0, &b1);
-		virt_seteffect(ctx, chn, DSP_EFFECT_FILTER_A0, a0);
-		virt_seteffect(ctx, chn, DSP_EFFECT_FILTER_B0, b0);
-		virt_seteffect(ctx, chn, DSP_EFFECT_FILTER_B1, b1);
-		virt_seteffect(ctx, chn, DSP_EFFECT_RESONANCE, resonance);
+		libxmp_filter_setup(s->freq, cutoff, resonance, &a0, &b0, &b1);
+		libxmp_virt_seteffect(ctx, chn, DSP_EFFECT_FILTER_A0, a0);
+		libxmp_virt_seteffect(ctx, chn, DSP_EFFECT_FILTER_B0, b0);
+		libxmp_virt_seteffect(ctx, chn, DSP_EFFECT_FILTER_B1, b1);
+		libxmp_virt_seteffect(ctx, chn, DSP_EFFECT_RESONANCE, resonance);
 	}
 
 	/* Always set cutoff */
-	virt_seteffect(ctx, chn, DSP_EFFECT_CUTOFF, cutoff);
+	libxmp_virt_seteffect(ctx, chn, DSP_EFFECT_CUTOFF, cutoff);
 
 #endif
 }
 
-static void process_pan(struct context_data *ctx, int chn, int t, int act)
+static void process_pan(struct context_data *ctx, int chn, int act)
 {
 	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
@@ -531,45 +980,75 @@ static void process_pan(struct context_data *ctx, int chn, int t, int act)
 	struct xmp_instrument *instrument;
 	int finalpan, panbrello = 0;
 	int pan_envelope;
-	int end;
+	int channel_pan;
 
-	instrument = get_instrument(ctx, xc->ins);
+	instrument = libxmp_get_instrument(ctx, xc->ins);
 
-	pan_envelope = get_envelope(&instrument->pei, xc->p_idx, 32, &end);
-	xc->p_idx = update_envelope(&instrument->pei, xc->p_idx, DOENV_RELEASE,
-						HAS_QUIRK(QUIRK_ENVSUS));
+	if (!TEST_PER(PENV_PAUSE)) {
+		xc->p_idx = update_envelope(&instrument->pei, xc->p_idx,
+			DOENV_RELEASE, TEST(KEY_OFF), IS_PLAYER_MODE_IT());
+	}
+	pan_envelope = get_envelope(&instrument->pei, xc->p_idx, 32);
 
+#ifndef LIBXMP_CORE_DISABLE_IT
 	if (TEST(PANBRELLO)) {
-		panbrello = get_lfo(&xc->panbrello.lfo, 512);
-		update_lfo(&xc->panbrello.lfo);
+		panbrello = libxmp_lfo_get(ctx, &xc->panbrello.lfo, 0) / 512;
+		if (is_first_frame(ctx)) {
+			libxmp_lfo_update(&xc->panbrello.lfo);
+		}
 	}
+#endif
+
+	channel_pan = xc->pan.val;
+
+#if 0
+#ifdef LIBXMP_PAULA_SIMULATOR
+	/* Always use 100% pan separation in Amiga mode */
+	if (p->flags & XMP_FLAGS_A500) {
+		if (IS_AMIGA_MOD()) {
+			channel_pan = channel_pan < 0x80 ? 0 : 0xff;
+		}
+	}
+#endif
+#endif
 
-	finalpan = xc->pan.val + panbrello + (pan_envelope - 32) *
+	finalpan = channel_pan + panbrello + (pan_envelope - 32) *
 				(128 - abs(xc->pan.val - 128)) / 32;
 
-	if (s->format & XMP_FORMAT_MONO) {
+	if (IS_PLAYER_MODE_IT()) {
+		finalpan = finalpan + xc->rpv * 4;
+	}
+
+	CLAMP(finalpan, 0, 255);
+
+	if (s->format & XMP_FORMAT_MONO || xc->pan.surround) {
 		finalpan = 0;
 	} else {
 		finalpan = (finalpan - 0x80) * s->mix / 100;
 	}
 
-	CLAMP(finalpan, -128, 127);
-
 	xc->info_finalpan = finalpan + 0x80;
 
-	virt_setpan(ctx, chn, finalpan);
+	if (xc->pan.surround) {
+		libxmp_virt_setpan(ctx, chn, PAN_SURROUND);
+	} else {
+		libxmp_virt_setpan(ctx, chn, finalpan);
+	}
 }
 
-static void update_volume(struct context_data *ctx, int chn, int t)
+static void update_volume(struct context_data *ctx, int chn)
 {
 	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
+#ifndef LIBXMP_CORE_DISABLE_IT
+	struct flow_control *f = &p->flow;
+#endif
 	struct channel_data *xc = &p->xc_data[chn];
 
 	/* Volume slides happen in all frames but the first, except when the
 	 * "volume slide on all frames" flag is set.
 	 */
-	if (t % p->speed != 0 || HAS_QUIRK(QUIRK_VSALL)) {
+	if (p->frame % p->speed != 0 || HAS_QUIRK(QUIRK_VSALL)) {
 		if (TEST(GVOL_SLIDE)) {
 			p->gvol += xc->gvol.slide;
 		}
@@ -599,59 +1078,90 @@ static void update_volume(struct context_data *ctx, int chn, int t)
 		}
 	}
 
-	if (t % p->speed == 0) {
+	if (p->frame % p->speed == 0) {
 		/* Process "fine" effects */
-		if (TEST(FINE_VOLS))
+		if (TEST(FINE_VOLS)) {
 			xc->volume += xc->vol.fslide;
+		}
 
-		if (TEST(TRK_FVSLIDE))
+#ifndef LIBXMP_CORE_DISABLE_IT
+		if (TEST(FINE_VOLS_2)) {
+			/* OpenMPT FineVolColSlide.it:
+			 * Unlike fine volume slides in the effect column,
+			 * fine volume slides in the volume column are only
+			 * ever executed on the first tick -- not on multiples
+			 * of the first tick if there is a pattern delay. 
+			 */
+			if (!f->rowdelay_set || f->rowdelay_set & 2) {
+				xc->volume += xc->vol.fslide2;
+			}
+		}
+		f->rowdelay_set &= ~2;
+#endif
+
+		if (TEST(TRK_FVSLIDE)) {
 			xc->mastervol += xc->trackvol.fslide;
+		}
 
-		if (TEST(GVOL_SLIDE))
+		if (TEST(GVOL_SLIDE)) {
 			p->gvol += xc->gvol.fslide;
+		}
 	}
 
 	/* Clamp volumes */
 	CLAMP(xc->volume, 0, m->volbase);
 	CLAMP(p->gvol, 0, m->gvolbase);
 	CLAMP(xc->mastervol, 0, m->volbase);
+
+	if (xc->split) {
+		p->xc_data[xc->pair].volume = xc->volume;
+	}
 }
 
-static void update_frequency(struct context_data *ctx, int chn, int t)
+static void update_frequency(struct context_data *ctx, int chn)
 {
 	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
 	struct channel_data *xc = &p->xc_data[chn];
 
-	if (t % p->speed != 0 || HAS_QUIRK(QUIRK_PBALL)) {
+	if (!is_first_frame(ctx) || HAS_QUIRK(QUIRK_PBALL)) {
 		if (TEST(PITCHBEND) || TEST_PER(PITCHBEND)) {
 			xc->period += xc->freq.slide;
+			if (HAS_QUIRK(QUIRK_PROTRACK)) {
+				xc->porta.target = xc->period;
+			}
 		}
 
 		/* Do tone portamento */
 		if (TEST(TONEPORTA) || TEST_PER(TONEPORTA)) {
-			int end = 0;
-			if (xc->porta.dir > 0) {
-				xc->period += xc->porta.slide;
-				if (xc->period >= xc->porta.target)
-					end = 1;
-			} else {
-				xc->period -= xc->porta.slide;
-				if (xc->period <= xc->porta.target)
-					end = 1;
-			}
+			if (xc->porta.target > 0) {
+				int end = 0;
+				if (xc->porta.dir > 0) {
+					xc->period += xc->porta.slide;
+					if (xc->period >= xc->porta.target)
+						end = 1;
+				} else {
+					xc->period -= xc->porta.slide;
+					if (xc->period <= xc->porta.target)
+						end = 1;
+				}
+
+				if (end) {
+					/* reached end */
+					xc->period = xc->porta.target;
+					xc->porta.dir = 0;
+					RESET(TONEPORTA);
+					RESET_PER(TONEPORTA);
 
-			if (end) {
-				/* reached end */
-				xc->period = xc->porta.target;
-				xc->porta.dir = 0;
-				RESET(TONEPORTA);
-				RESET_PER(TONEPORTA);
+					if (HAS_QUIRK(QUIRK_PROTRACK)) {
+						xc->porta.target = -1;
+					}
+				}
 			}
 		} 
 	}
 
-	if (t % p->speed == 0) {
+	if (is_first_frame(ctx)) {
 		if (TEST(FINE_BEND)) {
 			xc->period += xc->freq.fslide;
 		}
@@ -659,38 +1169,42 @@ static void update_frequency(struct context_data *ctx, int chn, int t)
 #ifndef LIBXMP_CORE_PLAYER
 		if (TEST(FINE_NSLIDE)) {
 			xc->note += xc->noteslide.fslide;
-			xc->period = note_to_period(xc->note, xc->finetune,
-					HAS_QUIRK(QUIRK_LINEAR), xc->per_adj);
+			xc->period = libxmp_note_to_period(ctx, xc->note,
+				xc->finetune, xc->per_adj);
 		}
 #endif
 	}
 
-	if (HAS_QUIRK(QUIRK_LINEAR)) {
+	switch (m->period_type) {
+	case PERIOD_LINEAR:
 		CLAMP(xc->period, MIN_PERIOD_L, MAX_PERIOD_L);
-	} else if (HAS_QUIRK(QUIRK_MODRNG)) {
-		CLAMP(xc->period, note_to_period(83, xc->finetune, 0, 0),
-				  note_to_period(48, xc->finetune, 0, 0));
+		break;
+	case PERIOD_MODRNG:
+		CLAMP(xc->period,
+			libxmp_note_to_period(ctx, MAX_NOTE_MOD, xc->finetune, 0),
+			libxmp_note_to_period(ctx, MIN_NOTE_MOD, xc->finetune, 0));
+		break;
 	}
 
+	xc->arpeggio.count++;
+	xc->arpeggio.count %= xc->arpeggio.size;
+
 	/* Check for invalid periods (from Toru Egashira's NSPmod)
 	 * panic.s3m has negative periods
 	 * ambio.it uses low (~8) period values
 	 */
-	if (xc->period < 1) {
-		xc->volume = 0;
+	if (xc->period < 0.25) {
+		libxmp_virt_setvol(ctx, chn, 0);
 	}
-
-	xc->arpeggio.count++;
-	xc->arpeggio.count %= xc->arpeggio.size;
 }
 
-static void update_pan(struct context_data *ctx, int chn, int t)
+static void update_pan(struct context_data *ctx, int chn)
 {
 	struct player_data *p = &ctx->p;
 	struct channel_data *xc = &p->xc_data[chn];
 
 	if (TEST(PAN_SLIDE)) {
-		if (t % p->speed == 0) {
+		if (is_first_frame(ctx)) {
 			xc->pan.val += xc->pan.fslide;
 		} else {
 			xc->pan.val += xc->pan.slide;
@@ -704,7 +1218,7 @@ static void update_pan(struct context_data *ctx, int chn, int t)
 	}
 }
 
-static void play_channel(struct context_data *ctx, int chn, int t)
+static void play_channel(struct context_data *ctx, int chn)
 {
 	struct player_data *p = &ctx->p;
 	struct smix_data *smix = &ctx->smix;
@@ -715,29 +1229,31 @@ static void play_channel(struct context_data *ctx, int chn, int t)
 
 	xc->info_finalvol = 0;
 
+#ifndef LIBXMP_CORE_DISABLE_IT
 	/* IT tempo slide */
-	if (TEST(TEMPO_SLIDE) && p->frame) {
+	if (!is_first_frame(ctx) && TEST(TEMPO_SLIDE)) {
 		p->bpm += xc->tempo.slide;
 		CLAMP(p->bpm, 0x20, 0xff);
 	}
+#endif
 
 	/* Do delay */
 	if (xc->delay > 0) {
 		if (--xc->delay == 0) {
-			read_event(ctx, &xc->delayed_event, chn);
+			libxmp_read_event(ctx, &xc->delayed_event, chn);
 		}
 	}
 
-	act = virt_cstat(ctx, chn);
+	act = libxmp_virt_cstat(ctx, chn);
 	if (act == VIRT_INVALID) {
 		/* We need this to keep processing global volume slides */
-		update_volume(ctx, chn, t);
+		update_volume(ctx, chn);
 		return;
 	}
 
-	if (t == 0 && act != VIRT_ACTIVE) {
+	if (p->frame == 0 && act != VIRT_ACTIVE) {
 		if (!IS_VALID_INSTRUMENT_OR_SFX(xc->ins) || act == VIRT_ACTION_CUT) {
-			virt_resetchannel(ctx, chn);
+			libxmp_virt_resetchannel(ctx, chn);
 			return;
 		}
 	}
@@ -746,7 +1262,7 @@ static void play_channel(struct context_data *ctx, int chn, int t)
 		return;
 
 #ifndef LIBXMP_CORE_PLAYER
-	play_extras(ctx, xc, chn, t);
+	libxmp_play_extras(ctx, xc, chn);
 #endif
 
 	/* Do cut/retrig */
@@ -758,7 +1274,9 @@ static void play_channel(struct context_data *ctx, int chn, int t)
 		if (cond) {
 			if (xc->retrig.type < 0x10) {
 				/* don't retrig on cut */
-				virt_voicepos(ctx, chn, 0);
+				libxmp_virt_voicepos(ctx, chn, 0);
+			} else {
+				SET_NOTE(NOTE_END);
 			}
 			xc->volume += rval[xc->retrig.type].s;
 			xc->volume *= rval[xc->retrig.type].m;
@@ -767,25 +1285,33 @@ static void play_channel(struct context_data *ctx, int chn, int t)
 		}
         }
 
-	process_volume(ctx, chn, t, act);
-	process_frequency(ctx, chn, t, act);
-	process_pan(ctx, chn, t, act);
-
-	update_volume(ctx, chn, t);
-	update_frequency(ctx, chn, t);
-	update_pan(ctx, chn, t);
-
 	/* Do keyoff */
 	if (xc->keyoff) {
 		if (--xc->keyoff == 0)
 			SET_NOTE(NOTE_RELEASE);
 	}
 
-	if (HAS_QUIRK(QUIRK_INVLOOP)) {
+	libxmp_virt_release(ctx, chn, TEST_NOTE(NOTE_RELEASE));
+
+	process_volume(ctx, chn, act);
+	process_frequency(ctx, chn, act);
+	process_pan(ctx, chn, act);
+
+	update_volume(ctx, chn);
+	update_frequency(ctx, chn);
+	update_pan(ctx, chn);
+
+#ifndef LIBXMP_CORE_PLAYER
+	if (HAS_QUIRK(QUIRK_PROTRACK) && xc->ins < mod->ins) {
 		update_invloop(m, xc);
 	}
+#endif
 
-	xc->info_position = virt_getvoicepos(ctx, chn);
+	if (TEST_NOTE(NOTE_SUSEXIT)) {
+		SET_NOTE(NOTE_RELEASE);
+	}
+
+	xc->info_position = libxmp_virt_getvoicepos(ctx, chn);
 }
 
 /*
@@ -803,7 +1329,7 @@ static void inject_event(struct context_data *ctx)
 	for (chn = 0; chn < mod->chn + smix->chn; chn++) {
 		struct xmp_event *e = &p->inject_event[chn];
 		if (e->_flag > 0) {
-			read_event(ctx, e, chn);
+			libxmp_read_event(ctx, e, chn);
 			e->_flag = 0;
 		}
 	}
@@ -819,18 +1345,20 @@ static void next_order(struct context_data *ctx)
 	struct flow_control *f = &p->flow;
 	struct module_data *m = &ctx->m;
 	struct xmp_module *mod = &m->mod;
+	int mark;
 
 	do {
     		p->ord++;
 
 		/* Restart module */
-		if (p->ord >= mod->len || mod->xxo[p->ord] == 0xff) {
+		mark = HAS_QUIRK(QUIRK_MARKER) && mod->xxo[p->ord] == 0xff;
+		if (p->ord >= mod->len || mark) {
 			if (mod->rst > mod->len ||
 			    mod->xxo[mod->rst] >= mod->pat ||
 			    p->ord < m->seq_data[p->sequence].entry_point) {
 				p->ord = m->seq_data[p->sequence].entry_point;
 			} else {
-				if (get_sequence(ctx, mod->rst) == p->sequence) {
+				if (libxmp_get_sequence(ctx, mod->rst) == p->sequence) {
 					p->ord = mod->rst;
 				} else {
 					p->ord = m->seq_data[p->sequence].entry_point;
@@ -868,15 +1396,6 @@ static void next_row(struct context_data *ctx)
 	struct player_data *p = &ctx->p;
 	struct flow_control *f = &p->flow;
 
-	/* If break during pattern delay, next row is skipped.
-	 * See corruption.mod order 1D (pattern 0D) last line:
-	 * EE2 + D31 ignores D00 in order 1C line 31
-	 * Reported by The Welder , Jan 14 2012
-	 */
-	if (f->delay && f->pbreak) {
-		f->skip_fetch = 1;
-	}
-
 	p->frame = 0;
 	f->delay = 0;
 
@@ -912,9 +1431,9 @@ static void next_row(struct context_data *ctx)
 #ifndef LIBXMP_CORE_DISABLE_IT
 
 /*
- * Set note action for virt_pastnote
+ * Set note action for libxmp_virt_pastnote
  */
-void player_set_release(struct context_data *ctx, int chn)
+void libxmp_player_set_release(struct context_data *ctx, int chn)
 {
 	struct player_data *p = &ctx->p;
 	struct channel_data *xc = &p->xc_data[chn];
@@ -922,7 +1441,7 @@ void player_set_release(struct context_data *ctx, int chn)
 	SET_NOTE(NOTE_RELEASE);
 }
 
-void player_set_fadeout(struct context_data *ctx, int chn)
+void libxmp_player_set_fadeout(struct context_data *ctx, int chn)
 {
 	struct player_data *p = &ctx->p;
 	struct channel_data *xc = &p->xc_data[chn];
@@ -932,14 +1451,28 @@ void player_set_fadeout(struct context_data *ctx, int chn)
 
 #endif
 
+static void update_from_ord_info(struct context_data *ctx)
+{
+	struct player_data *p = &ctx->p;
+	struct module_data *m = &ctx->m;
+	struct ord_data *oinfo = &m->xxo_info[p->ord];
+
+	if (oinfo->speed)
+		p->speed = oinfo->speed;
+	p->bpm = oinfo->bpm;
+	p->gvol = oinfo->gvl;
+	p->current_time = oinfo->time;
+	p->frame_time = m->time_factor * m->rrate / p->bpm;
+
+#ifndef LIBXMP_CORE_PLAYER
+	p->st26_speed = oinfo->st26_speed;
+#endif
+}
 
 int xmp_start_player(xmp_context opaque, int rate, int format)
 {
 	struct context_data *ctx = (struct context_data *)opaque;
 	struct player_data *p = &ctx->p;
-#ifndef LIBXMP_CORE_PLAYER
-	struct mixer_data *s = &ctx->s;
-#endif
 	struct smix_data *smix = &ctx->smix;
 	struct module_data *m = &ctx->m;
 	struct xmp_module *mod = &m->mod;
@@ -956,7 +1489,7 @@ int xmp_start_player(xmp_context opaque, int rate, int format)
 	if (ctx->state > XMP_STATE_LOADED)
 		xmp_end_player(opaque);
 
-	if (mixer_on(ctx, rate, format, m->c4rate) < 0)
+	if (libxmp_mixer_on(ctx, rate, format, m->c4rate) < 0)
 		return -XMP_ERROR_INTERNAL;
 
 	p->master_vol = 100;
@@ -995,16 +1528,14 @@ int xmp_start_player(xmp_context opaque, int rate, int format)
 		f->end_point = p->scan[0].num;
 	}
 
-	p->gvol = m->xxo_info[p->ord].gvl;
-	p->bpm = m->xxo_info[p->ord].bpm;
-	p->speed = m->xxo_info[p->ord].speed;
-	p->frame_time = m->time_factor * m->rrate / p->bpm;
+	update_from_ord_info(ctx);
 
-	if (virt_on(ctx, mod->chn + smix->chn) != 0) {
+	if (libxmp_virt_on(ctx, mod->chn + smix->chn) != 0) {
 		ret = -XMP_ERROR_INTERNAL;
 		goto err;
 	}
 
+	f->delay = 0;
 	f->jumpline = 0;
 	f->jump = -1;
 	f->pbreak = 0;
@@ -1025,16 +1556,9 @@ int xmp_start_player(xmp_context opaque, int rate, int format)
 #ifndef LIBXMP_CORE_PLAYER
 	for (i = 0; i < p->virt.virt_channels; i++) {
 		struct channel_data *xc = &p->xc_data[i];
-		if (new_channel_extras(ctx, xc) < 0)
+		if (libxmp_new_channel_extras(ctx, xc) < 0)
 			goto err2;
 	}
-
-	if (m->synth->init(ctx, s->freq) < 0) {
-		ret = -XMP_ERROR_INTERNAL;
-		goto err2;
-	}
-
-	m->synth->reset(ctx);
 #endif
 	reset_channels(ctx);
 
@@ -1052,6 +1576,23 @@ int xmp_start_player(xmp_context opaque, int rate, int format)
 	return ret;
 }
 
+static void check_end_of_module(struct context_data *ctx)
+{
+	struct player_data *p = &ctx->p;
+	struct flow_control *f = &p->flow;
+
+	/* check end of module */
+	if (p->ord == p->scan[p->sequence].ord &&
+			p->row == p->scan[p->sequence].row) {
+		if (f->end_point == 0) {
+			p->loop_count++;
+			f->end_point = p->scan[p->sequence].num;
+			/* return -1; */
+		}
+		f->end_point--;
+	}
+}
+
 int xmp_play_frame(xmp_context opaque)
 {
 	struct context_data *ctx = (struct context_data *)opaque;
@@ -1064,8 +1605,13 @@ int xmp_play_frame(xmp_context opaque)
 	if (ctx->state < XMP_STATE_PLAYING)
 		return -XMP_ERROR_STATE;
 
-	if (mod->len <= 0 || mod->xxo[p->ord] == 0xff)
+	if (mod->len <= 0) {
+		return -XMP_END;
+	}
+
+	if (HAS_QUIRK(QUIRK_MARKER) && mod->xxo[p->ord] == 0xff) {
 		return -XMP_END;
+	}
 
 	/* check reposition */
 	if (p->ord != p->pos) {
@@ -1101,49 +1647,61 @@ int xmp_play_frame(xmp_context opaque)
 
 		next_order(ctx);
 
-		if (m->xxo_info[p->ord].speed)
-			p->speed = m->xxo_info[p->ord].speed;
-		p->bpm = m->xxo_info[p->ord].bpm;
-		p->gvol = m->xxo_info[p->ord].gvl;
-		p->current_time = m->xxo_info[p->ord].time;
+		update_from_ord_info(ctx);
 
-		virt_reset(ctx);
+		libxmp_virt_reset(ctx);
 		reset_channels(ctx);
 	} else {
 		p->frame++;
 		if (p->frame >= (p->speed * (1 + f->delay))) {
+			/* If break during pattern delay, next row is skipped.
+			 * See corruption.mod order 1D (pattern 0D) last line:
+			 * EE2 + D31 ignores D00 in order 1C line 31. Reported
+			 * by The Welder , Jan 14 2012
+			 */
+			if (HAS_QUIRK(QUIRK_PROTRACK) && f->delay && f->pbreak)
+			{
+				next_row(ctx);
+				check_end_of_module(ctx);
+			}
 			next_row(ctx);
 		}
 	}
 
+	for (i = 0; i < mod->chn; i++) {
+		struct channel_data *xc = &p->xc_data[i];
+		RESET(KEY_OFF);
+	}
+
 	/* check new row */
 
 	if (p->frame == 0) {			/* first frame in row */
-		/* check end of module */
-	    	if (p->ord == p->scan[p->sequence].ord &&
-				p->row == p->scan[p->sequence].row) {
-			if (f->end_point == 0) {
-				p->loop_count++;
-				f->end_point = p->scan[p->sequence].num;
-				/* return -1; */
+		check_end_of_module(ctx);
+		read_row(ctx, mod->xxo[p->ord], p->row);
+
+#ifndef LIBXMP_CORE_PLAYER
+		if (p->st26_speed) {
+			if  (p->st26_speed & 0x10000) {
+				p->speed = (p->st26_speed & 0xff00) >> 8;
+			} else {
+				p->speed = p->st26_speed & 0xff;
 			}
-			f->end_point--;
+			p->st26_speed ^= 0x10000;
 		}
-
-		read_row(ctx, mod->xxo[p->ord], p->row);
+#endif
 	}
 
 	inject_event(ctx);
 
 	/* play_frame */
 	for (i = 0; i < p->virt.virt_channels; i++) {
-		play_channel(ctx, i, p->frame);
+		play_channel(ctx, i);
 	}
 
 	p->frame_time = m->time_factor * m->rrate / p->bpm;
 	p->current_time += p->frame_time;
 
-	mixer_softmixer(ctx);
+	libxmp_mixer_softmixer(ctx);
 
 	return 0;
 }
@@ -1211,7 +1769,6 @@ void xmp_end_player(xmp_context opaque)
 	struct player_data *p = &ctx->p;
 	struct flow_control *f = &p->flow;
 #ifndef LIBXMP_CORE_PLAYER
-	struct module_data *m = &ctx->m;
 	struct channel_data *xc;
 	int i;
 #endif
@@ -1225,14 +1782,11 @@ void xmp_end_player(xmp_context opaque)
 	/* Free channel extras */
 	for (i = 0; i < p->virt.virt_channels; i++) {
 		xc = &p->xc_data[i];
-		release_channel_extras(ctx, xc);
+		libxmp_release_channel_extras(ctx, xc);
 	}
 #endif
 
-	virt_off(ctx);
-#ifndef LIBXMP_CORE_PLAYER
-	m->synth->deinit(ctx);
-#endif
+	libxmp_virt_off(ctx);
 
 	free(p->xc_data);
 	free(f->loop);
@@ -1240,7 +1794,7 @@ void xmp_end_player(xmp_context opaque)
 	p->xc_data = NULL;
 	f->loop = NULL;
 
-	mixer_off(ctx);
+	libxmp_mixer_off(ctx);
 }
 
 void xmp_get_module_info(xmp_context opaque, struct xmp_module_info *info)
@@ -1343,4 +1897,3 @@ void xmp_get_frame_info(xmp_context opaque, struct xmp_frame_info *info)
 		}
 	}
 }
-
diff --git a/src/player.h b/src/player.h
index b411f30..4b46e60 100644
--- a/src/player.h
+++ b/src/player.h
@@ -2,7 +2,6 @@
 #define LIBXMP_PLAYER_H
 
 #include "lfo.h"
-#include "envelope.h"
 
 /* Quirk control */
 #define HAS_QUIRK(x)	(m->quirk & (x))
@@ -51,12 +50,23 @@ struct retrig_control {
 #define PANBRELLO	(1 << 19)
 #define GVOL_SLIDE	(1 << 20)
 #define TEMPO_SLIDE	(1 << 21)
+#define VENV_PAUSE	(1 << 22)
+#define PENV_PAUSE	(1 << 23)
+#define FENV_PAUSE	(1 << 24)
+#define FINE_VOLS_2	(1 << 25)
+#define KEY_OFF		(1 << 26)	/* for IT release on envloop end */
+#define TREMOR		(1 << 27)	/* for XM tremor */
 
 #define NOTE_FADEOUT	(1 << 0)
 #define NOTE_RELEASE	(1 << 1)
 #define NOTE_END	(1 << 2)
 #define NOTE_CUT	(1 << 3)
 #define NOTE_ENV_END	(1 << 4)
+#define NOTE_SAMPLE_END	(1 << 5)
+#define NOTE_SET	(1 << 6)	/* for IT portamento after keyoff */
+#define NOTE_SUSEXIT	(1 << 7)	/* for delayed note release */
+#define NOTE_KEY_CUT	(1 << 8)	/* note cut with XMP_KEY_CUT event */
+#define NOTE_GLISSANDO	(1 << 9)
 
 #define IS_VALID_INSTRUMENT(x) ((uint32)(x) < mod->ins && mod->xxi[(x)].nsm > 0)
 #define IS_VALID_INSTRUMENT_OR_SFX(x) (((uint32)(x) < mod->ins && mod->xxi[(x)].nsm > 0) || (smix->ins > 0 && (uint32)(x) < mod->ins + smix->ins))
@@ -77,22 +87,27 @@ struct channel_data {
 	int finetune;		/* Guess what */
 	int ins;		/* Instrument number */
 	int old_ins;		/* Last instruemnt */
-	int old_insvol;		/* Last instrument that did set a note */
 	int smp;		/* Sample number */
 	int mastervol;		/* Master vol -- for IT track vol effect */
 	int delay;		/* Note delay in frames */
 	int keyoff;		/* Key off counter */
 	int fadeout;		/* Current fadeout (release) value */
-	int gliss;		/* Glissando active */
+	int ins_fade;		/* Instrument fadeout value */
 	int volume;		/* Current volume */
 	int gvl;		/* Global volume for instrument for IT */
-	int offset;		/* Sample offset memory */
-	int offset_val;		/* Sample offset */
 
-	uint16 v_idx;		/* Volume envelope index */
-	uint16 p_idx;		/* Pan envelope index */
-	uint16 f_idx;		/* Freq envelope index */
+	int rvv;		/* Random volume variation */
+	int rpv;		/* Random pan variation */
 
+	uint8 split;		/* Split channel */
+	uint8 pair;		/* Split channel pair */
+
+	int v_idx;		/* Volume envelope index */
+	int p_idx;		/* Pan envelope index */
+	int f_idx;		/* Freq envelope index */
+
+	int key_porta;		/* Key number for portamento target
+				 * -- needed to handle IT portamento xpo */
 	struct {
 		struct lfo lfo;
 		int memory;
@@ -122,6 +137,12 @@ struct channel_data {
 		int sweep;
 	} insvib;
 
+	struct {
+		int val;
+		int val2;	/* For fx9 bug emulation */
+		int memory;
+	} offset;
+
 	struct {
 		int val;	/* Retrig value */
 		int count;	/* Retrig counter */
@@ -129,9 +150,9 @@ struct channel_data {
 	} retrig;
 
 	struct {
-		int val;	/* Tremor value */
-		int count;	/* Tremor counter */
-		int memory;	/* Tremor memory */
+		uint8 up,down;	/* Tremor value */
+		uint8 count;	/* Tremor counter */
+		uint8 memory;	/* Tremor memory */
 	} tremor;
 
 	struct {
@@ -139,6 +160,10 @@ struct channel_data {
 		int fslide;	/* Fine volume slide value */
 		int slide2;	/* Volume slide value */
 		int memory;	/* Volume slide effect memory */
+#ifndef LIBXMP_CORE_DISABLE_IT
+		int fslide2;
+		int memory2;	/* Volume slide effect memory */
+#endif
 	} vol;
 
 	struct {
@@ -181,6 +206,7 @@ struct channel_data {
 		int slide;	/* Pan slide value */
 		int fslide;	/* Pan fine slide value */
 		int memory;	/* Pan slide effect memory */
+		int surround;	/* Surround channel flag */
 	} pan;	
 
 	struct {
@@ -197,6 +223,7 @@ struct channel_data {
 	struct {
 		int cutoff;	/* IT filter cutoff frequency */
 		int resonance;	/* IT filter resonance */
+		int envelope;	/* IT filter envelope */
 	} filter;
 
 #endif
@@ -223,8 +250,9 @@ struct channel_data {
 };
 
 
-void process_fx(struct context_data *, struct channel_data *, int, uint8, uint8, uint8, int);
-void filter_setup(int, int, int, int*, int*, int *);
-int read_event(struct context_data *, struct xmp_event *, int);
+void	libxmp_process_fx	(struct context_data *, struct channel_data *,
+				 int, struct xmp_event *, int);
+void	libxmp_filter_setup	(int, int, int, int*, int*, int *);
+int	libxmp_read_event	(struct context_data *, struct xmp_event *, int);
 
 #endif /* LIBXMP_PLAYER_H */
diff --git a/src/precomp_blep.h b/src/precomp_blep.h
new file mode 100644
index 0000000..ec38073
--- /dev/null
+++ b/src/precomp_blep.h
@@ -0,0 +1,256 @@
+ /*
+  * Table generated by compute-blep.py (a1200 and vanilla tables removed)
+  */
+
+/* tables are: a500 off, a500 on */
+const int winsinc_integral[2][2048] = {
+    {
+131072,131072,131072,131072,131072,131072,131072,131072,131072,131072,131072,
+131072,131072,131072,131072,131072,131072,131072,131072,131072,131072,131071,131071,
+131071,131071,131071,131071,131071,131071,131071,131071,131071,131070,131070,131070,
+131070,131070,131069,131069,131069,131068,131068,131068,131067,131067,131066,131066,
+131065,131065,131064,131063,131063,131062,131061,131060,131059,131058,131056,131055,
+131054,131052,131050,131049,131047,131045,131043,131040,131038,131035,131033,131030,
+131026,131023,131020,131016,131012,131008,131003,130998,130993,130988,130982,130976,
+130970,130963,130956,130949,130941,130932,130924,130914,130905,130895,130884,130872,
+130861,130848,130835,130821,130807,130792,130776,130759,130742,130724,130705,130685,
+130664,130642,130620,130596,130571,130545,130518,130490,130461,130430,130398,130365,
+130331,130295,130257,130219,130178,130136,130093,130047,130000,129951,129901,129848,
+129794,129737,129679,129618,129555,129490,129423,129353,129281,129207,129130,129050,
+128968,128883,128795,128704,128611,128514,128415,128312,128206,128097,127985,127869,
+127750,127627,127501,127371,127237,127100,126959,126813,126664,126510,126353,126191,
+126025,125854,125679,125499,125315,125126,124933,124734,124531,124323,124110,123891,
+123668,123439,123205,122965,122720,122470,122214,121952,121685,121412,121133,120849,
+120558,120261,119959,119650,119335,119014,118687,118354,118014,117668,117315,116956,
+116591,116219,115840,115455,115063,114665,114260,113849,113430,113005,112574,112135,
+111690,111239,110780,110315,109843,109364,108879,108387,107888,107383,106871,106352,
+105827,105295,104757,104212,103661,103104,102540,101970,101394,100812,100223,99629,
+99028,98422,97810,97192,96568,95939,95305,94665,94020,93370,92714,92054,91389,90719,
+90045,89366,88682,87995,87303,86607,85908,85205,84498,83788,83075,82358,81639,80916,
+80191,79464,78734,78002,77268,76533,75795,75056,74316,73575,72833,72090,71346,70602,
+69858,69114,68370,67626,66883,66140,65399,64658,63919,63181,62445,61711,60979,60249,
+59521,58796,58074,57355,56639,55926,55217,54512,53810,53113,52419,51731,51046,50367,
+49693,49023,48359,47701,47048,46400,45759,45124,44495,43872,43256,42646,42043,41447,
+40858,40276,39702,39134,38575,38023,37478,36941,36413,35892,35379,34874,34378,33890,
+33410,32938,32475,32020,31574,31137,30708,30288,29876,29473,29079,28693,28317,27948,
+27589,27238,26896,26562,26238,25921,25613,25314,25023,24740,24466,24200,23942,23692,
+23451,23217,22991,22773,22562,22359,22164,21975,21794,21621,21454,21294,21140,20994,
+20853,20719,20592,20470,20354,20244,20139,20040,19946,19857,19774,19694,19620,19550,
+19484,19422,19364,19310,19260,19213,19169,19128,19090,19054,19022,18991,18963,18936,
+18912,18889,18867,18847,18828,18810,18792,18776,18759,18743,18727,18711,18695,18679,
+18662,18644,18626,18607,18587,18565,18542,18518,18492,18465,18436,18404,18371,18336,
+18298,18259,18216,18172,18124,18074,18022,17966,17908,17847,17783,17716,17646,17572,
+17496,17416,17334,17248,17159,17066,16971,16872,16770,16664,16556,16444,16329,16211,
+16090,15966,15839,15709,15576,15440,15301,15159,15015,14868,14718,14566,14412,14255,
+14096,13935,13771,13606,13439,13270,13099,12927,12753,12578,12401,12224,12045,11866,
+11685,11504,11322,11140,10958,10775,10592,10409,10226,10044,9862,9680,9499,9319,9139,
+8961,8783,8607,8432,8258,8086,7915,7747,7580,7415,7252,7091,6932,6776,6622,6471,
+6322,6176,6032,5892,5754,5619,5488,5359,5234,5111,4992,4877,4764,4655,4550,4448,
+4349,4254,4163,4075,3990,3910,3832,3759,3689,3622,3560,3500,3445,3393,3344,3299,
+3257,3219,3184,3153,3124,3099,3078,3059,3044,3031,3022,3015,3011,3010,3012,3016,
+3023,3033,3044,3058,3075,3093,3113,3136,3160,3186,3213,3242,3273,3305,3338,3372,
+3408,3444,3481,3520,3558,3597,3637,3677,3718,3758,3799,3839,3880,3920,3960,4000,
+4039,4077,4115,4152,4188,4224,4258,4291,4323,4354,4384,4412,4439,4464,4488,4510,
+4530,4549,4566,4581,4594,4606,4615,4623,4628,4631,4633,4632,4629,4624,4617,4608,
+4597,4583,4568,4550,4530,4508,4484,4458,4429,4399,4366,4332,4296,4257,4217,4175,
+4130,4085,4037,3988,3937,3884,3830,3774,3717,3658,3598,3537,3475,3411,3347,3281,
+3215,3147,3079,3010,2940,2870,2799,2728,2657,2585,2513,2440,2368,2296,2224,2151,
+2080,2008,1937,1866,1796,1726,1657,1589,1521,1454,1389,1324,1260,1197,1135,1075,
+1016,958,901,846,792,740,689,640,592,546,502,459,419,379,342,307,273,241,211,183,
+156,132,109,88,69,52,37,24,12,2,-5,-11,-16,-18,-19,-18,-16,-11,-6,2,11,21,33,47,61,
+77,95,113,133,154,176,200,224,249,275,302,329,358,387,416,447,477,508,540,572,604,
+636,669,702,734,767,800,832,864,896,928,960,991,1021,1051,1081,1110,1138,1166,1193,
+1219,1245,1270,1293,1316,1338,1359,1379,1398,1416,1433,1448,1463,1476,1488,1499,
+1509,1518,1525,1531,1536,1540,1542,1543,1543,1542,1539,1536,1530,1524,1517,1508,
+1498,1487,1475,1462,1447,1432,1415,1397,1379,1359,1338,1317,1294,1271,1247,1222,
+1196,1170,1143,1115,1086,1057,1028,998,967,936,905,874,842,809,777,744,712,679,646,
+613,581,548,515,483,450,418,387,355,324,293,263,233,204,175,147,119,92,66,40,15,
+-10,-33,-56,-78,-99,-120,-139,-158,-176,-193,-209,-224,-238,-252,-264,-275,-286,
+-295,-304,-311,-318,-324,-329,-332,-335,-337,-338,-338,-338,-336,-333,-330,-326,
+-321,-315,-308,-301,-293,-284,-274,-264,-253,-242,-229,-217,-203,-190,-175,-161,
+-145,-130,-114,-98,-81,-64,-47,-29,-11,6,24,42,61,79,97,115,134,152,170,188,206,223,
+241,258,275,291,308,324,340,355,370,384,399,412,425,438,450,462,473,484,494,503,
+512,521,529,536,542,548,553,558,562,566,568,570,572,573,573,573,572,570,568,565,
+562,558,553,548,543,537,530,523,515,507,498,489,479,469,459,448,437,426,414,402,
+389,377,364,351,337,324,310,296,282,268,254,239,225,211,196,182,168,153,139,125,
+111,97,83,70,56,43,30,17,5,-7,-19,-31,-42,-53,-64,-75,-85,-94,-104,-113,-121,-129,
+-137,-144,-151,-158,-164,-170,-175,-180,-184,-188,-192,-195,-198,-200,-202,-203,
+-204,-205,-205,-204,-204,-203,-201,-199,-197,-195,-192,-188,-185,-181,-176,-172,
+-167,-162,-156,-151,-145,-139,-132,-126,-119,-112,-104,-97,-90,-82,-74,-66,-59,-51,
+-42,-34,-26,-18,-10,-2,7,15,23,31,39,47,54,62,70,77,85,92,99,106,112,119,125,131,
+137,143,148,154,159,163,168,172,176,180,183,187,190,192,195,197,199,201,202,203,
+204,205,205,205,205,204,203,202,201,200,198,196,194,192,189,186,183,180,177,173,
+169,165,161,157,153,148,143,139,134,129,124,119,113,108,103,97,92,86,81,75,70,64,
+59,53,48,42,37,32,26,21,16,11,6,1,-4,-9,-13,-18,-22,-26,-30,-34,-38,-42,-46,-49,
+-52,-55,-58,-61,-64,-66,-69,-71,-73,-74,-76,-78,-79,-80,-81,-82,-82,-83,-83,-83,
+-83,-83,-83,-82,-82,-81,-80,-79,-78,-77,-75,-74,-72,-70,-68,-66,-64,-62,-60,-57,
+-55,-52,-50,-47,-44,-42,-39,-36,-33,-30,-27,-24,-21,-18,-15,-12,-9,-6,-3,0,3,6,8,
+11,14,17,20,22,25,27,30,32,35,37,39,41,43,45,47,49,50,52,54,55,56,58,59,60,61,61,
+62,63,63,64,64,65,65,65,65,65,64,64,64,63,63,62,61,61,60,59,58,57,56,55,53,52,51,
+49,48,46,45,43,41,40,38,36,35,33,31,29,28,26,24,22,20,19,17,15,13,11,10,8,6,5,3,1,
+0,-2,-3,-5,-6,-8,-9,-10,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-21,-22,-23,-23,
+-24,-24,-25,-25,-26,-26,-26,-26,-26,-26,-26,-26,-26,-26,-26,-26,-25,-25,-25,-24,
+-24,-23,-23,-22,-21,-21,-20,-19,-19,-18,-17,-16,-16,-15,-14,-13,-12,-11,-10,-10,-9,
+-8,-7,-6,-5,-4,-3,-2,-1,0,1,1,2,3,4,5,6,6,7,8,9,9,10,11,11,12,12,13,14,14,15,15,
+15,16,16,16,17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18,18,17,17,17,17,16,16,
+16,16,15,15,14,14,14,13,13,12,12,11,11,11,10,10,9,9,8,8,7,7,6,6,5,5,4,4,3,3,2,2,1,
+1,0,0,-1,-1,-1,-2,-2,-3,-3,-3,-4,-4,-4,-4,-5,-5,-5,-5,-6,-6,-6,-6,-6,-6,-6,-7,-7,
+-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-6,-6,-6,-6,-6,-6,-6,-6,-5,-5,-5,-5,-5,-4,-4,-4,
+-4,-4,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1,-1,-1,-1,0,0,0,0,1,1,1,1,1,2,2,2,2,2,2,3,3,3,
+3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,
+3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    },
+    {
+131072,131072,131072,131072,131072,131072,131072,131072,131072,131072,131072,
+131072,131072,131072,131072,131072,131072,131072,131072,131072,131072,131072,131072,
+131072,131072,131072,131072,131072,131072,131072,131072,131072,131071,131071,131071,
+131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,
+131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,
+131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,131071,
+131071,131071,131071,131071,131071,131071,131070,131070,131070,131070,131070,131070,
+131070,131070,131070,131070,131070,131070,131070,131070,131070,131070,131069,131069,
+131069,131069,131069,131069,131069,131069,131068,131068,131068,131068,131068,131068,
+131067,131067,131067,131067,131066,131066,131066,131066,131065,131065,131064,131064,
+131064,131063,131063,131062,131062,131061,131061,131060,131060,131059,131058,131058,
+131057,131056,131055,131055,131054,131053,131052,131051,131050,131049,131047,131046,
+131045,131044,131042,131041,131039,131038,131036,131034,131032,131031,131029,131027,
+131024,131022,131020,131017,131015,131012,131009,131007,131004,131001,130997,130994,
+130991,130987,130983,130979,130975,130971,130967,130962,130958,130953,130948,130942,
+130937,130931,130926,130920,130913,130907,130900,130893,130886,130879,130871,130863,
+130855,130847,130838,130829,130820,130810,130800,130790,130779,130768,130757,130745,
+130733,130721,130708,130695,130682,130668,130654,130639,130624,130608,130592,130576,
+130559,130541,130523,130505,130486,130466,130446,130426,130405,130383,130361,130338,
+130314,130290,130265,130240,130214,130187,130160,130132,130103,130074,130044,130013,
+129981,129949,129916,129882,129847,129812,129775,129738,129700,129661,129621,129581,
+129539,129497,129453,129409,129364,129318,129270,129222,129173,129123,129071,129019,
+128966,128911,128856,128799,128742,128683,128623,128562,128500,128436,128372,128306,
+128239,128171,128101,128031,127959,127886,127811,127736,127659,127580,127501,127420,
+127337,127254,127169,127082,126995,126906,126815,126723,126630,126535,126439,126341,
+126242,126142,126040,125936,125831,125725,125617,125507,125396,125284,125170,125055,
+124938,124819,124699,124577,124454,124329,124203,124075,123946,123815,123683,123549,
+123413,123276,123137,122997,122855,122711,122566,122420,122272,122122,121971,121818,
+121663,121507,121350,121191,121030,120868,120704,120539,120372,120204,120034,119863,
+119690,119515,119339,119162,118983,118803,118621,118438,118253,118067,117879,117690,
+117500,117308,117114,116920,116724,116526,116327,116127,115926,115723,115519,115313,
+115106,114898,114689,114478,114266,114053,113839,113624,113407,113189,112970,112750,
+112528,112306,112082,111858,111632,111405,111177,110948,110718,110487,110255,110022,
+109788,109553,109317,109080,108842,108604,108364,108124,107883,107641,107398,107154,
+106909,106664,106418,106171,105923,105675,105426,105176,104926,104675,104423,104171,
+103918,103664,103410,103155,102899,102643,102387,102130,101872,101614,101356,101096,
+100837,100577,100316,100055,99794,99532,99270,99007,98745,98481,98217,97953,97689,
+97424,97159,96894,96628,96362,96096,95829,95563,95296,95028,94761,94493,94225,93957,
+93688,93419,93151,92881,92612,92343,92073,91803,91534,91263,90993,90723,90452,90182,
+89911,89640,89369,89098,88827,88556,88284,88013,87741,87470,87198,86926,86654,86382,
+86110,85838,85566,85294,85022,84750,84477,84205,83933,83660,83388,83116,82843,82571,
+82298,82026,81753,81481,81208,80936,80663,80391,80118,79846,79573,79301,79029,78756,
+78484,78212,77939,77667,77395,77123,76851,76579,76307,76035,75763,75491,75220,74948,
+74676,74405,74134,73862,73591,73320,73049,72778,72507,72237,71966,71696,71426,71156,
+70886,70616,70346,70077,69807,69538,69269,69000,68732,68463,68195,67927,67659,67391,
+67124,66857,66590,66323,66056,65790,65524,65258,64993,64728,64463,64198,63934,63670,
+63406,63143,62880,62617,62354,62092,61830,61569,61308,61047,60787,60527,60267,60008,
+59749,59491,59233,58975,58718,58461,58205,57949,57694,57439,57184,56930,56676,56423,
+56171,55918,55667,55416,55165,54915,54665,54416,54167,53919,53671,53424,53178,52932,
+52686,52442,52197,51954,51710,51468,51226,50984,50743,50503,50263,50024,49786,49548,
+49310,49074,48838,48602,48367,48133,47899,47666,47434,47202,46971,46740,46510,46281,
+46052,45824,45597,45370,45144,44918,44693,44469,44245,44022,43800,43578,43357,43137,
+42917,42698,42479,42261,42044,41827,41612,41396,41181,40967,40754,40541,40329,40118,
+39907,39696,39487,39278,39069,38862,38655,38448,38242,38037,37832,37628,37425,37222,
+37020,36819,36618,36417,36218,36019,35820,35622,35425,35228,35032,34837,34642,34448,
+34254,34061,33869,33677,33486,33295,33105,32916,32727,32539,32352,32164,31978,31792,
+31607,31422,31238,31055,30872,30690,30508,30327,30147,29967,29787,29609,29431,29253,
+29076,28900,28724,28549,28374,28200,28027,27854,27682,27510,27339,27169,26999,26830,
+26661,26493,26326,26159,25993,25827,25662,25498,25334,25171,25008,24846,24685,24524,
+24364,24204,24045,23887,23729,23572,23416,23260,23104,22950,22796,22642,22490,22337,
+22186,22035,21884,21735,21586,21437,21289,21142,20996,20850,20704,20560,20416,20272,
+20129,19987,19845,19705,19564,19425,19285,19147,19009,18872,18735,18599,18464,18329,
+18195,18062,17929,17797,17665,17534,17404,17274,17145,17017,16889,16762,16635,16509,
+16384,16259,16135,16011,15888,15766,15644,15523,15403,15283,15163,15044,14926,14809,
+14692,14575,14460,14344,14230,14116,14002,13889,13777,13665,13554,13443,13333,13224,
+13115,13007,12899,12792,12685,12579,12473,12368,12264,12160,12056,11953,11851,11749,
+11648,11547,11447,11347,11248,11149,11051,10953,10856,10759,10663,10568,10472,10378,
+10284,10190,10097,10004,9912,9820,9729,9638,9548,9458,9369,9280,9191,9104,9016,8929,
+8843,8757,8671,8586,8501,8417,8333,8250,8167,8085,8003,7921,7840,7759,7679,7599,
+7520,7441,7363,7285,7207,7130,7053,6977,6901,6826,6751,6676,6602,6528,6455,6382,
+6310,6237,6166,6095,6024,5954,5884,5814,5745,5676,5608,5540,5473,5405,5339,5273,
+5207,5141,5076,5012,4947,4884,4820,4757,4694,4632,4570,4509,4448,4387,4327,4267,
+4208,4149,4090,4032,3974,3917,3859,3803,3746,3691,3635,3580,3525,3471,3417,3363,
+3310,3257,3204,3152,3100,3049,2998,2947,2897,2847,2797,2748,2699,2651,2603,2555,
+2507,2460,2414,2367,2321,2276,2230,2185,2141,2096,2052,2009,1966,1923,1880,1838,
+1796,1754,1713,1672,1631,1591,1551,1511,1472,1432,1394,1355,1317,1279,1242,1204,
+1167,1131,1094,1058,1023,987,952,917,882,848,814,780,747,713,680,648,615,583,551,
+519,488,457,426,396,365,335,305,276,246,217,188,160,132,103,76,48,21,-7,-34,-60,
+-87,-113,-139,-165,-190,-216,-241,-266,-290,-315,-339,-363,-387,-410,-434,-457,
+-480,-502,-525,-547,-569,-591,-613,-634,-656,-677,-697,-718,-739,-759,-779,-799,
+-818,-838,-857,-876,-895,-914,-932,-951,-969,-987,-1005,-1022,-1040,-1057,-1074,
+-1091,-1107,-1124,-1140,-1156,-1172,-1188,-1203,-1219,-1234,-1249,-1264,-1279,-1293,
+-1308,-1322,-1336,-1350,-1363,-1377,-1390,-1403,-1416,-1429,-1442,-1454,-1467,-1479,
+-1491,-1503,-1514,-1526,-1537,-1548,-1559,-1570,-1581,-1592,-1602,-1613,-1623,-1633,
+-1643,-1652,-1662,-1671,-1680,-1690,-1699,-1707,-1716,-1725,-1733,-1741,-1750,-1758,
+-1765,-1773,-1781,-1788,-1796,-1803,-1810,-1817,-1824,-1830,-1837,-1843,-1850,-1856,
+-1862,-1868,-1874,-1880,-1885,-1891,-1896,-1902,-1907,-1912,-1917,-1922,-1926,-1931,
+-1935,-1940,-1944,-1948,-1952,-1956,-1960,-1964,-1968,-1971,-1975,-1978,-1982,-1985,
+-1988,-1991,-1994,-1997,-2000,-2002,-2005,-2007,-2010,-2012,-2014,-2017,-2019,-2021,
+-2022,-2024,-2026,-2028,-2029,-2031,-2032,-2034,-2035,-2036,-2037,-2038,-2039,-2040,
+-2041,-2042,-2042,-2043,-2044,-2044,-2045,-2045,-2045,-2045,-2046,-2046,-2046,-2046,
+-2046,-2045,-2045,-2045,-2044,-2044,-2044,-2043,-2042,-2042,-2041,-2040,-2039,-2039,
+-2038,-2037,-2035,-2034,-2033,-2032,-2031,-2029,-2028,-2026,-2025,-2023,-2022,-2020,
+-2018,-2017,-2015,-2013,-2011,-2009,-2007,-2005,-2003,-2001,-1999,-1996,-1994,-1992,
+-1989,-1987,-1984,-1982,-1979,-1977,-1974,-1971,-1969,-1966,-1963,-1960,-1957,-1954,
+-1951,-1948,-1945,-1942,-1939,-1936,-1933,-1929,-1926,-1923,-1919,-1916,-1913,-1909,
+-1906,-1902,-1899,-1895,-1891,-1888,-1884,-1880,-1877,-1873,-1869,-1865,-1861,-1857,
+-1853,-1849,-1845,-1841,-1837,-1833,-1829,-1825,-1821,-1817,-1813,-1809,-1804,-1800,
+-1796,-1791,-1787,-1783,-1778,-1774,-1770,-1765,-1761,-1756,-1752,-1747,-1743,-1738,
+-1734,-1729,-1725,-1720,-1716,-1711,-1706,-1702,-1697,-1692,-1688,-1683,-1678,-1673,
+-1669,-1664,-1659,-1654,-1650,-1645,-1640,-1635,-1630,-1626,-1621,-1616,-1611,-1606,
+-1601,-1596,-1591,-1586,-1582,-1577,-1572,-1567,-1562,-1557,-1552,-1547,-1542,-1537,
+-1532,-1527,-1522,-1517,-1512,-1507,-1502,-1497,-1492,-1487,-1482,-1477,-1472,-1467,
+-1462,-1457,-1452,-1447,-1442,-1437,-1432,-1427,-1422,-1417,-1412,-1407,-1402,-1397,
+-1392,-1386,-1381,-1376,-1371,-1366,-1361,-1356,-1351,-1346,-1341,-1336,-1331,-1326,
+-1321,-1316,-1311,-1306,-1301,-1296,-1291,-1286,-1281,-1276,-1271,-1266,-1261,-1256,
+-1251,-1246,-1241,-1236,-1231,-1226,-1221,-1216,-1211,-1206,-1201,-1196,-1191,-1186,
+-1181,-1176,-1171,-1166,-1161,-1156,-1152,-1147,-1142,-1137,-1132,-1127,-1122,-1117,
+-1112,-1108,-1103,-1098,-1093,-1088,-1083,-1079,-1074,-1069,-1064,-1060,-1055,-1050,
+-1045,-1040,-1036,-1031,-1026,-1022,-1017,-1012,-1008,-1003,-998,-994,-989,-984,-980,
+-975,-970,-966,-961,-957,-952,-947,-943,-938,-934,-929,-925,-920,-916,-911,-907,
+-902,-898,-894,-889,-885,-880,-876,-872,-867,-863,-859,-854,-850,-846,-841,-837,
+-833,-828,-824,-820,-816,-812,-807,-803,-799,-795,-791,-787,-782,-778,-774,-770,
+-766,-762,-758,-754,-750,-746,-742,-738,-734,-730,-726,-722,-718,-714,-710,-706,
+-702,-699,-695,-691,-687,-683,-679,-676,-672,-668,-664,-661,-657,-653,-649,-646,
+-642,-638,-635,-631,-627,-624,-620,-617,-613,-609,-606,-602,-599,-595,-592,-588,
+-585,-581,-578,-574,-571,-568,-564,-561,-557,-554,-551,-547,-544,-541,-537,-534,
+-531,-528,-524,-521,-518,-515,-511,-508,-505,-502,-499,-496,-492,-489,-486,-483,
+-480,-477,-474,-471,-468,-465,-462,-459,-456,-453,-450,-447,-444,-441,-438,-435,
+-433,-430,-427,-424,-421,-418,-416,-413,-410,-407,-405,-402,-399,-396,-394,-391,
+-388,-386,-383,-380,-378,-375,-373,-370,-367,-365,-362,-360,-357,-355,-352,-350,
+-347,-345,-342,-340,-337,-335,-333,-330,-328,-325,-323,-321,-318,-316,-314,-311,
+-309,-307,-305,-302,-300,-298,-296,-293,-291,-289,-287,-285,-282,-280,-278,-276,
+-274,-272,-270,-268,-266,-264,-261,-259,-257,-255,-253,-251,-249,-247,-246,-244,
+-242,-240,-238,-236,-234,-232,-230,-228,-226,-225,-223,-221,-219,-217,-216,-214,
+-212,-210,-209,-207,-205,-203,-202,-200,-198,-197,-195,-193,-192,-190,-188,-187,
+-185,-183,-182,-180,-179,-177,-176,-174,-172,-171,-169,-168,-166,-165,-163,-162,
+-161,-159,-158,-156,-155,-153,-152,-151,-149,-148,-146,-145,-144,-142,-141,-140,
+-138,-137,-136,-134,-133,-132,-131,-129,-128,-127,-126,-124,-123,-122,-121,-120,
+-118,-117,-116,-115,-114,-113,-111,-110,-109,-108,-107,-106,-105,-104,-103,-102,
+-100,-99,-98,-97,-96,-95,-94,-93,-92,-91,-90,-89,-88,-87,-86,-85,-85,-84,-83,-82,
+-81,-80,-79,-78,-77,-76,-75,-75,-74,-73,-72,-71,-70,-70,-69,-68,-67,-66,-66,-65,
+-64,-63,-62,-62,-61,-60,-59,-59,-58,-57,-56,-56,-55,-54,-54,-53,-52,-52,-51,-50,
+-50,-49,-48,-48,-47,-46,-46,-45,-45,-44,-43,-43,-42,-42,-41,-40,-40,-39,-39,-38,
+-38,-37,-36,-36,-35,-35,-34,-34,-33,-33,-32,-32,-31,-31,-30,-30,-29,-29,-29,-28,
+-28,-27,-27,-26,-26,-25,-25,-25,-24,-24,-23,-23,-23,-22,-22,-21,-21,-21,-20,-20,
+-20,-19,-19,-18,-18,-18,-17,-17,-17,-16,-16,-16,-15,-15,-15,-15,-14,-14,-14,-13,
+-13,-13,-13,-12,-12,-12,-11,-11,-11,-11,-10,-10,-10,-10,-9,-9,-9,-9,-9,-8,-8,-8,-8,
+-7,-7,-7,-7,-7,-6,-6,-6,-6,-6,-6,-5,-5,-5,-5,-5,-5,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,
+-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+0,0,0,0,0,0,0,0,0,
+    }
+};
diff --git a/src/read_event.c b/src/read_event.c
index cb36e80..2832898 100644
--- a/src/read_event.c
+++ b/src/read_event.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -21,6 +21,7 @@
  */
 
 #include 
+#include 
 #include "common.h"
 #include "player.h"
 #include "effects.h"
@@ -32,12 +33,9 @@
 #endif
 
 
-static inline void copy_channel(struct player_data *p, int to, int from)
+static inline int is_valid_note(int note)
 {
-	if (to > 0 && to != from) {
-		memcpy(&p->xc_data[to], &p->xc_data[from],
-					sizeof (struct channel_data));
-	}
+	return (note >= 0 && note < XMP_MAX_KEYS);
 }
 
 static struct xmp_subinstrument *get_subinstrument(struct context_data *ctx,
@@ -47,70 +45,115 @@ static struct xmp_subinstrument *get_subinstrument(struct context_data *ctx,
 	struct xmp_module *mod = &m->mod;
 	struct xmp_instrument *instrument;
 
-	if (ins >= 0 && ins < mod->ins) {
+	if (IS_VALID_INSTRUMENT(ins)) {
 		instrument = &mod->xxi[ins];
-		if (key >= 0 && key < XMP_MAX_KEYS) {
+		if (is_valid_note(key)) {
 			int mapped = instrument->map[key].ins;
 			if (mapped != 0xff && mapped >= 0 && mapped < instrument->nsm)
 			  	return &instrument->sub[mapped];
-	  }
+		} else {
+			if (mod->xxi[ins].nsm > 0) {
+				return &instrument->sub[0];
+			}
+		}
 	}
 
 	return NULL;
 }
 
-static void reset_envelopes(struct context_data *ctx, struct channel_data *xc,
-				int force_cut)
+static void reset_envelopes(struct context_data *ctx, struct channel_data *xc)
+{
+	struct module_data *m = &ctx->m;
+	struct xmp_module *mod = &m->mod;
+
+	if (!IS_VALID_INSTRUMENT(xc->ins))
+		return;
+
+ 	RESET_NOTE(NOTE_ENV_END);
+
+	xc->v_idx = -1;
+	xc->p_idx = -1;
+	xc->f_idx = -1;
+}
+
+#ifndef LIBXMP_CORE_DISABLE_IT
+
+static void reset_envelopes_carry(struct context_data *ctx,
+				struct channel_data *xc)
 {
+	struct module_data *m = &ctx->m;
+	struct xmp_module *mod = &m->mod;
 	struct xmp_instrument *xxi;
 
-	xxi = get_instrument(ctx, xc->ins);
+	if (!IS_VALID_INSTRUMENT(xc->ins))
+		return;
+
+ 	RESET_NOTE(NOTE_ENV_END);
+
+	xxi = libxmp_get_instrument(ctx, xc->ins);
 
 	/* Reset envelope positions */
-	if (force_cut || (~xxi->aei.flg & XMP_ENVELOPE_CARRY)) {
-		xc->v_idx = 0;
+	if (~xxi->aei.flg & XMP_ENVELOPE_CARRY) {
+		xc->v_idx = -1;
 	}
-	if (force_cut || (~xxi->pei.flg & XMP_ENVELOPE_CARRY)) {
-		xc->p_idx = 0;
+	if (~xxi->pei.flg & XMP_ENVELOPE_CARRY) {
+		xc->p_idx = -1;
 	}
-	if (force_cut || (~xxi->fei.flg & XMP_ENVELOPE_CARRY)) {
-		xc->f_idx = 0;
+	if (~xxi->fei.flg & XMP_ENVELOPE_CARRY) {
+		xc->f_idx = -1;
 	}
-
-	RESET_NOTE(NOTE_ENV_END);
 }
 
+#endif
+
 static void set_effect_defaults(struct context_data *ctx, int note,
 				struct xmp_subinstrument *sub,
 				struct channel_data *xc, int is_toneporta)
 {
+	struct module_data *m = &ctx->m;
+	struct xmp_module *mod = &m->mod;
+	struct smix_data *smix = &ctx->smix;
+	
 	if (sub != NULL && note >= 0) {
-		xc->finetune = sub->fin;
+		struct xmp_instrument *xxi;
+
+		if (xc->ins >= mod->ins) {
+			xxi = &smix->xxi[xc->ins - mod->ins];
+		} else {
+			xxi = &mod->xxi[xc->ins];
+		}
+
+		if (!HAS_QUIRK(QUIRK_PROTRACK)) {
+			xc->finetune = sub->fin;
+		}
 		xc->gvl = sub->gvl;
 
+#ifndef LIBXMP_CORE_DISABLE_IT
 		if (sub->ifc & 0x80) {
 			xc->filter.cutoff = (sub->ifc - 0x80) * 2;
-		} /*else {
+		} else if (~xxi->fei.flg & XMP_ENVELOPE_FLT) {
 			xc->filter.cutoff = 0xff;
-		} */
+		}
+		xc->filter.envelope = 0x100;
 
 		if (sub->ifr & 0x80) {
 			xc->filter.resonance = (sub->ifr - 0x80) * 2;
 		} /* else {
 			xc->filter.resonance = 0;
 		} */
+#endif
 
-		set_lfo_depth(&xc->insvib.lfo, sub->vde);
-		set_lfo_rate(&xc->insvib.lfo, sub->vra >> 2);
-		set_lfo_waveform(&xc->insvib.lfo, sub->vwf);
+		libxmp_lfo_set_depth(&xc->insvib.lfo, sub->vde);
+		libxmp_lfo_set_rate(&xc->insvib.lfo, sub->vra >> 2);
+		libxmp_lfo_set_waveform(&xc->insvib.lfo, sub->vwf);
 		xc->insvib.sweep = sub->vsw;
 
-		set_lfo_phase(&xc->vibrato.lfo, 0);
-		set_lfo_phase(&xc->tremolo.lfo, 0);
+		libxmp_lfo_set_phase(&xc->vibrato.lfo, 0);
+		libxmp_lfo_set_phase(&xc->tremolo.lfo, 0);
 	}
 
 	xc->delay = 0;
-	xc->tremor.val = 0;
+	xc->tremor.up = xc->tremor.down = 0;
 
 	/* Reset arpeggio */
 	xc->arpeggio.val[0] = 0;
@@ -118,6 +161,14 @@ static void set_effect_defaults(struct context_data *ctx, int note,
 	xc->arpeggio.size = 1;
 }
 
+/* From OpenMPT PortaTarget.mod:
+ * "A new note (with no portamento command next to it) does not reset the
+ *  portamento target. That is, if a previous portamento has not finished yet,
+ *  calling 3xx or 5xx after the new note will slide it towards the old target.
+ *  Once the portamento target period is reached, the target is reset. This
+ *  means that if the period is modified by another slide (e.g. 1xx or 2xx),
+ *  a following 3xx will not slide back to the original target."
+ */
 static void set_period(struct context_data *ctx, int note,
 				struct xmp_subinstrument *sub,
 				struct channel_data *xc, int is_toneporta)
@@ -125,16 +176,43 @@ static void set_period(struct context_data *ctx, int note,
 	struct module_data *m = &ctx->m;
 
 	if (sub != NULL && note >= 0) {
-		xc->porta.target = note_to_period(note, xc->finetune,
-				HAS_QUIRK(QUIRK_LINEAR), xc->per_adj);
+		double per = libxmp_note_to_period(ctx, note, xc->finetune,
+							xc->per_adj);
+
+		if (!HAS_QUIRK(QUIRK_PROTRACK) || (note > 0 && is_toneporta)) {
+			xc->porta.target = per;
+		}
+
 		if (xc->period < 1 || !is_toneporta) {
-			xc->period = xc->porta.target;
+			xc->period = per;
+		}
+	}
+}
+
+/* From OpenMPT Porta-Pickup.xm:
+ * "An instrument number should not reset the current portamento target. The
+ *  portamento target is valid until a new target is specified by combining a
+ *  note and a portamento effect."
+ */
+static void set_period_ft2(struct context_data *ctx, int note,
+				struct xmp_subinstrument *sub,
+				struct channel_data *xc, int is_toneporta)
+{
+	if (note > 0 && is_toneporta) {
+		xc->porta.target = libxmp_note_to_period(ctx, note, xc->finetune,
+								xc->per_adj);
+	}
+	if (sub != NULL && note >= 0) {
+		if (xc->period < 1 || !is_toneporta) {
+			xc->period = libxmp_note_to_period(ctx, note, xc->finetune,
+								xc->per_adj);
 		}
 	}
 }
 
 
 #ifndef LIBXMP_CORE_PLAYER
+#define IS_SFX_PITCH(x) ((x) == FX_PITCH_ADD || (x) == FX_PITCH_SUB)
 #define IS_TONEPORTA(x) ((x) == FX_TONEPORTA || (x) == FX_TONE_VSLIDE \
 		|| (x) == FX_PER_TPORTA)
 #else
@@ -142,7 +220,7 @@ static void set_period(struct context_data *ctx, int note,
 #endif
 
 #define set_patch(ctx,chn,ins,smp,note) \
-	virt_setpatch(ctx, chn, ins, smp, note, 0, 0, 0)
+	libxmp_virt_setpatch(ctx, chn, ins, smp, note, 0, 0, 0)
 
 static int read_event_mod(struct context_data *ctx, struct xmp_event *e, int chn)
 {
@@ -173,23 +251,36 @@ static int read_event_mod(struct context_data *ctx, struct xmp_event *e, int chn
 		SET(NEW_INS);
 		xc->fadeout = 0x10000;	/* for painlace.mod pat 0 ch 3 echo */
 		xc->per_flags = 0;
-		xc->offset_val = 0;
+		xc->offset.val = 0;
 		RESET_NOTE(NOTE_RELEASE|NOTE_FADEOUT);
 
 		if (IS_VALID_INSTRUMENT(ins)) {
+			sub = get_subinstrument(ctx, ins, e->note - 1);
+
 			if (is_toneporta) {
 				/* Get new instrument volume */
-				sub = get_subinstrument(ctx, ins, e->note);
 				if (sub != NULL) {
-					xc->volume = sub->vol;
+					/* Dennis Lindroos: instrument volume
+					 * is not used on split channels
+					 */
+					if (!xc->split) {
+						xc->volume = sub->vol;
+					}
 					use_ins_vol = 0;
 				}
 			} else {
 				xc->ins = ins;
+				xc->ins_fade = mod->xxi[ins].rls;
+
+				if (sub != NULL) {
+					if (HAS_QUIRK(QUIRK_PROTRACK)) {
+						xc->finetune = sub->fin;
+					}
+				}
 			}
 		} else {
 			new_invalid_ins = 1;
-			virt_resetchannel(ctx, chn);
+			libxmp_virt_resetchannel(ctx, chn);
 		}
 	}
 
@@ -233,7 +324,7 @@ static int read_event_mod(struct context_data *ctx, struct xmp_event *e, int chn
 
 	set_effect_defaults(ctx, note, sub, xc, is_toneporta);
 	if (e->ins && sub != NULL) {
-		reset_envelopes(ctx, xc, 0);
+		reset_envelopes(ctx, xc);
 	}
 
 	/* Process new volume */
@@ -243,12 +334,18 @@ static int read_event_mod(struct context_data *ctx, struct xmp_event *e, int chn
 	}
 
 	/* Secondary effect handled first */
-	process_fx(ctx, xc, chn, e->note, e->f2t, e->f2p, 1);
-	process_fx(ctx, xc, chn, e->note, e->fxt, e->fxp, 0);
-	set_period(ctx, note, sub, xc, is_toneporta);
+	libxmp_process_fx(ctx, xc, chn, e, 1);
+	libxmp_process_fx(ctx, xc, chn, e, 0);
 
-	if (TEST(NEW_VOL))
-		use_ins_vol = 0;
+#ifndef LIBXMP_CORE_PLAYER
+	if (IS_SFX_PITCH(e->fxt)) {
+ 		xc->period = libxmp_note_to_period(ctx, note, xc->finetune,
+                                			xc->per_adj);
+	} else
+#endif
+	{
+		set_period(ctx, note, sub, xc, is_toneporta);
+	}
 
 	if (sub == NULL) {
 		return 0;
@@ -256,21 +353,31 @@ static int read_event_mod(struct context_data *ctx, struct xmp_event *e, int chn
 
 	if (note >= 0) {
 		xc->note = note;
+		libxmp_virt_voicepos(ctx, chn, xc->offset.val);
+	}
 
-		virt_voicepos(ctx, chn, xc->offset_val);
-		if (TEST(OFFSET) && p->flags & XMP_FLAGS_FX9BUG)
-			xc->offset_val <<= 1;
+	if (TEST(OFFSET)) {
+		if (HAS_QUIRK(QUIRK_PROTRACK) || p->flags & XMP_FLAGS_FX9BUG) {
+			xc->offset.val += xc->offset.val2;
+		}
 		RESET(OFFSET);
 	}
 
-	if (use_ins_vol) {
+	if (use_ins_vol && !TEST(NEW_VOL) && !xc->split) {
 		xc->volume = sub->vol;
-		SET(NEW_VOL);
 	}
 
 	return 0;
 }
 
+static int sustain_check(struct xmp_envelope *env, int idx)
+{
+	return (env &&
+		(env->flg & XMP_ENVELOPE_ON) &&
+		(~env->flg & XMP_ENVELOPE_LOOP) &&
+		idx == env->data[env->sus << 1]);
+}
+
 static int read_event_ft2(struct context_data *ctx, struct xmp_event *e, int chn)
 {
 	struct player_data *p = &ctx->p;
@@ -282,16 +389,57 @@ static int read_event_ft2(struct context_data *ctx, struct xmp_event *e, int chn
 	int new_invalid_ins;
 	int is_toneporta;
 	int use_ins_vol;
+	int k00 = 0;
+	struct xmp_event ev;
+
+	/* From the OpenMPT DelayCombination.xm test case:
+         * "Naturally, Fasttracker 2 ignores notes next to an out-of-range
+	 *  note delay. However, to check whether the delay is out of range,
+	 *  it is simply compared against the current song speed, not taking
+	 *  any pattern delays into account."
+	 */
+	if (p->frame >= p->speed) {
+		return 0;
+	}
+
+	memcpy(&ev, e, sizeof (struct xmp_event));
+
+	/* From OpenMPT TremorReset.xm test case:
+	 * "Even if a tremor effect muted the sample on a previous row, volume
+	 *  commands should be able to override this effect."
+	 */
+	if (ev.vol) {
+		xc->tremor.count &= ~0x80;
+	}
 
 	xc->flags = 0;
 	note = -1;
-	key = e->note;
-	ins = e->ins;
+	key = ev.note;
+	ins = ev.ins;
 	new_invalid_ins = 0;
 	is_toneporta = 0;
 	use_ins_vol = 0;
 
-	if (IS_TONEPORTA(e->fxt) || IS_TONEPORTA(e->f2t)) {
+	/* From the OpenMPT key_off.xm test case:
+	 * "Key off at tick 0 (K00) is very dodgy command. If there is a note
+	 *  next to it, the note is ignored. If there is a volume column
+	 *  command or instrument next to it and the current instrument has
+	 *  no volume envelope, the note is faded out instead of being cut."
+	 */
+	if (ev.fxt == FX_KEYOFF && ev.fxp == 0) {
+		k00 = 1;
+		key = 0;
+
+		if (ins || ev.vol || ev.f2t) {
+			if (IS_VALID_INSTRUMENT(xc->ins) &&
+			    ~mod->xxi[xc->ins].aei.flg & XMP_ENVELOPE_ON) {
+				SET_NOTE(NOTE_FADEOUT);
+				ev.fxt = 0;
+			}
+		}
+	}
+
+	if (IS_TONEPORTA(ev.fxt) || IS_TONEPORTA(ev.f2t)) {
 		is_toneporta = 1;
 	}
 
@@ -305,13 +453,40 @@ static int read_event_ft2(struct context_data *ctx, struct xmp_event *e, int chn
 		ins = 0;
 	}
 
+	/* FT2: Retrieve old instrument volume */
+	if (ins) {
+		if (key == 0 || key >= XMP_KEY_OFF) {
+			struct xmp_subinstrument *sub;
+
+			/* Previous instrument */
+			sub = get_subinstrument(ctx, xc->ins, xc->key);
+
+			/* No note */
+			if (sub != NULL) {
+				int p = mod->xxc[chn].pan - 128;
+				xc->volume = sub->vol;
+
+				if (!HAS_QUIRK(QUIRK_FTMOD)) {
+					xc->pan.val = p + ((sub->pan - 128) *
+						(128 - abs(p))) / 128 + 128;
+				}
+
+				xc->ins_fade = mod->xxi[xc->ins].rls;
+				SET(NEW_VOL);
+			}
+		}
+	}
+
 	/* Do this regardless if the instrument is invalid or not */
-	if (e->ins) {
+	if (ev.ins) {
 		SET(NEW_INS);
 		use_ins_vol = 1;
 		xc->fadeout = 0x10000;
 		xc->per_flags = 0;
-		RESET_NOTE(NOTE_RELEASE|NOTE_FADEOUT);
+		RESET_NOTE(NOTE_RELEASE|NOTE_SUSEXIT);
+		if (!k00) {
+			RESET_NOTE(NOTE_FADEOUT);
+		}
 
 		if (IS_VALID_INSTRUMENT(ins - 1)) {
 			if (!is_toneporta)
@@ -329,16 +504,92 @@ static int read_event_ft2(struct context_data *ctx, struct xmp_event *e, int chn
 				key = 0;
 			}
 		}
+
+		xc->tremor.count = 0x20;
 	}
 
 	/* Check note */
 
+	if (ins) {
+		if (key > 0 && key < XMP_KEY_OFF) {
+			struct xmp_subinstrument *sub;
+
+			/* Retrieve volume when we have note */
+
+			/* and only if we have instrument, otherwise we're in
+			 * case 1: new note and no instrument
+			 */
+
+			/* Current instrument */
+			sub = get_subinstrument(ctx, xc->ins, key - 1);
+			if (sub != NULL) {
+				int p = mod->xxc[chn].pan - 128;
+				xc->volume = sub->vol;
+
+				if (!HAS_QUIRK(QUIRK_FTMOD)) {
+					xc->pan.val = p + ((sub->pan - 128) *
+						(128 - abs(p))) / 128 + 128;
+				}
+
+				xc->ins_fade = mod->xxi[xc->ins].rls;
+			} else {
+				xc->volume = 0;
+			}
+			SET(NEW_VOL);
+		}
+	}
+
 	if (key) {
 		SET(NEW_NOTE);
 
 		if (key == XMP_KEY_OFF) {
-			SET_NOTE(NOTE_RELEASE);
-			use_ins_vol = 0;
+			int env_on = 0;
+			int vol_set = ev.vol != 0 || ev.fxt == FX_VOLSET;
+			int delay_fx = ev.fxt == FX_EXTENDED && ev.fxp == 0xd0;
+			struct xmp_envelope *env = NULL;
+
+			/* OpenMPT NoteOffVolume.xm:
+			 * "If an instrument has no volume envelope, a note-off
+			 *  command should cut the sample completely - unless
+			 *  there is a volume command next it. This applies to
+			 *  both volume commands (volume and effect column)."
+			 *
+			 * ...and unless we have a keyoff+delay without setting
+			 * an instrument. See OffDelay.xm.
+			 */
+			if (IS_VALID_INSTRUMENT(xc->ins)) {
+				env = &mod->xxi[xc->ins].aei;
+				if (env->flg & XMP_ENVELOPE_ON) {
+					env_on = 1;
+				}
+			}
+			
+			if (env_on || (!vol_set && (!ev.ins || !delay_fx))) {
+				if (sustain_check(env, xc->v_idx)) {
+					/* See OpenMPT EnvOff.xm. In certain
+					 * cases a release event is effective
+					 * only in the next frame
+					 */
+					SET_NOTE(NOTE_SUSEXIT);
+				} else {
+					SET_NOTE(NOTE_RELEASE);
+				}
+				use_ins_vol = 0;
+			} else {
+				SET_NOTE(NOTE_FADEOUT);
+			}
+
+			/* See OpenMPT keyoff+instr.xm, pattern 2 row 0x40 */
+			if (env_on && ev.fxt == FX_EXTENDED &&
+			    (ev.fxp >> 4) == EX_DELAY) {
+				/* See OpenMPT OffDelay.xm test case */
+				if ((ev.fxp & 0xf) != 0) {
+					RESET_NOTE(NOTE_RELEASE|NOTE_SUSEXIT);
+				}
+			}
+		} else if (key == XMP_KEY_FADE) {
+			/* Handle keyoff + instrument case (NoteOff2.xm) */
+			SET_NOTE(NOTE_FADEOUT);
 		} else if (is_toneporta) {
 			/* set key to 0 so we can have the tone portamento from
 			 * the original note (see funky_stars.xm pos 5 ch 9)
@@ -350,58 +601,47 @@ static int read_event_ft2(struct context_data *ctx, struct xmp_event *e, int chn
 			 */
 		}
 
-		if (e->ins == 0 && !IS_VALID_INSTRUMENT(xc->old_ins - 1)) {
+		if (ev.ins == 0 && !IS_VALID_INSTRUMENT(xc->old_ins - 1)) {
 			new_invalid_ins = 1;
 		}
 
 		if (new_invalid_ins) {
-			virt_resetchannel(ctx, chn);
+			libxmp_virt_resetchannel(ctx, chn);
 		}
 	}
 
-	/* FT2: Retrieve old instrument volume */
-	if (ins) {
-		struct xmp_subinstrument *sub;
 
-		if (key == 0 || key >= XMP_KEY_OFF) {
-			/* Previous instrument */
-			sub = get_subinstrument(ctx, xc->old_insvol, xc->key);
-
-			/* No note */
-			if (sub != NULL) {
-				xc->volume = sub->vol;
-				xc->pan.val = sub->pan;
-				SET(NEW_VOL);
-			}
-		} else {
-			/* Retrieve volume when we have note */
-
-			/* and only if we have instrument, otherwise we're in
-			 * case 1: new note and no instrument
-			 */
-
-			/* Current instrument */
-			sub = get_subinstrument(ctx, xc->ins, key - 1);
-			if (sub != NULL) {
-				xc->volume = sub->vol;
-				xc->pan.val = sub->pan;
-			} else {
-				xc->volume = 0;
+	/* Check note range -- from the OpenMPT test NoteLimit.xm:
+	 * "I think one of the first things Fasttracker 2 does when parsing a
+	 *  pattern cell is calculating the “real” note (i.e. pattern note +
+	 *  sample transpose), and if this “real” note falls out of its note
+	 *  range, it is ignored completely (wiped from its internal channel
+	 *  memory). The instrument number next it, however, is not affected
+	 *  and remains in the memory."
+	 */
+	if (is_valid_note(key - 1)) {
+		int k = key - 1;
+		sub = get_subinstrument(ctx, xc->ins, k);
+		if (!new_invalid_ins && sub != NULL) {
+			int transp = mod->xxi[xc->ins].map[k].xpo;
+			int k2 = k + sub->xpo + transp;
+			if (k2 < 12 || k2 > 130) {
+				key = 0;
+				RESET(NEW_NOTE);
 			}
-			xc->old_insvol = xc->ins;
-			SET(NEW_VOL);
 		}
 	}
 
-	if ((uint32)key <= XMP_MAX_KEYS && key > 0) {
+	if (is_valid_note(key - 1)) {
 		xc->key = --key;
 		xc->fadeout = 0x10000;
 		RESET_NOTE(NOTE_END);
-		if (~mod->xxi[xc->ins].aei.flg & XMP_ENVELOPE_ON) {
-			RESET_NOTE(NOTE_RELEASE|NOTE_FADEOUT);
-		}
 
-		sub = get_subinstrument(ctx, xc->ins, key);
+		if (sub != NULL) {
+			if (~mod->xxi[xc->ins].aei.flg & XMP_ENVELOPE_ON) {
+				RESET_NOTE(NOTE_RELEASE|NOTE_FADEOUT);
+			}
+		}
 
 		if (!new_invalid_ins && sub != NULL) {
 			int transp = mod->xxi[xc->ins].map[key].xpo;
@@ -428,17 +668,17 @@ static int read_event_ft2(struct context_data *ctx, struct xmp_event *e, int chn
 
 	set_effect_defaults(ctx, note, sub, xc, is_toneporta);
 
-	if (ins && sub != NULL) {
+	if (ins && sub != NULL && !k00) {
 		/* Reset envelopes on new instrument, see olympic.xm pos 10
 		 * But make sure we have an instrument set, see Letting go
 		 * pos 4 chn 20
 		 */
-		reset_envelopes(ctx, xc, 0);
+		reset_envelopes(ctx, xc);
 	}
 
 	/* Process new volume */
-	if (e->vol) {
-		xc->volume = e->vol - 1;
+	if (ev.vol) {
+		xc->volume = ev.vol - 1;
 		SET(NEW_VOL);
 		if (TEST_NOTE(NOTE_END)) {	/* m5v-nine.xm */
 			xc->fadeout = 0x10000;	/* OpenMPT NoteOff.xm */
@@ -447,15 +687,12 @@ static int read_event_ft2(struct context_data *ctx, struct xmp_event *e, int chn
 	}
 
 	/* FT2: always reset sample offset */
-	xc->offset_val = 0;
+	xc->offset.val = 0;
 
 	/* Secondary effect handled first */
-	process_fx(ctx, xc, chn, e->note, e->f2t, e->f2p, 1);
-	process_fx(ctx, xc, chn, e->note, e->fxt, e->fxp, 0);
-	set_period(ctx, note, sub, xc, is_toneporta);
-
-	if (TEST(NEW_VOL))
-		use_ins_vol = 0;
+	libxmp_process_fx(ctx, xc, chn, &ev, 1);
+	libxmp_process_fx(ctx, xc, chn, &ev, 0);
+	set_period_ft2(ctx, note, sub, xc, is_toneporta);
 
 	if (sub == NULL) {
 		return 0;
@@ -466,11 +703,14 @@ static int read_event_ft2(struct context_data *ctx, struct xmp_event *e, int chn
 
 		/* From the OpenMPT test cases (3xx-no-old-samp.xm):
 		 * "An offset effect that points beyond the sample end should
-		 * stop playback on this channel."
+		 *  stop playback on this channel."
+		 *
+		 * ... except in Skale Tracker (and possibly others), so make this a
+		 *  FastTracker2 quirk. See Armada Tanks game.it (actually an XM).
+		 *  Reported by Vladislav Suschikh.
 		 */
-
-		if (xc->offset_val >= mod->xxs[sub->sid].len) {
-			virt_resetchannel(ctx, chn);
+		if (HAS_QUIRK(QUIRK_FT2BUGS) && xc->offset.val >= mod->xxs[sub->sid].len) {
+			libxmp_virt_resetchannel(ctx, chn);
 		} else {
 
 			/* (From Decibelter - Cosmic 'Wegian Mamas.xm p04 ch7)
@@ -478,13 +718,12 @@ static int read_event_ft2(struct context_data *ctx, struct xmp_event *e, int chn
 			 * without tone portamento, otherwise we won't play
 			 * sweeps and loops correctly.
 			 */
-			virt_voicepos(ctx, chn, xc->offset_val);
+			libxmp_virt_voicepos(ctx, chn, xc->offset.val);
 		}
 	}
 
-	if (use_ins_vol) {
+	if (use_ins_vol && !TEST(NEW_VOL)) {
 		xc->volume = sub->vol;
-		SET(NEW_VOL);
 	}
 
 	return 0;
@@ -512,7 +751,7 @@ static int read_event_st3(struct context_data *ctx, struct xmp_event *e, int chn
 		is_toneporta = 1;
 	}
 
-	if (virt_mapchannel(ctx, chn) < 0 && xc->ins != e->ins - 1) {
+	if (libxmp_virt_mapchannel(ctx, chn) < 0 && xc->ins != e->ins - 1) {
 		is_toneporta = 0;
 	}
 
@@ -524,7 +763,7 @@ static int read_event_st3(struct context_data *ctx, struct xmp_event *e, int chn
 		use_ins_vol = 1;
 		xc->fadeout = 0x10000;
 		xc->per_flags = 0;
-		xc->offset_val = 0;
+		xc->offset.val = 0;
 		RESET_NOTE(NOTE_RELEASE|NOTE_FADEOUT);
 
 		if (IS_VALID_INSTRUMENT(ins)) {
@@ -533,9 +772,10 @@ static int read_event_st3(struct context_data *ctx, struct xmp_event *e, int chn
 				not_same_ins = 1;
 				if (!is_toneporta) {
 					xc->ins = ins;
+					xc->ins_fade = mod->xxi[ins].rls;
 				} else {
 					/* Get new instrument volume */
-					sub = get_subinstrument(ctx, ins, e->note);
+					sub = get_subinstrument(ctx, ins, e->note - 1);
 					if (sub != NULL) {
 						xc->volume = sub->vol;
 						use_ins_vol = 0;
@@ -564,7 +804,7 @@ static int read_event_st3(struct context_data *ctx, struct xmp_event *e, int chn
 			 * 7spirits.s3m, mod.Biomechanoid
 			 */
 			if (not_same_ins) {
-				xc->offset_val = 0;
+				xc->offset.val = 0;
 			}
 		} else {
 			xc->key = e->note - 1;
@@ -598,7 +838,7 @@ static int read_event_st3(struct context_data *ctx, struct xmp_event *e, int chn
 
 	set_effect_defaults(ctx, note, sub, xc, is_toneporta);
 	if (e->ins && sub != NULL) {
-		reset_envelopes(ctx, xc, 0);
+		reset_envelopes(ctx, xc);
 	}
 
 	/* Process new volume */
@@ -608,29 +848,24 @@ static int read_event_st3(struct context_data *ctx, struct xmp_event *e, int chn
 	}
 
 	/* Secondary effect handled first */
-	process_fx(ctx, xc, chn, e->note, e->f2t, e->f2p, 1);
-	process_fx(ctx, xc, chn, e->note, e->fxt, e->fxp, 0);
+	libxmp_process_fx(ctx, xc, chn, e, 1);
+	libxmp_process_fx(ctx, xc, chn, e, 0);
 	set_period(ctx, note, sub, xc, is_toneporta);
 
-	if (TEST(NEW_VOL))
-		use_ins_vol = 0;
-
 	if (sub == NULL) {
 		return 0;
 	}
 
 	if (note >= 0) {
 		xc->note = note;
-		virt_voicepos(ctx, chn, xc->offset_val);
+		libxmp_virt_voicepos(ctx, chn, xc->offset.val);
 	}
 
-	if (use_ins_vol) {
+	if (use_ins_vol && !TEST(NEW_VOL)) {
 		xc->volume = sub->vol;
-		SET(NEW_VOL);
 	}
 
-	/* ST3: check QUIRK_ST3GVOL only in ST3 event reader */
-	if (HAS_QUIRK(QUIRK_ST3GVOL) && TEST(NEW_VOL)) {
+	if (HAS_QUIRK(QUIRK_ST3BUGS) && TEST(NEW_VOL)) {
 		xc->volume = xc->volume * p->gvol / m->volbase;
 	}
 
@@ -639,6 +874,72 @@ static int read_event_st3(struct context_data *ctx, struct xmp_event *e, int chn
 
 #ifndef LIBXMP_CORE_DISABLE_IT
 
+static inline void copy_channel(struct player_data *p, int to, int from)
+{
+	if (to > 0 && to != from) {
+		memcpy(&p->xc_data[to], &p->xc_data[from],
+					sizeof (struct channel_data));
+	}
+}
+
+static inline int has_note_event(struct xmp_event *e)
+{
+	return (e->note && e->note <= XMP_MAX_KEYS);
+}
+
+static int check_fadeout(struct context_data *ctx, struct channel_data *xc, int ins)
+{
+	struct xmp_instrument *xxi = libxmp_get_instrument(ctx, ins);
+
+	if (xxi == NULL) {
+		return 1;
+	}
+
+	return (~xxi->aei.flg & XMP_ENVELOPE_ON ||
+		~xxi->aei.flg & XMP_ENVELOPE_CARRY ||
+		xc->ins_fade == 0 ||
+		xc->fadeout <= xc->ins_fade);
+}
+
+static int check_invalid_sample(struct context_data *ctx, int ins, int key)
+{
+	struct module_data *m = &ctx->m;
+	struct xmp_module *mod = &m->mod;
+
+	if (ins < mod->ins) {
+		int smp = mod->xxi[ins].map[key].ins;
+		if (smp == 0xff || smp >= mod->smp) {
+			return 1;
+		};
+	}
+
+	return 0;
+}
+
+static void fix_period(struct context_data *ctx, int chn, struct xmp_subinstrument *sub)
+{
+	if (sub->nna == XMP_INST_NNA_CONT) {
+		struct player_data *p = &ctx->p;
+		struct channel_data *xc = &p->xc_data[chn];
+		struct xmp_instrument *xxi = libxmp_get_instrument(ctx, xc->ins);
+
+		xc->period = libxmp_note_to_period(ctx, xc->key + sub->xpo +
+			xxi->map[xc->key_porta].xpo, xc->finetune, xc->per_adj);
+	}
+}
+
+static int is_same_sid(struct context_data *ctx, int chn, int ins, int key)
+{
+	struct player_data *p = &ctx->p;
+	struct channel_data *xc = &p->xc_data[chn];
+	struct xmp_subinstrument *s1, *s2;
+
+	s1 = get_subinstrument(ctx, ins, key);
+	s2 = get_subinstrument(ctx, xc->ins, xc->key);
+
+	return (s1 && s2 && s1->sid == s2->sid);
+}
+
 static int read_event_it(struct context_data *ctx, struct xmp_event *e, int chn)
 {
 	struct player_data *p = &ctx->p;
@@ -647,12 +948,16 @@ static int read_event_it(struct context_data *ctx, struct xmp_event *e, int chn)
 	struct channel_data *xc = &p->xc_data[chn];
 	int note, key;
 	struct xmp_subinstrument *sub;
-	int not_same_ins;
+	int not_same_ins, not_same_smp;
 	int new_invalid_ins;
 	int is_toneporta, is_release;
 	int candidate_ins;
 	int reset_env;
 	int use_ins_vol;
+	int sample_mode;
+	int toneporta_offset;
+	int disabled_toneporta;
+	int retrig_ins;
 	struct xmp_event ev;
 
 	memcpy(&ev, e, sizeof (struct xmp_event));
@@ -669,24 +974,42 @@ static int read_event_it(struct context_data *ctx, struct xmp_event *e, int chn)
 	note = -1;
 	key = ev.note;
 	not_same_ins = 0;
+	not_same_smp = 0;
 	new_invalid_ins = 0;
 	is_toneporta = 0;
 	is_release = 0;
 	reset_env = 0;
 	use_ins_vol = 0;
 	candidate_ins = xc->ins;
+	sample_mode = !HAS_QUIRK(QUIRK_VIRTUAL);
+	toneporta_offset = 0;
+	disabled_toneporta = 0;
+	retrig_ins = 0;
+
+	/* Keyoff + instrument retrigs current instrument in old fx mode */
+	if (HAS_QUIRK(QUIRK_ITOLDFX)) {
+		if (ev.note == XMP_KEY_OFF && IS_VALID_INSTRUMENT(ev.ins -1)) {
+			retrig_ins = 1;
+		}
+	}
 
 	/* Notes with unmapped instruments are ignored */
-	if (ev.ins && ev.ins <= mod->ins && ev.note && ev.note <= XMP_MAX_KEYS) {
-		int ins = ev.ins - 1;
-		int key = ev.note - 1;
-
-		if (ins < mod->ins) {
-			int smp = mod->xxi[ins].map[key].ins;
-			if (smp == 0xff || smp >= mod->smp) {
+	if (ev.ins) {
+		if (ev.ins <= mod->ins && has_note_event(&ev)) {
+			int ins = ev.ins - 1;
+			if (check_invalid_sample(ctx, ins, ev.note - 1)) {
 				candidate_ins = ins;
-				memset(&ev, 0, sizeof(struct xmp_event));
-			};
+				memset(&ev, 0, sizeof (ev));
+			}
+		}
+	} else {
+		if (has_note_event(&ev)) {
+			int ins = xc->old_ins - 1;
+			if (!IS_VALID_INSTRUMENT(ins)) {
+				new_invalid_ins = 1;
+			} else if (check_invalid_sample(ctx, ins, ev.note - 1)) {
+				memset(&ev, 0, sizeof (ev));
+			}
 		}
 	}
 
@@ -698,16 +1021,53 @@ static int read_event_it(struct context_data *ctx, struct xmp_event *e, int chn)
 		is_release = 1;
 	}
 
-	if (!HAS_QUIRK(QUIRK_VIRTUAL) && virt_mapchannel(ctx, chn) < 0) {
+	if (xc->period <= 0 || TEST_NOTE(NOTE_END)) {
 		is_toneporta = 0;
 	}
 
+	/* Off-Porta.it */
+	if (is_toneporta && ev.fxt == FX_OFFSET) {
+		disabled_toneporta = 1;
+		is_toneporta = 0;
+ 		if (!HAS_QUIRK(QUIRK_PRENV)) {
+			toneporta_offset = 1;
+			RESET_NOTE(NOTE_ENV_END);
+		}
+	}
+
 	/* Check instrument */
 
 	if (ev.ins) {
 		int ins = ev.ins - 1;
+		int set_new_ins = 1;
 
-		if (!is_release || (!is_toneporta || xc->ins != ins)) {
+		/* portamento_after_keyoff.it test case */
+		if (is_release && !key) {
+			if (is_toneporta) {
+				if (HAS_QUIRK(QUIRK_PRENV) || TEST_NOTE(NOTE_SET)) {
+					is_toneporta = 0;
+					reset_envelopes_carry(ctx, xc);
+				}
+			} else {
+				/* fixes OpenMPT wnoteoff.it */
+				reset_envelopes_carry(ctx, xc);
+			}
+		}
+
+		if (is_toneporta && xc->ins == ins) {
+			if (!HAS_QUIRK(QUIRK_PRENV)) {
+				if (is_same_sid(ctx, chn, ins, key - 1)) {
+					/* same instrument and same sample */
+					set_new_ins = !is_release;
+				} else {
+					/* same instrument, different sample */
+					not_same_ins = 1; /* need this too */
+					not_same_smp = 1;
+				}
+			}
+		}
+
+		if (set_new_ins) {
 			SET(NEW_INS);
 			use_ins_vol = 1;
 			reset_env = 1;
@@ -717,7 +1077,13 @@ static int read_event_it(struct context_data *ctx, struct xmp_event *e, int chn)
 		if (IS_VALID_INSTRUMENT(ins)) {
 			/* valid ins */
 
-			if (!key) {
+			/* See OpenMPT StoppedInstrSwap.it for cut case */
+			if (!key && !TEST_NOTE(NOTE_KEY_CUT)) {
+				/* Retrig in new ins in sample mode */
+				if (sample_mode && TEST_NOTE(NOTE_END)) {
+					libxmp_virt_voicepos(ctx, chn, 0);
+				}
+
 				/* IT: Reset note for every new != ins */
 				if (xc->ins == ins) {
 					SET(NEW_INS);
@@ -725,20 +1091,31 @@ static int read_event_it(struct context_data *ctx, struct xmp_event *e, int chn)
 				} else {
 					key = xc->key + 1;
 				}
+
+				RESET_NOTE(NOTE_SET);
 			}
+
 			if (xc->ins != ins && (!is_toneporta || !HAS_QUIRK(QUIRK_PRENV))) {
-				not_same_ins = 1;
 				candidate_ins = ins;
-				if (is_toneporta) {
-					/* Get new instrument volume */
-					sub = get_subinstrument(ctx, ins, key);
-					if (sub != NULL) {
-						xc->volume = sub->vol;
-						use_ins_vol = 0;
+
+				if (!is_same_sid(ctx, chn, ins, key - 1)) {
+					not_same_ins = 1;
+					if (is_toneporta) {
+						/* Get new instrument volume */
+						sub = get_subinstrument(ctx, ins, key);
+						if (sub != NULL) {
+							xc->volume = sub->vol;
+							use_ins_vol = 0;
+						}
 					}
 				}
 			}
 		} else {
+			/* In sample mode invalid ins cut previous ins */
+			if (sample_mode) {
+				xc->volume = 0;
+			}
+
 			/* Ignore invalid instruments */
 			new_invalid_ins = 1;
 			xc->flags = 0;
@@ -750,36 +1127,56 @@ static int read_event_it(struct context_data *ctx, struct xmp_event *e, int chn)
 
 	if (key && !new_invalid_ins) {
 		SET(NEW_NOTE);
+		SET_NOTE(NOTE_SET);
 
 		if (key == XMP_KEY_FADE) {
 			SET_NOTE(NOTE_FADEOUT);
 			reset_env = 0;
 			use_ins_vol = 0;
 		} else if (key == XMP_KEY_CUT) {
-			SET_NOTE(NOTE_END | NOTE_CUT);
+			SET_NOTE(NOTE_END | NOTE_CUT | NOTE_KEY_CUT);
 			xc->period = 0;
-			virt_resetchannel(ctx, chn);
+			libxmp_virt_resetchannel(ctx, chn);
 		} else if (key == XMP_KEY_OFF) {
-			SET_NOTE(NOTE_RELEASE);
+			struct xmp_envelope *env = NULL;
+			if (IS_VALID_INSTRUMENT(xc->ins)) {
+				env = &mod->xxi[xc->ins].aei;
+			}
+			if (sustain_check(env, xc->v_idx)) {
+				SET_NOTE(NOTE_SUSEXIT);
+			} else {
+				SET_NOTE(NOTE_RELEASE);
+			}
+			SET(KEY_OFF);
 			reset_env = 0;
 			use_ins_vol = 0;
-			if (HAS_QUIRK(QUIRK_PRENV))
-				SET_NOTE(NOTE_END);
-		} else if (is_toneporta) {
+		} else {
+			/* portamento_after_keyoff.it test case */
+			/* also see suburban_streets o13 c45 */
+			if (ev.ins || !is_toneporta) {
+				if (!disabled_toneporta) {
+					reset_env = 1;
+				}
+			}
 
-			/* Always retrig on tone portamento: Fix portamento in
-			 * 7spirits.s3m, mod.Biomechanoid
-			 */
-			if (not_same_ins || TEST_NOTE(NOTE_END)) {
-				SET(NEW_INS);
-				RESET_NOTE(NOTE_RELEASE|NOTE_FADEOUT);
-			} else {
-				key = 0;
+			if (is_toneporta) {
+				if (not_same_ins || TEST_NOTE(NOTE_END)) {
+					SET(NEW_INS);
+					RESET_NOTE(NOTE_RELEASE|NOTE_SUSEXIT|NOTE_FADEOUT);
+				} else {
+					if (is_valid_note(key - 1)) {
+						xc->key_porta = key - 1;
+					}
+					key = 0;
+				}
 			}
 		}
 	}
 
-	if ((uint32)key <= XMP_MAX_KEYS && key > 0 && !new_invalid_ins) {
+	if (is_valid_note(key - 1) && !new_invalid_ins) {
+		if (TEST_NOTE(NOTE_CUT)) {
+			use_ins_vol = 1;	/* See OpenMPT NoteOffInstr.it */
+		}
 		xc->key = --key;
 		RESET_NOTE(NOTE_END);
 
@@ -788,6 +1185,7 @@ static int read_event_it(struct context_data *ctx, struct xmp_event *e, int chn)
 		if (sub != NULL) {
 			int transp = mod->xxi[candidate_ins].map[key].xpo;
 			int smp, to;
+			int rvv;
 
 			note = key + sub->xpo + transp;
 			smp = sub->sid;
@@ -795,12 +1193,33 @@ static int read_event_it(struct context_data *ctx, struct xmp_event *e, int chn)
 				smp = -1;
 			}
 
-			to = virt_setpatch(ctx, chn, candidate_ins,
-				smp, note, sub->nna, sub->dct, sub->dca);
+			if (not_same_smp) {
+				fix_period(ctx, chn, sub);
+				libxmp_virt_resetchannel(ctx, chn);
+			}
+			to = libxmp_virt_setpatch(ctx, chn, candidate_ins, smp,
+				note, sub->nna, sub->dct, sub->dca);
+
+			/* Random value for volume swing */
+			rvv = sub->rvv & 0xff;
+			if (rvv) {
+				CLAMP(rvv, 0, 100);
+				xc->rvv = rand() % (rvv + 1);
+			} else {
+				xc->rvv = 0;
+			}
+
+			/* Random value for pan swing */
+			rvv = (sub->rvv & 0xff00) >> 8;
+			if (rvv) {
+				CLAMP(rvv, 0, 64);
+				xc->rpv = rand() % (rvv + 1) - (rvv / 2);
+			} else {
+				xc->rpv = 0;
+			}
 
 			if (to < 0)
 				return -1;
-
 			if (to != chn) {
 				copy_channel(p, to, chn);
 				p->xc_data[to].flags = 0;
@@ -816,26 +1235,48 @@ static int read_event_it(struct context_data *ctx, struct xmp_event *e, int chn)
 	}
 
 	/* Do after virtual channel copy */
-	if (is_toneporta) {
+	if (is_toneporta || retrig_ins) {
 		if (HAS_QUIRK(QUIRK_PRENV) && ev.ins) {
-			reset_envelopes(ctx, xc, 0);
+			reset_envelopes_carry(ctx, xc);
+		}
+	}
+
+	if (IS_VALID_INSTRUMENT(candidate_ins)) {
+		if (xc->ins != candidate_ins) {
+			/* Reset envelopes if instrument changes */
+			reset_envelopes(ctx, xc);
 		}
+		xc->ins = candidate_ins;
+		xc->ins_fade = mod->xxi[candidate_ins].rls;
 	}
 
 	/* Reset in case of new instrument and the previous envelope has
 	 * finished (OpenMPT test EnvReset.it). This must take place after
 	 * channel copies in case of NNA (see test/test.it)
+	 * Also if we have envelope in carry mode, check fadeout
 	 */
 	if (ev.ins && TEST_NOTE(NOTE_ENV_END)) {
-		reset_envelopes(ctx, xc, 1);
+		if (check_fadeout(ctx, xc, candidate_ins)) {
+			reset_envelopes(ctx, xc);
+		} else {
+			reset_env = 0;
+		}
 	}
 
-	if (IS_VALID_INSTRUMENT(candidate_ins)) {
-		if (xc->ins != candidate_ins) {
-			/* Reset envelopes if instrument changes */
-			reset_envelopes(ctx, xc, 1);
+	if (reset_env) {
+		if (ev.note) {
+			RESET_NOTE(NOTE_RELEASE|NOTE_SUSEXIT|NOTE_FADEOUT);
 		}
-		xc->ins = candidate_ins;
+		/* Set after copying to new virtual channel (see ambio.it) */
+		xc->fadeout = 0x10000;
+	}
+
+	/* See OpenMPT wnoteoff.it vs noteoff3.it */
+	if (retrig_ins && not_same_ins) {
+		SET(NEW_INS);
+		libxmp_virt_voicepos(ctx, chn, 0);
+		xc->fadeout = 0x10000;
+		RESET_NOTE(NOTE_RELEASE|NOTE_SUSEXIT|NOTE_FADEOUT);
 	}
 
 	sub = get_subinstrument(ctx, xc->ins, xc->key);
@@ -843,54 +1284,50 @@ static int read_event_it(struct context_data *ctx, struct xmp_event *e, int chn)
 	set_effect_defaults(ctx, note, sub, xc, is_toneporta);
 	if (sub != NULL) {
 		if (note >= 0) {
-			if (sub->pan >= 0)
+			/* Reset pan, see OpenMPT PanReset.it */
+			if (sub->pan >= 0) {
 				xc->pan.val = sub->pan;
-			reset_envelopes(ctx, xc, TEST_NOTE(NOTE_CUT));
+				xc->pan.surround = 0;
+			}
+
+			if (TEST_NOTE(NOTE_CUT)) {
+				reset_envelopes(ctx, xc);
+			} else if (!toneporta_offset) {
+				reset_envelopes_carry(ctx, xc);
+			}
 			RESET_NOTE(NOTE_CUT);
-		} else if (ev.ins) {
-			if (sub->pan >= 0)
-				xc->pan.val = sub->pan;
 		}
 	}
 	
 	/* Process new volume */
-	if (ev.vol) {
-		xc->volume = ev.vol - 1;
-		SET(NEW_VOL);
+	if (ev.vol && (!TEST_NOTE(NOTE_CUT) || ev.ins != 0)) {
+		if (key != XMP_KEY_OFF) {    /* See OpenMPT NoteOffInstr.it */
+			xc->volume = ev.vol - 1;
+			SET(NEW_VOL);
+		}
 	}
 
 	/* IT: always reset sample offset */
-	xc->offset_val = 0;
+	xc->offset.val &= ~0xffff;
 
 	/* According to Storlek test 25, Impulse Tracker handles the volume
-	 * column effects last.
+	 * column effects after the standard effects.
 	 */
-	process_fx(ctx, xc, chn, ev.note, ev.fxt, ev.fxp, 0);
-	process_fx(ctx, xc, chn, ev.note, ev.f2t, ev.f2p, 1);
+	libxmp_process_fx(ctx, xc, chn, &ev, 0);
+	libxmp_process_fx(ctx, xc, chn, &ev, 1);
 	set_period(ctx, note, sub, xc, is_toneporta);
 
-	if (TEST(NEW_VOL)) {
-		use_ins_vol = 0;
-	}
-
 	if (sub == NULL) {
 		return 0;
 	}
 
 	if (note >= 0) {
 		xc->note = note;
-		virt_voicepos(ctx, chn, xc->offset_val);
+		libxmp_virt_voicepos(ctx, chn, xc->offset.val);
 	}
 
-	if (reset_env) {
-		RESET_NOTE(NOTE_RELEASE | NOTE_FADEOUT);
-		/* Set after copying to new virtual channel (see ambio.it) */
-		xc->fadeout = 0x10000;
-	}
-
-	if (use_ins_vol) {
+	if (use_ins_vol && !TEST(NEW_VOL)) {
 		xc->volume = sub->vol;
-		SET(NEW_VOL);
 	}
 
 	return 0;
@@ -929,23 +1366,24 @@ static int read_event_med(struct context_data *ctx, struct xmp_event *e, int chn
 		use_ins_vol = 1;
 		SET(NEW_INS);
 		xc->fadeout = 0x10000;
-		xc->offset_val = 0;
+		xc->offset.val = 0;
 		RESET_NOTE(NOTE_RELEASE|NOTE_FADEOUT);
 
 		if (IS_VALID_INSTRUMENT(ins)) {
 			if (is_toneporta) {
 				/* Get new instrument volume */
-				sub = get_subinstrument(ctx, ins, e->note);
+				sub = get_subinstrument(ctx, ins, e->note - 1);
 				if (sub != NULL) {
 					xc->volume = sub->vol;
 					use_ins_vol = 0;
 				}
 			} else {
 				xc->ins = ins;
+				xc->ins_fade = mod->xxi[ins].rls;
 			}
 		} else {
 			new_invalid_ins = 1;
-			virt_resetchannel(ctx, chn);
+			libxmp_virt_resetchannel(ctx, chn);
 		}
 
 		MED_CHANNEL_EXTRAS(*xc)->arp = 0;
@@ -968,7 +1406,7 @@ static int read_event_med(struct context_data *ctx, struct xmp_event *e, int chn
 		} else if (e->note == XMP_KEY_CUT) {
 			SET_NOTE(NOTE_END);
 			xc->period = 0;
-			virt_resetchannel(ctx, chn);
+			libxmp_virt_resetchannel(ctx, chn);
 		} else if (!is_toneporta && IS_VALID_INSTRUMENT(xc->ins)) {
 			struct xmp_instrument *xxi = &mod->xxi[xc->ins];
 
@@ -1019,7 +1457,7 @@ static int read_event_med(struct context_data *ctx, struct xmp_event *e, int chn
 	}
 
 	if (e->ins && sub != NULL) {
-		reset_envelopes(ctx, xc, 0);
+		reset_envelopes(ctx, xc);
 	}
 
 	/* Process new volume */
@@ -1029,26 +1467,21 @@ static int read_event_med(struct context_data *ctx, struct xmp_event *e, int chn
 	}
 
 	/* Secondary effect handled first */
-	process_fx(ctx, xc, chn, e->note, e->f2t, e->f2p, 1);
-	process_fx(ctx, xc, chn, e->note, e->fxt, e->fxp, 0);
+	libxmp_process_fx(ctx, xc, chn, e, 1);
+	libxmp_process_fx(ctx, xc, chn, e, 0);
 	set_period(ctx, note, sub, xc, is_toneporta);
 
-	if (TEST(NEW_VOL)) {
-		use_ins_vol = 0;
-	}
-
 	if (sub == NULL) {
 		return 0;
 	}
 
 	if (note >= 0) {
 		xc->note = note;
-		virt_voicepos(ctx, chn, xc->offset_val);
+		libxmp_virt_voicepos(ctx, chn, xc->offset.val);
 	}
 
-	if (use_ins_vol) {
+	if (use_ins_vol && !TEST(NEW_VOL)) {
 		xc->volume = sub->vol;
-		SET(NEW_VOL);
 	}
 
 	return 0;
@@ -1077,13 +1510,15 @@ static int read_event_smix(struct context_data *ctx, struct xmp_event *e, int ch
 	SET(NEW_INS);
 	xc->fadeout = 0x10000;
 	xc->per_flags = 0;
-	xc->offset_val = 0;
+	xc->offset.val = 0;
 	RESET_NOTE(NOTE_RELEASE);
 
 	xc->ins = ins;
 
-	if (ins >= mod->ins && ins < mod->ins + smix->ins)
+	if (ins >= mod->ins && ins < mod->ins + smix->ins) {
 		is_smix_ins = 1;
+		xc->ins_fade = smix->xxi[xc->ins - mod->ins].rls;
+	}
 
 	SET(NEW_NOTE);
 
@@ -1097,8 +1532,9 @@ static int read_event_smix(struct context_data *ctx, struct xmp_event *e, int ch
 
 	if (is_smix_ins) {
 		sub = &smix->xxi[xc->ins - mod->ins].sub[0];
-		if (sub == NULL)
+		if (sub == NULL) {
 			return 0;
+		}
 
 		note = xc->key + sub->xpo;
 		smp = sub->sid;
@@ -1112,6 +1548,9 @@ static int read_event_smix(struct context_data *ctx, struct xmp_event *e, int ch
 	} else {
 		transp = mod->xxi[xc->ins].map[xc->key].xpo;
 		sub = get_subinstrument(ctx, xc->ins, xc->key);
+		if (sub == NULL) {
+			return 0;
+		}
 		note = xc->key + sub->xpo + transp;
 		smp = sub->sid;
 		if (mod->xxs[smp].len == 0)
@@ -1125,20 +1564,19 @@ static int read_event_smix(struct context_data *ctx, struct xmp_event *e, int ch
 	set_effect_defaults(ctx, note, sub, xc, 0);
 	set_period(ctx, note, sub, xc, 0);
 
-	if (e->ins && sub != NULL) {
-		reset_envelopes(ctx, xc, 0);
+	if (e->ins) {
+		reset_envelopes(ctx, xc);
 	}
 
 	xc->volume = e->vol - 1;
-	SET(NEW_VOL);
 
 	xc->note = note;
-	virt_voicepos(ctx, chn, xc->offset_val);
+	libxmp_virt_voicepos(ctx, chn, xc->offset.val);
 
 	return 0;
 }
 
-int read_event(struct context_data *ctx, struct xmp_event *e, int chn)
+int libxmp_read_event(struct context_data *ctx, struct xmp_event *e, int chn)
 {
 	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
@@ -1147,6 +1585,10 @@ int read_event(struct context_data *ctx, struct xmp_event *e, int chn)
 	if (e->ins != 0)
 		xc->old_ins = e->ins;
 
+	if (TEST_NOTE(NOTE_SAMPLE_END)) {
+		SET_NOTE(NOTE_END);
+	}
+
 	if (chn >= m->mod.chn) {
 		return read_event_smix(ctx, e, chn);
 	} else switch (m->read_event_type) {
diff --git a/src/scan.c b/src/scan.c
index a59d788..1bbbea8 100644
--- a/src/scan.c
+++ b/src/scan.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -54,17 +54,21 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
     struct module_data *m = &ctx->m;
     struct xmp_module *mod = &m->mod;
     int parm, gvol_memory, f1, f2, p1, p2, ord, ord2;
-    int row, last_row, break_row, cnt_row;
+    int row, last_row, break_row, row_count;
     int gvl, bpm, speed, base_time, chn;
-    int alltmp;
-    double clock, clock_rst;
-    int loop_chn, loop_flg;
-    int pdelay = 0, skip_fetch;
-    int loop_stk[XMP_MAX_CHANNELS];
+    int frame_count;
+    double time, start_time;
+    int loop_chn, loop_num, inside_loop;
+    int pdelay = 0;
+    int loop_count[XMP_MAX_CHANNELS];
     int loop_row[XMP_MAX_CHANNELS];
     struct xmp_event* event;
     int i, pat;
+    int has_marker;
     struct ord_data *info;
+#ifndef LIBXMP_CORE_PLAYER
+    int st26_speed;
+#endif
 
     if (mod->len == 0)
 	return 0;
@@ -75,15 +79,23 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
 			mod->xxp[pat]->rows ? mod->xxp[pat]->rows : 1);
     }
 
-    memset(loop_stk, 0, sizeof(int) * mod->chn);
-    memset(loop_row, 0, sizeof(int) * mod->chn);
-    loop_chn = loop_flg = 0;
+    for (i = 0; i < mod->chn; i++) {
+	loop_count[i] = 0;
+	loop_row[i] = -1;
+    }
+    loop_num = 0;
+    loop_chn = -1;
 
     gvl = mod->gvl;
     bpm = mod->bpm;
 
     speed = mod->spd;
     base_time = m->rrate;
+#ifndef LIBXMP_CORE_PLAYER
+    st26_speed = 0;
+#endif
+
+    has_marker = HAS_QUIRK(QUIRK_MARKER);
 
     /* By erlk ozlr 
      *
@@ -104,16 +116,16 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
     ord2 = -1;
     ord = ep - 1;
 
-    gvol_memory = break_row = cnt_row = alltmp = 0;
-    clock_rst = clock = 0.0;
-    skip_fetch = 0;
+    gvol_memory = break_row = row_count = frame_count = 0;
+    start_time = time = 0.0;
+    inside_loop = 0;
 
     while (42) {
 	if ((uint32)++ord >= mod->len) {
 	    if (mod->rst > mod->len || mod->xxo[mod->rst] >= mod->pat) {
-		ord = m->seq_data[chain].entry_point;
+		ord = ep;
 	    } else {
-		if (get_sequence(ctx, mod->rst) == chain) {
+		if (libxmp_get_sequence(ctx, mod->rst) == chain) {
 	            ord = mod->rst;
 		} else {
 		    ord = ep;
@@ -121,7 +133,7 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
 	    }
 	   
 	    pat = mod->xxo[ord];
-	    if (pat == S3M_END) {
+	    if (has_marker && pat == S3M_END) {
 		break;
 	    }
 	} 
@@ -137,32 +149,46 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
 
 	/* All invalid patterns skipped, only S3M_END aborts replay */
 	if (pat >= mod->pat) {
-	    if (pat == S3M_END) {
+	    if (has_marker && pat == S3M_END) {
 		ord = mod->len;
 	        continue;
 	    }
 	    continue;
 	}
 
-	if (break_row < mod->xxp[pat]->rows && m->scan_cnt[ord][break_row]) {
-	    break;
-	}
-
-	info->gvl = gvl;
-	info->bpm = bpm;
-	info->speed = speed;
-	info->time = clock + m->time_factor * alltmp / bpm;
+        if (break_row >= mod->xxp[pat]->rows) {
+            break_row = 0;
+        }
+
+        /* Loops can cross pattern boundaries, so check if we're not looping */
+        if (m->scan_cnt[ord][break_row] && !inside_loop) {
+            break;
+        }
+
+        /* Don't update pattern information if we're inside a loop, otherwise
+         * a loop containing e.g. a global volume fade can make the pattern
+         * start with the wrong volume.
+         */
+        if (!inside_loop && info->gvl < 0) {
+            info->gvl = gvl;
+            info->bpm = bpm;
+            info->speed = speed;
+            info->time = time + m->time_factor * frame_count * base_time / bpm;
+#ifndef LIBXMP_CORE_PLAYER
+            info->st26_speed = st26_speed;
+#endif
+        }
 
 	if (info->start_row == 0 && ord != 0) {
 	    if (ord == ep) {
-		clock_rst = clock + m->time_factor * alltmp / bpm;
+		start_time = time + m->time_factor * frame_count * base_time / bpm;
 	    }
 
 	    info->start_row = break_row;
 	}
 
 	last_row = mod->xxp[pat]->rows;
-	for (row = break_row, break_row = 0; row < last_row; row++, cnt_row++) {
+	for (row = break_row, break_row = 0; row < last_row; row++, row_count++) {
 	    /* Prevent crashes caused by large softmixer frames */
 	    if (bpm < XMP_MIN_BPM) {
 	        bpm = XMP_MIN_BPM;
@@ -181,11 +207,11 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
 	     * (...) it dies at the end of position 2F
 	     */
 
-	    if (cnt_row > 512)	/* was 255, but Global trash goes to 318 */
+	    if (row_count > 512)  /* was 255, but Global trash goes to 318 */
 		goto end_module;
 
-	    if (!loop_flg && m->scan_cnt[ord][row]) {
-		cnt_row--;
+	    if (!loop_num && m->scan_cnt[ord][row]) {
+		row_count--;
 		goto end_module;
 	    }
 	    m->scan_cnt[ord][row]++;
@@ -198,17 +224,10 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
 
 		event = &EVENT(mod->xxo[ord], chn, row);
 
-		/* Pattern delay + pattern break cause target row events
-		 * to be ignored
-		 */
-		if (skip_fetch) {
-		    f1 = p1 = f2 = p2 = 0;
-		} else {
-		    f1 = event->fxt;
-		    p1 = event->fxp;
-		    f2 = event->f2t;
-		    p2 = event->f2p;
-		}
+		f1 = event->fxt;
+		p1 = event->fxp;
+		f2 = event->f2t;
+		p2 = event->f2p;
 
 		if (f1 == FX_GLOBALVOL || f2 == FX_GLOBALVOL) {
 		    gvl = (f1 == FX_GLOBALVOL) ? p1 : p2;
@@ -253,14 +272,19 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
 
 		if ((f1 == FX_SPEED && p1) || (f2 == FX_SPEED && p2)) {
 		    parm = (f1 == FX_SPEED) ? p1 : p2;
-		    alltmp += cnt_row * speed * base_time;
-		    cnt_row = 0;
+		    frame_count += row_count * speed;
+		    row_count = 0;
 		    if (parm) {
-			if (p->flags & XMP_FLAGS_VBLANK || parm < 0x20) {
-			    speed = parm;
+			if (HAS_QUIRK(QUIRK_NOBPM) || p->flags & XMP_FLAGS_VBLANK || parm < 0x20) {
+			    if (parm > 0) {
+			        speed = parm;
+#ifndef LIBXMP_CORE_PLAYER
+			        st26_speed = 0;
+#endif
+                            }
 			} else {
-			    clock += m->time_factor * alltmp / bpm;
-			    alltmp = 0;
+			    time += m->time_factor * frame_count * base_time / bpm;
+			    frame_count = 0;
 			    bpm = parm;
 			}
 		    }
@@ -273,22 +297,37 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
 		if (f2 == FX_SPEED_CP) {
 		    f2 = FX_S3M_SPEED;
 		}
+
+		/* ST2.6 speed processing */
+
+		if (f1 == FX_ICE_SPEED && p1) {
+		    if (LSN(p1)) {
+		        st26_speed = (MSN(p1) << 8) | LSN(p1);
+		    } else {
+			st26_speed = MSN(p1);
+		    }
+		}
 #endif
 
 		if ((f1 == FX_S3M_SPEED && p1) || (f2 == FX_S3M_SPEED && p2)) {
 		    parm = (f1 == FX_S3M_SPEED) ? p1 : p2;
-		    alltmp += cnt_row * speed * base_time;
-		    cnt_row  = 0;
-		    speed = parm;
+		    if (parm > 0) {
+		        frame_count += row_count * speed;
+		        row_count  = 0;
+		        speed = parm;
+#ifndef LIBXMP_CORE_PLAYER
+		        st26_speed = 0;
+#endif
+		    }
 		}
 
 		if ((f1 == FX_S3M_BPM && p1) || (f2 == FX_S3M_BPM && p2)) {
 		    parm = (f1 == FX_S3M_BPM) ? p1 : p2;
 		    if (parm >= 0x20) {
-			alltmp += cnt_row * speed * base_time;
-			cnt_row = 0;
-			clock += m->time_factor * alltmp / bpm;
-			alltmp = 0;
+			frame_count += row_count * speed;
+			row_count = 0;
+			time += m->time_factor * frame_count * base_time / bpm;
+			frame_count = 0;
 			bpm = parm;
 		    }
 		}
@@ -296,44 +335,58 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
 #ifndef LIBXMP_CORE_DISABLE_IT
 		if ((f1 == FX_IT_BPM && p1) || (f2 == FX_IT_BPM && p2)) {
 		    parm = (f1 == FX_IT_BPM) ? p1 : p2;
-		    alltmp += cnt_row * speed * base_time;
-		    cnt_row = 0;
-		    clock += m->time_factor * alltmp / bpm;
-		    alltmp = 0;
+		    frame_count += row_count * speed;
+		    row_count = 0;
+		    time += m->time_factor * frame_count * base_time / bpm;
+		    frame_count = 0;
 
 		    if (MSN(parm) == 0) {
-		        clock += m->time_factor * base_time / bpm;
+		        time += m->time_factor * base_time / bpm;
 			for (i = 1; i < speed; i++) {
 			    bpm -= LSN(parm);
 			    if (bpm < 0x20)
 				bpm = 0x20;
-		            clock += m->time_factor * base_time / bpm;
+		            time += m->time_factor * base_time / bpm;
 			}
 
-			// remove one row at final bpm
-			clock -= m->time_factor * speed * base_time / bpm;
+			/* remove one row at final bpm */
+			time -= m->time_factor * speed * base_time / bpm;
 
 		    } else if (MSN(parm) == 1) {
-		        clock += m->time_factor * base_time / bpm;
+		        time += m->time_factor * base_time / bpm;
 			for (i = 1; i < speed; i++) {
 			    bpm += LSN(parm);
 			    if (bpm > 0xff)
 				bpm = 0xff;
-		            clock += m->time_factor * base_time / bpm;
+		            time += m->time_factor * base_time / bpm;
 			}
 
-			// remove one row at final bpm
-			clock -= m->time_factor * speed * base_time / bpm;
+			/* remove one row at final bpm */
+			time -= m->time_factor * speed * base_time / bpm;
 
 		    } else {
 			bpm = parm;
 		    }
 		}
+
+		if (f1 == FX_IT_ROWDELAY) {
+	    		m->scan_cnt[ord][row] += p1 & 0x0f;
+			frame_count += (p1 & 0x0f) * speed;
+		}
+
+		if (f1 == FX_IT_BREAK) {
+		    break_row = p1;
+		    last_row = 0;
+		}
 #endif
 
 		if (f1 == FX_JUMP || f2 == FX_JUMP) {
 		    ord2 = (f1 == FX_JUMP) ? p1 : p2;
+		    break_row = 0;
 		    last_row = 0;
+
+		    /* prevent infinite loop, see OpenMPT PatLoop-Various.xm */
+		    inside_loop = 0;
 		}
 
 		if (f1 == FX_BREAK || f2 == FX_BREAK) {
@@ -346,43 +399,63 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
 		    parm = (f1 == FX_EXTENDED) ? p1 : p2;
 
 		    if ((parm >> 4) == EX_PATT_DELAY) {
-			pdelay = parm & 0x0f;
-			alltmp += pdelay * speed * base_time;
+			if (m->read_event_type != READ_EVENT_ST3 || !pdelay) {
+			    pdelay = parm & 0x0f;
+			    frame_count += pdelay * speed;
+                        }
 		    }
 
 		    if ((parm >> 4) == EX_PATTERN_LOOP) {
 			if (parm &= 0x0f) {
-			    if (loop_stk[chn]) {
-				if (--loop_stk[chn])
-				    loop_chn = chn + 1;
-				else {
-				    loop_flg--;
+			    /* Loop end */
+			    if (loop_count[chn]) {
+				if (--loop_count[chn]) {
+				    /* next iteraction */
+				    loop_chn = chn;
+				} else {
+				    /* finish looping */
+				    loop_num--;
+				    inside_loop = 0;
 				    if (m->quirk & QUIRK_S3MLOOP)
-					loop_row[chn] = row + 1;
+					loop_row[chn] = row;
 				}
 			    } else {
-				if (loop_row[chn] <= row) {
-				    loop_stk[chn] = parm;
-				    loop_chn = chn + 1;
-				    loop_flg++;
-				}
+				loop_count[chn] = parm;
+				loop_chn = chn;
+				loop_num++;
 			    }
 			} else { 
-			    loop_row[chn] = row;
+			    /* Loop start */
+			    loop_row[chn] = row - 1;
+			    inside_loop = 1;
+			    if (HAS_QUIRK(QUIRK_FT2BUGS))
+				break_row = row;
 			}
 		    }
 		}
 	    }
-	    skip_fetch = 0;
 
-	    if (loop_chn) {
-		row = loop_row[--loop_chn] - 1;
-		loop_chn = 0;
+	    if (loop_chn >= 0) {
+		row = loop_row[loop_chn];
+		loop_chn = -1;
 	    }
+
+#ifndef LIBXMP_CORE_PLAYER
+	    if (st26_speed) {
+	        frame_count += row_count * speed;
+	        row_count  = 0;
+		if (st26_speed & 0x10000) {
+			speed = (st26_speed & 0xff00) >> 8;
+		} else {
+			speed = st26_speed & 0xff;
+		}
+		st26_speed ^= 0x10000;
+	    }
+#endif
 	}
 
 	if (break_row && pdelay) {
-	    skip_fetch = 1;
+	    break_row++;
 	}
 
 	if (ord2 >= 0) {
@@ -390,29 +463,38 @@ static int scan_module(struct context_data *ctx, int ep, int chain)
 	    ord2 = -1;
 	}
 
-	alltmp += cnt_row * speed * base_time;
-	cnt_row = 0;
+	frame_count += row_count * speed;
+	row_count = 0;
     }
     row = break_row;
 
 end_module:
+
+    /* Sanity check */
+    {
+        pat = mod->xxo[ord];
+        if (pat >= mod->pat || row >= mod->xxp[pat]->rows) {
+            row = 0;
+        }
+    }
+
     p->scan[chain].num = m->scan_cnt[ord][row];
     p->scan[chain].row = row;
     p->scan[chain].ord = ord;
 
-    clock -= clock_rst;
-    alltmp += cnt_row * speed * base_time;
+    time -= start_time;
+    frame_count += row_count * speed;
 
-    return (clock + m->time_factor * alltmp / bpm);
+    return (time + m->time_factor * frame_count * base_time / bpm);
 }
 
-int get_sequence(struct context_data *ctx, int ord)
+int libxmp_get_sequence(struct context_data *ctx, int ord)
 {
 	struct player_data *p = &ctx->p;
 	return p->sequence_control[ord];
 }
 
-int scan_sequences(struct context_data *ctx)
+int libxmp_scan_sequences(struct context_data *ctx)
 {
 	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
@@ -421,6 +503,13 @@ int scan_sequences(struct context_data *ctx)
 	int seq;
 	unsigned char temp_ep[XMP_MAX_MOD_LENGTH];
 
+	/* Initialize order data to prevent overwrite when a position is used
+	 * multiple times at different starting points (see janosik.xm).
+	 */
+	for (i = 0; i < XMP_MAX_MOD_LENGTH; i++) {
+		m->xxo_info[i].gvl = -1;
+	}
+
 	ep = 0;
 	memset(p->sequence_control, 0xff, XMP_MAX_MOD_LENGTH);
 	temp_ep[0] = 0;
diff --git a/src/smix.c b/src/smix.c
index 4f49da6..ba801c5 100644
--- a/src/smix.c
+++ b/src/smix.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -27,36 +27,38 @@
 #include "hio.h"
 
 
-struct xmp_instrument *get_instrument(struct context_data *ctx, int ins)
+struct xmp_instrument *libxmp_get_instrument(struct context_data *ctx, int ins)
 {
 	struct smix_data *smix = &ctx->smix;
 	struct module_data *m = &ctx->m;
 	struct xmp_module *mod = &m->mod;
 	struct xmp_instrument *xxi;
 
-	if (ins < mod->ins)
+	if (ins < mod->ins) {
 		xxi = &mod->xxi[ins];
-	else if (ins < mod->ins + smix->ins)
+	} else if (ins < mod->ins + smix->ins) {
 		xxi = &smix->xxi[ins - mod->ins];
-	else
+	} else {
 		xxi = NULL;
+	}
 
 	return xxi;
 }
 
-struct xmp_sample *get_sample(struct context_data *ctx, int smp)
+struct xmp_sample *libxmp_get_sample(struct context_data *ctx, int smp)
 {
 	struct smix_data *smix = &ctx->smix;
 	struct module_data *m = &ctx->m;
 	struct xmp_module *mod = &m->mod;
 	struct xmp_sample *xxs;
 
-	if (smp < mod->smp)
+	if (smp < mod->smp) {
 		xxs = &mod->xxs[smp];
-	else if (smp < mod->smp + smix->smp)
+	} else if (smp < mod->smp + smix->smp) {
 		xxs = &smix->xxs[smp - mod->smp];
-	else
+	} else {
 		xxs = NULL;
+	}
 
 	return xxs;
 }
@@ -66,15 +68,18 @@ int xmp_start_smix(xmp_context opaque, int chn, int smp)
 	struct context_data *ctx = (struct context_data *)opaque;
 	struct smix_data *smix = &ctx->smix;
 
-	if (ctx->state > XMP_STATE_LOADED)
+	if (ctx->state > XMP_STATE_LOADED) {
 		return -XMP_ERROR_STATE;
+	}
 
 	smix->xxi = calloc(sizeof (struct xmp_instrument), smp);
-	if (smix->xxi == NULL)
+	if (smix->xxi == NULL) {
 		goto err;
+	}
 	smix->xxs = calloc(sizeof (struct xmp_sample), smp);
-	if (smix->xxs == NULL)
+	if (smix->xxs == NULL) {
 		goto err1;
+	}
 
 	smix->chn = chn;
 	smix->ins = smix->smp = smp;
@@ -96,14 +101,17 @@ int xmp_smix_play_instrument(xmp_context opaque, int ins, int note, int vol, int
 	struct xmp_module *mod = &m->mod;
 	struct xmp_event *event;
 
-	if (ctx->state < XMP_STATE_PLAYING)
+	if (ctx->state < XMP_STATE_PLAYING) {
 		return -XMP_ERROR_STATE;
+	}
 
-	if (chn >= smix->chn || ins >= mod->ins)
+	if (chn >= smix->chn || ins >= mod->ins) {
 		return -XMP_ERROR_INVALID;
+	}
 
-	if (note == 0)
+	if (note == 0) {
 		note = 60;		/* middle C note number */
+	}
 
 	event = &p->inject_event[mod->chn + chn];
 	memset(event, 0, sizeof (struct xmp_event));
@@ -124,14 +132,17 @@ int xmp_smix_play_sample(xmp_context opaque, int ins, int note, int vol, int chn
 	struct xmp_module *mod = &m->mod;
 	struct xmp_event *event;
 
-	if (ctx->state < XMP_STATE_PLAYING)
+	if (ctx->state < XMP_STATE_PLAYING) {
 		return -XMP_ERROR_STATE;
+	}
 
-	if (chn >= smix->chn || ins >= smix->ins)
+	if (chn >= smix->chn || ins >= smix->ins) {
 		return -XMP_ERROR_INVALID;
+	}
 
-	if (note == 0)
+	if (note == 0) {
 		note = 60;		/* middle C note number */
+	}
 
 	event = &p->inject_event[mod->chn + chn];
 	memset(event, 0, sizeof (struct xmp_event));
@@ -151,8 +162,9 @@ int xmp_smix_channel_pan(xmp_context opaque, int chn, int pan)
 	struct module_data *m = &ctx->m;
 	struct channel_data *xc;
 
-	if (chn >= smix->chn || pan < 0 || pan > 255)
+	if (chn >= smix->chn || pan < 0 || pan > 255) {
 		return -XMP_ERROR_INVALID;
+	}
 
 	xc = &p->xc_data[m->mod.chn + chn];
 	xc->pan.val = pan;
@@ -208,7 +220,10 @@ int xmp_smix_load_sample(xmp_context opaque, int num, char *path)
 		goto err2;
 	}
 
-	hio_seek(h, 22, SEEK_SET);
+	if (hio_seek(h, 22, SEEK_SET) < 0) {
+		retval = -XMP_ERROR_SYSTEM;
+		goto err2;
+	}
 	chn = hio_read16l(h);
 	if (chn != 1) {
 		retval = -XMP_ERROR_FORMAT;
@@ -216,14 +231,32 @@ int xmp_smix_load_sample(xmp_context opaque, int num, char *path)
 	}
 
 	rate = hio_read32l(h);
+	if (rate == 0) {
+		retval = -XMP_ERROR_FORMAT;
+		goto err2;
+	}
 
-	hio_seek(h, 34, SEEK_SET);
+	if (hio_seek(h, 34, SEEK_SET) < 0) {
+		retval = -XMP_ERROR_SYSTEM;
+		goto err2;
+	}
 	bits = hio_read16l(h);
+	if (bits == 0) {
+		retval = -XMP_ERROR_FORMAT;
+		goto err2;
+	}
 
-	hio_seek(h, 40, SEEK_SET);
+	if (hio_seek(h, 40, SEEK_SET) < 0) {
+		retval = -XMP_ERROR_SYSTEM;
+		goto err2;
+	}
 	size = hio_read32l(h) / (bits / 8);
+	if (size == 0) {
+		retval = -XMP_ERROR_FORMAT;
+		goto err2;
+	}
 
-	c2spd_to_note(rate, &xxi->sub[0].xpo, &xxi->sub[0].fin);
+	libxmp_c2spd_to_note(rate, &xxi->sub[0].xpo, &xxi->sub[0].fin);
 
 	xxs->len = 8 * size / bits;
 	xxs->lps = 0;
@@ -235,9 +268,14 @@ int xmp_smix_load_sample(xmp_context opaque, int num, char *path)
 		retval = -XMP_ERROR_SYSTEM;
 		goto err2;
 	}
-
-	hio_seek(h, 44, SEEK_SET);
-	hio_read(xxs->data, 1, size, h);
+	if (hio_seek(h, 44, SEEK_SET) < 0) {
+		retval = -XMP_ERROR_SYSTEM;
+		goto err2;
+	}
+	if (hio_read(xxs->data, 1, size, h) != size) {
+		retval = -XMP_ERROR_SYSTEM;
+		goto err2;
+	}
 	hio_close(h);
 
 	return 0;
@@ -256,8 +294,9 @@ int xmp_smix_release_sample(xmp_context opaque, int num)
 	struct context_data *ctx = (struct context_data *)opaque;
 	struct smix_data *smix = &ctx->smix;
 
-	if (num >= smix->ins)
+	if (num >= smix->ins) {
 		return -XMP_ERROR_INVALID;
+	}
 
 	free(smix->xxs[num].data);
 	free(smix->xxi[num].sub);
@@ -274,8 +313,9 @@ void xmp_end_smix(xmp_context opaque)
 	struct smix_data *smix = &ctx->smix;
 	int i;
 
-	for (i = 0; i < smix->smp; i++)
+	for (i = 0; i < smix->smp; i++) {
 		xmp_smix_release_sample(opaque, i);
+	}
 
 	free(smix->xxs);
 	free(smix->xxi);
diff --git a/src/synth.h b/src/synth.h
deleted file mode 100644
index d98a73f..0000000
--- a/src/synth.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef LIBXMP_SYNTH_H
-#define LIBXMP_SYNTH_H
-
-#include "common.h"
-
-struct synth_info {
-	int (*init)(struct context_data *, int);
-	int (*deinit)(struct context_data *);
-	int (*reset)(struct context_data *);
-	void (*setpatch)(struct context_data *, int, uint8 *);
-	void (*setnote)(struct context_data *, int, int, int);
-	void (*setvol)(struct context_data *, int, int);
-	void (*mixer)(struct context_data *, int32 *, int, int, int, int);
-};
-
-extern const struct synth_info synth_null;
-extern const struct synth_info synth_adlib;
-
-#define SYNTH_CHIP(x) ((x)->m.synth_chip)
-
-#endif
diff --git a/src/synth_null.c b/src/synth_null.c
deleted file mode 100644
index fa0269f..0000000
--- a/src/synth_null.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Extended Module Player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
- *
- * This file is part of the Extended Module Player and is distributed
- * under the terms of the GNU Lesser General Public License. See COPYING.LIB
- * for more information.
- */
-
-#include "xmp.h"
-#include "common.h"
-#include "synth.h"
-
-
-static int synth_init(struct context_data *ctx, int freq)
-{
-	return 0;
-}
-
-static int synth_deinit(struct context_data *ctx)
-{
-	return 0;
-}
-
-static int synth_reset(struct context_data *ctx)
-{
-	return 0;
-}
-
-const struct synth_info synth_null = {
-	synth_init,
-	synth_deinit,
-	synth_reset,
-};
diff --git a/src/tempfile.c b/src/tempfile.c
new file mode 100644
index 0000000..ad204e8
--- /dev/null
+++ b/src/tempfile.c
@@ -0,0 +1,148 @@
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifdef __SUNPRO_C
+#pragma error_messages (off,E_EMPTY_TRANSLATION_UNIT)
+#endif
+
+#ifndef LIBXMP_CORE_PLAYER
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef HAVE_UMASK
+#include 
+#endif
+
+#include "tempfile.h"
+
+#ifdef WIN32
+
+int mkstemp(char *);
+
+static int get_temp_dir(char *buf, int size)
+{
+	const char def[] = "C:\\WINDOWS\\TEMP";
+	char *tmp = getenv("TEMP");
+
+	strncpy(buf, tmp ? tmp : def, size);
+	strncat(buf, "\\", size);
+
+	return 0;
+}
+
+#elif defined __AMIGA__
+
+static int get_temp_dir(char *buf, int size)
+{
+	strncpy(buf, "T:", size);
+	return 0;
+}
+
+#elif defined __ANDROID__
+
+#include 
+#include 
+
+static int get_temp_dir(char *buf, int size)
+{
+#define APPDIR "/sdcard/Xmp for Android"
+	struct stat st;
+	if (stat(APPDIR, &st) < 0) {
+		if (mkdir(APPDIR, 0777) < 0)
+			return -1;
+	}
+	if (stat(APPDIR "/tmp", &st) < 0) {
+		if (mkdir(APPDIR "/tmp", 0777) < 0)
+			return -1;
+	}
+	strncpy(buf, APPDIR "/tmp/", size);
+
+	return 0;
+}
+
+#else
+
+static int get_temp_dir(char *buf, int size)
+{
+	char *tmp = getenv("TMPDIR");
+
+	if (tmp) {
+		snprintf(buf, size, "%s/", tmp);
+	} else {
+		strncpy(buf, "/tmp/", size);
+	}
+
+	return 0;
+}
+
+#endif
+
+
+FILE *make_temp_file(char **filename) {
+	char tmp[PATH_MAX];
+	FILE *temp;
+	int fd;
+
+	if (get_temp_dir(tmp, PATH_MAX) < 0)
+		return NULL;
+
+	strncat(tmp, "xmp_XXXXXX", PATH_MAX - 10);
+
+	if ((*filename = strdup(tmp)) == NULL)
+		goto err;
+
+#ifdef HAVE_UMASK
+	umask(0177);
+#endif
+	if ((fd = mkstemp(*filename)) < 0)
+		goto err2;
+
+	if ((temp = fdopen(fd, "w+b")) == NULL)
+		goto err3;
+
+	return temp;
+
+    err3:
+	close(fd);
+    err2:
+	free(*filename);
+    err:
+	return NULL;
+}
+
+/*
+ * Windows doesn't allow you to unlink an open file, so we changed the
+ * temp file cleanup system to remove temporary files after we close it
+ */
+void unlink_temp_file(char *temp)
+{
+	if (temp) {
+		unlink(temp);
+		free(temp);
+	}
+}
+
+#endif
diff --git a/src/tempfile.h b/src/tempfile.h
new file mode 100644
index 0000000..f3c8f77
--- /dev/null
+++ b/src/tempfile.h
@@ -0,0 +1,7 @@
+#ifndef XMP_PLATFORM_H
+#define XMP_PLATFORM_H
+
+FILE *make_temp_file(char **);
+void unlink_temp_file(char *);
+
+#endif
diff --git a/src/virtual.c b/src/virtual.c
index b64918b..33779b2 100644
--- a/src/virtual.c
+++ b/src/virtual.c
@@ -1,5 +1,5 @@
-/* Extended Module Player core player
- * Copyright (C) 1996-2014 Claudio Matsuoka and Hipolito Carraro Jr
+/* Extended Module Player
+ * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -23,60 +23,76 @@
 #include 
 #include 
 #include 
+#include "common.h"
 #include "virtual.h"
 #include "mixer.h"
 
+#ifdef LIBXMP_PAULA_SIMULATOR
+#include "paula.h"
+#endif
+
 #define	FREE	-1
 
 /* For virt_pastnote() */
-void player_set_release(struct context_data *, int);
-void player_set_fadeout(struct context_data *, int);
+void libxmp_player_set_release(struct context_data *, int);
+void libxmp_player_set_fadeout(struct context_data *, int);
 
 
 /* Get parent channel */
-int virt_getroot(struct context_data *ctx, int chn)
+int libxmp_virt_getroot(struct context_data *ctx, int chn)
 {
 	struct player_data *p = &ctx->p;
 	struct mixer_voice *vi;
 	int voc;
 
 	voc = p->virt.virt_channel[chn].map;
-	if (voc < 0)
+	if (voc < 0) {
 		return -1;
+	}
 
 	vi = &p->virt.voice_array[voc];
 
 	return vi->root;
 }
 
-void virt_resetvoice(struct context_data *ctx, int voc, int mute)
+void libxmp_virt_resetvoice(struct context_data *ctx, int voc, int mute)
 {
 	struct player_data *p = &ctx->p;
 	struct mixer_voice *vi = &p->virt.voice_array[voc];
+#ifdef LIBXMP_PAULA_SIMULATOR
+	struct paula_state *paula;
+#endif
 
-	if ((uint32)voc >= p->virt.maxvoc)
+	if ((uint32)voc >= p->virt.maxvoc) {
 		return;
+	}
 
 	if (mute) {
-		mixer_setvol(ctx, voc, 0);
+		libxmp_mixer_setvol(ctx, voc, 0);
 	}
 
 	p->virt.virt_used--;
 	p->virt.virt_channel[vi->root].count--;
 	p->virt.virt_channel[vi->chn].map = FREE;
+#ifdef LIBXMP_PAULA_SIMULATOR
+	paula = vi->paula;
+#endif
 	memset(vi, 0, sizeof(struct mixer_voice));
+#ifdef LIBXMP_PAULA_SIMULATOR
+	vi->paula = paula;
+#endif
 	vi->chn = vi->root = FREE;
 }
 
 /* virt_on (number of tracks) */
-int virt_on(struct context_data *ctx, int num)
+int libxmp_virt_on(struct context_data *ctx, int num)
 {
 	struct player_data *p = &ctx->p;
 	struct module_data *m = &ctx->m;
 	int i;
 
 	p->virt.num_tracks = num;
-	num = mixer_numvoices(ctx, -1);
+	num = libxmp_mixer_numvoices(ctx, -1);
 
 	p->virt.virt_channels = p->virt.num_tracks;
 
@@ -86,7 +102,7 @@ int virt_on(struct context_data *ctx, int num)
 		num = p->virt.virt_channels;
 	}
 
-	p->virt.maxvoc = mixer_numvoices(ctx, num);
+	p->virt.maxvoc = libxmp_mixer_numvoices(ctx, num);
 
 	p->virt.voice_array = calloc(p->virt.maxvoc,
 				sizeof(struct mixer_voice));
@@ -98,10 +114,23 @@ int virt_on(struct context_data *ctx, int num)
 		p->virt.voice_array[i].root = FREE;
 	}
 
+#ifdef LIBXMP_PAULA_SIMULATOR
+	/* Initialize Paula simulator */
+	if (IS_AMIGA_MOD()) {
+		for (i = 0; i < p->virt.maxvoc; i++) {
+			p->virt.voice_array[i].paula = calloc(1, sizeof (struct paula_state));
+			if (p->virt.voice_array[i].paula == NULL) {
+				goto err2;
+			}
+			libxmp_paula_init(ctx, p->virt.voice_array[i].paula);
+		}
+	}
+#endif
+
 	p->virt.virt_channel = malloc(p->virt.virt_channels *
 				sizeof(struct virt_channel));
 	if (p->virt.virt_channel == NULL)
-		goto err1;
+		goto err2;
 
 	for (i = 0; i < p->virt.virt_channels; i++) {
 		p->virt.virt_channel[i].map = FREE;
@@ -112,41 +141,70 @@ int virt_on(struct context_data *ctx, int num)
 
 	return 0;
 
-      err1:
+      err2:
+#ifdef LIBXMP_PAULA_SIMULATOR
+	if (IS_AMIGA_MOD()) {
+		for (i = 0; i < p->virt.maxvoc; i++) {
+			free(p->virt.voice_array[i].paula);
+		}
+	}
+#endif
 	free(p->virt.voice_array);
       err:
 	return -1;
 }
 
-void virt_off(struct context_data *ctx)
+void libxmp_virt_off(struct context_data *ctx)
 {
 	struct player_data *p = &ctx->p;
+#ifdef LIBXMP_PAULA_SIMULATOR
+	struct module_data *m = &ctx->m;
+	int i;
+#endif
 
-	if (p->virt.virt_channels < 1)
-		return;
+#ifdef LIBXMP_PAULA_SIMULATOR
+	/* Free Paula simulator state */
+	if (IS_AMIGA_MOD()) {
+		for (i = 0; i < p->virt.maxvoc; i++) {
+			free(p->virt.voice_array[i].paula);
+		}
+	}
+#endif
 
 	p->virt.virt_used = p->virt.maxvoc = 0;
 	p->virt.virt_channels = 0;
 	p->virt.num_tracks = 0;
+
 	free(p->virt.voice_array);
 	free(p->virt.virt_channel);
 }
 
-void virt_reset(struct context_data *ctx)
+void libxmp_virt_reset(struct context_data *ctx)
 {
 	struct player_data *p = &ctx->p;
 	int i;
 
-	if (p->virt.virt_channels < 1)
+	if (p->virt.virt_channels < 1) {
 		return;
+	}
 
-	mixer_numvoices(ctx, p->virt.maxvoc);
+	/* CID 129203 (#1 of 1): Useless call (USELESS_CALL)
+	 * Call is only useful for its return value, which is ignored. 
+	 *
+	 * libxmp_mixer_numvoices(ctx, p->virt.maxvoc);
+	 */
 
-	memset(p->virt.voice_array, 0,
-	       p->virt.maxvoc * sizeof(struct mixer_voice));
 	for (i = 0; i < p->virt.maxvoc; i++) {
-		p->virt.voice_array[i].chn = FREE;
-		p->virt.voice_array[i].root = FREE;
+		struct mixer_voice *vi = &p->virt.voice_array[i];
+#ifdef LIBXMP_PAULA_SIMULATOR
+		struct paula_state *paula = vi->paula;
+#endif
+		memset(vi, 0, sizeof(struct mixer_voice));
+#ifdef LIBXMP_PAULA_SIMULATOR
+		vi->paula = paula;
+#endif
+		vi->chn = FREE;
+		vi->root = FREE;
 	}
 
 	for (i = 0; i < p->virt.virt_channels; i++) {
@@ -175,9 +233,11 @@ static int free_voice(struct context_data *ctx)
 	}
 
 	/* Free voice */
-	p->virt.virt_channel[p->virt.voice_array[num].chn].map = FREE;
-	p->virt.virt_channel[p->virt.voice_array[num].root].count--;
-	p->virt.virt_used--;
+	if (num >= 0) {
+		p->virt.virt_channel[p->virt.voice_array[num].chn].map = FREE;
+		p->virt.virt_channel[p->virt.voice_array[num].root].count--;
+		p->virt.virt_used--;
+	}
 
 	return num;
 }
@@ -194,15 +254,18 @@ static int alloc_voice(struct context_data *ctx, int chn)
 	}
 
 	/* not found */
-	if (i == p->virt.maxvoc)
+	if (i == p->virt.maxvoc) {
 		i = free_voice(ctx);
+	}
 
-	p->virt.virt_channel[chn].count++;
-	p->virt.virt_used++;
+	if (i >= 0) {
+		p->virt.virt_channel[chn].count++;
+		p->virt.virt_used++;
 
-	p->virt.voice_array[i].chn = chn;
-	p->virt.voice_array[i].root = chn;
-	p->virt.virt_channel[chn].map = i;
+		p->virt.voice_array[i].chn = chn;
+		p->virt.voice_array[i].root = chn;
+		p->virt.virt_channel[chn].map = i;
+	}
 
 	return i;
 }
@@ -222,112 +285,144 @@ static int map_virt_channel(struct player_data *p, int chn)
 	return voc;
 }
 
-int virt_mapchannel(struct context_data *ctx, int chn)
+int libxmp_virt_mapchannel(struct context_data *ctx, int chn)
 {
 	return map_virt_channel(&ctx->p, chn);
 }
 
-void virt_resetchannel(struct context_data *ctx, int chn)
+void libxmp_virt_resetchannel(struct context_data *ctx, int chn)
 {
 	struct player_data *p = &ctx->p;
+	struct mixer_voice *vi;
+#ifdef LIBXMP_PAULA_SIMULATOR
+	struct paula_state *paula;
+#endif
 	int voc;
 
 	if ((voc = map_virt_channel(p, chn)) < 0)
 		return;
 
-	mixer_setvol(ctx, voc, 0);
+	libxmp_mixer_setvol(ctx, voc, 0);
 
 	p->virt.virt_used--;
 	p->virt.virt_channel[p->virt.voice_array[voc].root].count--;
 	p->virt.virt_channel[chn].map = FREE;
-	memset(&p->virt.voice_array[voc], 0, sizeof(struct mixer_voice));
-	p->virt.voice_array[voc].chn = p->virt.voice_array[voc].root = FREE;
+
+	vi = &p->virt.voice_array[voc];
+#ifdef LIBXMP_PAULA_SIMULATOR
+	paula = vi->paula;
+#endif
+	memset(vi, 0, sizeof(struct mixer_voice));
+#ifdef LIBXMP_PAULA_SIMULATOR
+	vi->paula = paula;
+#endif
+	vi->chn = vi->root = FREE;
 }
 
-void virt_setvol(struct context_data *ctx, int chn, int vol)
+void libxmp_virt_setvol(struct context_data *ctx, int chn, int vol)
 {
 	struct player_data *p = &ctx->p;
 	int voc, root;
 
-	if ((voc = map_virt_channel(p, chn)) < 0)
+	if ((voc = map_virt_channel(p, chn)) < 0) {
 		return;
+	}
 
 	root = p->virt.voice_array[voc].root;
-	if (root < XMP_MAX_CHANNELS && p->channel_mute[root])
+	if (root < XMP_MAX_CHANNELS && p->channel_mute[root]) {
 		vol = 0;
+	}
 
-	mixer_setvol(ctx, voc, vol);
+	libxmp_mixer_setvol(ctx, voc, vol);
 
-	if (!(vol || chn < p->virt.num_tracks))
-		virt_resetvoice(ctx, voc, 1);
+	if (vol == 0 && chn >= p->virt.num_tracks) {
+		libxmp_virt_resetvoice(ctx, voc, 1);
+	}
 }
 
-void virt_setpan(struct context_data *ctx, int chn, int pan)
+void libxmp_virt_release(struct context_data *ctx, int chn, int rel)
 {
 	struct player_data *p = &ctx->p;
 	int voc;
 
-	if ((voc = map_virt_channel(p, chn)) < 0)
+	if ((voc = map_virt_channel(p, chn)) < 0) {
 		return;
+	}
 
-	mixer_setpan(ctx, voc, pan);
+	libxmp_mixer_release(ctx, voc, rel);
 }
 
-void virt_seteffect(struct context_data *ctx, int chn, int type, int val)
+void libxmp_virt_setpan(struct context_data *ctx, int chn, int pan)
 {
 	struct player_data *p = &ctx->p;
 	int voc;
 
-	if ((voc = map_virt_channel(p, chn)) < 0)
+	if ((voc = map_virt_channel(p, chn)) < 0) {
 		return;
+	}
 
-	mixer_seteffect(ctx, voc, type, val);
+	libxmp_mixer_setpan(ctx, voc, pan);
 }
 
-int virt_getvoicepos(struct context_data *ctx, int chn)
+void libxmp_virt_seteffect(struct context_data *ctx, int chn, int type, int val)
 {
 	struct player_data *p = &ctx->p;
 	int voc;
 
-	if ((voc = map_virt_channel(p, chn)) < 0)
+	if ((voc = map_virt_channel(p, chn)) < 0) {
+		return;
+	}
+
+	libxmp_mixer_seteffect(ctx, voc, type, val);
+}
+
+double libxmp_virt_getvoicepos(struct context_data *ctx, int chn)
+{
+	struct player_data *p = &ctx->p;
+	int voc;
+
+	if ((voc = map_virt_channel(p, chn)) < 0) {
 		return -1;
+	}
 
-	return mixer_getvoicepos(ctx, voc);
+	return libxmp_mixer_getvoicepos(ctx, voc);
 }
 
 #ifndef LIBXMP_CORE_PLAYER
 
-void virt_setsmp(struct context_data *ctx, int chn, int smp)
+void libxmp_virt_setsmp(struct context_data *ctx, int chn, int smp)
 {
 	struct player_data *p = &ctx->p;
 	struct mixer_voice *vi;
-	int voc, pos, frac;
+	double pos;
+	int voc;
 
-	if ((voc = map_virt_channel(p, chn)) < 0)
+	if ((voc = map_virt_channel(p, chn)) < 0) {
 		return;
+	}
 
 	vi = &p->virt.voice_array[voc];
-	if (vi->smp == smp)
+	if (vi->smp == smp) {
 		return;
+	}
 
-	pos = vi->pos;
-	frac = vi->frac;
-
-	mixer_setpatch(ctx, voc, smp);
-	mixer_voicepos(ctx, voc, pos, frac);	/* Restore old position */
+	pos = libxmp_mixer_getvoicepos(ctx, voc);
+	libxmp_mixer_setpatch(ctx, voc, smp, 0);
+	libxmp_mixer_voicepos(ctx, voc, pos, 0);	/* Restore old position */
 }
 
 #endif
 
 #ifndef LIBXMP_CORE_DISABLE_IT
 
-void virt_setnna(struct context_data *ctx, int chn, int nna)
+void libxmp_virt_setnna(struct context_data *ctx, int chn, int nna)
 {
 	struct player_data *p = &ctx->p;
 	int voc;
 
-	if ((voc = map_virt_channel(p, chn)) < 0)
+	if ((voc = map_virt_channel(p, chn)) < 0) {
 		return;
+	}
 
 	p->virt.voice_array[voc].act = nna;
 }
@@ -350,7 +445,7 @@ static void check_dct(struct context_data *ctx, int i, int chn, int ins,
 				if (i != voc || vi->act)
 					vi->act = dca;
 			} else {
-				virt_resetvoice(ctx, i, 1);
+				libxmp_virt_resetvoice(ctx, i, 1);
 			}
 		}
 	}
@@ -358,24 +453,40 @@ static void check_dct(struct context_data *ctx, int i, int chn, int ins,
 
 #endif
 
-int virt_setpatch(struct context_data *ctx, int chn, int ins, int smp,
+/* For note slides */
+void libxmp_virt_setnote(struct context_data *ctx, int chn, int note)
+{
+	struct player_data *p = &ctx->p;
+	int voc;
+
+	if ((voc = map_virt_channel(p, chn)) < 0) {
+		return;
+	}
+
+	libxmp_mixer_setnote(ctx, voc, note);
+}
+
+int libxmp_virt_setpatch(struct context_data *ctx, int chn, int ins, int smp,
 		    			int note, int nna, int dct, int dca)
 {
 	struct player_data *p = &ctx->p;
 	int voc, vfree;
 
-	if ((uint32)chn >= p->virt.virt_channels)
+	if ((uint32)chn >= p->virt.virt_channels) {
 		return -1;
+	}
 
-	if (ins < 0)
+	if (ins < 0) {
 		smp = -1;
+	}
 
 #ifndef LIBXMP_CORE_DISABLE_IT
 	if (dct) {
 		int i;
 
-		for (i = 0; i < p->virt.maxvoc; i++)
+		for (i = 0; i < p->virt.maxvoc; i++) {
 			check_dct(ctx, i, chn, ins, smp, note, dct, dca);
+		}
 	}
 #endif
 
@@ -385,6 +496,10 @@ int virt_setpatch(struct context_data *ctx, int chn, int ins, int smp,
 		if (p->virt.voice_array[voc].act) {
 			vfree = alloc_voice(ctx, chn);
 
+			if (vfree < 0) {
+				return -1;
+			}
+
 			for (chn = p->virt.num_tracks;
 			     p->virt.virt_channel[chn++].map > FREE;) ;
 
@@ -394,54 +509,51 @@ int virt_setpatch(struct context_data *ctx, int chn, int ins, int smp,
 		}
 	} else {
 		voc = alloc_voice(ctx, chn);
+		if (voc < 0) {
+			return -1;
+		}
 	}
 
 	if (smp < 0) {
-		virt_resetvoice(ctx, voc, 1);
+		libxmp_virt_resetvoice(ctx, voc, 1);
 		return chn;	/* was -1 */
 	}
 
-	mixer_setpatch(ctx, voc, smp);
-
-	/* FIXME: Workaround for crash on notes that are too high
-	 *        see 6nations.it (+114 transposition on instrument 16)
-	 */
-	if (note > 149) {
-		note = 149;
-	}
-
-	mixer_setnote(ctx, voc, note);
+	libxmp_mixer_setpatch(ctx, voc, smp, 1);
+	libxmp_mixer_setnote(ctx, voc, note);
 	p->virt.voice_array[voc].ins = ins;
 	p->virt.voice_array[voc].act = nna;
 
 	return chn;
 }
 
-void virt_setbend(struct context_data *ctx, int chn, int bend)
+void libxmp_virt_setperiod(struct context_data *ctx, int chn, double period)
 {
 	struct player_data *p = &ctx->p;
 	int voc;
 
-	if ((voc = map_virt_channel(p, chn)) < 0)
+	if ((voc = map_virt_channel(p, chn)) < 0) {
 		return;
+	}
 
-	mixer_setbend(ctx, voc, bend);
+	libxmp_mixer_setperiod(ctx, voc, period);
 }
 
-void virt_voicepos(struct context_data *ctx, int chn, int pos)
+void libxmp_virt_voicepos(struct context_data *ctx, int chn, double pos)
 {
 	struct player_data *p = &ctx->p;
 	int voc;
 
-	if ((voc = map_virt_channel(p, chn)) < 0)
+	if ((voc = map_virt_channel(p, chn)) < 0) {
 		return;
+	}
 
-	mixer_voicepos(ctx, voc, pos, 0);
+	libxmp_mixer_voicepos(ctx, voc, pos, 1);
 }
 
 #ifndef LIBXMP_CORE_DISABLE_IT
 
-void virt_pastnote(struct context_data *ctx, int chn, int act)
+void libxmp_virt_pastnote(struct context_data *ctx, int chn, int act)
 {
 	struct player_data *p = &ctx->p;
 	int c, voc;
@@ -453,13 +565,13 @@ void virt_pastnote(struct context_data *ctx, int chn, int act)
 		if (p->virt.voice_array[voc].root == chn) {
 			switch (act) {
 			case VIRT_ACTION_CUT:
-				virt_resetvoice(ctx, voc, 1);
+				libxmp_virt_resetvoice(ctx, voc, 1);
 				break;
 			case VIRT_ACTION_OFF:
-				player_set_release(ctx, c);
+				libxmp_player_set_release(ctx, c);
 				break;
 			case VIRT_ACTION_FADE:
-				player_set_fadeout(ctx, c);
+				libxmp_player_set_fadeout(ctx, c);
 				break;
 			}
 		}
@@ -468,16 +580,18 @@ void virt_pastnote(struct context_data *ctx, int chn, int act)
 
 #endif
 
-int virt_cstat(struct context_data *ctx, int chn)
+int libxmp_virt_cstat(struct context_data *ctx, int chn)
 {
 	struct player_data *p = &ctx->p;
 	int voc;
 
-	if ((voc = map_virt_channel(p, chn)) < 0)
+	if ((voc = map_virt_channel(p, chn)) < 0) {
 		return VIRT_INVALID;
+	}
 
-	if (chn < p->virt.num_tracks)
+	if (chn < p->virt.num_tracks) {
 		return VIRT_ACTIVE;
+	}
 
 	return p->virt.voice_array[voc].act;
 }
diff --git a/src/virtual.h b/src/virtual.h
index d492a78..a7668c5 100644
--- a/src/virtual.h
+++ b/src/virtual.h
@@ -11,27 +11,28 @@
 #define VIRT_ACTIVE		0x100
 #define VIRT_INVALID		-1
 
-int	virt_on			(struct context_data *, int);
-void	virt_off		(struct context_data *);
-int	virt_mute		(struct context_data *, int, int);
-int	virt_setpatch		(struct context_data *, int, int, int, int,
+int	libxmp_virt_on		(struct context_data *, int);
+void	libxmp_virt_off		(struct context_data *);
+int	libxmp_virt_mute	(struct context_data *, int, int);
+int	libxmp_virt_setpatch	(struct context_data *, int, int, int, int,
 				 int, int, int);
-int	virt_cvt8bit		(void);
-void	virt_setsmp		(struct context_data *, int, int);
-void	virt_setnna		(struct context_data *, int, int);
-void	virt_pastnote		(struct context_data *, int, int);
-void	virt_setvol		(struct context_data *, int, int);
-void	virt_voicepos		(struct context_data *, int, int);
-int	virt_getvoicepos	(struct context_data *, int);
-void	virt_setbend		(struct context_data *, int, int);
-void	virt_setpan		(struct context_data *, int, int);
-void	virt_seteffect		(struct context_data *, int, int, int);
-int	virt_cstat		(struct context_data *, int);
-int	virt_mapchannel		(struct context_data *, int);
-void	virt_resetchannel	(struct context_data *, int);
-void	virt_resetvoice		(struct context_data *, int, int);
-void	virt_reset		(struct context_data *);
-int	virt_getroot		(struct context_data *, int);
-
+int	libxmp_virt_cvt8bit	(void);
+void	libxmp_virt_setnote	(struct context_data *, int, int);
+void	libxmp_virt_setsmp	(struct context_data *, int, int);
+void	libxmp_virt_setnna	(struct context_data *, int, int);
+void	libxmp_virt_pastnote	(struct context_data *, int, int);
+void	libxmp_virt_setvol	(struct context_data *, int, int);
+void	libxmp_virt_voicepos	(struct context_data *, int, double);
+double	libxmp_virt_getvoicepos	(struct context_data *, int);
+void	libxmp_virt_setperiod	(struct context_data *, int, double);
+void	libxmp_virt_setpan	(struct context_data *, int, int);
+void	libxmp_virt_seteffect	(struct context_data *, int, int, int);
+int	libxmp_virt_cstat	(struct context_data *, int);
+int	libxmp_virt_mapchannel	(struct context_data *, int);
+void	libxmp_virt_resetchannel(struct context_data *, int);
+void	libxmp_virt_resetvoice	(struct context_data *, int, int);
+void	libxmp_virt_reset	(struct context_data *);
+void	libxmp_virt_release	(struct context_data *, int, int);
+int	libxmp_virt_getroot	(struct context_data *, int);
 
 #endif /* LIBXMP_VIRTUAL_H */
diff --git a/src/win32/Makefile b/src/win32/Makefile
deleted file mode 100644
index 507dc7b..0000000
--- a/src/win32/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-
-WIN32_OBJS	= ptpopen.o debug.o
-WIN32_DFILES	= Makefile $(WIN32_OBJS:.o=.c) unistd.h ptpopen.h \
-		  osdcomm.h sys
-WIN32_PATH	= src/win32
-
-ifeq ($(PLATFORM_DIR),win32)
-OBJS += $(addprefix $(WIN32_PATH)/,$(WIN32_OBJS))
-CLEAN += $(addprefix $(WIN32_PATH)/,$(WIN32_CLEAN))
-endif
-
-dist-win32:
-	mkdir -p $(DIST)/$(WIN32_PATH)
-	cp -RPp $(addprefix $(WIN32_PATH)/,$(WIN32_DFILES)) $(DIST)/$(WIN32_PATH)
-
-W_OBJS		= $(addprefix $(WIN32_PATH)/,$(WIN32_OBJS))
-
diff --git a/src/win32/sys/Makefile b/src/win32/sys/Makefile
deleted file mode 100644
index 43de7c6..0000000
--- a/src/win32/sys/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-
-TOPDIR	= ../../..
-OBJS	=
-DFILES	= Makefile time.h
-DDIRS	=
-CFILES	=
-DCFILES	=
-
-all:
-
-include $(TOPDIR)/Makefile.rules
-
diff --git a/test/Makefile b/test/Makefile
deleted file mode 100644
index 3660bb9..0000000
--- a/test/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-
-TEST_OBJS	= test.o md5.o
-TEST_DFILES	= Makefile $(TEST_OBJS:.o=.c) test.itz md5.h
-TEST_PATH	= test
-
-T_OBJS = $(addprefix $(TEST_PATH)/,$(TEST_OBJS))
-
-default:
-	$(MAKE) -C .. check
-
-dist-test:
-	mkdir -p $(DIST)/$(TEST_PATH)
-	cp -RPp $(addprefix $(TEST_PATH)/,$(TEST_DFILES)) $(DIST)/$(TEST_PATH)
-
-check: $(TEST_PATH)/libxmp-test
-	cd $(TEST_PATH); LD_LIBRARY_PATH=../lib DYLD_LIBRARY_PATH=../lib LIBRARY_PATH=../lib:$$LIBRARY_PATH PATH=$$PATH:../lib ./libxmp-test
-
-$(TEST_PATH)/libxmp-test: $(T_OBJS)
-	@CMD='$(LD) -o $@ $(T_OBJS) $(LIBS) -Llib -lxmp'; \
-	if [ "$(V)" -gt 0 ]; then echo $$CMD; else echo LD $@ ; fi; \
-	eval $$CMD
-
diff --git a/test/md5.c b/test/md5.c
deleted file mode 100644
index 1b49326..0000000
--- a/test/md5.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest.	This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- */
-
-#include 
-#include 
-#include "../src/common.h"
-#include "md5.h"
-
-#define PUT_64BIT_LE(cp, value) do {					\
-	(cp)[7] = (value) >> 56;					\
-	(cp)[6] = (value) >> 48;					\
-	(cp)[5] = (value) >> 40;					\
-	(cp)[4] = (value) >> 32;					\
-	(cp)[3] = (value) >> 24;					\
-	(cp)[2] = (value) >> 16;					\
-	(cp)[1] = (value) >> 8;						\
-	(cp)[0] = (value); } while (0)
-
-#define PUT_32BIT_LE(cp, value) do {					\
-	(cp)[3] = (value) >> 24;					\
-	(cp)[2] = (value) >> 16;					\
-	(cp)[1] = (value) >> 8;						\
-	(cp)[0] = (value); } while (0)
-
-static uint8 PADDING[MD5_BLOCK_LENGTH] = {
-	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
-	( w += f(x, y, z) + data,  w = w<>(32-s),  w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data.  MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-static void MD5Transform(uint32 state[4], const uint8 block[MD5_BLOCK_LENGTH])
-{
-	uint32 a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-	memcpy(in, block, sizeof(in));
-#else
-	for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
-		in[a] = (uint32)(
-		    (uint32)(block[a * 4 + 0]) |
-		    (uint32)(block[a * 4 + 1]) <<  8 |
-		    (uint32)(block[a * 4 + 2]) << 16 |
-		    (uint32)(block[a * 4 + 3]) << 24);
-	}
-#endif
-
-	a = state[0];
-	b = state[1];
-	c = state[2];
-	d = state[3];
-
-	MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478,  7);
-	MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
-	MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
-	MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
-	MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf,  7);
-	MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
-	MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
-	MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
-	MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8,  7);
-	MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
-	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
-	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
-	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122,  7);
-	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
-	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
-	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
-	MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562,  5);
-	MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340,  9);
-	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
-	MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
-	MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d,  5);
-	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453,  9);
-	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
-	MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
-	MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6,  5);
-	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6,  9);
-	MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
-	MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
-	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
-	MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8,  9);
-	MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
-	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
-	MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942,  4);
-	MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
-	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
-	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
-	MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44,  4);
-	MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
-	MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
-	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
-	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
-	MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
-	MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
-	MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
-	MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039,  4);
-	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
-	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
-	MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
-
-	MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244,  6);
-	MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
-	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
-	MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
-	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3,  6);
-	MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
-	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
-	MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
-	MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f,  6);
-	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
-	MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
-	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
-	MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82,  6);
-	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
-	MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
-	MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
-
-	state[0] += a;
-	state[1] += b;
-	state[2] += c;
-	state[3] += d;
-}
-
-/*
- * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void MD5Init(MD5_CTX *ctx)
-{
-	ctx->count = 0;
-	ctx->state[0] = 0x67452301;
-	ctx->state[1] = 0xefcdab89;
-	ctx->state[2] = 0x98badcfe;
-	ctx->state[3] = 0x10325476;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len)
-{
-	size_t have, need;
-
-	/* Check how many bytes we already have and how many more we need. */
-	have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
-	need = MD5_BLOCK_LENGTH - have;
-
-	/* Update bitcount */
-	ctx->count += (uint64)len << 3;
-
-	if (len >= need) {
-		if (have != 0) {
-			memcpy(ctx->buffer + have, input, need);
-			MD5Transform(ctx->state, ctx->buffer);
-			input += need;
-			len -= need;
-			have = 0;
-		}
-
-		/* Process data in MD5_BLOCK_LENGTH-byte chunks. */
-		while (len >= MD5_BLOCK_LENGTH) {
-			MD5Transform(ctx->state, input);
-			input += MD5_BLOCK_LENGTH;
-			len -= MD5_BLOCK_LENGTH;
-		}
-	}
-
-	/* Handle any remaining bytes of data. */
-	if (len != 0)
-		memcpy(ctx->buffer + have, input, len);
-}
-
-/*
- * Pad pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-static void MD5Pad(MD5_CTX *ctx)
-{
-	uint8 count[8];
-	size_t padlen;
-
-	/* Convert count to 8 bytes in little endian order. */
-	PUT_64BIT_LE(count, ctx->count);
-
-	/* Pad out to 56 mod 64. */
-	padlen = MD5_BLOCK_LENGTH -
-	    ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
-	if (padlen < 1 + 8)
-		padlen += MD5_BLOCK_LENGTH;
-	MD5Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
-	MD5Update(ctx, count, 8);
-}
-
-/*
- * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
- */
-void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
-{
-	int i;
-
-	MD5Pad(ctx);
-	if (digest != NULL) {
-		for (i = 0; i < 4; i++)
-			PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
-		memset(ctx, 0, sizeof(*ctx));
-	}
-}
-
diff --git a/test/md5.h b/test/md5.h
deleted file mode 100644
index a3ec713..0000000
--- a/test/md5.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest.  This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- */
-
-#ifndef LIBXMP_MD5_H
-#define LIBXMP_MD5_H
-
-#include "common.h"
-
-#define	MD5_BLOCK_LENGTH		64
-#define	MD5_DIGEST_LENGTH		16
-#define	MD5_DIGEST_STRING_LENGTH	(MD5_DIGEST_LENGTH * 2 + 1)
-
-typedef struct MD5Context {
-	uint32 state[4];		/* state */
-	uint64 count;			/* number of bits, mod 2^64 */
-	uint8 buffer[MD5_BLOCK_LENGTH];	/* input buffer */
-} MD5_CTX;
-
-void	 MD5Init(MD5_CTX *);
-void	 MD5Update(MD5_CTX *, const unsigned char *, size_t);
-void	 MD5Final(uint8[MD5_DIGEST_LENGTH], MD5_CTX *);
-
-#endif /* LIBXMP_MD5_H */
-
diff --git a/test/test.c b/test/test.c
deleted file mode 100644
index d633cca..0000000
--- a/test/test.c
+++ /dev/null
@@ -1,118 +0,0 @@
-#include 
-#include 
-#include 
-#include "md5.h"
-#include "xmp.h"
-
-static inline int is_big_endian() {
-	unsigned short w = 0x00ff;
-	return (*(char *)&w == 0x00);
-}
-
-/* Convert little-endian 16 bit samples to big-endian */
-static void convert_endian(unsigned char *p, int l)
-{
-	unsigned char b;
-	int i;
-
-	for (i = 0; i < l; i++) {
-		b = p[0];
-		p[0] = p[1];
-		p[1] = b;
-		p += 2;
-	}
-}
-
-static int compare_md5(unsigned char *d, char *digest)
-{
-	int i;
-
-	/*for (i = 0; i < 16 ; i++)
-		printf("%02x", d[i]);
-	printf("\n");*/
-
-	for (i = 0; i < 16 && *digest; i++, digest += 2) {
-		char hex[3];
-		hex[0] = digest[0];
-		hex[1] = digest[1];
-		hex[2] = 0;
-
-		if (d[i] != strtoul(hex, NULL, 16))
-			return -1;
-	}
-
-	return 0;
-}
-
-int main()
-{
-	int ret;
-	xmp_context c;
-	struct xmp_frame_info info;
-	long time;
-	unsigned char digest[16];
-	MD5_CTX ctx;
-
-	c = xmp_create_context();
-	if (c == NULL)
-		goto err;
-
-	ret = xmp_load_module(c, "test.itz");
-	if (ret != 0) {
-		printf("can't load module\n");
-		goto err;
-	}
-
-	xmp_get_frame_info(c, &info);
-	if (info.total_time != 4800) {
-		printf("estimated replay time error\n");
-		goto err;
-	}
-
-	xmp_start_player(c, 22050, 0);
-	xmp_set_player(c, XMP_PLAYER_MIX, 100);
-	xmp_set_player(c, XMP_PLAYER_INTERP, XMP_INTERP_SPLINE);
-
-	printf("Testing ");
-	fflush(stdout);
-	time = 0;
-
-	MD5Init(&ctx);
-
-	while (1) {
-		xmp_play_frame(c);
-		xmp_get_frame_info(c, &info);
-		if (info.loop_count > 0)
-			break;
-
-		time += info.frame_time;
-
-		if (is_big_endian())
-			convert_endian(info.buffer, info.buffer_size >> 1);
-
-		MD5Update(&ctx, info.buffer, info.buffer_size);
-
-		printf(".");
-		fflush(stdout);
-	}
-
-	MD5Final(digest, &ctx);
-
-	if (compare_md5(digest, "7e39451c7e14938c41b146eb23943056") < 0) {
-		printf("rendering error\n");
-		goto err;
-	}
-
-	if (time / 1000 != info.total_time) {
-		printf("replay time error\n");
-		goto err;
-	}
-
-	printf(" pass\n");
-
-	exit(0);
-
-    err:
-	printf(" fail\n");
-	exit(1);
-}
diff --git a/test/test.itz b/test/test.itz
deleted file mode 100644
index 1906cd6..0000000
Binary files a/test/test.itz and /dev/null differ